/mirrors/msdos/keyboard/dvorakxt.asm from wuarchive.wustl.edu

warren@jessica.stanford.edu
Thu, 02 Jul 92 13:58:08 -0700

; keyboard program for ibm pc
; from page 404 of May 1983 BYTE magazine;

keyadr equ (offset keybrd - offset start) + 100h
keylen equ offset keyend - offset keybrd
tabadr equ (offset table - offset keybrd) + 5Ch

tabddr equ (offset tabled - offset keybrd) + 5Ch
ctadr equ (offset ctable - offset keybrd) + 5Ch
oaltlc equ (offset altlc - offset keybrd) + 5Ch
oaltuc equ (offset altuc - offset keybrd) + 5Ch

kb_data equ 60h ;keyboard data port
kb_ctl equ 61h ;keyboard control port

data segment at 40h
org 17h
kb_flag label byte ;ram keyboard flag byte

data ends
cseg segment
assume cs:cseg,ds:data

org 100h

start: mov dx, 5Ch ;set ds:dx to loc 5ch in program prefix
mov al,9 ;set the keyboard interrupt (int9)
mov ah,25h ; to ds:dx via DOS function call
int 21h
mov di,dx ;move keyboard routine down so it starts
mov si,keyadr ; at loc 5ch in program prefix
mov cx,keylen ; (saves space)
jmp finish

;keyboard interrupt routine. copy beginning of IBM PC ROM routne to
;allow easy jump to later ROM code

keybrd: push ax ;Save registers used
push bx
push cx
push dx
push si
push di
push ds
push es
cld
mov ax,data
mov ds,ax
sti
in al,kb_data ;get key code
push ax
in al,kb_ctl ;restore keyboard
mov ah,al
or al,80h
out kb_ctl,al
xchg ah,al
out kb_ctl,al
pop ax
mov ah,al ;save key code

;end of copied ROM code. Start special translations

cmp al,0ffh ;overrun?
jz romkey
mov di,tabadr ;translate key code
cmp cs:dvorak,28 ;use dvorak table?
jnz keybr0
mov di,tabddr ;y
keybr0: and al,7fh ;kill make/break bit
call trans
test ah,80h ;break code?
jnz romky0

test kb_flag,4 ;no. Ctrl key presse
mov di,ctadr
jz altran
cmp al,28 ;yep. enter key? (use dvorak?)
jz keybr2
keybr1: cmp al,1 ;escape key? (leave dvorak?)
jnz tran
keybr2: mov cs:dvorak,al
jmp far ptr k26 ;restore regs and reti

altran: test kb_flag,8 ;alt key pressed?
jz romkey
mov di,oaltlc
test kb_flag,43h ;shift?
jz tran
mov di,oaltuc

tran: call trans
jnz romkey
jmp far ptr k61

romky0: or al,80h
romkey: mov ah,al
jmp far ptr romadr

;translate routine. Replaces byte in string [di] by byte following
; matched byte. Returns Z if no match found; NZ if match found.

trans: cmp al,cs:[di]
jz xfnd
inc di
cmp byte ptr cs:[di],0
jnz trans
or al,al
ret ;RNZ
xfnd: mov al,cs:1[di]
ret ;RZ

finish: rep movsb
mov dx,di ;end pgm but leave keyboard resident
int 27h

dvorak db 28 ;dvorak flag

table db 43,42,74,43,0 ;backslash -> left shift, keypad- -> backslash

;for a Dvorak keyboard use

tabled db 16,40,17,51,18,52,19,25,20,21,21,33,22,34,23,46,24,19,25,38,26,26
db 30,30,31,24,32,18,33,22,34,23,35,32,36,35,37,20,38,49,39,31,40,53
db 44,39,45,16,46,36,47,37,48,45,49,48,50,50,51,17,52,47,53,44,0

ctable db 15,15,72,21 ;ctl_backtab-> ctl-O, ctl-uparrow->ctl-u
db 80,10,0 ;ctl-downarrow->ctl-j

altlc db 30,132,46,135,18,130,49,164,24,148,22,129,23,161,51,174,52,175
db 02,173,53,168,03,253,13,240,32,235,0
altuc db 30,142,46,128,18,138,49,165,24,153,22,154,02,173,53,168,05,156
db 41,247,13,241,32,127,0

keyend:

cseg ends

rom segment at 0f000h ;IBM ROM BIOS keyboard entry points
assume cs:rom
org 0e9a6h
romadr label far ;perform all bu initial processing

org 0ea59h
k26 label far ;restore registers and return

org 0ea7ch
k1234 label far ;reboot (ctl-alt-del addr)
org 0ec05h
k61 label far ;store char in keyboard buffer and return
rom ends

end start