I need to write a program in Assembly for DOSBOX using MASM.
Task: Write a resident (TSR) program for DOS that changes the keyboard repeat rate every second in a cyclic manner, from the slowest to the fastest setting. The program must unload the initialization section upon completion.
Program requirements:
DOS + MASM environment.
Terminate the program using: INT 27h.
Interrupt handler installation method: Manually modify the Interrupt Vector Table using the MOV instruction.
Calling the previous interrupt handler: Use a far CALL with the flags register pushed onto the stack beforehand.
Position of the call to the previous handler: At the end of the new interrupt handler.
My code:
.MODEL small
.STACK 100h
.DATA
old_handler_offset DW 0
old_handler_segment DW 0
TickCounter db 0
CurrentRate db 0
RepeatRates db 32 dup (?)
.CODE
InitRepeatRates proc
mov cx, 32
mov si, offset RepeatRates
mov al, 1Fh
FillLoop:
mov [si], al
dec al
inc si
loop FillLoop
ret
InitRepeatRates endp
int_handler proc far
push ax
push bx
push dx
push si0
push es
push di
inc cs:TickCounter
cmp cs:TickCounter, 18
jl skip_update
mov cs:TickCounter, 0
xor si, si
mov al, cs:CurrentRate
mov si, x
mov al, cs:RepeatRates[si]
inc cs:CurrentRate
cmp cs:CurrentRate, 32
jb no_reset
mov cs:CurrentRate, 0
no_reset:
wait_input_ready:
in al, 64h
test al, 02h
jnz wait_input_ready
mov al, 0F3h
out 60h, al
wait_data_ready:
in al, 64h
test al, 02h
jnz wait_data_ready
mov al, cs:RepeatRates[si]
out 60h, al
skip_update:
pushf
push word ptr cs:old_handler_segment
push word ptr cs:old_handler_offset
retf
pop di
pop es
pop si
pop dx
pop bx
pop ax
iret
int_handler endp
start:
mov ax, @DATA
mov ds, ax
call InitRepeatRates
xor ax, ax
mov es, ax
mov ax, es:[1Ch*4]
mov old_handler_offset, ax
mov ax, es:[1Ch*4+2]
mov old_handler_segment, ax
cli
mov word ptr es:[1Ch*4], offset int_handler
mov ax, seg int_handler
mov word ptr es:[1Ch*4+2], ax
sti
mov dx, offset start
int 27h
END start
The program compiles successfully, but after I run and exit it, DOS stops responding to keyboard input. Please help, i don`t know what to do with it. Or offer general advice for coding TSR's in DOS?