Защищенный режим процессоров Intel


Программа, которая работает с прерываниями - часть 7


code ..... Press any key... " CODESEG ; ----------------------------------------------- ; Вывод на экран номера исключения, кода ошибки, ; дампа регистров и возврат в реальный режим. ; ----------------------------------------------- PROC shutdown NEAR call rdump ; дамп регистров процессора push ax call beep ; звуковой сигнал ; Выводим сообщение об исключении mov ax,[vir_crt] mov es,ax mov bx,1d mov ax,4 mov si,OFFSET exc_msg mov dh,74h mov cx, SIZE exc_msg call writexy pop ax mov bx, 040bh ; номер исключения call Print_Word pop ax mov bx, 0420h ; код ошибки call Print_Word pop ax mov bx, 0416h ; смещение call Print_Word pop ax mov bx, 0411h ; селектор call Print_Word call set_rmode ; возвращаемся в реальный режим mov ax, 0 ; ожидаем нажатия на клавишу int 16h mov bh, 07h call clrscr mov ah,4Ch int 21h ENDP shutdown ; ------------------------------------------------- ; Перепрограммирование контроллера прерываний ; На входе: DX - порт контроллера прерывания ; AH - начальный номер прерывания ; ------------------------------------------------- PROC set_int_ctrlr NEAR mov al,11 out dx,al jmp SHORT $+2 mov al,ah inc dx out dx,al jmp SHORT $+2 mov al,4 out dx,al jmp SHORT $+2 mov al,1 out dx,al jmp SHORT $+2 mov al,0ff out dx,al dec dx ret ENDP set_int_ctrlr ; ------------------------------- ; Разрешение линии A20 ; ------------------------------- PROC enable_a20 NEAR mov al,A20_PORT out STATUS_PORT,al mov al,A20_ON out KBD_PORT_A,al ret ENDP enable_a20 ; ------------------------------- ; Запрещение линии A20 ; ------------------------------- PROC disable_a20 NEAR mov al,A20_PORT out STATUS_PORT,al mov al,A20_OFF out KBD_PORT_A,al ret ENDP disable_a20 ; ---------- Обработчик аппаратных прерываний IRQ2-IRQ7 PROC dummy_iret0 NEAR push ax ; Посылаем сигнал конца прерывания в первый контроллер 8259A mov al,EOI out MASTER8259A,al pop ax iret ENDP dummy_iret0 ; ---------- Обработчик аппаратных прерываний IRQ8-IRQ15 PROC dummy_iret1 NEAR push ax ; Посылаем сигнал конца прерывания в первый ; и второй контроллеры 8259A mov al,EOI out MASTER8259A,al out SLAVE8259A,al pop ax iret ENDP dummy_iret1 ; ------------------------------------------ ; Процедура выдаёт короткий звуковой сигнал ; ------------------------------------------ PROC beep NEAR push ax bx cx in al,KBD_PORT_B push ax mov cx,80 beep0: push cx and al,11111100b out KBD_PORT_B,al mov cx,60 idle1: loop idle1 or al,00000010b out KBD_PORT_B,al mov cx,60 idle2: loop idle2 pop cx loop beep0 pop ax out KBD_PORT_B,al pop cx bx ax ret ENDP beep ; ------------------------------------------------ ; Процедура задерживает выполнение программы ; на некоторое время, зависящее от быстродействия ; процессора. ; ------------------------------------------------ PROC pause NEAR push cx mov cx,10 ploop0: push cx xor cx,cx ploop1: loop ploop1 pop cx loop ploop0 pop cx ret ENDP pause ; ------------------------------------------ ; Процедуры для работы с клавиатурой ; ------------------------------------------ DATASEG key_flag db 0 key_code dw 0 ext_scan db 0 keyb_status dw 0 CODESEG ; ---------------------------------------------- ; Обработчик аппаратного прерывания клавиатуры ; ---------------------------------------------- PROC Keyb_int NEAR call beep ; выдаём звуковой сигнал push ax mov al, [ext_scan] ; расширенный скан-код cmp al, 0 ; или обычный ? jz normal_scan1 ; --------- обработка расширенного скан-кода ------------- cmp al, 0e1h ; это клавиша <Pause>? jz pause_key in al, 60h ; вводим скан-код cmp al, 2ah ; игнорируем префикс 2Ah jz intkeyb_exit_1 cmp al, 0aah ; игнорируем отпускание jz intkeyb_exit_1 ; клавиш mov ah, [ext_scan] ; записываем скан-код и call Keyb_PutQ ; расширенный скан-код ; в "очередь", состоящую ; из одного слова mov al, 0 ; сбрасываем признак mov [ext_scan], al ; получения расширенного jmp intkeyb_exit ; скан-кода pause_key: ; обработка клавиши <Pause> in al, 60h ; вводим скан-код cmp al, 0c5h ; если это код <Pause>, jz pause_key1 ; записываем его в очередь, cmp al, 45h ; иначе игнорируем jz pause_key1 jmp intkeyb_exit pause_key1: mov ah, [ext_scan] ; запись в очередь call Keyb_PutQ ; кода клавиши <Pause> mov al, 0 ; сбрасываем признак mov [ext_scan], al ; получения расширенного jmp intkeyb_exit ; скан-кода ; --------- обработка обычного скан-кода ------------- normal_scan1: in al, 60h ; вводим скан-код cmp al, 0feh ; игнорируем FEh jz intkeyb_exit cmp al, 0e1h ; расширенный скан-код? jz ext_key ; если да, то на обработку ; расширенного скан-кода cmp al, 0e0h jnz normal_scan ext_key: mov [ext_scan], al ; устанавливаем признак jmp intkeyb_exit ; расширенного скан-кода ; Сброс признака расширенного скан-кода и выход intkeyb_exit_1: mov al, 0 mov [ext_scan], al jmp intkeyb_exit ; Запись нормального скан-кода в очередь и выход normal_scan: mov ah, 0 call Keyb_PutQ intkeyb_exit: in al, 61h ; разблокируем клавиатуру mov ah, al or al, 80h out 61h, al xchg ah, al out 61h, al mov al,EOI ; посылаем сигнал конца out MASTER8259A,al ; прерывания pop ax sti iret ENDP Keyb_int ; --------------------------------------------------- ; Запись скан-кода и расширенного скан-кода в ; "буфер", состоящий из одного слова. ; --------------------------------------------------- PROC Keyb_PutQ NEAR push ax mov [key_code], ax ; записываемый код ; ------- Обрабатываем переключающие клавиши --------- cmp ax, 002ah ; L_SHIFT down jnz @@kb1 mov ax, [keyb_status] or ax, L_SHIFT mov [keyb_status], ax jmp keyb_putq_exit @@kb1: cmp ax, 00aah ; L_SHIFT up jnz @@kb2 mov ax, [keyb_status] and ax, NL_SHIFT mov [keyb_status], ax jmp keyb_putq_exit @@kb2: cmp ax, 0036h ; R_SHIFT down jnz @@kb3 mov ax, [keyb_status] or ax, R_SHIFT mov [keyb_status], ax jmp keyb_putq_exit @@kb3: cmp ax, 00b6h ; R_SHIFT up jnz @@kb4 mov ax, [keyb_status] and ax, NR_SHIFT mov [keyb_status], ax jmp keyb_putq_exit @@kb4: cmp ax, 001dh ; L_CTRL down jnz @@kb5 mov ax, [keyb_status] or ax, L_CTRL mov [keyb_status], ax jmp keyb_putq_exit @@kb5: cmp ax, 009dh ; L_CTRL up jnz @@kb6 mov ax, [keyb_status] and ax, NL_CTRL mov [keyb_status], ax jmp keyb_putq_exit @@kb6: cmp ax, 0e01dh ; R_CTRL down jnz @@kb7 mov ax, [keyb_status] or ax, R_CTRL mov [keyb_status], ax jmp keyb_putq_exit @@kb7: cmp ax, 0e09dh ; R_CTRL up jnz @@kb8 mov ax, [keyb_status] and ax, NR_CTRL mov [keyb_status], ax jmp keyb_putq_exit @@kb8: cmp ax, 0038h ; L_ALT down jnz @@kb9 mov ax, [keyb_status] or ax, L_ALT mov [keyb_status], ax jmp keyb_putq_exit @@kb9: cmp ax, 00b8h ; L_ALT up jnz @@kb10 mov ax, [keyb_status] and ax, NL_ALT mov [keyb_status], ax jmp keyb_putq_exit @@kb10: cmp ax, 0e038h ; R_ALT down jnz @@kb11 mov ax, [keyb_status] or ax, R_ALT mov [keyb_status], ax jmp keyb_putq_exit @@kb11: cmp ax, 0e0b8h ; R_ALT up jnz @@kb12 mov ax, [keyb_status] and ax, NR_ALT mov [keyb_status], ax jmp keyb_putq_exit @@kb12: cmp ax, 003ah ; CAPS_LOCK up jnz @@kb13 mov ax, [keyb_status] xor ax, CAPS_LOCK mov [keyb_status], ax jmp keyb_putq_exit @@kb13: cmp ax, 00bah ; CAPS_LOCK down jnz @@kb14 jmp keyb_putq_exit @@kb14: cmp ax, 0046h ; SCR_LOCK up jnz @@kb15 mov ax, [keyb_status] xor ax, SCR_LOCK mov [keyb_status], ax jmp keyb_putq_exit @@kb15: cmp ax, 00c6h ; SCR_LOCK down jnz @@kb16 jmp keyb_putq_exit @@kb16: cmp ax, 0045h ; NUM_LOCK up jnz @@kb17 mov ax, [keyb_status] xor ax, NUM_LOCK mov [keyb_status], ax jmp keyb_putq_exit @@kb17: cmp ax, 00c5h ; NUM_LOCK down jnz @@kb18 jmp keyb_putq_exit @@kb18: cmp ax, 0e052h ; INSERT up jnz @@kb19 mov ax, [keyb_status] xor ax, INSERT mov [keyb_status], ax jmp keyb_putq_exit @@kb19: cmp ax, 0e0d2h ; INSERT down jnz @@kb20 jmp keyb_putq_exit @@kb20: test ax, 0080h ; фильтруем отжатия клавиш jnz keyb_putq_exit mov al, 0ffh ; устанавиваем признак mov [key_flag], al ; готовности для чтения ; символа из "буфера" keyb_putq_exit: pop ax ret ENDP Keyb_PutQ ; ----------------------------------------------------- ; Программное прерывание, предназначенное для чтения ; символа из буфера клавиатуры.


Начало  Назад  Вперед