резидентный обработчик

Тема в разделе "WASM.ELECTRONICS", создана пользователем slip11, 1 май 2007.

  1. slip11

    slip11 New Member

    Публикаций:
    0
    Регистрация:
    17 апр 2007
    Сообщения:
    12
    В резидентном обработчике при нажатии ctrl-alt-del блокируется клавиатура(устанавливается в 1 переменная block_status) и выводится сообщение о блокировке, а при нажатии ctrl-alt-esc клавиатура разблокируется(переменная block_status устанавливается в 0) и сообщение о блокировке стирается. Так вот когда под досом запускаю прогу реакции на нажатия клавиш ни какой(на экране ничего не высвечивается и нет реакции на клавиши блокировки или разблокировки).
    Вот исходник:
    Код (Text):
    1. .model tiny
    2. prg segment para public 'code'
    3. assume cs:prg,ss:prg,es:prg,ds:prg
    4. org 100h
    5.  
    6.     ctrl_key        equ     04h             ;скан-коды клавиш
    7.     alt_key         equ     08h
    8.     del_key         equ     53h
    9.     keyb_port       equ     60h
    10.     esc_key         equ     01h
    11.     EOI         equ     20h
    12.     PIC8259         equ     20h
    13.    
    14.    
    15.     start:
    16.         jmp setup                       ;установка резидентной программы
    17.        
    18.         int9_handler proc far
    19.             sti
    20.             pushf
    21.             push ax                            
    22.             push di                        
    23.             push es                        
    24.            
    25.         L1:
    26.             mov ax,40h                      ;проверка байта 0040:0017h
    27.             mov es,ax
    28.             mov di,17h
    29.            
    30.             mov ah,es:[di]              ;в ah находится байт 0040:0017h
    31.             pop es
    32.            
    33.         L2:
    34.             test ah,ctrl_key                ;нажата ли клавиша ctrl
    35.             jz check_block              ;нет? проверка на блокировку
    36.                                     ;если да,то
    37.             test ah,alt_key             ;нажата ли клавиша alt
    38.             jz check_block              ;нет? проверка на блокировку    
    39.                                     ;да? проверка на нажатие esc
    40.         check_esc:                      ;нажата ли клавиша esc
    41.             in al,keyb_port
    42.             cmp al,esc_key
    43.             jne check_del               ;нет? нажата ли delete
    44.            
    45.            
    46.            
    47.             push es
    48.             mov bx,0B800h               ;стирание сообщения
    49.             mov es,bx
    50.             mov di,1960
    51.             mov cx,40
    52.             clear:
    53.                 mov byte ptr es:[di],''
    54.                 inc di
    55.                 inc di
    56.             loop clear
    57.             pop es
    58.            
    59.             xor ax,ax
    60.            
    61.             mov al,block_status         ;обнуляем блокировку
    62.             cmp al,0
    63.             je label1
    64.             mov al,0
    65.             mov block_status,al        
    66.  
    67.         label1:
    68.            
    69.             jmp L6
    70.            
    71.         check_del:                      ;нажата ли delete
    72.             in al,keyb_port
    73.             cmp al,del_key
    74.             jne check_block
    75.        
    76.             push cs             ;определение сегмента для message
    77.             pop ds
    78.                            
    79.             xor ax,ax
    80.             mov ah,0Ch
    81.             mov si,offset message
    82.             push es                        
    83.             mov bx,0B800h
    84.             mov es,bx
    85.             mov cx,40
    86.             mov di,1960
    87.             cld
    88.             scr:
    89.                     lodsb
    90.                 stosw                  
    91.             loop scr
    92.            
    93.             pop es
    94.            
    95.             xor ax,ax
    96.            
    97.             mov al,block_status
    98.             cmp al,1
    99.             je label2
    100.             mov al,1
    101.             mov block_status,al
    102.        
    103.         label2:
    104.                                    
    105.             jmp L6
    106.            
    107.         check_block:
    108.             mov al,block_status
    109.             cmp al,0
    110.             je process 
    111.         L6:
    112.             pop di
    113.             pop ax         
    114.             in al,61h
    115.             mov ah,al
    116.             or al,80h
    117.             out 61h,al
    118.             xchg ah,al
    119.             out 61h,al
    120.             mov al,EOI
    121.             out PIC8259,al
    122.             iret           
    123.            
    124.             process:
    125.                 pop di
    126.                 pop ax
    127.                 popf
    128.                 jmp cs:[old_interrupt9]
    129.            
    130.         old_interrupt9  dd  ?
    131.         message         db "Keyboard is blocked! To unblock it press$"
    132.         block_status    db  0
    133.        
    134.         int9_handler endp
    135.        
    136.         end_ISR label byte
    137.        
    138.         setup:         
    139.            
    140.             mov ax,3509h
    141.             int 21h
    142.            
    143.             mov word ptr old_interrupt9,bx
    144.             mov word ptr old_interrupt9+2,es
    145.            
    146.             mov ax,2509h
    147.             mov dx,offset int9_handler
    148.             int 21h
    149.            
    150.             mov ax,3100h
    151.            
    152.             mov dx,offset end_ISR
    153.             mov cl,4
    154.             shr dx,cl
    155.            
    156.             inc dx
    157.            
    158.             int 21h
    159.     prg ends
    160.     end start
     
  2. wasm_test

    wasm_test wasm test user

    Публикаций:
    0
    Регистрация:
    24 ноя 2006
    Сообщения:
    5.582
    кстати, а это зачем?
     
  3. slip11

    slip11 New Member

    Публикаций:
    0
    Регистрация:
    17 апр 2007
    Сообщения:
    12
    Great это разрешает возникать прерываниям с более высшим приоритетом, например таймер.
     
  4. wasm_test

    wasm_test wasm test user

    Публикаций:
    0
    Регистрация:
    24 ноя 2006
    Сообщения:
    5.582
    у тебя кстати доступ к block_status идет по умолчанию через DS, значение которого не определено на входе в ISR
    пиши явно cs:block_status чтоли тогда

    или добавь в начало
    push ds

    push cs
    pop ds
    и
    pop ds
    в конец
     
  5. wasm_test

    wasm_test wasm test user

    Публикаций:
    0
    Регистрация:
    24 ноя 2006
    Сообщения:
    5.582
    попробовал собрать это творение и отладить в Bochs.
    в принципе с моими поправками работает, только разблокируется почему-то не по Ctrl-Alt-Esc, а просто по альту =)
    И сообщение не выводится.


    зы.
    можно заменить на rep stosw


    ззы. зачем ты вначале сохраняешь в стеке ax & di, если используешь гораздо больше регистров?) лучше бы pusha сделал
     
  6. slip11

    slip11 New Member

    Публикаций:
    0
    Регистрация:
    17 апр 2007
    Сообщения:
    12
    Great
    Поисправлял. Блокирует клаву, выводит сообщение о блокировке. Но не разблокирует


    Код (Text):
    1. .model tiny
    2. .286
    3. prg segment para public 'code'
    4. assume cs:prg,ss:prg,es:prg,ds:prg
    5. org 100h
    6.  
    7.     ctrl_key        equ     04h             ;скан-коды клавиш
    8.     alt_key     equ     08h
    9.     del_key     equ     53h
    10.     keyb_port       equ     60h
    11.     esc_key     equ     01h
    12.     EOI         equ     20h
    13.     PIC8259     equ     20h
    14.    
    15.    
    16.     start:
    17.         jmp setup                               ;установка резидентной программы
    18.        
    19.         int9_handler proc far
    20.             sti
    21.             pushf
    22.             pusha
    23.            
    24.             push ds
    25.             push cs
    26.             pop ds
    27.                                
    28.            
    29.         L1:
    30.             mov ax,40h                      ;проверка байта 0040:0017h
    31.             mov es,ax
    32.             mov di,17h
    33.            
    34.             mov ah,es:[di]                      ;в ah находится байт 0040:0017h
    35.            
    36.         L2:
    37.             test ah,ctrl_key                        ;нажата ли клавиша ctrl
    38.             jz check_block                      ;нет? проверка на блокировку
    39.                                             ;если да,то
    40.             test ah,alt_key                     ;нажата ли клавиша alt
    41.             jz check_block                      ;нет? проверка на блокировку    
    42.                                             ;да? проверка на нажатие esc
    43.         check_esc:                              ;нажата ли клавиша esc
    44.             in al,keyb_port
    45.             cmp al,esc_key
    46.             jne check_del                       ;нет? нажата ли delete
    47.            
    48.             xor ax,ax
    49.             mov bx,0B800h                       ;стирание сообщения
    50.             mov es,bx
    51.             mov di,1960
    52.             mov cx,40
    53.             cld
    54.             rep stosw
    55.            
    56.             xor ax,ax
    57.        
    58.             mov al,0
    59.             mov block_status,al
    60.        
    61.            
    62.             jmp L6
    63.            
    64.            
    65.         check_del:                              ;нажата ли delete
    66.             in al,keyb_port
    67.             cmp al,del_key
    68.             jne check_block
    69.        
    70.                            
    71.             xor ax,ax
    72.             mov ah,0Ch
    73.             mov si,offset message                          
    74.             mov bx,0B800h
    75.             mov es,bx
    76.             mov cx,40
    77.             mov di,1960
    78.             cld
    79.             scr:
    80.                     lodsb
    81.                 stosw                  
    82.             loop scr
    83.            
    84.             xor ax,ax
    85.            
    86.             mov al,1
    87.             mov block_status,al
    88.                                        
    89.             jmp L6
    90.            
    91.         check_block:   
    92.             mov al,block_status
    93.             cmp al,0           
    94.             je process         
    95.                
    96.         L6:        
    97.             in al,61h
    98.             mov ah,al
    99.             or al,80h
    100.             out 61h,al
    101.             xchg ah,al
    102.             out 61h,al
    103.             mov al,EOI
    104.             out PIC8259,al
    105.             pop ds
    106.             popa
    107.             iret           
    108.            
    109.             process:
    110.                 pop ds
    111.                 popa
    112.                 popf
    113.                 jmp cs:[old_interrupt9]
    114.            
    115.         old_interrupt9  dd  ?
    116.         message         db "Keyboard is blocked! To unblock it press$"
    117.         block_status    db  0
    118.        
    119.         int9_handler endp
    120.        
    121.         end_ISR label byte
    122.        
    123.         setup:         
    124.            
    125.             mov ax,3509h
    126.             int 21h
    127.            
    128.             mov word ptr old_interrupt9,bx
    129.             mov word ptr old_interrupt9+2,es
    130.            
    131.             mov ax,2509h
    132.             mov dx,offset int9_handler
    133.             int 21h
    134.            
    135.             mov ax,3100h
    136.            
    137.             mov dx,offset end_ISR
    138.             mov cl,4
    139.             shr dx,cl
    140.            
    141.             inc dx
    142.            
    143.             int 21h
    144.     prg ends
    145.     end start
     
  7. wasm_test

    wasm_test wasm test user

    Публикаций:
    0
    Регистрация:
    24 ноя 2006
    Сообщения:
    5.582
    я это дело минут 40 отлаживал с Bochs'е и химичил с обработкой. так и не понял почему, но у меня блокируется по Ctrl-Delete, а разблокируется по Ctrl- или Alt-Esc

    кстати
    можно заменить одной проверкой типа test ah, ctrl_key + alt_key
     
  8. slip11

    slip11 New Member

    Публикаций:
    0
    Регистрация:
    17 апр 2007
    Сообщения:
    12
    По моему что-то с сегментами не то. Но вот что именно не могу понять. Блокировать, блокирует, но вот с разблокировкой нифига не получается. :dntknw:
     
  9. slip11

    slip11 New Member

    Публикаций:
    0
    Регистрация:
    17 апр 2007
    Сообщения:
    12
    Если у кого-то есть какие-то идеи по поводу исходника просьба высказываться :)
     
  10. wasm_test

    wasm_test wasm test user

    Публикаций:
    0
    Регистрация:
    24 ноя 2006
    Сообщения:
    5.582
    будет время отлажу в борще еще разок..
     
  11. Ultrin Faern

    Ultrin Faern New Member

    Публикаций:
    0
    Регистрация:
    25 июн 2006
    Сообщения:
    170
    1) Предлагаю вначале вызвать старую int 9, пусть все-таки нажатие нормально обработает, и флаги в состоянии клавиатуры исправит ;)

    2) Будете вызывать int 21 в аппаратном обработчике - прямая догрога к глюкисам. Перепишите все без использования int 21.
     
  12. slip11

    slip11 New Member

    Публикаций:
    0
    Регистрация:
    17 апр 2007
    Сообщения:
    12
    Great Ок. Заранее спасибо.
    Ultrin Faern
    Не понимаю как после вызова в начале стандартного обработчика можно будет потом заблокировать клаву? Обьясните по подробней.

    Вы имеете ввиду этот кусок кода?
    Код (Text):
    1. setup:         
    2.            
    3.             mov ax,3509h
    4.             int 21h
    5.            
    6.             mov word ptr old_interrupt9,bx
    7.             mov word ptr old_interrupt9+2,es
    8.            
    9.             mov ax,2509h
    10.             mov dx,offset int9_handler
    11.             int 21h
    12.            
    13.             mov ax,3100h
    14.            
    15.             mov dx,offset end_ISR
    16.             mov cl,4
    17.             shr dx,cl
    18.            
    19.             inc dx
    20.            
    21.             int 21h
    22.     prg ends
    23.     end start
    В самом обработчике я не вызываю int21h.
     
  13. slip11

    slip11 New Member

    Публикаций:
    0
    Регистрация:
    17 апр 2007
    Сообщения:
    12
    Все, разобрался. Если кому-то интересно,то ошибка была в том, что в начале обработчика прерывания не нужно сохранять флаги. Об этом я узнал на одном форуме. Странно, но почему то в тех книгах, которые я читал об этом не было сказано ни слова.
     
  14. wasm_test

    wasm_test wasm test user

    Публикаций:
    0
    Регистрация:
    24 ноя 2006
    Сообщения:
    5.582
    кстати ты вначале делаешь

    Код (Text):
    1. sti
    2. pushf
    3. pusha
    а в одной из веток

    Код (Text):
    1.             pop ds
    2.             popa
    3.             iret
    конечный код не противополжнен начальному.
    надо добавить popf перед iret'ом. или вообще выкинуть, как ты сказал, pushf.