Справочник функций

Ваш аккаунт

Логин:
Пароль:
Забыли пароль?
Регистрация
Информацию о новых материалах можно получать и без регистрации:
Убрать блок ВКонтакте навсегда

Последние темы форума

Показать новые сообщения »

Почтовая рассылка



Подписчиков: 19017
Последний выпуск: 23.04.2012

Модуль mtasks.asm

Установка новых прерываний, реализация многозадачности.

;# Тут мы получаем старые вектора ############################################
PROC           getvectors
               ; Сохраняем 08h и 20h прерывания
   IFDEF GlukOS   ;--- Для ГлюкОСы
               call    _di
               push    ds
               xor     bx,bx
               mov     ds,bx
               mov     bx,[ds:0020h]
               mov     es,[ds:0022h]
               mov     [cs:oldseg08],es
               mov     [cs:oldofs08],bx
               mov     bx,[ds:0080h]
               mov     es,[ds:0082h]
               mov     [cs:oldseg20],es
               mov     [cs:oldofs20],bx
               pop     ds
               call    _ei
               ret
   ELSE        ;--- Для ДОСа
               mov     ah,035h
               mov     al,008h
               int     021h
               mov     [cs:oldseg08],es
               mov     [cs:oldofs08],bx
               mov     ah,035h
               mov     al,020h
               int     021h
               mov     [cs:oldseg20],es
               mov     [cs:oldofs20],bx
               ret
   ENDIF       ;--- GlukOS
ENDP           getvectors
;# Тут мы вешаем новые - свои прерывания #####################################
PROC           setvectors
               ; Вешаемся на 08h и 20h прерывания
   IFDEF GlukOS   ;--- Для ГлюкОСы
               call    _di
               push    ds
               xor     bx,bx
               mov     ds,bx
               lea     bx,[cs:kernel]
               mov     [ds:0020h],bx
               mov     [ds:0022h],cs
               lea     bx,[newint20]
               mov     [ds:0080h],bx
               mov     [ds:0082h],cs
               pop     ds
               call    _ei
               ret
   ELSE        ;--- Для ДОСа
               push    ds
               mov     ax,cs
               mov     ds,ax
               lea     dx,[kernel]
               mov     ah,025h
               mov     al,008h
               int     021h
               ; Вешаемся на 20h прерывание
               mov     ax,cs
               mov     ds,ax
               lea     dx,[newint20]
               mov     ah,025h
               mov     al,020h
               int     021h
               pop     ds
               ret
   ENDIF       ;--- GlukOS
ENDP           setvectors
;# Тут мы восстанавливаем старoе прерывания ##################################
PROC           restorevectors
               ; Восстанавлмваем 08h и 20h прерывания
   IFDEF GlukOS   ;--- Для ГлюкОСы
               call    _di
               push    ds
               xor     bx,bx
               mov     ds,bx
               mov     es,[cs:oldseg08]
               mov     bx,[cs:oldofs08]
               mov     [ds:0020h],bx
               mov     [ds:0022h],es
               mov     es,[cs:oldseg20]
               mov     bx,[cs:oldofs20]
               mov     [ds:0080h],bx
               mov     [ds:0082h],es
               pop     ds
               call    _ei
               ret
   ELSE        ;--- Для ДОСа
               push  ds
               mov   ax,[cs:oldseg08]
               mov   ds,ax
               mov   dx,[cs:oldofs08]
               mov   ah,025h
               mov   al,008h
               int   021h
               mov   ax,[cs:oldseg20]
               mov   ds,ax
               mov   dx,[cs:oldofs20]
               mov   ah,025h
               mov   al,020h
               int   021h
               pop   ds
               ret
   ENDIF       ;--- GlukOS
ENDP           restorevectors
; # Переменные в кодовом сегменте ############################################
oldofs08       DW    ?
oldseg08       DW    ?
oldofs20       DW    ?
oldseg20       DW    ?
int08          DW    1                   ; Стоит ли переключать задачи ???
; # Разрешаем переключать задачи #############################################
PROC           _ei
               mov   [Word Ptr cs:int08],1
               ret
ENDP           _ei
; # Запрещаем переключать задачи #############################################
PROC           _di
               mov   [Word Ptr cs:int08],0
               ret
ENDP          _di
;# Прерывание 020h ###########################################################
PROC           newint20                  ; Прерывание 020h (выгрузка задачи)
               call  _di
               pop   ax                  ;¬
               pop   ax                  ;¦ Достаем всякое дерьмо из стека
               pop   ax                  ;+
               push  cs
               pop   ds
               lea   di,[cs:firsttask]   ; DI = Адрес начала структуры TTASK
               mov   al,[cs:numtask]     ; AL = Номер задачи
               xor   ah,ah               ; AX = Номер задачи
               push  dx
                mov   dx,515
                mul   dx                 ; AX = Смещения от начала firsttask
               pop   dx
               add   di,ax               ; DI = Абсолютное смещение вершины
                                         ; стека в структуре TTASK
               mov   [Byte Ptr cs:di],255
               mov   dx,[cs:di+3]
               call    FreeMemory
               call  _ei
               jmp   int08new
