home *** CD-ROM | disk | FTP | other *** search
- IDelay = 7 ; Initial delay (clock ticks).
- RDelay = 1 ; Repeat key delay (clock ticks).
- CSeg segment
- org 100h
- assume cs:CSeg,ds:nothing,es:nothing
- Install:;>>>>>>>>>>>> Installation <<<<<<<<<<<<<<<<<<<<<<<<<
- xor ax,ax
- mov es,ax ; Set to start of vectors.
- lds ax,dword ptr es:[4*08h]; Get vector for clock.
- cmp ax,offset Intercept08h; Check if already set up.
- je SI60 ; Exit to DOS if already there.
- cli ; Turn off the interrupts.
- mov cs:OldVec,ax ; Save the old vector.
- mov cs:OldVec+2,ds
- mov word ptr es:[4*08h],offset Intercept08h
- mov es:[4*08h+2],cs
- lds ax,dword ptr es:[4*09h]; Get vector for keyboard.
- mov cs:OldVec+4,ax ; Save the old vector.
- mov cs:OldVec+6,ds
- mov word ptr es:[4*09h],offset Intercept09h
- mov es:[4*09h+2],cs
- mov dx,offset Exit08h+32; Save this many bytes.
- int 27h ; Terminate and Stay Resident.
- SI60: int 20h ; Exit to DOS.
- ; >>>>>>>>>>>>>>>>>>>>> Data Storage <<<<<<<<<<<<<<<<<<<<<<<
- BIOSD dw 40h ; BIOS_Data segment.
- RepeatCNT db 0 ; Repeat count.
- RepeatChar dw 0 ; Repeat character here.
- OldVec dw 0,0,0,0 ; Old Timer & Keyboard vectors.
- Intercept09h:;>> Intercept Keyboard Routine <<<<<<<<<<<<<<<<
- push ds ; Save registers.
- push bx
- mov ds,cs:BIOSD ; Set DS to BIOS data segment.
- mov cs:RepeatCNT,0 ; Stop Repeat for now.
- mov bx,ds:[1ch] ; Pick up tail (at 40h:1ch).
- pushf ; Dummy up an interrupt.
- call dword ptr cs:OldVec+4; Go to regular routine.
- cmp bx,ds:[1ch] ; Did tail Change?
- jne NewKey ; Yes, a new key to consider.
- mov cs:RepeatChar,0 ; So won't match anything.
- jmp short Exit09h ; Exit with repeat off.
- NewKey: mov bx,[bx] ; Pick up key typed.
- or bh,bh ; Zero scan code indicates Alt
- jz Exit09h ; created keys which are skipped.
- cmp bx,cs:RepeatChar ; Present repeat key?
- mov cs:RepeatChar,bx ; Store as repeat key.
- mov cs:RepeatCnt,IDelay ; Assume initial delay.
- jne Exit09h ; A new key.
- mov cs:RepeatCnt,RDelay ; Change to Repeat delay.
- Exit09h:pop bx ; Restore registers.
- pop ds
- iret
- Intercept08h:;>>> Intercept Timer Interrupt <<<<<<<<<<<<<<<<
- dec cs:RepeatCNT ; Time to repeat?
- jg Exit08h ; Not time to repeat.
- mov cs:RepeatCNT,0 ; Reset for next time.
- jl Exit08h ; Not repeating.
- I08h00: push ds ; Repeat the character.
- push bx
- mov ds,cs:BIOSD ; Segment of buffer.
- mov bx,ds:[1ch] ; Get tail (at 40h:1ch).
- add bx,2 ; Bump pointer.
- cmp bx,ds:[82h] ; Check buffer end (at 40h:82h).
- jne I08h1 ; Not at end of buffer.
- mov bx,ds:[80h] ; Buffer start (at 40h:80h).
- I08h1: cmp bx,ds:[1ah] ; Check head (at 40h:1ah).
- je I08h50 ; Exit if buffer is full.
- push cs:RepeatChar ; Pick up character to repeat.
- xchg ds:[1ch],bx ; Update tail.
- pop word ptr [bx] ; Put character in buffer.
- mov cs:RepeatCNT,RDelay ; Set repeat delay count.
- I08h50: pop bx ; Restore registers.
- pop ds
- Exit08h:jmp dword ptr cs:OldVec ; Go to regular routine.
- CSeg ends
- end Install