Category : Utilities for DOS and Windows Machines
Archive   : KEYLOC.ZIP
Filename : KEYLOC.ASM

Output of file : KEYLOC.ASM contained in archive : KEYLOC.ZIP
page 64,132

Comment @
This is a patch to the ROM BIOS keyboard routine. When the patch is
loaded, the Alt, Ctrl, Left Shift and Right Shift keys toggle between
their shifted and unshifted states.

There are two main entry points.

1. 'Keyloc' sets up the keyboard interupt vector to point to the patch
instead of the normal BIOS routine. After Keyloc executes, it
leaves the new interupt handler resident in memory.

2. 'Ikeyloc' is the new keyboard interupt handler. The first section
is a duplication of the ROM BIOS routine until a point where tests
for the input of a Alt, Ctrl, Left Shift or Right Shift key can be
made. If it is one of those keys, the appropriate bits in the
keyboard flag byte are twiddled.

John Black
5225 Pooks Hill Rd. #1715 N.
Bethesda MD. 20814

port_b equ 60h ; 8255 port a addr
timer equ 40h
kb_data equ 60h ; keyboard scan code port
kb_ctl equ 61h ; control bits for keyboard sense data

abso segment at 0
org 24h
kb_vector label dword
abso ends

bioscode segment at 0F000h
; ...locations in ROM BIOS used to return from interupt
org 0E9AFh
K16 label far ; resume code if not shift

org 0EC24h
K62 label far

org 0EA23h
K23 label far ; break for shift key

org 0EA5Eh
K26 label far ; return from interupt
bioscode ends

biosdata segment at 40h

org 17h
kb_flag label byte
; ...bit definitions for kb_flag
ins_state equ 80h ; insert state is active
caps_state equ 40h ; caps lock state has been toggled
num_state equ 20h ; num lock state has been toggled
scroll_state equ 10h ; scroll lock state has been toggled
alt_shift equ 08h ; alternate shift key depressed
ctl_shift equ 04h ; control shift key depressed
left_shift equ 02h ; left shift key depressed
right_shift equ 01h ; right shift key depressed

; ...scan codes
num_key equ 69
scroll_key equ 70
alt_key equ 56
ctl_key equ 29
caps_key equ 58
left_key equ 42
right_key equ 54
ins_key equ 82
del_key equ 83
biosdata ends

keylocs segment para public 'CODE'
assume cs:keylocs

keyloc_ident db 'KEYLOC'
ident_length equ 6
ikeyloc proc far ; interupt entry point
sti ; begin copy of ROM BIOS
push ax
push bx
push cx
push dx
push si
push di
push ds
push es
mov ax,biosdata
mov ds,ax
in al,kb_data
push ax
in al,kb_ctl
mov ah,al
or al,80h
out kb_ctl,al
xchg ah,al
out kb_ctl,al
pop ax
mov ah,al
cmp al,0FFh
jnz keylocpatch
jmp K62
; End of rom code copy
push ax
assume ds:biosdata

and al,01111111b ; mask out break indicator
cmp al,alt_key
je alt_in
cmp al,ctl_key
je ctrl_in
cmp al,left_key
je leftshift_in
cmp al,right_key
je rightshift_in
; ...return to normal bios keyboard routine
retbioskey: pop ax
jmp K16

mov al,alt_shift
call Depress_lock
; ... if this is a break, enter bios at K23
pop ax
mov ah,alt_shift
test al,80h ; if
jz fi ; .
test kb_flag,alt_shift ; .
jnz fi ; .
; / break and not depressed
; .
or kb_flag,alt_shift ; . Reset depressed flag
jmp K23 ; . Return in case using
; . alt keypad entry
fi: ; fi
jmp K26

mov al,ctl_shift
call Depress_lock
jmp retdone
mov al,left_shift
call Depress_lock
jmp retdone
mov al,right_shift
call Depress_lock
jmp retdone

retdone: pop ax
jmp K26
ikeyloc endp

