4

I'm trying to write a simple program that will replace standard keyboard interrupt with a custom one that will decrement a variable. However, it won't work without a call to the old handler. Here is my interrupt handler:

handler proc
  push ax
  push di
  dec EF
  ;pushf      ;when these to instructions commented keyboard interrupts handling hangs
  ;call [OLD]
  mov al,20h
  out 20h,al
  pop di
  pop ax
  iret
handler endp

What actions I should also execute in my handler to make it works without calling the old handler?

Michael Petch
  • 46,082
  • 8
  • 107
  • 198
Filipp
  • 859
  • 1
  • 6
  • 20

2 Answers2

1
  1. You need to save DS on the stack and set it to the proper value for your program, then restore it before the iret.

  2. This part:

    mov al,20h
    out 20h,al
    

    acknowledges the interrupt. If you call the BIOS interrupt handler then you should not also do this, as the BIOS handler will do it.

Michael Slade
  • 13,802
  • 2
  • 39
  • 44
  • But it seems like acknowledgement is not working, because even if my handler contains only dec, out 20h to port 20h and iret then handler will be executed only first time and will not be called anymore. Maybe I should add anything else to it? – Filipp May 07 '12 at 20:16
1

You will not receive any further data from the keyboard until you read the current data from the keyboard buffer. Before sending the EOI to the PIC use

in al,60h

to read the scancode that is currently waiting to be processed. The reason calling the old interrupt handler works is because it does read the data waiting from the keyboard.

As was noted by Michael Slade, you need to concern yourself with the fact that the labels EF and OLD are accessed relative to the DS register. The value in DS can't be relied upon when reaching your interrupt handler. The only segment register guaranteed to be usable is CS since it is set based on the segment value of the interrupt vector in the Interrupt Vector Table (IVT). If you design the rest of your code so that the variables EF and OLD are in the same segment as the interrupt handler then you can override the segments on the memory operands this way:

dec cs:[EF]
pushf
call cs:[OLD]
Michael Petch
  • 46,082
  • 8
  • 107
  • 198