page 62,132 ; 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 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