home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Between Heaven & Hell 2
/
BetweenHeavenHell.cdr
/
300
/
294
/
capsunlk.asm
< prev
next >
Wrap
Assembly Source File
|
1985-09-24
|
4KB
|
87 lines
name capslk
page 55,96
title 'CAPSLK - a CapsLock unlatcher'
; This install and stay resident program releases the keyboard from
; the CapsLock state whenever a letter key is pressed while a shift
; key also depressed. tHIS ELIMINATES A WELL KNOWN ANNOYANCE.
;
; Note that keyboards with CapsLock indicator lights may get out of
; synchronization since they have no way of knowing when the caplock bit
; in KB_FLAG is changed.
;
; This source based on a disassembly of CAPSLOCK.BAS in the Oct 15 '85
; issue of PC Magazine. Annotation and some minor changes in code to
; shorten program and reduce the number of execution clocks, implementation
; of function call 31h vs INT 27h by Herb Shear, SVCS Librarian.
cseg segment para public 'CODE'
assume cs:cseg, ds:cseg, es:cseg
org 100h ;start of com program
begin: jmp short sta_res ;proceed to stay resident code
vector: dd ? ;storage for next code in daisychain
start proc near
sti ;enable interrupts
push ax ;save registers
push cx
push di
push es
pushf
xor ax,ax ;clear ax register
mov es,ax ;ES = seg 0
mov di,417h ;set a pointer to KB_FLAG
mov ah,es:[di] ;load KB_FLAG
test ah,03h ;see if a shift key is pressed
jz exit ;exit if not pressed
in al,60h ;get keyboard scan code from port
cmp al,10h ;compare to Q key position
jb exit ;lower numbered position than Q key
cmp al,19h ;compare to P key position
jna unlock ;key in Q..P range
cmp al,1eh ;compare to A key position
jb exit ;non-alpha key position
cmp al,26h ;compare to L key position
jna unlock ;key in A..L range
cmp al,2ch ;compare to Z key position
jb exit ;non-alpha key position
cmp al,32h ;compare to M key position
ja exit ;key not in Z..M range
unlock: and ah,0bfh ;clear CapsLock bit
mov es:[di],ah ;reset KB_FLAG
exit: popf ;restore registers
pop es
pop di
pop cx
pop ax
jmp dword ptr cs:[vector] ;follow the INT 9 daisychain
sta_res:
xor ax,ax ;zero ax register
mov es,ax ;zero es register
mov di,9h * 4h ;interrupt 9 address
mov ax,es:[di] ;get the interrupt vector
mov bx,es:[di+2]
mov si, offset vector ;pointer to vector storage
mov [si],ax ;save the interrupt vector
mov [si+2],bx
mov bx,ds ;get seg of resident code
cli ;turn off interrupts
mov ax,offset start ;get offset of resident code
mov es:[di],ax ;store as new INT 9 vector
mov es:[di+2],bx
sti ;turn interrupts back on
mov dx,offset sta_res ;end of resident code + 1
mov cl,4 ;prepare for shift
shr dx,cl ;convert to paragraphs
inc dx ;roundup to full paragraph
mov ax,3100h ;set exit code = zero
int 21h ;terminate & stay resident
start endp
cseg ends
end begin