ENDP           newint20
;# Прерывание 008h ###########################################################
PROC           kernel                   ; Прерывание 008h
               pushf
               call  [Dword Ptr cs:oldofs08]
               push  di
               push  bx
               push  ax
               push  es
               push  ds
               push  si
               cmp   [cs:int08],0        ;¬ Если нельзя переключать задачи,
               je    kernelend           ;+    то не переключаем их.
               mov   si,sp               ;¬
               mov   ax,ss               ;¦ ES:SI=SS:SP
               mov   es,ax               ;+
               ; Инитим DS
               push  cs
               pop   ds
               ; Ищем стек задачи
               lea   di,[ds:firsttask]   ; DI = Адрес начала структуры TTASK
               mov   al,[ds:numtask]     ; AL = Номер задачи
               xor   ah,ah               ; AX = Номер задачи
               push  dx
                mov   dx,515
                mul   dx                  ; AX = Смещения от начала firsttask
               pop   dx
               add   di,ax               ; DI = Абсолютное смещение вершины
                                         ; стека в структуре TTASK
               mov   [Word Ptr ds:di+5],ss
               mov   [Word Ptr ds:di+7],sp
               ; С учетом приоритетов -------------------¬
               dec   [Word Ptr ds:di+9]                ; ¦
               cmp   [Word Ptr ds:di+9],0              ; ¦
               jne   kernelend                         ; ¦
               mov   ax,[Word Ptr ds:di+11]            ; ¦
               mov   [Word Ptr ds:di+9],ax             ;--
kernel_01:     add   di,515              ;¬SP=DI+515
               mov   sp,di               ;-
               mov   ax,ds               ;¬SS=DS
               mov   ss,ax               ;-
               ; Сохранаяем 'остальные' регистры в структуре TTASK
               push  si                  ; SP
               push  es                  ; SS
               push  cx                  ; CX
               push  dx                  ; DX
               push  bp                  ; BP
               ; Ещем следующую задачу
int08new:      xor   ax,ax
               mov   al,[ds:numtask]
nexttask:      inc   al                  ;_следующую_
               lea   di,[ds:firsttask]
               cmp   al,9
               jne   int201
               xor   ax,ax
int201:        push  ax
                mov   dx,515
                mul   dx
                add   di,ax               ; DI = Абсолютное смещение вершины
                                          ; стека в структуре TTASK
               pop   ax
               cmp   [Byte Ptr ds:di],255
               je    nexttask
               cmp   [Byte Ptr ds:di],254 ; Приостановленная задача
               je    nexttask
               mov   [ds:numtask],al
               mov   ax,di
               add   ax,(515-10)
               mov   sp,ax               ; В SP имеем стек (тот что в структуре
                                         ; TTASK) следующей задачи
               push  ds
               pop   ss
               ; Востанавливаем оттуда 'остальные' регистры следующей задачи
               pop   bp
               pop   dx
               pop   cx
               pop   es
               pop   si
               ; SS:SP теперь должны указывать на реальный стек задачи
               mov   ax,es  ;¬
               mov   ss,ax  ;¦ SS:SP=ES:SI
               mov   sp,si  ;-
kernelend:     pop   si
               pop   ds
               pop   es
               pop   ax
               pop   bx
               pop   di
               push  ax
               mov   al,20h
               out   20h,al
               pop   ax
               iret
ENDP           kernel
; Инициализируем дескрипторы задач ###########################################
PROC           inittasks
               mov   [Byte Ptr cs:firsttask],0
               mov   [Byte Ptr cs:tasknum],0
               mov   [Byte Ptr cs:numtask],0
               lea   si,[tasks]
               mov   cx,8
it1:           mov   [Byte Ptr cs:si],255
               mov   [Byte Ptr cs:si+1],254
               add   si,515
               loop  it1
               ret
ENDP           inittasks

Оставить комментарий

Оставлять комментарии могут только зарегистрированные пользователи.

Если вы не являетесь зарегистрированным пользователем, то вам необходимо зарегистрироваться. Регистрация бесплатна. Если вы уже зарегистрированы на CodeNet, то вам необходимо ввести логин и пароль в верхней (Alt-U) части страницы.

Реклама на сайте | Обмен ссылками | Ссылки | Экспорт (RSS) | Контакты
Добавить статью | Добавить исходник | Добавить хостинг-провайдера | Добавить сайт в каталог