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