KEYBOARD.ASM 84 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203120412051206120712081209121012111212121312141215121612171218121912201221122212231224122512261227122812291230123112321233123412351236123712381239124012411242124312441245124612471248124912501251125212531254125512561257125812591260126112621263126412651266126712681269127012711272127312741275127612771278127912801281128212831284128512861287128812891290129112921293129412951296129712981299130013011302130313041305130613071308130913101311131213131314131513161317131813191320132113221323132413251326132713281329133013311332133313341335133613371338133913401341134213431344134513461347134813491350135113521353135413551356135713581359136013611362136313641365136613671368136913701371137213731374137513761377137813791380138113821383138413851386138713881389139013911392139313941395139613971398139914001401140214031404140514061407140814091410141114121413141414151416141714181419142014211422142314241425142614271428142914301431143214331434143514361437143814391440144114421443144414451446144714481449145014511452145314541455145614571458145914601461146214631464146514661467146814691470147114721473147414751476147714781479148014811482148314841485148614871488148914901491149214931494149514961497149814991500150115021503150415051506150715081509151015111512151315141515151615171518151915201521152215231524152515261527152815291530153115321533153415351536153715381539154015411542154315441545154615471548154915501551155215531554155515561557155815591560156115621563156415651566156715681569157015711572157315741575157615771578157915801581158215831584158515861587158815891590159115921593159415951596159715981599160016011602160316041605160616071608160916101611161216131614161516161617161816191620162116221623162416251626162716281629163016311632163316341635163616371638163916401641164216431644164516461647164816491650165116521653165416551656165716581659166016611662166316641665166616671668166916701671167216731674167516761677167816791680168116821683168416851686168716881689169016911692169316941695169616971698169917001701170217031704170517061707170817091710171117121713171417151716171717181719172017211722172317241725172617271728172917301731173217331734173517361737173817391740174117421743174417451746174717481749175017511752175317541755175617571758175917601761176217631764176517661767176817691770177117721773177417751776177717781779178017811782178317841785178617871788178917901791179217931794179517961797179817991800180118021803180418051806180718081809181018111812181318141815181618171818181918201821182218231824182518261827182818291830183118321833183418351836183718381839184018411842184318441845184618471848184918501851185218531854185518561857185818591860186118621863186418651866186718681869187018711872187318741875187618771878187918801881188218831884188518861887188818891890189118921893189418951896189718981899190019011902190319041905190619071908190919101911191219131914191519161917191819191920192119221923192419251926192719281929193019311932193319341935193619371938193919401941194219431944194519461947194819491950195119521953195419551956195719581959196019611962196319641965196619671968196919701971197219731974197519761977197819791980198119821983198419851986198719881989199019911992199319941995199619971998199920002001200220032004200520062007200820092010201120122013201420152016201720182019202020212022202320242025202620272028202920302031203220332034203520362037203820392040204120422043204420452046204720482049205020512052205320542055205620572058205920602061206220632064206520662067206820692070207120722073207420752076207720782079208020812082208320842085208620872088208920902091209220932094209520962097209820992100210121022103210421052106210721082109211021112112211321142115211621172118211921202121212221232124212521262127212821292130213121322133213421352136213721382139214021412142214321442145214621472148214921502151215221532154215521562157215821592160216121622163216421652166216721682169217021712172217321742175217621772178217921802181218221832184218521862187218821892190219121922193219421952196219721982199220022012202220322042205220622072208220922102211221222132214221522162217221822192220222122222223222422252226222722282229223022312232223322342235223622372238223922402241224222432244224522462247224822492250225122522253225422552256225722582259226022612262226322642265226622672268226922702271227222732274227522762277227822792280228122822283228422852286228722882289229022912292229322942295229622972298229923002301230223032304230523062307230823092310231123122313231423152316231723182319232023212322232323242325232623272328232923302331233223332334233523362337233823392340234123422343234423452346234723482349235023512352235323542355235623572358235923602361236223632364236523662367236823692370237123722373237423752376237723782379238023812382238323842385238623872388238923902391239223932394239523962397239823992400240124022403240424052406240724082409241024112412241324142415241624172418241924202421242224232424242524262427242824292430243124322433243424352436243724382439244024412442244324442445244624472448244924502451245224532454245524562457245824592460246124622463246424652466246724682469247024712472247324742475247624772478247924802481248224832484248524862487248824892490249124922493249424952496249724982499250025012502250325042505250625072508250925102511251225132514251525162517251825192520
  1. ;
  2. ; Command & Conquer Red Alert(tm)
  3. ; Copyright 2025 Electronic Arts Inc.
  4. ;
  5. ; This program is free software: you can redistribute it and/or modify
  6. ; it under the terms of the GNU General Public License as published by
  7. ; the Free Software Foundation, either version 3 of the License, or
  8. ; (at your option) any later version.
  9. ;
  10. ; This program is distributed in the hope that it will be useful,
  11. ; but WITHOUT ANY WARRANTY; without even the implied warranty of
  12. ; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  13. ; GNU General Public License for more details.
  14. ;
  15. ; You should have received a copy of the GNU General Public License
  16. ; along with this program. If not, see <http://www.gnu.org/licenses/>.
  17. ;
  18. ;***************************************************************************
  19. ;** C O N F I D E N T I A L --- W E S T W O O D A S S O C I A T E S **
  20. ;***************************************************************************
  21. ;* *
  22. ;* Project Name : Library *
  23. ;* *
  24. ;* File Name : KEYBOARD.ASM *
  25. ;* *
  26. ;* Programmer : Christopher Yates *
  27. ;* *
  28. ;* Start Date : May 21, 1992 *
  29. ;* *
  30. ;* Last Update : July 15, 1994 [PWG] *
  31. ;* *
  32. ;*-------------------------------------------------------------------------*
  33. ;* Functions: *
  34. ;* Get_RM_Timer_Address -- Return address of real mode code for copy. *
  35. ;* Get_RM_Keyboard_Size -- return size of real mode timer code. *
  36. ;* Check_Key -- checks queue for key (make) *
  37. ;* Check_Key_Num -- Checks if key in queue, return key num *
  38. ;* Get_Key_Num -- Returns the next key num in ax *
  39. ;* KN_To_KA -- Translates a key num to an ASCII key *
  40. ;* Low_Get_Key -- low level get key returns key num and bits *
  41. ;* Convert_Num_To_ASCII -- Assembly routine converts keynum to ASCII key *
  42. ;* KeyNum_Translate -- Performs a lowlevel xlate to a keycode *
  43. ;* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - *
  44. ;*
  45. ;* Keyboard driver -- 80386 Protected Mode Assembly portion *
  46. ;* updated by: Phil Gorrow for 32 bit Protected Mode
  47. ;***************************************************************************
  48. ;
  49. ; ----------------------------------------------------------------
  50. IDEAL ; the product runs in ideal mode
  51. P386 ; use 386 real mode instructions
  52. MODEL USE32 FLAT
  53. LOCALS ?? ; ?? is the symbol for a local
  54. ;WARN ; generate all warnings we can
  55. JUMPS ; optimize jumps if possible
  56. ;---------------------------------------------------------------------------
  57. ; Make some general equates for easy compatability
  58. ;---------------------------------------------------------------------------
  59. PROT_INT_ENABLE EQU 1 ; if false protected int just calls real mode int
  60. DPMI_INTR EQU 31h
  61. IRQ1INTNUM EQU 09h ; IRQ1 interrupt vector number.
  62. BRKINTNUM EQU 23h ; Crtl-C (Break) interrupt vector number
  63. DBGINTNUM EQU 3h ; Debug interrupt vector number
  64. DOS_SYS_CALL EQU 21h ; to do TNT DOS-XNDR system calls.
  65. LOCK_PAGES EQU 5 ; Lock pages subfunction using DX_MEM_MGT
  66. UNLOCK_PAGES EQU 6 ; Unlock pages subfunction using DX_MEM_MGT
  67. CLEARISR EQU 020H ; value to clear In Service Register
  68. INTCHIP0 EQU 020H ; 8259 interrupt chip controller 0
  69. ;---------------------------------------------------------------------------
  70. ; Include all of the keyboard specific defines
  71. ;---------------------------------------------------------------------------
  72. INCLUDE "keyboard.inc"
  73. INCLUDE "keystruc.inc"
  74. INCLUDE "mcgaprim.inc"
  75. GLOBAL RealModePtr:DWORD
  76. GLOBAL Install_Keyboard_Interrupt:NEAR
  77. GLOBAL Get_RM_Keyboard_Address:Near
  78. GLOBAL Get_RM_Keyboard_Size:Near
  79. GLOBAL Remove_Keyboard_Interrupt:NEAR
  80. GLOBAL Check_Key_Num:NEAR
  81. GLOBAL Get_Key_Num:NEAR
  82. GLOBAL KN_To_KA:NEAR
  83. GLOBAL KeyNum_Translate:NEAR
  84. GLOBAL Check_Key:NEAR
  85. GLOBAL Get_Key:NEAR
  86. GLOBAL Keyboard_Attributes_On:NEAR
  87. GLOBAL Clear_KeyBuffer:NEAR
  88. GLOBAL Key_Down:NEAR
  89. GLOBAL Keyboard_Attributes_Off:NEAR
  90. GLOBAL Check_Key_Bits:NEAR
  91. GLOBAL Get_Key_Bits:NEAR
  92. GLOBAL Key_Satisfied:NEAR
  93. GLOBAL Stuff_Key_WORD:NEAR
  94. GLOBAL Stuff_Key_Num:NEAR
  95. GLOBAL MouseQX:DWORD
  96. GLOBAL MouseQY:DWORD
  97. ;DBG
  98. GLOBAL Keyboard_Interrupt:NEAR
  99. DATASEG
  100. ; For the current time we will just include the real mode stuff
  101. ; into the protected mode code and then copy it down. The C side of
  102. ; this will handle this method or reading it off of disk in the real
  103. ; method.
  104. LABEL RealBinStart BYTE
  105. include "keyireal.ibn"
  106. LABEL RealBinEnd BYTE
  107. LABEL LockedDataStart BYTE
  108. RMVector DD 0
  109. RealModeSel DD 0
  110. RealModePtr DD 0 ; Pointer to real mode memory.
  111. RealModeSize DD 0 ; Pointer to real mode memory.
  112. LABEL LockedDataEnd BYTE
  113. Ascii DB 0,"`1234567890-=",0,8,9,"qwertyuiop[]\",0,"asdfghjkl;'"
  114. DB 0,13,0,45,"zxcvbnm,./",0,0,0,0,0," "
  115. Shift DB 0,"~!@#$%^&*()_+",0,8,9,"QWERTYUIOP{}|",0,"ASDFGHJKL:",22H
  116. DB 0,13,0,45,"ZXCVBNM<>?",0,0,0,0,0," "
  117. Alpha_Lower DB 0
  118. DB "~!@#$%^&*()_+",0,8,9,"qwertyuiop{}|",0,"asdfghjkl:",22H
  119. DB 0,13,0,45,"zxcvbnm<>?",0,0,0,0,0," "
  120. Alpha_Shift DB 0
  121. DB "`1234567890-=",0,8,9,"QWERTYUIOP[]\",0,"ASDFGHJKL;'"
  122. DB 0,13,0,45,"ZXCVBNM,./",0,0,0,0,0," "
  123. Edit DB 0AEH,0ADH,000H,000H,0B5H,0B9H,0B1H,000H,0B8H,0B0H,0B7H,0AFH
  124. DB 000H,000H,0B3H,000H,0B9H,0B5H,0B1H,000H, "/",0B8H,0B4H,0B0H
  125. DB 0AEH, "*",0B7H,0B3H,0AFH,0ADH, "-", "+",000H,00DH,000H
  126. NumPad DB 0,"741",0,"/8520*963.-+",0,13,0
  127. GetKeyLock DW 0 ; snap shot of num and caps lock bits
  128. InitFlags DW 0
  129. MouseQX DD 0
  130. MouseQY DD 0
  131. CODESEG
  132. ;***************************************************************************
  133. ;* GET_RM_TIMER_ADDRESS -- Return address of real mode code for copy. *
  134. ;* *
  135. ;* INPUT: none *
  136. ;* *
  137. ;* OUTPUT: VOID * to the address of the real mode timer *
  138. ;* *
  139. ;* PROTO: VOID *Get_RM_Keyboard_Address(VOID); *
  140. ;* *
  141. ;* HISTORY: *
  142. ;* 07/06/1994 SKB : Created. *
  143. ;*=========================================================================*
  144. PROC Get_RM_Keyboard_Address C Near
  145. mov eax, OFFSET RealBinStart
  146. ret
  147. ENDP
  148. ;***************************************************************************
  149. ;* GET_RM_KEYBOARD_SIZE -- return size of real mode timer code. *
  150. ;* *
  151. ;* INPUT: none *
  152. ;* *
  153. ;* OUTPUT: LONG size of the real mode timer code *
  154. ;* *
  155. ;* PROTO: LONG Get_RM_Keyboard_Size(VOID);
  156. ;* *
  157. ;* HISTORY: *
  158. ;* 07/06/1994 SKB : Created. *
  159. ;*=========================================================================*
  160. PROC Get_RM_Keyboard_Size C Near
  161. mov eax, OFFSET RealBinEnd - OFFSET RealBinStart
  162. ret
  163. ENDP
  164. ;***************************************************************************
  165. ;* INSTALL_KEYBOARD_INTERRUPT -- Installs the keyboard interrupt *
  166. ;* *
  167. ;* INPUT: int rm_ptr - ptr to the real mode handler * *
  168. ;* int rm_size - size of the real mode handler *
  169. ;* *
  170. ;* OUTPUT: none *
  171. ;* *
  172. ;* PROTO: VOID Install_Keyboard_Interrupt(int rm_ptr, int rm_size); *
  173. ;* *
  174. ;* HISTORY: *
  175. ;* 07/11/1994 PWG : Created. *
  176. ;*=========================================================================*
  177. PROC Install_Keyboard_Interrupt C NEAR
  178. USES eax,ebx,ecx,edx,esi,edi
  179. ARG rm_ptr:DWORD
  180. ARG rm_size:DWORD
  181. ; Are they attempting to set timer again?
  182. cmp [RealModePtr],0
  183. jnz ??error
  184. ; Make sure all flags are cleared.
  185. cmp [InitFlags],0
  186. jnz ??error
  187. ; Before setting the interrupt vectors, the code needs to be locked
  188. ; for DPMI compatability. Any code or data accessed must be lockded
  189. ; so that no page faults accure during an interrupt.
  190. ; First lock the code, then the data. The stack will already be locked.
  191. ; The real mode code is also already locked be default.
  192. ; To lock a page set up registers :
  193. ; AX = 0600h
  194. ; BX:CX = starting linear address of memory block
  195. ; SI:DI = size of region
  196. mov eax,0600h ; function number.
  197. mov ecx,OFFSET LockedCodeStart ; ecx must have start of memory.
  198. mov edi,OFFSET LockedCodeEnd ; edi will have size of region in bytes.
  199. shld ebx,ecx,16
  200. sub edi, ecx
  201. shld esi,edi,16
  202. int DPMI_INTR ; do call.
  203. jc ??error ; eax = 8 if mem err, eax = 9 if invalid mem region.
  204. or [InitFlags],IF_LOCKED_PM_CODE
  205. mov eax,0600h ; function number.
  206. mov ecx,OFFSET LockedDataStart ; ecx must have start of memory.
  207. mov edi,OFFSET LockedDataEnd ; edi will have size of region in bytes.
  208. shld ebx,ecx,16
  209. sub edi, ecx
  210. shld esi,edi,16
  211. int DPMI_INTR ; do call.
  212. jc ??error ; eax = 8 if mem err, eax = 9 if invalid mem region.
  213. or [InitFlags],IF_LOCKED_PM_DATA
  214. ; now allocate real mode memory and copy the rm binary down to it.
  215. mov eax,0100h ; set function number
  216. mov ebx,[rm_size] ; get size of RM binary.
  217. mov [RealModeSize],ebx
  218. add ebx,15 ; round up
  219. shr ebx,4 ; convert to pages.
  220. int DPMI_INTR ; do call.
  221. jc ??error ; check for error.
  222. or [InitFlags],IF_ALLOC_RM ; set successful
  223. mov [RealModeSel],edx
  224. shl eax,4 ; convert segment to offset.
  225. mov [RealModePtr],eax ; save offset to global variable.
  226. ; now lock the real mode memory that we allocated
  227. mov eax,0600h ; function number.
  228. mov ecx,[RealModePtr] ; ecx must have start of memory.
  229. mov edi,[RealModeSize] ; edi will have size of region in bytes.
  230. shld ebx,ecx,16
  231. shld esi,edi,16
  232. int DPMI_INTR ; do call.
  233. jc ??error ; eax = 8 if mem err, eax = 9 if invalid mem region.
  234. or [InitFlags],IF_LOCKED_RM_CODE
  235. ; set up source and destination pointers for the copy.
  236. mov eax,[RealModePtr]; ; set up our dest pointer
  237. mov esi,[rm_ptr] ; Set up our source pointer.
  238. mov edi,eax ; put it into esi for copy.
  239. mov ecx,[rm_size]
  240. rep movsb ; write RM bin to RM memory.
  241. ; restore esi to point to data and initialize some of it.
  242. mov esi,[RealModePtr]
  243. mov eax,esi
  244. shl eax,12 ; make seg in high eax.
  245. mov ax,[(KeyboardType PTR esi).CallKeyRMIntOffset] ; create RM addr of call chain.
  246. mov [(KeyboardType PTR esi).CallKeyRMIntAddr],eax ; save it for use in PM int.
  247. IF NOT PROT_INT_ENABLE
  248. ; Chain the Real Keyboard interrupt to any avilable
  249. ; Interrupt vector so We make sure that the Real Mode
  250. ; Keyboard Interrupt service get called at debuging time
  251. ; of the library.
  252. mov edi , eax
  253. mov bl , 060h
  254. mov bh , 6
  255. mov eax , 200h
  256. ??find:
  257. int DPMI_INTR
  258. jc ??error
  259. or cx,dx
  260. jz ??found
  261. inc bl
  262. dec bh
  263. jnz ??find
  264. jmp ??error
  265. ??found:
  266. movzx ebx , bl
  267. mov [ byte ptr RMVector ] , bl
  268. mov [ 4 * ebx ] , edi
  269. ENDIF
  270. ;-------------------------------------------------------
  271. ; Initialize all of the keyboard specific information
  272. ;-------------------------------------------------------
  273. xor eax,eax ; clear the high bits of eax
  274. mov al,[417H] ; get keyboard status flags
  275. test eax,040H ; caps lock active?
  276. je short ??nocap ; not active
  277. or [(KeyboardType PTR esi).KeyLock],CAPSLOCK
  278. ??nocap:
  279. test eax,020H ; num lock active?
  280. je short ??nonumlock ; not active
  281. or [(KeyboardType PTR esi).KeyLock],NUMLOCK
  282. ??nonumlock:
  283. test eax,002H ; is left shift key down?
  284. je short ??noleftshift ; try the right
  285. or [(KeyboardType PTR esi+5).KeysUpDown],010H
  286. ??noleftshift:
  287. and eax,001H ; get right shift bit
  288. shl eax,9 ; put it into the proper position (shl al,1 mov ah,al)
  289. mov al,[418H] ; get alt and ctrl bits
  290. shl al,2 ; put in proper position
  291. shl al,1
  292. and al,00CH ; only alt and ctrl bits
  293. or ah,al ; put them ah for Keys+7 later
  294. mov al,[496H] ; get extended keys
  295. test al,008H ; check for right alt key
  296. je short ??noralt
  297. or ah,040H
  298. ??noralt:
  299. mov [(KeyboardType PTR esi+7).KeysUpDown],ah
  300. test al,004H ; test for right ctrl
  301. je short ??norctrl
  302. or [(KeyboardType PTR esi+8).KeysUpDown],001h
  303. ??norctrl:
  304. test al,002H ; last code E0?
  305. je short ??noe0
  306. mov [(KeyboardType PTR esi).LastKeyE0],001h
  307. ??noe0:
  308. test al,001H ; last code E1?
  309. je short ??noe1
  310. mov [(KeyboardType PTR esi).LastKeyE1],002h
  311. ??noe1:
  312. ;==========================================================================
  313. ; Get the protected mode interrupt vector keyboard.
  314. ; input ax = 0204
  315. ; bl = number of interrupt to get
  316. ; output: cf error
  317. ; ES:EBX = address of PM int handler routine.
  318. ;==========================================================================
  319. mov eax,0204h ; Get proteced mode
  320. mov bl,IRQ1INTNUM ; IRQ1 interrupt vector
  321. int DPMI_INTR ; do call.
  322. jc ??error
  323. mov [(KeyboardType PTR esi).KeyOldPMIOffset],edx ; save offset.
  324. mov [(KeyboardType PTR esi).KeyOldPMISelector],ecx ; save selector.
  325. ;==========================================================================
  326. ; Get the real mode interrupt vector keyboard
  327. ; input ax = 2503, cl = number of interrupt to get
  328. ; output cf error, EBX = address (seg:off) of RM int handler routine.
  329. ; cl set above
  330. ;==========================================================================
  331. mov eax,0200h
  332. mov bl,IRQ1INTNUM ; IRQ1 interrupt vector
  333. int DPMI_INTR ; do call.
  334. jc ??error
  335. shl edx,16
  336. shld ecx,edx,16
  337. mov [(KeyboardType PTR esi).KeyOldRMI],ecx
  338. ;==========================================================================
  339. ; Now it is time to set the Protected mode interrupt Keyboard
  340. ; ax = function number (0205
  341. ; bl = number of interrupt to set
  342. ; cx:edx = address of PM interrupt handler
  343. ;==========================================================================
  344. mov eax, 0205h
  345. mov bl,IRQ1INTNUM
  346. mov cx , cs
  347. lea edx, [Keyboard_Interrupt] ; get address of protected code int hand.
  348. int DPMI_INTR ; do call.
  349. jc ??error
  350. or [InitFlags],IF_SET_VECTORS
  351. ;==========================================================================
  352. ; Now it is time to set the real Interrupt Keyboard
  353. ; ax = function number (0201
  354. ; bl = number of interrupt to set
  355. ; cx:dx = address of RM interrupt handler
  356. ;==========================================================================
  357. mov eax, 0201h
  358. mov bl,IRQ1INTNUM
  359. mov ecx,[RealModePtr] ; get address of real code int hand.
  360. shr ecx,4 ; put segment in hi word.
  361. mov dx,[(KeyboardType PTR esi).KeyCodeOffset] ; Get address of code
  362. int DPMI_INTR ; do call.
  363. jc ??error
  364. ;==========================================================================
  365. ; Get the protected mode interrupt vector - for the break interrupt
  366. ; input ax = 0204
  367. ; bl = number of interrupt to get
  368. ; output: cf error
  369. ; ES:EBX = address of PM int handler routine.
  370. ;==========================================================================
  371. mov eax,0204h ; Get proteced mode
  372. mov bl,BRKINTNUM ; IRQ1 interrupt vector
  373. int DPMI_INTR ; do call.
  374. jc ??error
  375. mov [(KeyboardType PTR esi).BrkOldPMIOffset],edx ; save offset.
  376. mov [(KeyboardType PTR esi).BrkOldPMISelector],ecx ; save selector.
  377. ;==========================================================================
  378. ; Get the real mode interrupt vector - for the break interrupt
  379. ; input ax = 0200, bl = number of interrupt to get
  380. ; output cf error, EBX = address (seg:off) of RM int handler routine.
  381. ; cl set above
  382. ;==========================================================================
  383. mov eax,0200h
  384. mov bl,BRKINTNUM ; IRQ1 interrupt vector
  385. int DPMI_INTR ; do call.
  386. jc ??error
  387. shl edx,16
  388. shld ecx,edx,16
  389. mov [(KeyboardType PTR esi).BrkOldRMI],ecx
  390. ;==========================================================================
  391. ; Now it is time to set the Protected mode interrupt
  392. ; ax = function number (0205
  393. ; bl = number of interrupt to set
  394. ; cx:edx = address of PM interrupt handler
  395. ;==========================================================================
  396. mov eax, 0205h
  397. mov bl,BRKINTNUM
  398. mov cx , cs
  399. lea edx, [Break_Interrupt] ; get address of protected code int hand.
  400. int DPMI_INTR ; do call.
  401. jc ??error
  402. or [InitFlags],IF_SET_VECTORS
  403. ;==========================================================================
  404. ; Now it is time to set the real Interrupt
  405. ; ax = function number (0201
  406. ; bl = number of interrupt to set
  407. ; cx:dx = address of RM interrupt handler
  408. ;==========================================================================
  409. mov eax, 0201h
  410. mov bl,BRKINTNUM
  411. mov ecx,[RealModePtr] ; get address of real code int hand.
  412. shr ecx,4 ; put segment in hi word.
  413. mov dx,[(KeyboardType PTR esi).BrkCodeOffset] ; Get address of code
  414. int DPMI_INTR ; do call.
  415. jc ??error
  416. or [InitFlags],IF_SET_VECTORS
  417. IF DEBUG
  418. ;==========================================================================
  419. ; Get the protected mode interrupt vector - for the Debug interrupt
  420. ; input ax = 0204
  421. ; bl = number of interrupt to get
  422. ; output: cf error
  423. ; ES:EBX = address of PM int handler routine.
  424. ;==========================================================================
  425. mov eax,0204h ; Get proteced mode
  426. mov bl,DBGINTNUM ; IRQ1 interrupt vector
  427. int DPMI_INTR ; do call.
  428. jc ??error
  429. mov [(KeyboardType PTR esi).DbgOldPMIOffset],edx ; save offset.
  430. mov [(KeyboardType PTR esi).DbgOldPMISelector],ecx ; save selector.
  431. ;==========================================================================
  432. ; Now it is time to set the Protected mode interrupt
  433. ; ax = function number (0205
  434. ; bl = number of interrupt to set
  435. ; cx:edx = address of PM interrupt handler
  436. ;==========================================================================
  437. mov eax, 0205h
  438. mov bl,DBGINTNUM
  439. mov cx , cs
  440. lea edx, [Debug_Interrupt] ; get address of protected code int hand.
  441. int DPMI_INTR ; do call.
  442. jc ??error
  443. or [InitFlags],IF_SET_VECTORS
  444. ENDIF
  445. ; we have finished with success.
  446. mov eax,1 ; signal success.
  447. ret
  448. ??error:
  449. xor eax,eax ; signal an error.
  450. ??exit:
  451. ret
  452. ENDP Install_Keyboard_Interrupt
  453. ;***************************************************************************
  454. ;* REMOVE_INTERRUPT -- Removes keyboard interrupt and restores chain *
  455. ;* *
  456. ;* INPUT: none *
  457. ;* *
  458. ;* OUTPUT: none *
  459. ;* *
  460. ;* PROTO: VOID Remove_Interrupt(VOID) *
  461. ;* *
  462. ;* HISTORY: *
  463. ;* 07/13/1994 PWG : Created. *
  464. ;*=========================================================================*
  465. PROC Remove_Keyboard_Interrupt C NEAR
  466. USES ebx,ecx,edx
  467. ; verifie that the keyboard was previosly install
  468. ; this is here in case of a page fault crash
  469. mov esi,[RealModePtr]
  470. test esi,esi
  471. jz ??error
  472. test [InitFlags],IF_SET_VECTORS
  473. jz ??vectors_not_set
  474. ; disengage Keyboard Interrupt handle
  475. ;==========================================================================
  476. ; Now it is time to set the real Interrupt
  477. ; ax = function number (0201
  478. ; bl = number of interrupt to set
  479. ; cx:dx = address of RM interrupt handler
  480. ;==========================================================================
  481. mov eax, 0201h
  482. mov bl,IRQ1INTNUM
  483. mov edx,[(KeyboardType esi).KeyOldRMI] ; get address of real code int hand.
  484. shld ecx , edx , 16
  485. int DPMI_INTR ; do call.
  486. jc ??error
  487. ;==========================================================================
  488. ; Now it is time to set the Protected mode interrupt
  489. ; ax = function number (0205
  490. ; bl = number of interrupt to set
  491. ; cx:edx = address of PM interrupt handler
  492. ;==========================================================================
  493. mov eax, 0205h
  494. mov bl,IRQ1INTNUM
  495. mov ecx,[(KeyboardType esi).KeyOldPMISelector] ; Get PM segment to put int ds later.
  496. mov edx,[(KeyboardType esi).KeyOldPMIOffset] ; Get PM offset
  497. int DPMI_INTR ; do call.
  498. jc ??error
  499. ; disengage Control Break Interrupt handle
  500. ;==========================================================================
  501. ; Now it is time to set the real Interrupt
  502. ; ax = function number (0201
  503. ; bl = number of interrupt to set
  504. ; cx:dx = address of RM interrupt handler
  505. ;==========================================================================
  506. mov eax, 0201h
  507. mov bl,BRKINTNUM
  508. mov edx,[(KeyboardType esi).BrkOldRMI] ; get address of real code int hand.
  509. shld ecx , edx , 16
  510. int DPMI_INTR ; do call.
  511. jc ??error
  512. ;==========================================================================
  513. ; Now it is time to set the Protected mode interrupt
  514. ; ax = function number (0205
  515. ; bl = number of interrupt to set
  516. ; cx:edx = address of PM interrupt handler
  517. ;==========================================================================
  518. mov eax, 0205h
  519. mov bl,BRKINTNUM
  520. mov ecx,[(KeyboardType esi).BrkOldPMISelector] ; Get PM segment to put int ds later.
  521. mov edx,[(KeyboardType esi).BrkOldPMIOffset] ; Get PM offset
  522. int DPMI_INTR ; do call.
  523. jc ??error
  524. IF DEBUG
  525. ; disengage Keyboard Interrupt handle
  526. ;==========================================================================
  527. ; Now it is time to set the Protected mode interrupt
  528. ; ax = function number (0205
  529. ; bl = number of interrupt to set
  530. ; cx:edx = address of PM interrupt handler
  531. ;==========================================================================
  532. mov eax, 0205h
  533. mov bl,DBGINTNUM
  534. mov ecx,[(KeyboardType esi).DbgOldPMISelector] ; Get PM segment to put int ds later.
  535. mov edx,[(KeyboardType esi).DbgOldPMIOffset] ; Get PM offset
  536. int DPMI_INTR ; do call.
  537. jc ??error
  538. ENDIF
  539. IF NOT PROT_INT_ENABLE
  540. ; Clean up the Users interrupt table
  541. mov eax , 201h
  542. mov bl , [ byte ptr RMVector ]
  543. xor ecx , ecx
  544. xor edx , edx
  545. int DPMI_INTR
  546. jc ??error
  547. ENDIF
  548. ??vectors_not_set:
  549. ; now free up the real mode memory.
  550. test [InitFlags],IF_LOCKED_RM_CODE
  551. jz ??rm_not_locked
  552. mov eax , 0601h
  553. mov ecx,[RealModePtr] ; ecx must have start of memory.
  554. mov edi,[RealModeSize] ; edx will have size of region in bytes.
  555. shld ebx , ecx , 16
  556. shld esi , edi , 16
  557. int DPMI_INTR ; do call.
  558. jc ??error ; eax = 8 if mem err, eax = 9 if invalid mem region.
  559. ??rm_not_locked:
  560. test [InitFlags],IF_ALLOC_RM
  561. jz ??mem_not_allocated
  562. mov eax , 0101h
  563. mov edx,[ RealModeSel ] ; get physical address of real mode buffer.
  564. int DPMI_INTR ; do call.
  565. jc ??error
  566. ??mem_not_allocated:
  567. ; Now we can unlock all stuff needed for the interrupt.
  568. ; Unlock Code
  569. test [InitFlags],IF_LOCKED_PM_CODE
  570. jz ??code_not_locked
  571. mov eax , 0601h
  572. mov ecx,OFFSET LockedCodeStart ; ecx must have start of memory.
  573. mov edi,OFFSET LockedCodeEnd ; edx will have size of region in bytes.
  574. sub edi,ecx ; - figure size.
  575. shld ebx , ecx , 16
  576. shld esi , edi , 16
  577. int DPMI_INTR ; do call.
  578. jc ??error ; eax = 8 if mem err, eax = 9 if invalid mem region.
  579. ??code_not_locked:
  580. ; Unlock data
  581. test [InitFlags],IF_LOCKED_PM_DATA
  582. jz ??data_not_locked
  583. mov ax,0601h ; set es to descriptor of data.
  584. mov ecx,OFFSET LockedDataStart ; ecx must have start of memory.
  585. mov edi,OFFSET LockedDataEnd ; edx will have size of region in bytes.
  586. sub edi,ecx ; - figure size.
  587. shld ebx , ecx , 16
  588. shld esi , edi , 16
  589. int DPMI_INTR ; do call.
  590. jc ??error ; eax = 8 if mem err, eax = 9 if invalid mem region.
  591. ??data_not_locked:
  592. ; we have finished with success.
  593. mov [RealModePtr],0 ; To say we can do it again sometime.
  594. mov [InitFlags],0 ; To say we can do it again sometime.
  595. mov eax,1 ; signal success.
  596. ret
  597. ??error:
  598. xor eax,eax ; signal an error.
  599. ret
  600. ENDP Remove_Keyboard_Interrupt
  601. ;***************************************************************************
  602. ;* CHECK_KEY_NUM -- Checks if key in queue, return key num *
  603. ;* *
  604. ;* INPUT: none *
  605. ;* *
  606. ;* OUTPUT: Keynum of the key that was pressed, FALSE otherwise *
  607. ;*
  608. ;* PROTO: INT Check_Key_Num(VOID);
  609. ;* *
  610. ;* HISTORY: *
  611. ;* 07/14/1994 PWG : Created. *
  612. ;*=========================================================================*
  613. PROC Check_Key_Num C NEAR
  614. USES ebx,esi
  615. pushf ; save off the flags
  616. cli ; disable interrupts
  617. mov esi,[RealModePtr] ; Point to start of RM data.
  618. mov eax,[(KeyboardType PTR esi).KeyBufferHead]
  619. xor eax,[(KeyboardType PTR esi).KeyBufferTail]
  620. or eax,eax ; check to see if head == tail
  621. jz short ??fini ; if so we are done
  622. mov eax,[(KeyboardType PTR esi).KeyBufferHead] ; get the head
  623. mov ax,[(KeyboardType PTR esi+eax).KeyBuffer] ; get key num
  624. ??fini:
  625. sti
  626. popf
  627. ret
  628. ENDP Check_Key_Num
  629. ;***************************************************************************
  630. ;* GET_KEY_NUM -- Returns the next key num in ax *
  631. ;* *
  632. ;* INPUT: none *
  633. ;* *
  634. ;* OUTPUT: WORD key flags are in the high byte of return word, key *
  635. ;* num is in the low byte.
  636. ;* *
  637. ;* PROTO: WORD Get_Key_Num(VOID);
  638. ;* *
  639. ;* HISTORY: *
  640. ;* 07/14/1994 PWG : Created. *
  641. ;*=========================================================================*
  642. PROC Get_Key_Num C NEAR
  643. USES esi,edi
  644. mov esi,[RealModePtr] ; Point to start of RM data.
  645. ??wait:
  646. cli ; disable interrupts
  647. mov eax,[(KeyboardType PTR esi).KeyBufferHead] ; get the head
  648. cmp eax,[(KeyboardType PTR esi).KeyBufferTail] ; get the head
  649. jne short ??getkey
  650. sti ; enable interrupts
  651. jmp ??wait
  652. ??getkey:
  653. call Low_Get_Key
  654. sti ; enable interrupts
  655. ret
  656. ENDP Get_Key_Num
  657. ;***************************************************************************
  658. ;* KN_TO_KA -- Translates a key num to an ASCII key *
  659. ;* *
  660. ;* INPUT: WORD the keynum to translate *
  661. ;* *
  662. ;* OUTPUT: WORD the ASCII key that is returned *
  663. ;* *
  664. ;* PROTO: INT KN_To_KA(INT keynum); *
  665. ;* *
  666. ;* HISTORY: *
  667. ;* 07/15/1994 PWG : Created. *
  668. ;*=========================================================================*
  669. PROC KN_To_KA C NEAR
  670. ARG keynum:DWORD
  671. mov eax,[keynum]
  672. call near ptr Convert_Num_To_ASCII
  673. ret
  674. ENDP KN_To_KA
  675. ;***************************************************************************
  676. ;* LOW_GET_KEY -- low level get key returns key num and bits *
  677. ;* *
  678. ;* INPUT: AX - index into the buffer *
  679. ;* *
  680. ;* OUTPUT: AX - key num with bits *
  681. ;* *
  682. ;* PROTO: none - assembly callable routine only. *
  683. ;* *
  684. ;* HISTORY: *
  685. ;* 07/14/1994 PWG : Created. *
  686. ;*=========================================================================*
  687. PROC Low_Get_Key C NEAR
  688. USES ebx,esi,edi
  689. mov edi,eax ; save off value in ax
  690. ; We should set up both DS & ES because we are a low level function
  691. ; and don't know who might have called us or what the registers
  692. ; currently are.
  693. ; No reason to set DS & ES.
  694. ; This is not a hardware interrupt and if the funtion is being called
  695. ; from within a hardware interrupt then DS and ES will be preset to
  696. ; DGROUP _DATA
  697. mov esi,[RealModePtr] ; Point to start of RM data.
  698. mov ax,[(KeyboardType PTR esi+edi).KeyBuffer] ; get the head
  699. add edi,2
  700. and edi,0FFH ; 128 word circular buffer
  701. cmp al,KN_LMOUSE
  702. jb short ??cont
  703. cmp al,KN_RMOUSE
  704. ja short ??chkjoy
  705. push eax ; save off the keynum we got
  706. mov ax,[(KeyboardType PTR esi+edi).KeyBuffer] ; get the head
  707. add edi,2
  708. and edi,0FFH ; 128 word circular buffer
  709. mov [MouseQX],eax
  710. mov ax,[(KeyboardType PTR esi+edi).KeyBuffer] ; get the head
  711. add edi,2
  712. and edi,0FFH ; 128 word circular buffer
  713. mov [MouseQY],eax
  714. pop eax ; restore keynum for return
  715. jmp short ??cont
  716. ??chkjoy:
  717. cmp al,KN_JBUTTON2 ; mouse button before joystick button
  718. ja short ??cont
  719. push eax ; save off the keynum we got
  720. mov ax,[(KeyboardType PTR esi+edi).KeyBuffer] ; get the head
  721. add edi,2
  722. and edi,0FFH ; 128 word circular buffer
  723. mov ax,[(KeyboardType PTR esi+edi).KeyBuffer] ; get the head
  724. add edi,2
  725. and edi,0FFH ; 128 word circular buffer
  726. pop eax ; restore keynum for return
  727. ??cont:
  728. mov [(KeyboardType PTR esi).KeyBufferHead],edi ; set the head
  729. ??out:
  730. ret
  731. ENDP Low_Get_Key
  732. ;***************************************************************************
  733. ;* CONVERT_NUM_TO_ASCII -- Assembly routine converts keynum to ASCII key *
  734. ;* *
  735. ;* INPUT: EAX where: *
  736. ;* AH - holds the key num bits *
  737. ;* AL - holds the key num value *
  738. ;* *
  739. ;* OUTPUT: EAX where: *
  740. ;* AH - hold the key bits *
  741. ;* AL - holds the ASCII key value *
  742. ;* *
  743. ;* PROTO: none - assembly callable routine only. *
  744. ;* *
  745. ;* WARNINGS: GetKeyLock must be set prior to calling this function *
  746. ;* *
  747. ;* HISTORY: *
  748. ;* 07/15/1994 PWG : Created. *
  749. ;*=========================================================================*
  750. PROC Convert_Num_To_ASCII C NEAR
  751. USES ebx,ecx,esi,edi
  752. ;*===================================================================
  753. ;* Force all breaks to be thrown out.
  754. ;*===================================================================
  755. test eax,08000h ; If it is a button number
  756. jne short ??button ; don't process it
  757. test ah,KEYRELEASE ; If it is not key release
  758. je short ??ok ; then go process it
  759. ??button:
  760. xor eax,eax ; no ascii value for a button
  761. ret
  762. ??ok:
  763. ;*===================================================================
  764. ;* ES points to the DOSMEM selector, esi is the offset of the
  765. ;* protected mode structure.
  766. ;*===================================================================
  767. mov esi,[RealModePtr] ; Point to start of RM data.
  768. ;*===================================================================
  769. ;* Start dealing with the keys.
  770. ;*===================================================================
  771. cmp al,110 ; is it esc
  772. je ??esc ; if so then deal with it
  773. ;??chkext:
  774. cmp al,62 ; is it extended?
  775. jae short ??extended ; its extended so return ext code
  776. mov ebx,eax ; get an index
  777. and ebx,03FH ; only 0-63 allowed
  778. test ah,1 ; if not, test for shift
  779. jnz short ??shifted ; if shifted get shift value
  780. ;*===================================================================
  781. ;* Here when we have an unshifted ascii key
  782. ;*===================================================================
  783. mov al,[Ascii+ebx] ; get the ascii code for this number
  784. jmp short ??ctrlkey
  785. ;*===================================================================
  786. ;* CAPS key is on, forcing all alphabetic characters to lower case (all
  787. ;* others are shifted)
  788. ;*===================================================================
  789. ??alpha_lowered:
  790. mov al,[Alpha_Lower+ebx] ; get the s_ascii code for number
  791. jmp short ??ctrlkey
  792. ;*===================================================================
  793. ;* CAPS key is on, forcing all alphabetic characters to lower case (all
  794. ;* others are shifted)
  795. ;*===================================================================
  796. ??alpha_shifted:
  797. mov al,[Alpha_Shift+ebx] ; get the s_ascii code for number
  798. jmp short ??ctrlkey
  799. ;*===================================================================
  800. ;* Shift'ed character
  801. ;*===================================================================
  802. ??shifted:
  803. mov al,[Shift+ebx] ; get ascii shift code for number
  804. ??ctrlkey:
  805. test ah,2 ; is it ctrl?
  806. jz short ??jexit ; izf not skip ctrl check
  807. mov edi,ebx ; get index
  808. and edi,7 ; only bits 0-7
  809. mov cl,[(KeyboardType PTR esi+edi).Bits]
  810. shr ebx,3 ; div by 8 for byte offset
  811. test [(KeyboardType PTR esi+ebx).KeysCapsLock],cl
  812. je short ??jexit
  813. and al,01FH ; force to ctrl value
  814. ??jexit:
  815. jmp short ??exit
  816. ??extended:
  817. cmp al,75 ; if less than insert
  818. jb short ??special
  819. cmp al,110 ; if >= esc
  820. jae short ??funckey
  821. ??editkeys:
  822. xor ebx,ebx
  823. mov bl,al
  824. sub ebx,75 ; get value from 0-34
  825. test [(KeyboardType PTR esi).KeyFlags],NONUMLOCK
  826. jne short ??no_numpad
  827. test [GetKeyLock],NUMLOCK ; look at the snap shot of bits
  828. jne short ??numpad
  829. ??no_numpad:
  830. mov al,[Edit+ebx] ; get the ascii code for this number
  831. jmp short ??exit
  832. ??numpad:
  833. sub ebx,15 ; adjust to numpad entries
  834. mov al,[NumPad+ebx] ; get the ascii code for this number
  835. jmp short ??exit
  836. ??funckey:
  837. cmp al,112 ; if less than function keys
  838. jb short ??extout
  839. cmp al,121 ; if greater than function keys 1-10
  840. ja short ??extout
  841. mov bl,al
  842. sub bl,112 ; get value 0-9
  843. mov bh,0C5H ; function key 1 no shift-ctrl-alt
  844. test ah,7 ; any shift-ctrl-alt
  845. je short ??funcadj
  846. mov bh,098H ; function key 1 alt
  847. test ah,ALTPRESS ; (highest prescendence)
  848. jne short ??funcadj
  849. mov bh,0A2H ; function key 1 ctrl (next highest)
  850. test ah,CTRLPRESS
  851. jne short ??funcadj
  852. mov bh,0ACH ; function key 1 shift (lowest)
  853. ??funcadj:
  854. sub bh,bl ; adjust function key to a
  855. mov al,bh ; shift/no shift etc
  856. jmp short ??exit
  857. ??special:
  858. cmp al,65 ; if less than specials
  859. jb short ??extout
  860. add al,133 ; make value between 198-207 or
  861. jmp short ??exit ; 0C6H-0CFH
  862. ??extout:
  863. or al,080H
  864. jmp short ??exit
  865. ??esc:
  866. mov al,01BH
  867. ??exit:
  868. ret
  869. ENDP Convert_Num_To_ASCII
  870. ;***************************************************************************
  871. ;* CHECK_KEY -- checks for ASCII keys sitting in the keybuffer *
  872. ;* *
  873. ;* INPUT: none *
  874. ;* *
  875. ;* OUTPUT: INT the ASCII sequence for the key that was pressed *
  876. ;* *
  877. ;* PROTO: INT Check_Key(VOID); *
  878. ;* *
  879. ;* HISTORY: *
  880. ;* 07/15/1994 PWG : Created. *
  881. ;*=========================================================================*
  882. PROC Check_Key C NEAR
  883. USES ebx,edi,esi
  884. pushf
  885. cld
  886. mov ebx,[RealModePtr] ; Point to start of RM data.
  887. ??clrloop:
  888. cli ; disable interrupts
  889. mov eax,[(KeyboardType PTR ebx).KeyBufferHead]
  890. cmp eax,[(KeyboardType PTR ebx).KeyBufferTail]
  891. je short ??clrexit
  892. mov esi,eax
  893. mov ax,[(KeyboardType PTR ebx+eax).KeyBuffer] ; get key num
  894. mov edi,ebx
  895. add edi,OFFSET (KeyboardType PTR 0).PassAlways
  896. mov ecx,(OFFSET (KeyboardType PTR 0).PassAlwaysEnd-OFFSET (KeyboardType PTR 0).PassAlways)+1 ; get number of pass always
  897. repne scasb ; look for a match
  898. or ecx,ecx ; see if there was a match
  899. jne short ??getinvalid
  900. test ah,KEYRELEASE ; is this a break?
  901. jne short ??getinvalid
  902. cmp al,122 ; is code a valid ascii key??
  903. jb short ??convkey
  904. ??getinvalid:
  905. cmp al,KN_LMOUSE ; check if it is a mouse or joystick
  906. jb short ??contget
  907. cmp al,KN_JBUTTON2
  908. ja short ??contget
  909. add si,4 ; get rid of the x and y values
  910. ??contget:
  911. add esi,2 ; get rid of invalid ascii key
  912. and esi,0FFH ; 128 word circular buffer
  913. mov [(KeyboardType PTR ebx).KeyBufferHead],esi
  914. sti ; enable interrupts
  915. jmp ??clrloop
  916. ??clrexit:
  917. xor eax,eax
  918. ??convkey:
  919. mov cx,[(KeyboardType PTR ebx).KeyLock]
  920. mov [GetKeyLock],cx ; save status for convert to ASCII
  921. sti ; enable interrupts
  922. or eax,eax
  923. je short ??exit ; exit if no key
  924. ; AX has key num code with bits
  925. call near ptr Convert_Num_To_ASCII
  926. ; AX has ASCII code with bits
  927. xor ah,ah ; clear key bits
  928. ??exit:
  929. popf
  930. ret
  931. ENDP Check_Key
  932. ;***************************************************************************
  933. ;* GET_KEY -- Gets the next available ASCII keystroke. *
  934. ;* *
  935. ;* INPUT: none *
  936. ;* *
  937. ;* OUTPUT: AH - hold the key bits *
  938. ;* AL - holds the ASCII key value *
  939. ;* *
  940. ;* PROTO: INT Get_Key(VOID); *
  941. ;* *
  942. ;* HISTORY: *
  943. ;* 07/15/1994 PWG : Created. *
  944. ;*=========================================================================*
  945. PROC Get_Key C NEAR
  946. USES ebx,ecx,edi
  947. cld ; clear the direction flag for speed
  948. ; Check_Key had to be copied because of enable and disable of ints
  949. ; with mod to get the key
  950. mov ebx,[RealModePtr] ; Point to start of RM data.
  951. ??chkkey:
  952. cli ; disable interrupts
  953. mov eax,[(KeyboardType PTR ebx).KeyBufferHead]
  954. cmp eax,[(KeyboardType PTR ebx).KeyBufferTail]
  955. jne short ??getkey
  956. sti ; enable interrupts
  957. jmp ??chkkey
  958. ??getkey:
  959. ; AX has index into keybuffer
  960. call near ptr Low_Get_Key
  961. ; AX has key num code with bits
  962. mov cx,[(KeyboardType PTR ebx).KeyLock]
  963. mov [GetKeyLock],cx ; save status for convert to ASCII
  964. sti ; enable interrupts
  965. mov edi,ebx
  966. add edi,OFFSET (KeyboardType PTR 0).PassAlways
  967. mov ecx,(OFFSET (KeyboardType PTR 0).PassAlwaysEnd-OFFSET (KeyboardType PTR 0).PassAlways)+1 ; get number of pass always
  968. repne scasb ; look for a match
  969. or ecx,ecx ; see if there was a match
  970. jne ??chkkey
  971. test ah,KEYRELEASE ; is this a break?
  972. jne ??chkkey
  973. cmp al,122 ; is code a valid ascii key??
  974. jae ??chkkey
  975. ; AX has key num code with bits
  976. call near ptr Convert_Num_To_ASCII
  977. xor ah,ah
  978. ret
  979. ENDP Get_Key
  980. ;***************************************************************************
  981. ;* KEYBOARD_ATTRIBUTES_ON -- Sets the specified keyflags on *
  982. ;* *
  983. ;* INPUT: INT the keyflags that need to be turned on *
  984. ;* *
  985. ;* OUTPUT: INT the current keyflags that are on *
  986. ;* *
  987. ;* PROTO: INT Keyboard_Attributes_On(INT key_flags); *
  988. ;* *
  989. ;* HISTORY: *
  990. ;* 07/19/1994 PWG : Created. *
  991. ;*=========================================================================*
  992. PROC Keyboard_Attributes_On C NEAR
  993. USES esi,edi
  994. ARG bits:DWORD
  995. mov esi,[RealModePtr] ; Point to start of RM data.
  996. mov eax,[bits]
  997. or [(KeyboardType PTR esi).KeyFlags],eax
  998. ; Only do this if in playback or record mode.
  999. test eax,PASSBREAKS
  1000. je short ??fini
  1001. xor eax,eax
  1002. mov edi,esi
  1003. add edi,OFFSET (KeyboardType PTR 0).KeysUpDown
  1004. mov [edi],eax
  1005. mov [edi+4],eax
  1006. mov [edi+8],eax
  1007. mov [edi+12],eax
  1008. ??fini:
  1009. mov eax,[(KeyboardType PTR esi).KeyFlags]
  1010. ret
  1011. ENDP Keyboard_Attributes_On
  1012. ;***************************************************************************
  1013. ;* KEYBOARD_ATTRIBUTES_OFF -- Sets the specified keyflags off *
  1014. ;* *
  1015. ;* INPUT: INT the keyflags that need to be turned off *
  1016. ;* *
  1017. ;* OUTPUT: INT the current keyflags that are off *
  1018. ;* *
  1019. ;* PROTO: INT Keyboard_Attributes_Off(INT key_flags); *
  1020. ;* *
  1021. ;* HISTORY: *
  1022. ;* 07/19/1994 PWG : Created. *
  1023. ;*=========================================================================*
  1024. PROC Keyboard_Attributes_Off C NEAR
  1025. USES esi
  1026. ARG bits:DWORD
  1027. mov esi,[RealModePtr] ; Point to start of RM data.
  1028. mov eax,[bits]
  1029. not eax
  1030. and [(KeyboardType PTR esi).KeyFlags],eax
  1031. xor eax,eax
  1032. mov eax,[(KeyboardType PTR esi).KeyFlags]
  1033. ret
  1034. ENDP Keyboard_Attributes_Off
  1035. ;***************************************************************************
  1036. ;* CLEAR_KEYBUFFER -- Clears keystrokes out of the key buffer *
  1037. ;* *
  1038. ;* INPUT: none *
  1039. ;* *
  1040. ;* OUTPUT: none *
  1041. ;* *
  1042. ;* PROTO: VOID Clear_KeyBuffer(VOID); *
  1043. ;* *
  1044. ;* HISTORY: *
  1045. ;* 07/19/1994 PWG : Created. *
  1046. ;*=========================================================================*
  1047. PROC Clear_KeyBuffer C NEAR
  1048. USES eax,esi
  1049. mov esi,[RealModePtr] ; Point to start of RM data.
  1050. cli
  1051. mov eax,[(KeyboardType PTR esi).KeyBufferHead]
  1052. mov [(KeyboardType PTR esi).KeyBufferTail],eax
  1053. sti
  1054. ret
  1055. ENDP Clear_KeyBuffer
  1056. ;***************************************************************************
  1057. ;* KEY_DOWN -- tests the status of a keyboard key *
  1058. ;* *
  1059. ;* INPUT: INT the key num to check *
  1060. ;* *
  1061. ;* OUTPUT: INT zero if the key is up, none zero if the key is down *
  1062. ;* *
  1063. ;* PROTO: INT Key_Down(INT key); *
  1064. ;* *
  1065. ;* HISTORY: *
  1066. ;* 07/19/1994 PWG : Created. *
  1067. ;*=========================================================================*
  1068. PROC Key_Down C NEAR
  1069. USES ebx,ecx,edi,esi
  1070. ARG key:DWORD
  1071. push [key]
  1072. call KeyNum_Translate
  1073. add esp,4
  1074. xor ah,ah ; Always ignore the control bits.
  1075. mov esi,[RealModePtr] ; Point to start of RM data.
  1076. mov edi,eax
  1077. shr edi,3
  1078. mov cl,al
  1079. and cl,0111b
  1080. mov al,01b
  1081. shl al,cl
  1082. and al,[(KeyboardType PTR esi+edi).KeysUpDown]
  1083. ret
  1084. ENDP Key_Down
  1085. ;***************************************************************************
  1086. ;* CHECK_KEY_BITS -- checks ascii key in key buff with shift,ctrl,alt bits *
  1087. ;* *
  1088. ;* INPUT: none *
  1089. ;* *
  1090. ;* OUTPUT: INT 0 = no key in buffer, !0 = a key with the bits set *
  1091. ;* *
  1092. ;* PROTO: INT Check_Key_Bits(VOID); *
  1093. ;* *
  1094. ;* HISTORY: *
  1095. ;* 07/20/1994 PWG : Created. *
  1096. ;*=========================================================================*
  1097. PROC Check_Key_Bits C NEAR
  1098. USES ebx,ecx,edi,esi
  1099. pushf ; save off the direction flag
  1100. cld ; we will go forward
  1101. mov ebx,[RealModePtr] ; Point to start of RM data.
  1102. ??clrloop:
  1103. cli ; disable interrupts
  1104. mov eax,[(KeyboardType PTR ebx).KeyBufferHead]
  1105. cmp eax,[(KeyboardType PTR ebx).KeyBufferTail]
  1106. je short ??clrexit
  1107. ??playback:
  1108. mov esi,eax
  1109. mov ax,[(KeyboardType PTR ebx+eax).KeyBuffer] ; get key num
  1110. mov edi,ebx
  1111. add edi,OFFSET (KeyboardType PTR 0).PassAlways
  1112. mov ecx,(OFFSET (KeyboardType PTR 0).PassAlwaysEnd-OFFSET (KeyboardType PTR 0).PassAlways)+1 ; get number of pass always
  1113. repne scasb ; look for a match
  1114. or ecx,ecx ; see if there was a match
  1115. jne short ??getinvalid
  1116. ;------ If there is a NULL in the keyboard buffer, we must NOT treat it
  1117. ; as a valid ASCII value because the calling code will falsely
  1118. ; assume that the NULL return value indicates an empty buffer.
  1119. or al,al
  1120. je short ??getinvalid
  1121. cmp al,122 ; is code a valid ascii key??
  1122. jb short ??convkey
  1123. ??getinvalid:
  1124. add esi,2 ; get rid of invalid ascii key
  1125. and esi,0FFH ; 128 word circular buffer
  1126. mov [(KeyboardType PTR ebx).KeyBufferHead],esi
  1127. sti ; enable interrupts
  1128. jmp ??clrloop
  1129. ??clrexit:
  1130. xor ax,ax
  1131. ??convkey:
  1132. mov cx,[(KeyboardType PTR ebx).KeyLock]
  1133. mov [GetKeyLock],cx ; save status for convert to ASCII
  1134. sti ; enable interrupts
  1135. or eax,eax
  1136. je short ??exit ; exit if no key
  1137. ; AX has key num code with bits
  1138. mov ch,ah
  1139. and ch,KEYRELEASE ; keep only KEYRELEASE bit
  1140. and ah,NOTKEYRELEASE ; keep everything but KEYRELEASE bit
  1141. call near ptr Convert_Num_To_ASCII
  1142. ; AX has ASCII code with bits
  1143. or ah,ch ; replace KEYRELEASE bit
  1144. ??exit:
  1145. popf
  1146. ret
  1147. ENDP Check_Key_Bits
  1148. ;***************************************************************************
  1149. ;* GET_KEY_BITS -- Gets ascii key in key buff with shift,ctrl,alt bits *
  1150. ;* *
  1151. ;* INPUT: none *
  1152. ;* *
  1153. ;* OUTPUT: INT 0 = no key in buffer, !0 = a key with the bits set *
  1154. ;* *
  1155. ;* PROTO: INT Check_Key_Bits(VOID); *
  1156. ;* *
  1157. ;* HISTORY: *
  1158. ;* 07/20/1994 PWG : Created. *
  1159. ;*=========================================================================*
  1160. PROC Get_Key_Bits C NEAR
  1161. USES ebx,ecx,edi
  1162. cld
  1163. ; Check_Key_Bits was copied because of enable and disable of interrupts
  1164. ; with mod to get the key
  1165. mov ebx,[RealModePtr] ; Point to start of RM data.
  1166. ??chkkey:
  1167. cli ; disable interrupts
  1168. mov eax,[(KeyboardType PTR ebx).KeyBufferHead]
  1169. cmp eax,[(KeyboardType PTR ebx).KeyBufferTail]
  1170. jne short ??getkey
  1171. sti ; enable interrupts
  1172. jmp ??chkkey
  1173. ??getkey:
  1174. ; AX has index into keybuffer
  1175. call near ptr Low_Get_Key
  1176. ; AX has key num code with bits
  1177. mov cx,[(KeyboardType PTR ebx).KeyLock]
  1178. mov [GetKeyLock],cx ; save status for convert to ASCII
  1179. sti ; enable interrupts
  1180. mov edi,ebx
  1181. add edi,OFFSET (KeyboardType PTR 0).PassAlways
  1182. mov ecx,(OFFSET (KeyboardType PTR 0).PassAlwaysEnd-OFFSET (KeyboardType PTR 0).PassAlways)+1 ; get number of pass always
  1183. repne scasb ; look for a match
  1184. or ecx,ecx ; see if there was a match
  1185. jne ??chkkey
  1186. cmp al,122 ; is code a valid ascii key??
  1187. jae ??chkkey
  1188. ; AX has key num code with bits
  1189. mov ch,ah
  1190. and ch,KEYRELEASE ; keep only KEYRELEASE bit
  1191. and ah,NOTKEYRELEASE ; keep everything but KEYRELEASE bit
  1192. call near ptr Convert_Num_To_ASCII
  1193. ; AX has ASCII code with bits
  1194. or ah,ch ; replace KEYRELEASE bit
  1195. ret
  1196. ENDP Get_Key_Bits
  1197. ;***************************************************************************
  1198. ;* KEY_SATISFIED -- checks to see if the given key is satisfied *
  1199. ;* *
  1200. ;* INPUT: INT the key flags/number to check *
  1201. ;* *
  1202. ;* OUTPUT: INT 0 if the key is not satisfied, !0 if the key is satisfied *
  1203. ;* *
  1204. ;* PROTO: VOID Key_Satisfied(INT key); *
  1205. ;* *
  1206. ;* HISTORY: *
  1207. ;* 07/20/1994 PWG : Created. *
  1208. ;*=========================================================================*
  1209. PROC Key_Satisfied C NEAR
  1210. USES ebx,ecx,esi,edi
  1211. ARG key:DWORD
  1212. mov eax,[key]
  1213. mov ebx,eax ; save key code
  1214. push eax
  1215. call Key_Down ; see it its even down
  1216. add esp,4
  1217. cmp eax,0
  1218. je ??out ; if not it can't be satisfied
  1219. mov esi,[RealModePtr] ; Point to start of RM data.
  1220. mov eax,ebx ; if so, restore code
  1221. xor ah,ah ; clear out flags area
  1222. mov edi,eax ; set as an index
  1223. shr edi,3 ; div by 8 for bytes
  1224. mov ch,1h ; set a bit for mask
  1225. mov cl,al ; get the code number
  1226. and cl,7 ; get the actual bit this code is
  1227. shl ch,cl ; move bit into mask position
  1228. ; now test the ctrl,alt and shift bits
  1229. test [(KeyboardType PTR esi+7).KeysUpDown],04h ; is the left ctrl down?
  1230. jne short ??ctrlon ; if so, ctrl is on
  1231. test [(KeyboardType PTR esi+8).KeysUpDown],01h ; is the right ctrl down?
  1232. je short ??ctrloff ; if not, neither are down, no ctrl
  1233. ??ctrlon:
  1234. or ah,02h ; or on the ctrl bit in flags
  1235. ??ctrloff:
  1236. test [(KeyboardType PTR esi+7).KeysUpDown],50h ; is either alt key down?
  1237. je short ??altoff
  1238. or ah,04h ; or on the alt bit in flags
  1239. ??altoff:
  1240. test [(KeyboardType PTR esi+5).KeysUpDown],10h ; is the left shift down?
  1241. jne short ??shifton ; if so the sift is on
  1242. test [(KeyboardType PTR esi+7).KeysUpDown],02h ; is the right shift down?
  1243. je short ??shiftoff ; if not then neither shift is down
  1244. ??shifton:
  1245. or ah,01h ; or on the shift bit in flags
  1246. ??shiftoff:
  1247. test [(KeyboardType PTR esi).KeyLock],CAPSLOCK ; is the caps lock on?
  1248. je short ??capsoff ; if not don't worry about it
  1249. test ch,[(KeyboardType PTR esi+edi).KeysCapsLock] ; get code for keycaps
  1250. je short ??capsoff ; its not effected
  1251. xor ah,1h ; toggle the shift flag
  1252. ??capsoff:
  1253. test [(KeyboardType PTR esi).KeyLock],NUMLOCK ; is the num lock key on?
  1254. je short ??numlockoff ; if not don't worry about it
  1255. test ch,[(KeyboardType PTR esi+edi).KeysNumLock] ; get code for numlock
  1256. je short ??numlockoff ; if not effected skip toggle
  1257. xor ah,1h ; toggle the shift flag if effected
  1258. ??numlockoff:
  1259. mov al,0ffh ; set to match by default
  1260. cmp ah,bh ; if flags match return !0
  1261. je short ??out ; just exit
  1262. xor eax,eax ; otherwise, clear all bits FALSE
  1263. ??out:
  1264. or eax,eax
  1265. ret
  1266. ENDP Key_Satisfied
  1267. ;***************************************************************************
  1268. ;* Interrupt routines start here - Interrupts must be within the Locked
  1269. ;* code area for DPMI compatability.
  1270. ;***************************************************************************
  1271. LABEL LockedCodeStart BYTE
  1272. ;***************************************************************************
  1273. ;* KEYNUM_TRANSLATE -- Performs a lowlevel xlate to a keycode *
  1274. ;* *
  1275. ;* INPUT: WORD the code that needs to be translated *
  1276. ;* *
  1277. ;* OUTPUT: WORD the translated code *
  1278. ;* *
  1279. ;* PROTO: INT KeyNum_Translate(INT keynum); *
  1280. ;* *
  1281. ;* HISTORY: *
  1282. ;* 07/15/1994 PWG : Created. *
  1283. ;*=========================================================================*
  1284. PROC KeyNum_Translate C NEAR
  1285. USES ebx,ecx,esi,edi
  1286. ARG keycode:DWORD
  1287. ;*===================================================================
  1288. ;* ES points to the DOSMEM selector, esi is the offset of the
  1289. ;* protected mode structure.
  1290. ;*===================================================================
  1291. mov esi,[RealModePtr] ; Point to start of RM data.
  1292. mov eax,[keycode]
  1293. test [(KeyboardType PTR esi).KeyFlags],TRACKEXT
  1294. jne short ??fini
  1295. mov ecx,OFFSET ((KeyboardType PTR 0).ExtRemap)- OFFSET((KeyboardType PTR 0).ExtNums)
  1296. mov edi,OFFSET (KeyboardType PTR 0).ExtNums
  1297. add edi,esi
  1298. repne scasb
  1299. jcxz short ??fini ; No match found.
  1300. mov edi,esi
  1301. add edi,OFFSET (KeyboardType PTR 0).ExtRemapEnd
  1302. dec edi
  1303. sub edi,ecx
  1304. mov al,[edi]
  1305. ??fini:
  1306. ret
  1307. ENDP KeyNum_Translate
  1308. ;***************************************************************************
  1309. ;* STUFF_KEY_WORD -- Stuffs a word of data into keyboard buffer *
  1310. ;* *
  1311. ;* INPUT: WORD the code to stick into the circular buffer *
  1312. ;* *
  1313. ;* OUTPUT: WORD !=0 is sucessful, ==0 is not enough room *
  1314. ;* *
  1315. ;* PROTO: VOID Stuff_Key_WORD(INT code); *
  1316. ;* *
  1317. ;* HISTORY: *
  1318. ;* 07/11/1994 PWG : Created. *
  1319. ;*=========================================================================*
  1320. PROC Stuff_Key_WORD C NEAR
  1321. USES ebx,esi,edi
  1322. ARG code:WORD
  1323. mov esi,[RealModePtr] ; Point to start of RM data.
  1324. mov eax,[(KeyboardType PTR esi).KeyBufferTail]
  1325. mov edi,eax
  1326. add eax,2
  1327. and eax,0FFh ; New KeyBufferTail value.
  1328. cmp [(KeyboardType PTR esi).KeyBufferHead],eax
  1329. je short ??noroom
  1330. mov bx,[code]
  1331. mov [(KeyboardType PTR esi+edi).KeyBuffer],bx ; Record the keystroke.
  1332. mov [(KeyboardType PTR esi).KeyBufferTail],eax
  1333. xor eax,eax
  1334. ret
  1335. ??noroom:
  1336. mov eax,1
  1337. ret
  1338. ENDP Stuff_Key_WORD
  1339. ;***************************************************************************
  1340. ;* STUFF_KEY_NUM -- Stuffs a key num code into the circular buffer *
  1341. ;* *
  1342. ;* INPUT: WORD the keycode to stuff *
  1343. ;* *
  1344. ;* OUTPUT: WORD !=0 is sucessful, ==0 is not enough room *
  1345. ;* *
  1346. ;* PROTO: VOID Stuff_Key_Num(INT keynum); *
  1347. ;* *
  1348. ;* HISTORY: *
  1349. ;* 07/11/1994 PWG : Created. *
  1350. ;*=========================================================================*
  1351. PROC Stuff_Key_Num C NEAR
  1352. USES ebx,ecx,edx,edi,esi
  1353. ARG keycode:DWORD
  1354. LOCAL tail:DWORD ; Original keybuffer tail (safety copy).
  1355. LOCAL size:WORD ; Size of write.
  1356. ; for the moment we do not check for the interrupt flag
  1357. ; mov eax,2534h ; function to get the interrupt status
  1358. ; int 21 ; eax = interrupt status
  1359. ; push eax ; save the result on the stack
  1360. pushf ; store off the flags
  1361. cli ; disable interrupts
  1362. ; We need to set the data segment because we might be being called
  1363. ; from within an interrupt
  1364. ; Soo, if that is the case then DS & ES point to DGROUP _DATA
  1365. mov esi,[RealModePtr] ; Point to start of RM data.
  1366. ; Record the mouse position to be stuffed into buffer.
  1367. mov eax,[(KeyboardType PTR esi).MouseX]
  1368. mov [(KeyboardType PTR esi).LocalMouseX],ax
  1369. mov eax,[(KeyboardType PTR esi).MouseY]
  1370. mov [(KeyboardType PTR esi).LocalMouseY],ax
  1371. ??cando:
  1372. mov eax,[keycode] ; get the code
  1373. or eax,eax ; Null keycodes are not recorded.
  1374. jne short ??validkey
  1375. jmp ??exit
  1376. ??validkey:
  1377. test [(KeyboardType PTR esi).KeyFlags],KEYMOUSE ; is the numeric keypad moving the mouse?
  1378. je ??no_pad_move
  1379. ; ALT-cursor keys are undefined. Pass them on to the program.
  1380. test ah,ALTPRESS ; is either alt key down?
  1381. jne ??no_pad_move
  1382. test [(KeyboardType PTR esi).KeyFlags],SIMLBUTTON ; are we simulating left mouse presses
  1383. je short ??chkinsert
  1384. cmp al,KN_RETURN
  1385. je short ??forceleft
  1386. cmp al,KN_SPACE
  1387. je short ??forceleft
  1388. cmp al,KN_KEYPAD_RETURN
  1389. je short ??forceleft
  1390. ??chkinsert:
  1391. cmp al,KN_INSERT
  1392. jne short ??regular
  1393. ??forceleft:
  1394. mov al,KN_LMOUSE
  1395. or [(KeyboardType PTR esi).Button],1 ; Left mouse bit.
  1396. test ah,KEYRELEASE
  1397. je ??mousefake
  1398. and [(KeyboardType PTR esi).Button],NOT 1
  1399. jmp ??mousefake
  1400. ??regular:
  1401. cmp al,KN_DELETE
  1402. jne short ??regular2
  1403. mov al,KN_RMOUSE
  1404. or [(KeyboardType PTR esi).Button],2 ; Right mouse bit.
  1405. test ah,KEYRELEASE
  1406. je ??mousefake
  1407. and [(KeyboardType PTR esi).Button],NOT 2
  1408. jmp ??mousefake
  1409. ??regular2:
  1410. ; DRD correction to ignore key releases for key mouse movement
  1411. test ah,KEYRELEASE
  1412. jne ??no_pad_move
  1413. cmp al,KN_CENTER
  1414. je short ??pad_move
  1415. cmp al,KN_UPLEFT ; less than upleft?
  1416. jb ??no_pad_move ; yes, then it isn't a keypad key
  1417. cmp al,KN_DOWNRIGHT ; greater than downright?
  1418. ja ??no_pad_move ; yes, then it isn't a keypad key
  1419. cmp al,KN_DOWNLEFT ; is it UPLEFT, LEFT, or DOWNLEFT?
  1420. jbe short ??pad_move
  1421. cmp al,KN_UPRIGHT ; is it UPRIGHT, RIGHT, or DOWNRIGHT?
  1422. jae short ??pad_move
  1423. cmp al,KN_UP ; up?
  1424. je short ??pad_move
  1425. cmp al,KN_DOWN ; down?
  1426. jne ??no_pad_move
  1427. ??pad_move:
  1428. ; DRD correction to use ch for ah
  1429. mov ch,ah ; save shift-ctrl-alt-rlse status
  1430. xor ah,ah ; get rid of any bits
  1431. xor ebx,ebx
  1432. sub al,KN_UPLEFT ; get a number between 0 and 12
  1433. mov bx,ax
  1434. shl ebx,1 ; double for WORD index
  1435. mov ax,[WORD PTR ((KeyboardType PTR esi+ebx).XYAdjust)]
  1436. movsx ebx,ah
  1437. movsx eax,al
  1438. ; DRD correction to use ch
  1439. ; The CTRL key moves the mouse to the edge of the screen.
  1440. test ch,CTRLPRESS ; is either ctrl key down?
  1441. jne short ??ctrlon ; if so, ctrl is on
  1442. ; DRD correction to use ch
  1443. ; use fast speed of the mouse move if the shift key is held down.
  1444. mov edx,1 ; for slow speed
  1445. test ch,SHIFTPRESS ; is either shift key down?
  1446. je short ??normspeed ; if not then neither shift is down
  1447. ??doublespeed:
  1448. add edx,3 ; for fast speed
  1449. ??normspeed:
  1450. add ebx,edx ; add speed for y index
  1451. mov bl,[(KeyboardType PTR esi+ebx).KeyMouseMove] ; get speed for y delta
  1452. movsx ebx,bl
  1453. xchg ebx,edx ; save mouse y delta
  1454. add ebx,eax ; add speed for x index
  1455. mov al,[(KeyboardType PTR esi+ebx).KeyMouseMove] ; get speed for x delta
  1456. movsx eax,al
  1457. xchg ebx,edx ; restore mouse y delta
  1458. jmp short ??ctrloff
  1459. ??ctrlon:
  1460. ; Table lookup method for determining hotkey positions for CTRL
  1461. ; cursor combination. This algorithm is hard coded for an ADJUST
  1462. ; value of 3. If this value changed, then this section will also
  1463. ; have to be modified.
  1464. and ebx,011b ; Y = 1, 0, 3
  1465. and eax,011b ; X = 1, 0, 3
  1466. ; Table lookup method for determining hotkey positions for CTRL
  1467. ; cursor combination. This algorithm is hard coded.
  1468. ; -1, 0, 1
  1469. and ebx,011b ; Y = 3, 0, 1
  1470. and eax,011b ; X = 3, 0, 1
  1471. shl ebx,2
  1472. or ebx,eax ; Lookup index.
  1473. ; Convert raw index into logical (clockwise) index.
  1474. shl ebx,1
  1475. movzx ebx,[(KeyboardType PTR esi+ebx).EdgeConv]
  1476. shl ebx,2
  1477. mov ax,[(KeyboardType PTR esi+ebx).ScreenEdge] ; New absolute X
  1478. mov bx,[(KeyboardType PTR esi+ebx+2).ScreenEdge] ; New absolute Y
  1479. mov [(KeyboardType PTR esi).LocalMouseX],ax
  1480. mov [(KeyboardType PTR esi).LocalMouseY],bx
  1481. ??set_xyz:
  1482. mov ax,[(KeyboardType PTR esi).LocalMouseX] ; get new mouse x,y
  1483. mov bx,[(KeyboardType PTR esi).LocalMouseY]
  1484. jmp short ??set_xy
  1485. ; Process a normal faked mouse move.
  1486. ??ctrloff:
  1487. ; DRD change
  1488. add [(KeyboardType PTR esi).LocalMouseX],ax ; save it in our local
  1489. jns short ??not_negative_x
  1490. xor eax,eax
  1491. mov [(KeyboardType PTR esi).LocalMouseX],ax ; clear our local
  1492. ??not_negative_x:
  1493. ; DRD change
  1494. add [(KeyboardType PTR esi).LocalMouseY],bx ; save it in our local
  1495. jns short ??not_negative_y
  1496. xor ebx,ebx
  1497. mov [(KeyboardType PTR esi).LocalMouseY],bx ; clear our local
  1498. ??not_negative_y:
  1499. mov ax,[(KeyboardType PTR esi).LocalMouseX] ; get new mouse x,y
  1500. mov bx,[(KeyboardType PTR esi).LocalMouseY]
  1501. cmp ax,MAX_X_PIXEL ; bigger than
  1502. jle short ??check_y
  1503. mov ax,MAX_X_PIXEL
  1504. ??check_y:
  1505. cmp bx,MAX_Y_PIXEL ; bigger than
  1506. jle short ??set_xy
  1507. mov bx,MAX_Y_PIXEL
  1508. ??set_xy:
  1509. mov [(KeyboardType PTR esi).LocalMouseX],ax
  1510. mov [(KeyboardType PTR esi).LocalMouseY],bx
  1511. mov [WORD PTR (KeyboardType PTR esi).MouseX],ax
  1512. mov [WORD PTR (KeyboardType PTR esi).MouseY],bx
  1513. cmp [(KeyboardType PTR esi).MouseUpdate],0 ; wait until mouse interrupt is done
  1514. jne short ??noshow
  1515. ; PWG: ARRGGGHHHH!
  1516. ; call Low_Hide_Mouse
  1517. ; call Low_Show_Mouse
  1518. ??noshow:
  1519. mov eax,KN_MOUSE_MOVE
  1520. ??mousefake:
  1521. mov [keycode],eax ; Fake a MOUSE_MOVE event.
  1522. ??no_pad_move:
  1523. ; Fetch working pointers to the keyboard ends.
  1524. mov edi,[(KeyboardType PTR esi).KeyBufferTail]
  1525. mov [tail],edi ; Safety record.
  1526. ; Record the base keycode (if there is room).
  1527. cwde
  1528. push eax
  1529. call Stuff_Key_WORD
  1530. add esp,4
  1531. or eax,eax
  1532. jne short ??jmpnoroom
  1533. ; Also record the mouse coordinates if necessary.
  1534. mov eax,[keycode] ; get key code
  1535. cmp al,KN_MOUSE_MOVE ; mouse move?
  1536. je short ??recordmouse ; yes? then record the mouse cooordinates
  1537. cmp al,KN_LMOUSE
  1538. je short ??recordmouse
  1539. cmp al,KN_RMOUSE
  1540. je short ??recordmouse
  1541. jmp short ??ok
  1542. ??jmpnoroom:
  1543. jmp ??noroom
  1544. ; Record mouse coordinate X.
  1545. ??recordmouse:
  1546. movzx eax,[(KeyboardType esi).LocalMouseX]
  1547. push eax
  1548. call Stuff_Key_WORD
  1549. add esp,4
  1550. or eax,eax
  1551. jne ??jmpnoroom
  1552. add [size],2
  1553. ; Record mouse coordinate Y.
  1554. movzx eax,[(KeyboardType esi).LocalMouseY]
  1555. push eax
  1556. call Stuff_Key_WORD
  1557. add esp,4
  1558. or eax,eax
  1559. jne ??jmpnoroom
  1560. add [size],2
  1561. ??ok:
  1562. ; If PASSBREAKS is not active and this is a keyboard
  1563. ; break AND it is not a mouse event, then don't put
  1564. ; it into the buffer.
  1565. mov ebx,0101h ; Bit control tools.
  1566. mov eax,[keycode]
  1567. cmp al,KN_MOUSE_MOVE
  1568. je short ??notreal
  1569. cmp al,127
  1570. je short ??notreal
  1571. test ah,KEYRELEASE
  1572. je short ??real
  1573. xor bl,bl
  1574. test [(KeyboardType PTR esi).KeyFlags],PASSBREAKS
  1575. jne short ??real
  1576. cmp al,KN_LMOUSE
  1577. je short ??real
  1578. cmp al,KN_RMOUSE
  1579. je short ??real
  1580. ??notreal:
  1581. mov [(KeyboardType esi).KeyBufferTail],edi ; Nullify any KeyBufferTail changes.
  1582. ??real:
  1583. ; Update the KeysUpDown bit array.
  1584. mov edi,eax
  1585. and edi,07Fh
  1586. mov cl,3
  1587. shr edi,cl ; DI = Byte offset into bit table.
  1588. mov cl,al
  1589. and cl,0111b ; CL = Bit offset into bit table byte.
  1590. shl bx,cl
  1591. not bh
  1592. ; If this is a reapeat key and the key is already being held
  1593. ; down, then don't stuff it into the keyboard buffer.
  1594. test bl,[(KeyboardType esi+edi).KeysUpDown]
  1595. je short ??notalready
  1596. test [(KeyboardType PTR esi).KeyFlags],REPEATON
  1597. jne short ??notalready
  1598. mov edx,[tail]
  1599. mov [(KeyboardType esi).KeyBufferTail],edx ; Nullify any KeyBufferTail changes.
  1600. ??notalready:
  1601. and [(KeyboardType esi+edi).KeysUpDown],bh ; Force key bit to zero.
  1602. or [(KeyboardType esi+edi).KeysUpDown],bl ; Insert key bit as appropriate.
  1603. ;??notreal:
  1604. ; Successful keybuffer stuff could result in a
  1605. ??norecord:
  1606. mov eax,1
  1607. jmp short ??exit
  1608. ; Unsuccessful keybuffer stuff.
  1609. ??noroom:
  1610. mov eax,[tail]
  1611. mov [(KeyboardType PTR esi).KeyBufferTail],eax
  1612. xor eax,eax ; Signal an error.
  1613. ??exit:
  1614. sti
  1615. popf
  1616. ; popf
  1617. ; pop ebx
  1618. ; or ebx,ebx
  1619. ; jz ??final_exit
  1620. ; sti
  1621. ??final_exit:
  1622. ret
  1623. ENDP Stuff_Key_Num
  1624. ;***************************************************************************
  1625. ;* BREAK_INTERRUPT -- Handles break interrupt for protected mode *
  1626. ;* *
  1627. ;* INPUT: none *
  1628. ;* *
  1629. ;* OUTPUT: none *
  1630. ;* *
  1631. ;* WARNINGS: This is an interrupt routine. *
  1632. ;* *
  1633. ;* HISTORY: *
  1634. ;* 07/28/1994 PWG : Created. *
  1635. ;*=========================================================================*
  1636. PROC Break_Interrupt C NEAR
  1637. iret
  1638. ENDP Break_Interrupt
  1639. IF DEBUG
  1640. ;***************************************************************************
  1641. ;* DEBUG_INTERRUPT -- Handles debug (INT 3) interrupt for protected mode *
  1642. ;* *
  1643. ;* INPUT: none *
  1644. ;* *
  1645. ;* OUTPUT: none *
  1646. ;* *
  1647. ;* WARNINGS: This is an interrupt routine. *
  1648. ;* *
  1649. ;* HISTORY: *
  1650. ;* 07/28/1994 PWG : Created. *
  1651. ;*=========================================================================*
  1652. PROC Debug_Interrupt C NEAR
  1653. ;*==================================================================
  1654. ;* Setup fake Interrupt entry sequence so that we can execute our
  1655. ;* code and then IRET painlessly into the debuggers interrupt
  1656. ;* handler.
  1657. ;*==================================================================
  1658. pushfd ; Step 1
  1659. sub esp,8 ; Step 2
  1660. push ebp ; Step 3
  1661. mov ebp,esp ; Set up a stack frame to know where to poke address.
  1662. ;*==================================================================
  1663. ;* Preserve all of the registers that we intend to use.
  1664. ;*=======================================Dbg========================
  1665. pushad
  1666. push ds es gs fs
  1667. cld
  1668. mov ax , _DATA
  1669. mov ds , ax
  1670. mov es , ax
  1671. inc [BYTE PTR 0B0000h]
  1672. ;*==================================================================
  1673. ;* Setup the pointers to the real mode data and the protected mode
  1674. ;* data and selectors.
  1675. ;*==================================================================
  1676. mov esi,[RealModePtr] ; Point to start of RM data.
  1677. ;*==================================================================
  1678. ;* Do the deed.
  1679. ;*==================================================================
  1680. mov [(KeyboardType PTR esi).KeyIntDisabled],1
  1681. ;*==================================================================
  1682. ;* Now get the address of the real debug handler and poke it into
  1683. ;* the stack so we can IRET to it.
  1684. ;*==================================================================
  1685. mov eax,[(KeyboardType PTR esi).DbgOldPMIOffset] ; Get orig offset.
  1686. mov ebx,[(KeyboardType PTR esi).DbgOldPMISelector] ; Get orig selector.
  1687. mov [ss:ebp+4],eax ; Poke offset.
  1688. mov [ss:ebp+8],ebx ; Poke selector.
  1689. ;*==================================================================
  1690. ;* Restore the stack so it looks like we just did an IRET entry
  1691. ;*==================================================================
  1692. pop fs gs es ds
  1693. popad
  1694. pop ebp
  1695. ;*==================================================================
  1696. ;* This iret should go directly to the real debugger handler
  1697. ;* painlessly and effectively.
  1698. ;*==================================================================
  1699. iretd
  1700. ENDP Debug_Interrupt
  1701. ENDIF
  1702. IF PROT_INT_ENABLE
  1703. ;***************************************************************************
  1704. ;* KEYBOARD_INTERRUPT -- Handles input that comes from the keyboard *
  1705. ;* *
  1706. ;* This routine intercepts the key codes on their way to the *
  1707. ;* BIOS. With the adjustment of the Flags described above *
  1708. ;* you can get a wide variety of effects. *
  1709. ;* *
  1710. ;* INPUT: none *
  1711. ;* *
  1712. ;* OUTPUT: none *
  1713. ;* *
  1714. ;* WARNINGS: This is an interrupt function *
  1715. ;* *
  1716. ;* HISTORY: *
  1717. ;* 07/13/1994 PWG : Created. *
  1718. ;*=========================================================================*
  1719. PROC Keyboard_Interrupt C NEAR
  1720. ; This routine will do what it needs to,
  1721. ; then it will decide if the old vector should be called.
  1722. ; if so, it calls it and never returns to this function.
  1723. ; if not, we do our own return.
  1724. ; the method for doing this is found in:
  1725. ; "Phar Lap TNT DOS-Extender Reference Manual, First Addition, p. 142"
  1726. ; It says:
  1727. ; 1 - Execute a PUSHFD to save the current flags.
  1728. ; 2 - Dec the stack ptr by 8 bytes to save room for the addr of orig handler
  1729. ; 3 - Push register I use.
  1730. ; 4 - Do any processing.
  1731. ; 5 - Put the address of the original handler in the reserved slot.
  1732. ; 6 - Pop saved register values
  1733. ; 7 - Execute an IRETD to transfer control to original handler.
  1734. pushfd ; Step 1
  1735. sub esp,8 ; Step 2
  1736. push ebp ; Step 3
  1737. mov ebp,esp ; Set up a stack frame to know where to poke address.
  1738. pushad
  1739. push ds es gs fs
  1740. cld
  1741. ; this is the part of the interrupt that set the segment registers
  1742. mov ax , _DATA
  1743. mov es , ax
  1744. mov ds , ax
  1745. mov esi,[RealModePtr] ; Point to start of RM data.
  1746. mov edx,[(KeyboardType PTR esi).KeyFlags]
  1747. ;*** The following fix allows proper caps and num lock tracking on Tandy
  1748. ; 10-6-89 LJC, DRD
  1749. and [(KeyboardType PTR esi).KeyLock],NOT (NUMLOCK OR CAPSLOCK); assume caps and num inactive
  1750. test [BYTE PTR 417H],040H ; test Caps lock bit in BIOS
  1751. je short ??bioscapsoff ; skip activate code
  1752. or [(KeyboardType PTR esi).KeyLock],CAPSLOCK ; Caps Lock active
  1753. ??bioscapsoff:
  1754. test [BYTE PTR 417H],020H ; test Num lock bit in BIOS
  1755. je short ??biosnumoff ; skip activate code
  1756. or [(KeyboardType PTR esi).KeyLock],NUMLOCK ; Num Lock active
  1757. ??biosnumoff:
  1758. mov [(KeyboardType PTR esi).ExtKeyboard],TRUE ; assume 101/102-key keyboard
  1759. test [BYTE PTR 496H],010H ; test for 101/102-key keyboard
  1760. jne short ??extkeyboard ; skip deactivate code
  1761. mov [(KeyboardType PTR esi).ExtKeyboard],FALSE ; no 101/102-key keyboard
  1762. ??extkeyboard:
  1763. xor ah,ah ; clear ctrl flags to 0
  1764. mov ebx,0101H ; set key to a make by default
  1765. in al,KEYDATA ; get a code from the keyboard
  1766. ;
  1767. ; New CODE to montior key stream
  1768. ;
  1769. xor ebx,ebx
  1770. mov bx,[(KeyboardType PTR esi).KeyStreamIndex]
  1771. mov [(KeyboardType PTR esi+ebx).KeyStream],al
  1772. inc ebx
  1773. and ebx,15
  1774. mov [(KeyboardType PTR esi).KeyStreamIndex],bx
  1775. mov ebx,0101H ; set key to a make by default
  1776. ;
  1777. ; END OF SEQUENCE
  1778. ;
  1779. ;
  1780. ; Handle the PAUSE key being pressed. If it is pressed, then
  1781. ; signal that the next two input codes are to be thrown out.
  1782. ;
  1783. cmp al,0E1H ; see if this is a pause/break
  1784. jne short ??notpcode ; not a pause/break start code
  1785. mov [(KeyboardType PTR esi).LastKeyE1],3 ; absorb this and next two codes
  1786. ??notpcode:
  1787. cmp [(KeyboardType PTR esi).LastKeyE1],0 ; are we in a pause/break code
  1788. je short ??notpause ; no, just keep going
  1789. dec [(KeyboardType PTR esi).LastKeyE1] ; yes, dec the count
  1790. test edx,PAUSEON ; should it pass these codes
  1791. jne ??passcode ; pass the code
  1792. jmp ??absorbcode ; don't pass code
  1793. ??notpause:
  1794. ;
  1795. ; Record any extended key codes that arrive. They will be
  1796. ; taken into account with the next code.
  1797. ;
  1798. cmp al,0E0H ; is it an extended code
  1799. jne short ??notextcode ; if not skip to handle key
  1800. mov [(KeyboardType PTR esi).LastKeyE0],TRUE ; set the extended code to 1
  1801. ??jmppasscode:
  1802. jmp ??passcode ; always pass E0s
  1803. ??notextcode:
  1804. ;
  1805. ; Check and acknowledge if the key is a make or a break.
  1806. ;
  1807. test al,080H ; test for high bit
  1808. je short ??make ; if off its a make
  1809. xor bl,bl ; set make/break to break
  1810. and al,07FH ; clear high bit
  1811. or ah,KEYRELEASE ; CDY NEW -- ABSENT IN OLD CODE
  1812. ??make:
  1813. ;
  1814. ; Translate the raw keycode into the Westwood keycode.
  1815. ;
  1816. cmp [(KeyboardType PTR esi).LastKeyE0],FALSE ; was the prev byte an E0?
  1817. je short ??normal ; if not it is a normal key
  1818. mov [(KeyboardType PTR esi).LastKeyE0],FALSE ; if so clear for next read
  1819. mov [(KeyboardType PTR esi).IsExtKey],TRUE ; it is an extended key
  1820. mov edi,OFFSET (KeyboardType PTR 0).ExtCodes
  1821. add edi,esi
  1822. mov ecx,(OFFSET (KeyboardType PTR 0).ExtNums-OFFSET (KeyboardType PTR 0).ExtCodes) ; get number of entrys in ext table
  1823. repne scasb ; look for a match
  1824. jcxz ??absorbcode ; Not recognized, so throw it away.
  1825. mov al,[(OFFSET (KeyboardType PTR 0).ExtNums - OFFSET (KeyboardType PTR 0).ExtCodes) - 1 + edi] ; get the match
  1826. mov [(KeyboardType PTR esi).IsExtKey],FALSE ; it is not an extended key
  1827. jmp short ??notext
  1828. ??normal:
  1829. cmp al,07Ah
  1830. jne short ??normok
  1831. mov al,128
  1832. jmp short ??notext
  1833. ??normok:
  1834. mov edi,eax ; use code as an index
  1835. and edi,007Fh ; Mask off any release bit.
  1836. mov al,[(KeyboardType PTR esi+edi).KeyNums] ; get the key number of this key
  1837. ??notext:
  1838. ;
  1839. ; Test and set the CTRL bit.
  1840. ;
  1841. test [(KeyboardType PTR esi+8).KeysUpDown],001H ; is the right ctrl down?
  1842. jne short ??ctrlon ; if so, ctrl is on
  1843. test [(KeyboardType PTR esi+7).KeysUpDown],004H ; is the left ctrl down?
  1844. je short ??ctrloff ; if not, neither are down, no ctrl
  1845. ; DRD
  1846. ; check for CTRL-NUMLOCK for pause on some keyboards
  1847. cmp al,KN_NUMLOCK ; check for CTRL-NUMLOCK
  1848. jne short ??ctrlon
  1849. cmp [(KeyboardType PTR esi).ExtKeyboard],TRUE ; if 101/102-key keyboard it is ok
  1850. je short ??ctrlon
  1851. test edx,PAUSEON ; should it pass these codes
  1852. jne short ??ctrlon ; pass the code
  1853. jmp ??absorbcode ; don't pass code
  1854. ??ctrlon:
  1855. or ah,CTRLPRESS ; or on the ctrl bit in flags
  1856. ??ctrloff:
  1857. ;
  1858. ; Test and set the ALT bit.
  1859. ;
  1860. test [(KeyboardType PTR esi+7).KeysUpDown],050H ; is either alt key down?
  1861. je short ??altoff
  1862. or ah,ALTPRESS ; or on the alt bit in flags
  1863. ??altoff:
  1864. ;
  1865. ; Remap the keyboard keys if this is requested. (Do not set DGROUP
  1866. ; as it is unecessary)
  1867. push eax
  1868. call KeyNum_Translate
  1869. add esp,4
  1870. ;------ Set the shift bit if necessary.
  1871. test [(KeyboardType PTR esi+5).KeysUpDown],010H ; is the left shift down?
  1872. jne short ??shifton ; if so the shift is on
  1873. test [(KeyboardType PTR esi+7).KeysUpDown],002H ; is the right shift down?
  1874. je short ??shiftoff ; if not then neither shift is down
  1875. ??shifton:
  1876. or ah,SHIFTPRESS ; or on the shift bit in flags
  1877. ??shiftoff:
  1878. ;
  1879. ;------ Toggle the shift state if the caps lock key is on (if necessary).
  1880. ;
  1881. mov edi,eax
  1882. and edi,07Fh
  1883. shr edi,3
  1884. mov ebx,eax
  1885. and ebx,07Fh
  1886. and bl,0111b
  1887. mov ch,[(KeyboardType PTR esi+ebx).Bits] ; get the bit to test
  1888. test [(KeyboardType PTR esi).KeyLock],CAPSLOCK ; is the caps lock on?
  1889. je short ??capsoff ; if not don't worry about it
  1890. test ch,[(KeyboardType PTR esi+edi).KeysCapsLock] ; get code for keycaps
  1891. je short ??capsoff ; its not effected
  1892. xor ah,SHIFTPRESS ; toggle the shift flag
  1893. ??capsoff:
  1894. ;
  1895. ;------ Toggle the shift state if the num-lock key is on (if necessary).
  1896. ;
  1897. test [(KeyboardType PTR esi).KeyLock],NUMLOCK ; is the num lock key on?
  1898. je short ??numlockoff ; if not don't worry about it
  1899. test ch,[(KeyboardType PTR esi+edi).KeysNumLock] ; get code for numlock
  1900. je short ??numlockoff ; if not effected skip toggle
  1901. xor ah,SHIFTPRESS ; toggle the shift flag if effected
  1902. ??numlockoff:
  1903. ;------ Remember the current control/shift/alt bit settings for later use.
  1904. ;??noshiftever:
  1905. mov [(KeyboardType PTR esi).CtrlFlags],ah ; save off shift-ctrl-alt flags
  1906. ; for the mouse and joystick routines
  1907. ; to use in stuffing key into the
  1908. ; keyboard buffer.
  1909. mov ecx,eax
  1910. xor eax,eax
  1911. mov ax,cx
  1912. IF DEBUG
  1913. cmp [(KeyboardType PTR esi).KeyIntDisabled],1
  1914. jne ??not_currently_disabled
  1915. inc [BYTE PTR 0B0002h]
  1916. cmp eax,115 ; is it the F4 key
  1917. je ??disable
  1918. cmp eax,118 ; is it less then F7 key
  1919. jb ??justpass
  1920. cmp eax,120 ; is it greater than F9 key
  1921. ja ??justpass
  1922. ??disable:
  1923. mov [(KeyboardType PTR esi).KeyIntDisabled],0
  1924. ??justpass:
  1925. jmp ??passcode
  1926. ??not_currently_disabled:
  1927. cmp eax,125
  1928. jne ??not_toggle
  1929. inc [BYTE PTR 0B0000h]
  1930. mov [(KeyboardType PTR esi).KeyIntDisabled],1
  1931. jmp ??absorbcode
  1932. ENDIF
  1933. ??not_toggle:
  1934. ;------ The CTRL-ALT-DEL key combination always gets passed to the system.
  1935. cmp eax,0668H ; is it ctrl alt del?
  1936. je ??passcode
  1937. cmp eax,064CH ; is it ctrl alt ext del?
  1938. je ??passcode ; if so don't add it to the buffer
  1939. ;------ Special Ctrl-C check.
  1940. cmp eax,0230h
  1941. je short ??breaker
  1942. cmp eax,027Eh
  1943. jne short ??nobreak
  1944. ??breaker:
  1945. mov [(KeyboardType PTR esi).Break],1
  1946. ??nobreak:
  1947. ;------ Check for Music and Sound control keys.
  1948. ; cmp ax,0420H ; is this an alt s
  1949. ; jne short ??checkmusic ; toggle the Sound variable
  1950. ; push ax
  1951. ; mov ax,[SoundOn]
  1952. ; xor ax,01H
  1953. ; push ax
  1954. ; add sp,2
  1955. ; pop ax
  1956. ;??checkmusic:
  1957. ; cmp ax,0434H ; is this an alt m
  1958. ; jne short ??esc ; toggle the Music variable
  1959. ; push ax
  1960. ; mov ax,[MusicOn]
  1961. ; xor ax,01H
  1962. ; push ax
  1963. ; add sp,2
  1964. ; pop ax
  1965. ;??esc:
  1966. push eax
  1967. call Stuff_Key_Num
  1968. pop eax
  1969. ??skipstuff:
  1970. ;------ Do the special ESC routine if necessary.
  1971. cmp al,110 ; is this the esc key?
  1972. jne short ??noroutine ; if not goto the pass always
  1973. cmp [(KeyboardType PTR esi).EscRoutine],0 ;if vector is 0 don't jump
  1974. je short ??noroutine
  1975. push eax
  1976. call [(KeyboardType PTR esi).EscRoutine]
  1977. pop eax
  1978. ??noroutine:
  1979. ;------ Check to see if the key is to be passed to the system or not.
  1980. mov edi,OFFSET (KeyboardType PTR 0).PassAlways ; get offset to table
  1981. add edi,esi
  1982. mov ecx,(OFFSET (KeyboardType PTR 0).PassAlwaysEnd - OFFSET (KeyboardType PTR 0).PassAlways) ; get number of pass always CDY JLB MOD 7/11 was
  1983. repne scasb ; look for a match
  1984. or ecx,ecx ; see if there was no match
  1985. jne ??passcode ; CDY JLB 7/11 optimization
  1986. ??passalways:
  1987. ; now check for conditional passes
  1988. mov edi,OFFSET (KeyboardType PTR 0).CondPassKey ; get offset to cond key table
  1989. add edi,esi
  1990. mov ecx,(OFFSET (KeyboardType PTR 0).CondPassCond-OFFSET (KeyboardType PTR 0).CondPassKey) ; get number of entries
  1991. shr ecx,1 ; cut in half for words
  1992. repne scasw ; look for a match
  1993. jcxz short ??notcondpass ; OPTIMIZATION CDY JLB
  1994. mov bx,[(OFFSET (KeyboardType PTR 0).CondPassCond - OFFSET (KeyboardType PTR 0).CondPassKey) - 2 + edi]
  1995. and bx,dx ; are the conditions met?
  1996. je short ??notcondpass ; NO... check normally.
  1997. jmp short ??passcode ; YES... pass back to system.
  1998. ;
  1999. ;------ Last check before passing keycode back to the system.
  2000. ;
  2001. ??notcondpass:
  2002. test edx,FILTERONLY ; is the filter only flag on?
  2003. je short ??absorbcode ; if not, absorb the code.
  2004. ??passcode:
  2005. inc [(KeyboardType PTR esi).PassCount]
  2006. ; Step 5.
  2007. ; Now it is time to set up for the call by returning by poking
  2008. ; the old interupt handle address in.
  2009. mov [(KeyboardType PTR esi).PMIssuedKeyInt],1 ; Make it TRUE
  2010. mov eax,[(KeyboardType PTR esi).KeyOldPMIOffset] ; Get orig offset.
  2011. mov ebx,[(KeyboardType PTR esi).KeyOldPMISelector] ; Get orig selector.
  2012. mov [ss:ebp+4],eax ; Poke offset.
  2013. mov [ss:ebp+8],ebx ; Poke selector.
  2014. ; Step 6.
  2015. pop fs gs es ds
  2016. popad
  2017. pop ebp
  2018. ; Step 7.
  2019. iretd
  2020. ??absorbcode:
  2021. in al,KEYCTRL ; get the control port
  2022. mov ah,al
  2023. or al,080H ; reset bit for keyboard
  2024. out KEYCTRL,al
  2025. xchg ah,al ; get orig control data
  2026. out KEYCTRL,al ; restore control data
  2027. mov al,[496h] ; get extended keys
  2028. and al,0FDh ; turn off last key e0 flag
  2029. mov [496h],al ; set extended keys
  2030. mov al,CLEARISR ; value to clear In Service Register
  2031. out INTCHIP0,al ; 8259 interrupt chip controller 0
  2032. pop fs gs es ds
  2033. popad
  2034. pop ebp
  2035. add esp,8
  2036. popfd
  2037. iret
  2038. ENDP Keyboard_Interrupt
  2039. ELSE
  2040. ;***************************************************************************
  2041. ;* KEYBOARD_INTERRUPT -- Stub for the keyboard interrupt call real mode *
  2042. ;* *
  2043. ;* INPUT: none *
  2044. ;* *
  2045. ;* OUTPUT: none *
  2046. ;* *
  2047. ;* WARNINGS: This is an interrupt routine. *
  2048. ;* *
  2049. ;* HISTORY: *
  2050. ;* 07/06/1994 SKB : Created. *
  2051. ;*=========================================================================*
  2052. DATASEG
  2053. STRUC RealModeCallStruc
  2054. _EDI DD 0
  2055. _ESI DD 0
  2056. _EBP DD 0
  2057. DD 0
  2058. _EBX DD 0
  2059. _EDX DD 0
  2060. _ECX DD 0
  2061. _EAX DD 0
  2062. FLAGS DW 0
  2063. _ES DW 0
  2064. _DS DW 0
  2065. _FS DW 0
  2066. _GS DW 0
  2067. _IP DW 0
  2068. _CS DW 0
  2069. _SP DW 0
  2070. _SS DW 0
  2071. dd 0
  2072. dd 0
  2073. nothing dd 0
  2074. ENDS
  2075. RMDS RealModeCallStruc <>
  2076. CODESEG
  2077. PROC Keyboard_Interrupt Near
  2078. ; This option of the keyboard interrupt handle will not be
  2079. ; available at this moment because the light version of Rational System DOS
  2080. ; Extender do not allow a DPMI real mode call which is
  2081. ; DMPI INT 31h funtion 0301h
  2082. pushad
  2083. push fs gs es ds
  2084. mov ax , _DATA
  2085. mov es , ax
  2086. mov ds , ax
  2087. lea edi , [ RMDS ]
  2088. lea ecx , [ RMDS . nothing ]
  2089. sub ecx , edi
  2090. xor eax , eax
  2091. shr ecx , 2
  2092. rep stosd
  2093. mov eax , 0300h
  2094. mov bl , [ byte ptr RMVector ]
  2095. xor bh , bh
  2096. xor cx , cx
  2097. lea edi , [RMDS]
  2098. int DPMI_INTR
  2099. ; this is here only for testing to make sure
  2100. ; that a real mode interrupt is bieng issued.
  2101. mov ax , _DATA
  2102. mov es , ax
  2103. mov ds , ax
  2104. mov [ byte ptr 0b0000h + 10 * 80 + 40 ] , 040h
  2105. jc ??error
  2106. mov [ byte ptr 0b0000h + 10 * 80 + 42 ] , 041h
  2107. ??error:
  2108. pop ds es gs fs
  2109. popad
  2110. iretd
  2111. ENDP
  2112. ENDIF
  2113. LABEL LockedCodeEnd BYTE
  2114. ;***************************************************************************
  2115. ;* End of File. *
  2116. ;***************************************************************************
  2117. END