How do you properly set, and then reset, the keyboard ISR in DOS? (x86 assembly, real mode, 16 bit, with TASM)
I have the following assembly code which sets up my ISR for the keyboard. All it is supposed to do is print out a sentence each time a key is pressed, up to five times. Then it is supposed to exit.
It seems like the ISR is being installed correctly. It will print out a sentence each time a key is pressed (once for down, once for up). However, it appears as though I am uninstalling the ISR incorrectly as I'm unable to enter text into the DOS command line after running the program.
(I have updated the code below to store/restore DS in the ISR, read from port 60h, and handle EOI calls thanks to feedback received so far.)
.model small
.data
our_text db "Interrupt intercepted", 0dh, 0ah, "$"
old_int_seg dw 0
old_int_off dw 0
keyCount dw 0
.code
.startup
cli
mov ah, 035 ; get current keyboard int vector
mov al, 09h ; and save it, so we can restore it later
int 21h
mov [old_int_off], bx
mov bx, es
mov [old_int_seg], bx
mov ax, cs
mov ds, ax ; load data segment with code segment
;(the one we are in now)
mov ah, 25h ; Set Interrupt Vector Command
mov al, 9 ; Interrupt to replace
lea dx, ISR ;load dx with our interrupt address
int 21h
sti
mov ax,@data
mov ds,ax
infinite:
mov ax,keyCount[0]
cmp ax,5
jl infinite ;check for 5 presses
cli ;restore old interrupt
mov ax, [old_int_seg]
mov ds, ax
mov dx, [old_int_off]
mov ah, 25h
mov al, 09h
int 21h
sti
mov ah,4Ch ; quit
mov al,00h
int 21h
ISR proc far
; save old registers
push ax
push cx
push dx
push bx
push sp
push bp
push si
push di
push ds
mov ax,@data ;print text
mov ds,ax
xor ah,ah
mov ah, 9
lea dx, our_text
int 21h
mov ax,keyCount
inc ax
mov [keyCount],ax
in al, 60h
; send EOI to keyboard
in al, 61h
mov ah, al
or al, 80h
out 61h, al
mov al, ah
out 61h, al
; send EOI to master PIC
mov al, 20h
out 20h, al
pop ds
pop di
pop si
pop bp
pop sp
pop bx
pop dx
pop cx
pop ax
iret
ISR endp
What's wrong with how I'm restoring the original keyboard ISR? Why am I unable to type anything into the command prompt in DOS after running the program?
mov ah, 035
should bemov ah, 35h
. You called the wrong software interrupt and acquired garbage for a vector. Another issue is that this code is incorrect:mov ax, [old_int_seg]
mov ds, ax
mov dx, [old_int_off]
You change DS before you read the offset which is incorrect. Should bemov ax, [old_int_seg]
mov dx, [old_int_off]
mov ds, ax
– Anticipate