; Depress_lock
; For keys that normally are depressed and held down
; while another key is depressed. (Cntl for example)
; ah input key, with break indicator (80h)
; al contains depressed indicator bit mask
Down db ? ; indicates the key is held down
Depress_lock proc near
push dx
test ah,80h ; if1
jnz fi1 ; .
test Down,al ; .
jnz fi1 ; .
; / make and not down
test kb_flag,al ; . if2
je else2 ; . .
; . / depressed
call high_beep ; . .
call delay ; . .
call low_beep ; . .
mov dl,al ; . . dl:=depressed bit
not dl ; . .
and kb_flag,dl ; . . key := not depressed
jmp fi1 ; . .
else2: ; . / not depressed
call low_beep ; . .
call delay ; . .
call high_beep ; . .
or kb_flag,al ; . . key := depressed
fi1: ; fi1 fi2

test ah,80h ; if5
jnz else5 ; .
; / make
or Down,al ; . down := true
jmp fi5 ; .
else5: ; / break
mov dl,al ; .
not dl ; .
and Down,dl ; . down := false
fi5: ; fi5
pop dx
Depress_lock endp

h_cycles equ 20
h_half equ 300
l_cycles equ h_cycles / 3
l_half equ h_half * 3

low_beep proc
push dx
push bx
mov bx,l_cycles
mov dx,l_half
call beep
pop bx
pop dx
low_beep endp

high_beep proc
push dx
push bx
mov bx,h_cycles
mov dx,h_half
call beep
pop bx
pop dx
high_beep endp

; Adapted from BIOS Beep routine
; bx = # of cycles
; dx = length of half cycle

beep proc near
push ax
push cx
in al,kb_ctl
push ax
and al,0FCh
out kb_ctl,al
mov cx,dx
k66: loop k66
or al,2
out kb_ctl,al
mov cx,dx
k67: loop k67
dec bx
jnz k65
pop ax
out kb_ctl,al
pop cx
pop ax
beep endp

delay proc near
push cx
mov cx,15000
loop $
pop cx
delay endp

ikeylast equ $ ; last location + 1 to remain in memory

stacks segment stack 'STACK'
db 64 dup('stack ')
stacks ends

loaded_mess db 'KEYLOC loaded$'
err_mess db 'error - KEYLOC is already loaded$'
keyloc proc far
push ds
sub ax,ax
push ax
push ds ; save program seg

; ...Check to see if a copy of KEYLOC has
; already been loaded by comparing Keyloc_ident
; with the same locations relative the the current
; keyboard interupt routine ( it is pointed to by the
; the keyboard interupt vector)
cld ; increment
assume ds:abso
mov ax,abso
mov ds,ax
mov si,offset keyloc_ident
mov ax,kb_vector+2 ; segment
mov di,kb_vector ; offset to ident
sub di,ident_length
mov es,ax
assume ds:keylocs
mov ax,keylocs
mov ds,ax
mov cx,ident_length
repne cmpsb ; ds:[si],es:[di]
cmp cx,0 ; if
je NotLoaded ; .
; / already loaded
mov ah,9h ; . print string
mov dx,offset err_mess ; .
int 21h ; .
pop ds ; . get rid of pseg
ret ; . return to DOS
NotLoaded: ; fi

; ...set up keyboard interupt vector
mov ah,9h
mov dx,offset loaded_mess
int 21h
assume ds:abso
mov ax,abso
mov ds,ax
mov ax,offset ikeyloc ; ip
mov kb_vector,ax
mov ax,seg ikeyloc ; cs
mov kb_vector+2,ax
; ...return to DOS, but leave ikeyloc resident
pop es ; get program segment
mov es:byte ptr 1,27h ; change int 20 to 27
mov dx,offset ikeylast+100h ; dx:=lastaddr+1+prfx
keyloc endp

keylocs ends

end keyloc

  3 Responses to “Category : Utilities for DOS and Windows Machines
Archive   : KEYLOC.ZIP
Filename : KEYLOC.ASM

  1. Very nice! Thank you for this wonderful archive. I wonder why I found it only now. Long live the BBS file archives!

  2. This is so awesome! 😀 I’d be cool if you could download an entire archive of this at once, though.

  3. But one thing that puzzles me is the “mtswslnkmcjklsdlsbdmMICROSOFT” string. There is an article about it here. It is definitely worth a read: