home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Frostbyte's 1980s DOS Shareware Collection
/
floppyshareware.zip
/
floppyshareware
/
USCX
/
DOSUT-03.ZIP
/
KEYLK3.ASM
< prev
next >
Wrap
Assembly Source File
|
1983-07-20
|
14KB
|
370 lines
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
rom_version = 3
if (rom_version eq 1) or (rom_version eq 2)
bioscode segment at 0F000h
;
; Location definitions from Technical Reference Manual for Versions
; 04/24/81 or 10/19/81 of BIOS rom.
;
org 0E9AFh ; page A-27 of Technical Reference
K16 label far ; resume code if not shift
org 0EA23h ; page A-27
K23 label far ; break for shift key
org 0EA5Eh ; page A-27
K26 label far ; return from interupt
org 0EC24h ; page A-31
K62 label far ; error
bioscode ends
endif
if rom_version eq 3
bioscode segment at 0F000h
;
; Location definitions from Technical Reference Manual for Version
; 10/27/82 of BIOS rom
;
org 0E9ADh ; page A-30 of Technical Reference
K16 label far ; resume code if not shift
org 0EA1Eh ; page A-30
K23 label far ; break for shift key
org 0EA59h ; page A-31
K26 label far ; return from interupt
org 0EC27h ; page A-35
K62 label far ; error
bioscode ends
endif
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
cld
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
keylocpatch:
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
alt_in:
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
ctrl_in:
mov al,ctl_shift
call Depress_lock
jmp retdone
leftshift_in:
mov al,left_shift
call Depress_lock
jmp retdone
rightshift_in:
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
ret
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
ret
low_beep endp
high_beep proc
push dx
push bx
mov bx,h_cycles
mov dx,h_half
call beep
pop bx
pop dx
ret
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
k65:
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
ret
beep endp
;--------------------------------
delay proc near
push cx
mov cx,15000
loop $
pop cx
ret
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
ret
keyloc endp
keylocs ends
end keyloc