arrowkey.asm 9.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452
  1. ; $Id$
  2. ; MegaZeux
  3. ;
  4. ; Copyright (C) 1996 Greg Janson
  5. ; Copyright (C) 1998 Matthew D. Williams - dbwilli@scsn.net
  6. ;
  7. ; This program is free software; you can redistribute it and/or
  8. ; modify it under the terms of the GNU General Public License as
  9. ; published by the Free Software Foundation; either version 2 of
  10. ; the License, or (at your option) any later version.
  11. ;
  12. ; This program is distributed in the hope that it will be useful,
  13. ; but WITHOUT ANY WARRANTY; without even the implied warranty of
  14. ; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
  15. ; General Public License for more details.
  16. ;
  17. ; You should have received a copy of the GNU General Public License
  18. ; along with this program; if not, write to the Free Software
  19. ; Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
  20. ;
  21. ; ARROWKEY.ASM- Code to intercept int 9 to handle the keyboard and keep
  22. ; track of the status of arrow keys, space, and delete.
  23. ;
  24. Ideal
  25. include "arrowkey.inc"
  26. p186
  27. JUMPS
  28. include "model.inc"
  29. Codeseg
  30. keyb_mode db 0
  31. key_code db 0
  32. up_pressed db 0
  33. dn_pressed db 0
  34. lf_pressed db 0
  35. rt_pressed db 0
  36. sp_pressed db 0
  37. del_pressed db 0
  38. old_vector_09 dd 0
  39. kb_installed db 0
  40. curr_table db 1
  41. ; 256 byte table for keyboard codes-
  42. ; 0 means pass on to normal handler
  43. ; 1 means discard
  44. ; 2 means dump and loop for another keypress
  45. ; 3 means special (arrow, space, or delete)
  46. action_table db 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 ;000h - 00Fh
  47. db 0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0 ;010h - 01Fh
  48. db 0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0 ;020h - 02Fh
  49. db 0,0,0,0,0,0,1,1,1,3,0,0,0,0,0,0 ;030h - 03Fh
  50. db 0,0,0,0,0,1,1,0,3,0,0,3,0,3,0,0 ;040h - 04Fh
  51. db 3,0,0,3,1,0,0,0,0,0,0,0,0,0,0,0 ;050h - 05Fh
  52. db 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1 ;060h - 06Fh
  53. db 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 ;070h - 07Fh
  54. db 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 ;080h - 08Fh
  55. db 0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0 ;090h - 09Fh
  56. db 0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0 ;0A0h - 0AFh
  57. db 0,0,0,0,0,0,1,1,1,3,0,0,0,0,0,0 ;0B0h - 0BFh
  58. db 0,0,0,0,0,1,1,0,3,0,0,3,0,3,0,0 ;0C0h - 0CFh
  59. db 3,0,0,3,1,0,0,0,0,0,0,0,0,0,0,0 ;0D0h - 0DFh
  60. db 1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,1 ;0E0h - 0EFh
  61. db 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 ;0F0h - 0FFh
  62. ; Table #2 is a more normal table- It lets arrows, space, delete, alt,
  63. ; and shift through normally.
  64. action_tbl2 db 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 ;000h - 00Fh
  65. db 0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0 ;010h - 01Fh
  66. db 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 ;020h - 02Fh
  67. db 0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0 ;030h - 03Fh
  68. db 0,0,0,0,0,1,1,0,0,0,0,0,0,0,0,0 ;040h - 04Fh
  69. db 0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0 ;050h - 05Fh
  70. db 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1 ;060h - 06Fh
  71. db 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 ;070h - 07Fh
  72. db 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 ;080h - 08Fh
  73. db 0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0 ;090h - 09Fh
  74. db 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 ;0A0h - 0AFh
  75. db 0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0 ;0B0h - 0BFh
  76. db 0,0,0,0,0,1,1,0,0,0,0,0,0,0,0,0 ;0C0h - 0CFh
  77. db 0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0 ;0D0h - 0DFh
  78. db 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1 ;0E0h - 0EFh
  79. db 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 ;0F0h - 0FFh
  80. ;
  81. ; Function- intercept_09
  82. ;
  83. ; New keyboard handler. (game orientated) Above variables will now contain
  84. ; current status (1=pressed, 0=not pressed) of the arrow keys, (both numpad
  85. ; and regular) delete, and space. Pause, scroll-lock, num-lock, print screen,
  86. ; sysrq, ctrl-c, and ctrl-s are all surpressed. Alt, Ctrl, and Shift are all
  87. ; ignored from now on. All other keypressed are interpreted as normal and
  88. ; eventually sent to the keyboard buffer to be read as normal. The above
  89. ; variables are set to 1 and held there if a key is held, but if you change
  90. ; one to another number other than 0 it will stay there instead of flipping
  91. ; back to 0. IE if you set rt_pressed to 2 and right is held, it will NOT
  92. ; change rt_pressed to 1. Release will still set it to 0 however.
  93. ;
  94. proc intercept_09 far
  95. pusha
  96. @@key_loop:
  97. ; Get scan code
  98. sti
  99. in al,60h
  100. mov [key_code],al
  101. ; Set dl to 0, which means no loop
  102. ; xor dl,dl
  103. ; AL: (according to table above)
  104. ; 48h UP C8h UP RELEASED
  105. ; 50h DOWN D0h DOWN RELEASED
  106. ; 4Bh LEFT CBh LEFT RELEASED
  107. ; 4Dh RIGHT CDh RIGHT RELEASED
  108. ; 39h SPACE B9h SPACE RELEASED
  109. ; 53h DELETE D3h DELETE RELEASED
  110. ;
  111. ; E0h or E1h : Dump and loop
  112. ;
  113. ; Discard:
  114. ; 1Dh, 2Ah, 36h, 37h, 38h, 45h, 46h, 54h, 6Fh,
  115. ; 9Dh, AAh, B6h, B7h, B8h, C5h, C6h, D4h, EFh
  116. ; Save al in cl, get correct table in CS:BX
  117. mov cl,al
  118. mov bx,OFFSET cs:action_table
  119. cmp [curr_table],0
  120. je @@table_correct
  121. add bx,256 ; Table 2.
  122. @@table_correct:
  123. ; xlat to get code
  124. xlat [cs:bx]
  125. ; Check code- 0 to pass on, 1 to dump, 2 to dump and continue
  126. cmp al,0
  127. je @@normal_handler
  128. cmp al,1
  129. je @@discard_key
  130. ; cmp al,2
  131. ; jne @@special_key
  132. ; Dump and continue- set dl to 1 to note a loop, then go to dump
  133. ; inc dl
  134. ; jmp @@discard_key
  135. @@special_key:
  136. ; Key press-
  137. cmp cl,53h
  138. je @@del
  139. cmp cl,48h
  140. je @@up
  141. cmp cl,50h
  142. je @@dn
  143. cmp cl,4Bh
  144. je @@lf
  145. cmp cl,4Dh
  146. je @@rt
  147. cmp cl,39h
  148. je @@space
  149. ; Key release-
  150. cmp cl,0D3h
  151. je @@del_off
  152. cmp cl,0C8h
  153. je @@up_off
  154. cmp cl,0D0h
  155. je @@dn_off
  156. cmp cl,0CBh
  157. je @@lf_off
  158. cmp cl,0CDh
  159. je @@rt_off
  160. ; Must be 0B9h, or @@space_off
  161. @@space_off:
  162. mov [cs:sp_pressed],0
  163. jmp @@discard_key
  164. @@del:
  165. ; Only set if not already set somehow
  166. cmp [cs:del_pressed],0
  167. jne @@discard_key
  168. mov [cs:del_pressed],1
  169. jmp @@discard_key
  170. @@del_off:
  171. mov [cs:del_pressed],0
  172. jmp @@discard_key
  173. @@up:
  174. cmp [cs:up_pressed],0
  175. jne @@discard_key
  176. mov [cs:up_pressed],1
  177. jmp @@discard_key
  178. @@dn:
  179. cmp [cs:dn_pressed],0
  180. jne @@discard_key
  181. mov [cs:dn_pressed],1
  182. jmp @@discard_key
  183. @@lf:
  184. cmp [cs:lf_pressed],0
  185. jne @@discard_key
  186. mov [cs:lf_pressed],1
  187. jmp @@discard_key
  188. @@rt:
  189. cmp [cs:rt_pressed],0
  190. jne @@discard_key
  191. mov [cs:rt_pressed],1
  192. jmp @@discard_key
  193. @@space:
  194. cmp [cs:sp_pressed],0
  195. jne @@discard_key
  196. mov [cs:sp_pressed],1
  197. jmp @@discard_key
  198. @@up_off:
  199. mov [cs:up_pressed],0
  200. jmp @@discard_key
  201. @@dn_off:
  202. mov [cs:dn_pressed],0
  203. jmp @@discard_key
  204. @@lf_off:
  205. mov [cs:lf_pressed],0
  206. jmp @@discard_key
  207. @@rt_off:
  208. mov [cs:rt_pressed],0
  209. @@discard_key:
  210. ; Two modes of discarding keys. (second chosen via command line)
  211. cmp [cs:keyb_mode],1
  212. je @@discard_key2
  213. in al,061h
  214. or al,80h
  215. out 061h,al
  216. and al,07Fh
  217. out 061h,al
  218. ; Loop?
  219. ; cmp dl,1
  220. ; je @@key_loop
  221. ; Reset interrupt
  222. cli
  223. mov al,020h
  224. out 020h,al
  225. sti
  226. popa
  227. iret
  228. @@discard_key2:
  229. in al,061h
  230. mov ah,al
  231. or al,80h
  232. out 061h,al
  233. mov al,ah
  234. out 061h,al
  235. ; Loop?
  236. ; cmp dl,1
  237. ; je @@key_loop
  238. ; Reset interrupt
  239. cli
  240. mov al,020h
  241. out 020h,al
  242. sti
  243. popa
  244. iret
  245. @@normal_handler:
  246. ; Reset ALT+Number work area
  247. mov bx,ds
  248. mov ax,0040h
  249. mov ds,ax
  250. mov [BYTE PTR ds:0019h],0
  251. mov ds,bx
  252. ; Not a key important to us- cycle through normal handler.
  253. popa
  254. jmp [DWORD PTR cs:old_vector_09]
  255. endp intercept_09
  256. ;
  257. ; Function- install_i09
  258. ;
  259. ; Installs new keyboard handler. Necessary before up_pressed, dn_pressed,
  260. ; etc. have any meaning.
  261. ;
  262. proc install_i09 far
  263. push ds es
  264. pusha
  265. ; All keys are released
  266. xor al,al
  267. mov [cs:dn_pressed],al
  268. mov [cs:up_pressed],al
  269. mov [cs:lf_pressed],al
  270. mov [cs:rt_pressed],al
  271. mov [cs:sp_pressed],al
  272. mov [cs:del_pressed],al
  273. ; Turn off all BIOS shift flags and "Last was E0, E1" flags
  274. mov ax,0040h
  275. mov ds,ax
  276. mov si,0017h
  277. and [BYTE PTR ds:si],0F0h
  278. inc si
  279. and [BYTE PTR ds:si],0E0h
  280. mov si,0096h
  281. and [BYTE PTR ds:si],0F0h
  282. ; Intercept int 9
  283. cli
  284. mov ah,35h
  285. mov al,09h
  286. int 21h
  287. mov si,OFFSET cs:old_vector_09
  288. mov [cs:si],bx
  289. mov [cs:si+2],es
  290. mov ah,25h
  291. mov al,09h
  292. push cs
  293. pop ds
  294. mov dx,OFFSET cs:intercept_09
  295. int 21h
  296. sti
  297. mov [cs:kb_installed],1
  298. popa
  299. pop es ds
  300. ret
  301. endp install_i09
  302. ;
  303. ; Function- uninstall_i09
  304. ;
  305. ; Uninstalls new keyboard handler. Must be called before exiting program!
  306. ;
  307. proc uninstall_i09 far
  308. push ds es
  309. pusha
  310. ; Turn off all BIOS shift flags and "Last was E0, E1" flags
  311. mov ax,0040h
  312. mov ds,ax
  313. mov si,0017h
  314. and [BYTE PTR ds:si],0F0h
  315. inc si
  316. and [BYTE PTR ds:si],0E0h
  317. mov si,0096h
  318. and [BYTE PTR ds:si],0F0h
  319. ; Restore int 9
  320. cli
  321. mov ah,25h
  322. mov al,09h
  323. lds dx,[cs:old_vector_09]
  324. int 21h
  325. sti
  326. mov [cs:kb_installed],0
  327. popa
  328. pop es ds
  329. ret
  330. endp uninstall_i09
  331. ;
  332. ; Function- switch_keyb_table
  333. ;
  334. ; Changes to table 0 or 1. Table 1 is less strict, letting arrow keys,
  335. ; space, delete, alt, and shift through.
  336. ;
  337. proc switch_keyb_table far
  338. arg table_num:byte
  339. pusha
  340. push ds es
  341. ; All keys are released
  342. xor al,al
  343. mov [cs:dn_pressed],al
  344. mov [cs:up_pressed],al
  345. mov [cs:lf_pressed],al
  346. mov [cs:rt_pressed],al
  347. mov [cs:sp_pressed],al
  348. mov [cs:del_pressed],al
  349. ; Turn off all BIOS shift flags and "Last was E0, E1" flags
  350. mov ax,0040h
  351. mov ds,ax
  352. mov si,0017h
  353. and [BYTE PTR ds:si],0F0h
  354. inc si
  355. and [BYTE PTR ds:si],0E0h
  356. mov si,0096h
  357. and [BYTE PTR ds:si],0F0h
  358. ; Change table number
  359. mov al,[table_num]
  360. and al,1
  361. mov [curr_table],al
  362. ; Done!
  363. pop es ds
  364. popa
  365. ret
  366. endp switch_keyb_table
  367. ;
  368. ; Replacements for kbhit and getch
  369. ;
  370. proc kbhit far
  371. mov ah,11h
  372. int 16h
  373. jz @@nokey
  374. mov ax,1
  375. ret
  376. @@nokey:
  377. xor ax,ax
  378. ret
  379. endp kbhit
  380. next_press db 0
  381. proc getch far
  382. cmp [cs:next_press],0
  383. je @@norm_press
  384. mov al,[cs:next_press]
  385. mov [cs:next_press],0
  386. xor ah,ah
  387. ret
  388. @@norm_press:
  389. mov ah,10h
  390. int 16h
  391. or al,al
  392. jz @@ext
  393. cmp al,224
  394. jne @@ok
  395. @@ext:
  396. mov [cs:next_press],ah
  397. xor al,al
  398. @@ok:
  399. xor ah,ah
  400. ret
  401. endp getch
  402. public kbhit
  403. public getch
  404. ends
  405. end