KEYBOARD.ASM 85 KB

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