]>
wirehaze git hosting - MS-DOS.git/blob - v4.0/src/MEMM/MEMM/KBD.ASM
4 ;******************************************************************************
5 title KBD
.ASM
- - protected mode
AT keyboard driver
6 ;******************************************************************************
8 ; (C) Copyright MICROSOFT Corp. 1986
10 ; Title: MEMMD.EXE - MICROSOFT Expanded Memory Manager 386 DEBUG Driver
12 ; Module: KBD.ASM - - protected mode AT keyboard driver for debugger
16 ; Date: January 31, 1986
20 ;******************************************************************************
24 ; DATE REVISION DESCRIPTION
25 ; -------- -------- -------------------------------------------------------
27 ; A- Removed STIs and changed CLI/STIs to keep interrupt
28 ; status stable (OFF) during debugger execution. The
29 ; specific problem was in reporting unexpected traps
30 ; fielded from Virtual Mode during DOS execution,
32 ; B- Fixed Ctrl-NumLock, Ctrl-Alt-Del, Ctrl-Break, and
34 ; 05/12/86 C Cleanup and segment reorganization
35 ; 06/28/86 0.02 Name changed from MEMM386 to MEMM
36 ; 07/05/86 0.04 Moved to DCODE segment
38 ;******************************************************************************
40 ; Functional Description:
42 ; THIS CODE IS USED BY THE DEBUGGER ONLY !
44 ; This is a PC/AT keyboard driver capable of running
45 ; in protected mode. It does not require any ROM support.
47 ; The major modifications are:
49 ; - Remove foreign tables, use US only
50 ; - Hard code machine type rather than looking in ROM
51 ; - hard code BeepFreq, BeepDur
52 ; - removed KeyVector, put read-only data in CS
53 ; - removed Accent stuff, which had code writes
54 ; - removed code writes in foreign kbd
55 ; - removed INT 15h sysreq and post
56 ; - removed T&SR stuff, added buffer read routine "getc"
57 ; - made it polled, removed all interrupt stuff
58 ; - changed "data" segment to "romdata"
61 ; SCCSID = @(#)keybxx.asm 4.1 85/10/09
62 ;------------------------------------------------------
64 ; KEYBXX - foreign keyboard driver.
66 ; April 1985 by Michael Hanson
67 ; Copyright 1985 by Microsoft Corporation
69 ; KeybXX is a keyboard handling program using tables
70 ; supplied in a separate file to do foreign language
71 ; keyboard support. It is the basis for the KEYB??.EXE
72 ; programs which use this program and the corresponding
73 ; table defined in KEYB??.ASM.
75 ; KeybXX.OBJ must be linked with one of the Keyb??.OBJ
76 ; programs to work, the KEYB?? file must be first.
77 ; See the accompanying makefile for examples.
79 ; Note: KEYB?? refers to any of KEYBFR ( French ),
80 ; KEYBGR (German), KEYBUK (United Kingdom),
81 ; KEYBIT (Italian), KEYBSP (Spanish) and
82 ; KEYBDV (Dvorak). These are the currently
83 ; defined data tables for KEYBXX.
85 ; Compatability notes:
86 ; 1. The IBM foreign keyboard drivers don't return
87 ; anything for a CTRL-ALT space. This is not
88 ; what I expect from the manuals, but for
89 ; compatibility, KEYBXX doesn't return anything
90 ; in this case either.
92 ; 2. For the AT the keyboard driver should do a post
93 ; call (int 15). The ROM keyboard driver does, but
94 ; IBM's foreign keyboard drivers appear not to.
95 ; Currently KEYBXX does a post code, though only
96 ; one is issued at any one time (that is, only 1 post
97 ; call for the 2 characters returned by an illegal
98 ; accent combination).
100 ; This program is a modified version of the keyboard handler from -
102 ; Microsoft Mach 10 Enhancement Software
104 ; Copyright 1984 by Microsoft Corporation
105 ; Written June 1984 by Chris Peters
107 ;******************************************************************************
108 .lfcond
; list false conditionals
116 MASTER_IMR equ 21h
; mask port for master 8259
118 ;*** ROM BIOS data area, set up addresses
119 romdata
segment use16 at 40h
126 KbBuffer dw 16 dup (?
)
127 KbBufferEnd
label word
148 ;*** Routines used by data table modules (Keyb??)
174 assume
cs:DCODE
,ds:romdata
,es:nothing
177 ;*** Tables for foreign language key layout
178 ; See Keyb?? files for more details
181 ;* Actual foreign language key layout
182 ; extrn ForeignTable :word
185 ;* Tables to map CNTRL ALT char
186 ; extrn AltChrs :byte
188 ; extrn AltChrsEnd :byte
189 AltChrsEnd
label byte
195 ;* Tables to map accented characters
196 ; extrn AccentChTbl :word
197 AccentChTbl
label word
199 ; extrn AccentMpTbl :word
200 AccentMpTbl
label word
203 ;* Table of accent characters, shifted, ALTed and CTRLed.
204 ; defined using the AccChStruc struct
205 ; extrn AccChTbl :word
210 ;*** Internal variables used by KEYBXX interrupt handler
211 ; KeyVector dd ? ; origin of keyboard decode table
212 ;PCType db ? ; type of PC running on
213 PCType db 0fch ; type of PC running on
215 PC_AT
= 0FCh ;if anything else, assume PC/XT
217 ;Accent db 0 ; set for accent key, =0 for none.
218 ;AccentKey dw ? ; last accent key pressed
220 ; BeepFreq dw PCBeepFreq ;Count for beep half-cycle
221 BeepFreq dw ATBeepFreq
;Count for beep half-cycle
222 ; BeepDur dw PCBeepDur ;Count of half-cycles to beep
223 BeepDur dw ATBeepDur
;Count of half-cycles to beep
226 ;*** Normal keyboard table, used in CTRL-ALT F1 mode
228 ; See Keyb?? files for structure information.
230 ForeignTable
label word
231 KeyMapTable
label word
292 db CtrlShift
,(255-CtrlShift
)
318 db LeftShift
,(255-LeftShift
)
342 db RightShift,(255-RightShift)
346 db AltShift,(255-AltShift) ;56
350 db CapsState,(255-CapsState)
372 db NumState,(255-NumState) ;69
374 db ScrollState,(255-ScrollState)
402 db 0, 0 ;84 (On AT only)
407 ;*** Tables for keypad with ALT and control
408 ; Same for foreign as normal
415 CtrlKeyPad label byte
423 ;*** Table for ALT alphabetical character
425 ; Since uses alpha char as index, this is the same
426 ; for normal and foreign keyboards.
429 ; a, b, c, d, e, f, g, h, i, j, k, l, m
430 db 30,48,46,32,18,33,34,35,23,36,37,38,50
431 ; n, o, p, q, r, s, t, u, v, w, x, y, z
432 db 49,24,25,16,19,31,20,22,47,17,45,21,44
436 SUBTTL Keyboard Interrupt Handler
439 ;*** Keyboard interrupt handler
455 ; First see if there is any data in the kbd buffer.
456 ; Return to caller if not.
466 call GetSCode ;Get scan code from keyboard in al
467 mov ah,al ;(ah) = scan code
470 jmp BufferFull ;go handle overrun code
473 and bx,7fh ;(bl) = scan code without break bit
476 jmp KeyRet ;ignore code if not in range
478 shl bx,1 ;index into lookup table
480 ;* Check for CTRL-ALT chars
481 test ah, 80h ;no CTRL-ALT remap on break code
483 ; cmp word ptr [KeyVector],offset KeyMapTable
484 ; je KbI23 ;Not foreign keyboard
486 test [KeyState], CtrlShift
488 test [KeyState], AltShift
490 push ax ; save scan code
493 ; look up chars in table, if found then put out corresponding
494 ; entry from map table.
495 mov si, offset AltChrs - 1 ;Set up index to lookup
497 inc si ; Advance to next entry
498 cmp si, offset AltChrsEnd
499 jae KbI22 ;at end of table, so no remap
501 jne KbI21 ;this isn't it so loop
502 ; Found character, so do the mapping
503 sub si, offset AltChrs
504 add si, offset AltMap ;get index into remaped table
505 pop ax ;get scan code
506 mov al, cs:[si] ;get new character to use
513 mov si, offset KeyMapTable
514 mov cx,cs:[si+bx] ;(cx) = lc, uc bytes
515 mov al,cl ;(al) = lc code for key
516 mov dl,[KeyState] ;(dl) = keyboard flags
517 jmp word ptr cs:[si+bx+2] ;Call appropriate key handler
519 ; for all key handler routines,
521 ; (CX) = uc, lc code bytes from table
522 ; (DL) = keyboard flags byte (see equates above for bits)
523 ; (AL) = lc code from cl
524 ; (AH) = scan code from keyboard
531 ;*** Key handling routines, called as specified by the key table
533 ;------------------------------------------------------
535 ; Alphabetical key, caps lock works as do CTRL and ALT
543 mov ah,[AltTable+bx-"a
"]
546 ak1: test dl,CtrlShift
552 test dl,RightShift+LeftShift
563 ;------------------------------------------------------
565 ; Keys that do something different when CTRL is down
575 ;-----------------------------------------------------
577 ; Normal, Non Alphabetic key
579 NormalKey: ;These return nothing on ALT
585 Keys$2$13: ;Keys #2 - 13 have ALT codes 120,...
592 ky2: test dl,CtrlShift
593 jnz Ca20 ;handle CTRL key same as for CapKey
595 test dl,RightShift+LeftShift
601 ;-----------------------------------------------------
603 ; Non Alphabetic key for which cap lock works
605 CapKey: ; CAPLOCK works, ALT doesn't
611 Cap$2$13: ; KEYS 2-13 with CAPLOCK working
618 ca2: test dl,CtrlShift
620 ca20: cmp ah, 3 ;Keep CTRL keys at same scan code locations
640 ca25: cmp al, '-' ;Except for - key, which moves around.
648 test dl,RightShift+LeftShift
659 ;---------------------------------------------------
661 ; Scroll Lock, Caps Lock, Num Lock
675 mov ax,0003 ;*a simulate ^C
678 NumKey: ; NUM LOCK key
683 or [BreakState],HoldState ; CTRL NUMLOCK
686 call handler ;*a (look for key since no interrupts)
687 test [BreakState],HoldState ; Wait for a key press
691 StateKey: ; Toggle key
694 stk0: and [BreakState],ch ; Indicate key no longer held down
699 jnz shf4 ; Ignore if key already down
700 or [BreakState],ah ; Indicate key held down
701 xor dl,ah ; Toggle bit for this key
702 jmp short shf3 ; And go store it.
705 ;---------------------------------------------------
711 jz shf2 ; Indicate that ALT key down
713 xchg al,[AltKey] ; Find numeric code entered
715 jz shf1 ; Just reset indicator if none
717 xor ah,ah ; Make it a key with 0 scan code
720 ;----------------------------------------------------
727 shf1: and dl,ch ; Unset indicator bit for break code
729 shf2: or dl,al ; Set indicator bit for make code
730 shf3: mov [KeyState],dl
734 ;----------------------------------------------------
738 ReBoot: call NoBreak ; Del key pressed, check CTRL ALT DEL
743 XBoot: ; Reboot system.
744 mov ax,romdata ; ds = romdata segment
748 ;*a 02/12/86 - use shutdown code 10 and [40:67] to return to real mode
749 ;*a and enter the ROM at the CTRL-ALT-DEL entry point
752 mov al,0Fh or 80h ; shutdown byte address/disable NMI
753 out 70h,al ; write CMOS address
754 jmp short $+2 ; (delay)
755 mov al,0Ah ; Shutdown code 10 = jump [dword @40:67]
756 out 71h,al ; write shutdown code to shutdown byte
758 ; Set up entry point after the reset
760 mov ds:[67h],0EA81h ; offset of CTRL-ALT-DEL entry point
761 mov ds:[67h+2],0F000h ; segment of CTRL-ALT-DEL entry point
765 mov al,0FEh ; FEh = pulse output bit 0 (286 reset)
766 out 64h,al ; command to 8042
767 hlt ; don't want to coast
769 ;*a end inserted code
776 ;*a ret ; To reboot system, do a far return to FFFFh:0
780 ;----------------------------------------------------
788 jz pdk2 ; Not entering a character number
791 mov cl,cs:AltKeyPad[bx] ; Get numeric value for this key
793 jz pdk0 ; Start over if non-digit key
799 pdk1: mov [AltKey],al
805 xor bx,bx ; Lookup CTRL keypad key code
807 mov ah,cs:CtrlKeyPad[bx]
809 pdk3: cmp ah,74 ; - key independent of shift state
811 cmp ah,78 ; + key independent of shift state
814 test dl,RightShift+LeftShift
821 pdk41: mov al,ch ; use char2 if shifted or in numlock
825 jz pdk8 ; Ignore CTRL with keypad 2, etc.
832 ;----------------------------------------------------
838 test dl,AltShift+CtrlShift+LeftShift+RightShift
839 jz fk1 ; Normal function key
841 test dl,AltShift+CtrlShift
842 jz fk1 ; Shifted function key
845 jz fk1 ; Just CTRL function key
848 jz fk1 ; Just ALT function key
849 mov bx,offset KeyMapTable
850 cmp ah,104 ; CTRL ALT f1 to use normal keyboard
852 cmp ah,105 ; CTRL ALT f2 for foreign keyboard
853 jnz fk1 ; if not F1 or F2 then treat as ALT
854 mov bx,offset ForeignTable
856 cli ; Change translation table used
857 ; mov word ptr [KeyVector],bx
858 ; mov word ptr [KeyVector+2],cs
864 ;--------------------------------------------------------------------
874 ps1: test dl,LeftShift+RightShift
876 call VideoOn ;CTRL PrtSc - enable video and do Print Screen
881 ;--------------------------------------------------------------------
891 jmp KeyRet ; Don't return anything on CTRL-ALT space
896 ;--------------------------------------------------------------------
900 ; Each accent key is assumed to be accent both non-shifted
901 ; and shifted, and the accent number for the shifted should
902 ; be the next one up from the unshifted accent number.
906 ; cbw ;convert accent number to an index
910 ; shl bx,1 ;index to table of AccChStruc's
912 ; jz acc2 ;ALT not down
913 ; mov ax, [AccChTbl+bx].alt
917 ; jz acc3 ;just a normal or shifted keypress
918 ; mov ax, [AccChTbl+bx].ctrl
921 ; test dl, leftshift+rightshift
922 ; jz acc4 ; not shifted (caps lock not used)
923 ; mov Accent,ch ; Get shifted accent number
924 ; mov ax, [AccChTbl+bx].shift
925 ; mov AccentKey, ax ; Save key and scn code next key int
929 ; mov ax, [AccChTbl+bx].normal
937 ;--------------------------------------------------------------------
943 jnz sys2 ;this is break code
944 test BreakState, SysShift
946 jmp KeyRet ;Ignore if SysReq already down
949 or BreakState, SysShift ;set held down flag
953 and BreakState, Not SysShift ;turn off held down flag
956 push ax ; Save SysReq action number
957 mov al,20h ; EOI to control port
961 ; int 15h ; Indicate SysReq to BIOS
967 ;*** Finish up processing of interrupt
970 ;* Make this an ALT seq by removing chr code (ret scan code, 0)
973 ;* Put Key in buffer and return
975 ; cmp Accent, 0 ; check for accented char
976 ; je puk3 ;no accent pressed, just put out key
978 ; dec bl ;make accent no an index
980 ; mov Accent, bh ;Accent only this character
981 ; shl bx,1 ;index into word table
982 ; mov si, AccentChTbl[bx] ;Get pointer to string for this accent
983 ; dec si ;Negate effect of initial inc in loop
987 ; jz puk2 ;This is an accentable char - so remap
988 ; cmp byte ptr cs:[si], 0
989 ; jnz puk1 ;not done yet
991 ;;* The character is not in this list, so do a beep and put
992 ;; out booth accent char and this char
995 ; mov ax,AccentKey ;Put out accent
999 ; je puk4 ;Char is space, just beep and put out accent.
1000 ; jmp short puk3 ;Put out the character
1003 ; xor ah, ah ;Zero scan code for accented chrs
1004 ; cmp al, 0 ;for accented ALT chr put out 0, don't beep
1006 ; sub si, AccentChTbl[bx] ; Make index to map table
1007 ; add si, AccentMpTbl[bx]
1008 ; mov al, cs:[si] ; Get remapped char
1013 jnz KeyRet ; just return for non-AT
1015 mov al,20h ; EOI to control port
1018 ; mov ax, 09102h ; Send a post code
1024 ;* Common validity check routines (Check for ALT, ignore break codes)
1027 NoAlt: test dl,AltShift ; Don't allow ALT with this key
1029 NoBreak: ; Ignore break code for this key
1034 test [BreakState],HoldState ; in hold state?
1036 and [BreakState],(255-HoldState)
1038 IgB0: mov [AltKey],bl
1040 IgB1: pop ax ; pop off return address
1044 ;* buffer is full, beep the speaker and return from interrupt
1053 ;* Normal return from interrupt, handle EOI and enable KB
1081 ;*** VideoOn - enable keyboard and video
1085 ; EXIT: (dx), (al) destroyed.
1088 mov al,20h ; EOI to control port
1090 call EnableKB ; Enable AT keyboard
1092 jz vdo1 ; Do nothing for monochrome monitor
1095 out dx,al ; Enable video controller
1102 ;*** EnableKB - Enable the keyboard interface on an AT, no effect on PC/XT.
1106 ; EXIT: (al) destroyed
1108 ; EFFECTS: Enables the Keyboard interface.
1112 jne ena1 ;for non-AT simply ignore
1113 pushf ;* save interrupt status
1116 mov al,0AEh ;output enable keyboard command
1118 popf ;* restore original interrupt status
1127 ;*** DisableKB - Disable the keyboard interface on an AT, no effect on PC/XT
1131 ; EXIT: (al) destroyed
1133 ; EFFECTS: Disables the Keyboard interface.
1137 jne dis1 ; Ignore if not an AT
1138 pushf ;* save interrupt status
1141 mov al,0ADh ;output disable command
1143 popf ;* restore original interrupt status
1152 ;*** ErrBeep - beep the speaker
1158 ; USES: (ax) - to access I/O port
1159 ; (bx) - length of beep in cycles
1160 ; (cx) - counter for cycle length
1162 ; EFFECTS: Speaker is beeped
1164 ; WARNING: Uses in/out to keyboard port to beep speaker directly.
1170 mov bx,BeepDur ; count of speaker cycles
1173 and al,0fch ; turn off bits 0 and 1 (speaker off)
1174 bee1: xor al,2 ; toggle speaker bit
1177 bee2: loop bee2 ; wait for half cycle
1179 jnz bee1 ; keep cycling speaker
1180 pop ax ; restore speaker/keyboard port value
1191 ;*** PutKey - put key in the buffer
1193 ; ENTRY: (ax) = key code and scn code to go in buffer
1195 ; EXIT: (si), (di) destroyed.
1198 ; EFFECTS: KbTail updated
1199 ; (ax) put in buffer at end.
1200 ; On AT - do post call.
1202 ; If it isn't possible to put key in buffer (full) then beep
1204 ; If (ax) = -1 then the key is not put in buffer.
1207 cmp ax, -1 ; Code to ignore a key
1209 cli ; Make sure only ones using buffer now
1211 mov di,si ; Get old buffer end and save it
1212 inc si ; Advance pointer
1216 mov si,[KbStart] ; Wrap to beginning if at end
1219 jnz put1 ; Buffer not Full
1220 pop ax ; Drop return address
1221 jmp BufferFull ; Go beep and return from interrupt
1224 mov [di],ax ; Put key in buffer at end
1233 ;*** GetSCode - read the scan code from the keyboard
1237 ; EXIT: (al) = key scan code from keyboard
1240 ; USES: PCType - to use PC/AT sequence, for AT - handles LEDs
1244 je gsc1 ;handle AT differently
1245 in al,KbData ;get key code
1246 xchg bx,ax ;save scan code
1247 in al,KbCtl ;acknowledge to keyboard
1253 xchg ax,bx ;(al) = scan code
1256 gsc1: ;have to do handshake
1258 pushf ;* save interrupt status
1261 in al,KbData ;read in character
1262 popf ;* restore original interrupt status
1265 ; check for and flag control bytes from keyboard
1267 jne gsc2 ;it isn't a resend
1269 or [ATKbFlags], KbResend
1270 pop bx ;throw away return address
1271 jmp KeyRet ;and don't do anything more with key
1275 jne gsc3 ;it isn't an ack
1277 or [ATKbFlags], KBAck
1278 pop bx ;throw away return address
1279 jmp KeyRet ;and don't do anything more with key
1282 call UpdateLeds ;update AT's leds
1288 ;*** Don't need to keep code after here when not running on an AT
1293 ;*** UpdateLeds - update the leds on the AT keyboard
1297 ; EXIT: All regs preserved
1299 ; EFFECTS: Sets the keyboard LEDs according to the status byte.
1301 ; WARNING: Assumes it is operating on an AT, must not be called for a PC.
1303 UpdateLeds proc near
1304 pushf ;* save interrupt status
1307 mov ah, KeyState ; get the toggle key states
1308 and ah, CapsState + NumState + ScrollState
1312 rol ah, 1 ; in format for ATKbFlags
1316 jz Updn1 ; No change in leds, so don't update
1317 test ATKbFlags, KBSndLed
1318 jnz Updn1 ; Already updating, so don't update
1319 or ATKbFlags, KBSndLed
1321 ; out 20h, al ; send EOI
1322 mov al, 0EDh ; Set indicators command
1324 test ATKbFlags, KBErr
1326 mov al, ah ; Send indicator values
1328 test ATKbFlags, KBErr
1331 or ATKbFlags, ah ; Record indicators
1333 and ATKbFlags, Not (KBSndLed + KBErr)
1336 popf ;* restore original interrupt status
1344 ;*** SendByte - send a byte to the keyboard
1346 ; ENTRY: (al) - command/data to send
1348 ; EXIT: BreakState flags set according to success of operation.
1349 ; Ints disabled on completion.
1351 ; USES: (al) - byte to send.
1352 ; (ah) - count of retries.
1353 ; (cx) - time out counter on wait for response.
1355 ; Send the byte in al to the AT keyboard controller, and
1356 ; do handshaking to make sure they get there OK.
1357 ; Must not be called for the PC.
1362 mov ah, 03 ; Set up count of retries
1364 pushf ;* save interrupt status
1366 and ATKbFlags, Not (KBResend + KBAck + KBErr)
1367 push ax ; save byte to send
1368 call WaitStatus ; Wait for keyboard ready
1370 out KbData, al ; Send byte to keyboard
1371 popf ;* restore original interrupt status
1373 mov cx,2000h ; Time out length, Approximate value for AT ROM
1374 Sen2: ; Wait for ACK
1375 call handler ;*a (look for key since no interrupts)
1376 test ATKbFlags, KBResend + KBAck
1379 Sen3: ; Timed out - try to resend
1385 call handler ;*a (look for key since no interrupts)
1386 test ATKbFlags, KBResend
1398 ;*** WaitStatus - wait for status to indicate ready for new command
1402 ; EXIT: (AL) Destroyed.
1404 WaitStatus proc near
1407 wai1: ;wait for empty buffer
1415 SUBTTL Initialization
1419 ;* Initialization, called when run by DOS, doesn't stay resident.
1423 mov al,0ffh ; all OFF
1428 pop ds ; establish segment, since offsets are from cs
1431 int 21h ;Set interrupt 9 (keyboard) vector
1435 init1: cmp [KbStart],0
1436 jnz init2 ;New PC/AT - KbStart already initialized
1437 pushf ;* save interrupt status
1438 cli ;For old PC - initialize pointers to KbBuffer
1439 mov ax,offset KbBuffer
1443 mov [KbEnd],offset KbBufferEnd
1444 popf ;* restore original interrupt status
1446 init2: ; Start up in Foreign keyboard mode
1447 ; mov word ptr [KeyVector],offset ForeignTable
1448 ; mov word ptr [KeyVector+2],cs
1450 ; mov [accent],0 ; No previous accent key pressed
1452 ; Get PC type information and save in PCType flag
1463 ; mov dx,offset xt_endcode + 100h
1464 ; cmp [PCType], PC_AT
1465 ; jnz init6 ; Drop AT specific code
1467 ;* Initialization specific to AT
1468 ; Set up speaker counts, exchange keys 41, 43
1469 ; And keep AT specific code when terminate
1470 ; mov [BeepFreq], ATBeepFreq
1471 ; mov [BeepDur], ATBeepDur
1473 ; Reverse keys 41 and 43 for foreign keyboards
1474 ; mov ax, [ForeignTable + (41 * 4)] ; exchange char codes
1475 ; xchg ax, [ForeignTable + (43 * 4)]
1476 ; mov [ForeignTable + (41 * 4)], ax
1477 ; mov ax, [ForeignTable + (41 * 4) + 2] ;exchange function codes also
1478 ; xchg ax, [ForeignTable + (43 * 4) + 2]
1479 ; mov [ForeignTable + (41 * 4) + 2], ax
1480 ; Also handle for Ctrl Alt table
1481 ; mov si, offset AltChrs - 1
1482 ;init3: ;search AltChrs table
1484 ; cmp si, offset AltChrsEnd
1485 ; jae init5 ;Done scaning - go terminate
1486 ; cmp byte ptr cs:[si], 43
1488 ; mov byte ptr cs:[si], 41 ; found key 43 - replace with 41
1491 ; cmp byte ptr cs:[si], 41
1493 ; mov byte ptr cs:[si], 43 ; found key 41 - replace with 43
1497 ; mov dx,offset init_bios + 100h ; Keep AT specific code
1499 ; Terminate and stay resident, don't keep init code
1500 ; push ds ; adjust cs to psp
1501 ; mov bx, offset init7 + 100h ; by doing a far return to init7
1527 ;*** getc - read character out of keyboard buffer
1529 ; This routine gets characters from the buffer
1530 ; in the ROM data area.
1534 ; EXIT AL - character
1538 ; or 'Z' = 1 if no code available
1545 assume cs:DCODE, ds:nothing, es:nothing, ss:nothing
1562 call handler ; pull data into kbd buffer
1570 push ds ; save caller's regs
1574 mov ds, bx ; DS -> ROM data area
1577 mov bx, ds:[KbHead] ; bx = start of buffer
1578 cmp bx, ds:[KbTail] ; is buffer empty
1583 mov ax, [bx] ; AX = character and scan code
1584 add bx, 2 ; step buffer pointer
1585 cmp bx, ds:[KbEnd] ; is it at end of buffer
1587 mov bx, ds:[KbStart] ; move it back to start
1589 mov ds:[KbHead], bx ; store new start pointer
1591 and bx, 0ffffh ; just to clear zero flag