home *** CD-ROM | disk | FTP | other *** search
/ Black Box 4 / BlackBox.cdr / editors / tde150.arj / SIMUL101.ASM < prev    next >
Assembly Source File  |  1992-04-01  |  14KB  |  319 lines

  1. ; This function simulates the scan codes of the 101 keyboard on older 83/84 key
  2. ; keyboard systems that lack bios support for some often used 101 keyboard
  3. ; control key combinations.  I miss being able to use the Control+Up, which is
  4. ; one of the key combinations that the old BIOS does not support on my old
  5. ; machine at home.  Not all of the 101 keys are simulated.  I decided to return
  6. ; simulated scan codes for the 83/84 keypad keys only.  It would be trivial to
  7. ; expand this utility to include almost all of the 101 extended codes, but
  8. ; I sorta doubt users will miss keys like Alt + ; or Alt + ~ on 83/84 keyboards
  9. ; especially if they couldn't use them in the first place.
  10. ;
  11. ;
  12. ; ****************************************************************************
  13. ;  ****** for tde 1.3, i added support for alt+<, alt+>, and alt+?      ******
  14. ;  ****** for tde 1.4, i added support for alt+;:, alt+'", and alt+`~   ******
  15. ;                                          alt+[{  and alt+]}
  16. ;  Since users can now reassign regular text keys to unused function keys,
  17. ;  I decided to support a few more 101 key combinations, so other punctuation
  18. ;  characters maybe assigned to those keys.  This should be especially useful
  19. ;  for languages that use characters in 128-255 extended ASCII set.
  20. ; ****************************************************************************
  21. ;
  22. ;
  23. ; If this routine were to mimic the enhanced BIOS exactly, it would return
  24. ; 0xE0 in register al and the extended code in ah for the simulated scan codes.
  25. ; I have decided to stay with the original BIOS convention and return 0x00 in
  26. ; register al and the extended code in register ah.
  27. ;
  28. ;  *************************************************************************
  29. ;  ****  The above paragraph is abso-damn-lutely wrong.  I have demon-  ****
  30. ;  ****  strated once again that I have trouble reading manuals.  After ****
  31. ;  ****  reading the MASM 6.0 manual numerous times over the past six   ****
  32. ;  ****  months,  I have finally realized that only the cursor movement ****
  33. ;  ****  keys in the cursor/control cluster on 101 keyboards return     ****
  34. ;  ****  0xe0 in al.  The other keypad keys are just extensions, which  ****
  35. ;  ****  is what I am simulating.                                       ****
  36. ;  *************************************************************************
  37. ;
  38. ; To see if control+up is pressed, we have to look at the keyboard status flags
  39. ; in the bios data area.  The flags at byte 0040:0017 are as follows:
  40. ;
  41. ;   Bit
  42. ;    7   Insert state  1 = active,  0 = inactive
  43. ;    6   Caps Lock     1 = active,  0 = inactive
  44. ;    5   Num Lock      1 = active,  0 = inactive
  45. ;    4   Scroll Lock   1 = active,  0 = inactive
  46. ;    3   Alt Shift     1 = active,  0 = inactive
  47. ;    2   Ctrl Shift    1 = active,  0 = inactive
  48. ;    1   Left Shift    1 = active,  0 = inactive
  49. ;    0   Right Shift   1 = active,  0 = inactive
  50. ;
  51. ; We are only concerned with bits 0-3, the shift status bits.  At label "k1"
  52. ; in this routine, the status byte is tested with 0x0f.  With simple tests,
  53. ; the status of the shift keys can be determined.  Then, it easy to use the
  54. ; tables to translate (XLAT) the raw key codes to extended scan codes.
  55. ;
  56. ; This function was designed to be linked with C object code.  The prototype
  57. ; for this function is far so it may be easily used with any memory model.
  58. ;
  59. ; For those of you (like me) who use keyboard speed up or other keyboard TSRs
  60. ; on XT's, you will find that those TSRs do not work with simulated scan codes
  61. ; generated by this utility.  This function grabs the raw keys before the TSR
  62. ; gets them and they don't get passed to the TSR.  This is the reason I mapped
  63. ; the "Keypad -" and "Keypad +" to the scroll up and scroll down functions -
  64. ; they aren't filtered by this function and get through to the typefast (TSR)
  65. ; utilities, so you can scroll really fast thru files.
  66. ;
  67. ; Editor name:   tde, the Thomson-Davis Editor.
  68. ; Author:        Frank Davis
  69. ; Date:          September 9, 1991
  70. ;
  71. ; This code is released into the public domain, Frank Davis.  You may
  72. ; distribute it freely.
  73.  
  74. kb_data_port    EQU     60h
  75. kb_cntl_port    EQU     61h
  76.  
  77. bios_data       SEGMENT AT 40h
  78.                 ORG     17h
  79. kb_status       DB      ?
  80.                 ORG     1ah
  81. buffer_head     DW      ?
  82. buffer_tail     DW      ?
  83.                 ORG     80h
  84. buffer_start    DW      ?
  85. buffer_end      DW      ?
  86. bios_data       ENDS
  87.  
  88.  
  89. _TEXT   SEGMENT WORD PUBLIC 'CODE'
  90.         ASSUME  cs:_TEXT, ds:NOTHING, es:bios_data
  91.         public  _simulate_enh_kbd
  92.  
  93.  
  94. ;
  95. ; Prototype this function as far in the C header file so it may be used easily
  96. ; with any memory model.  See the last section in tdefunc.h for more info.
  97. ;
  98. _simulate_enh_kbd       PROC    FAR
  99.         jmp     initialize
  100.  
  101.  
  102. ; Map the keys starting at scan code 47h, which is the Home key.  This routine
  103. ; DOES NOT return most of these values from systems with a 101 enhanced keyboard
  104. ; connected, but the codes are included here for reference.  One should use the
  105. ; extended BIOS keyboard services with the 101 keyboard and not this function.
  106. ; Indeed, tde uses the extended BIOS if a 101 keyboard is detected.
  107. ;
  108. ; These tables are patterned after the ones in the IBM AT Technical Reference
  109. ; Manual, page 5-170 (the system bios listing), labels k8 thru k15.
  110. ;
  111. ;       Home   = 47h    Left   = 4bh    End   = 4fh    Del    = 53h   F11 = 57h
  112. ;       Up     = 48h    Center = 4ch    Down  = 50h    SysReq = 54h   F12 = 58h
  113. ;       PgUp   = 49h    Right  = 4dh    PgDn  = 51h    ---    = 55h
  114. ;       Grey - = 4ah    Grey + = 4eh    Ins   = 52h    ---    = 56h
  115. ;
  116. ;               47,  48,  49,  4a,  4b,  4c,  4d,  4e,  4f,  50,  51,  52,
  117. ;               53   54,  55,  56,  57,  58
  118. table:
  119.         DB      -1,  -1,  -1,  -1,  -1,  76,  -1,  -1,  -1,  -1,  -1,  -1
  120.         DB      -1,  -1,  -1,  -1, 133, 134
  121. shift_table:
  122.         DB      -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1
  123.         DB      -1,  -1,  -1,  -1, 135, 136
  124. ctrl_table:
  125.         DB      -1, 141,  -1, 142,  -1, 143,  -1, 144,  -1, 145,  -1, 146
  126.         DB     147,  -1,  -1,  -1, 137, 138
  127. alt_table:
  128.         DB      -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1
  129.         DB      -1,  -1,  -1,  -1, 139, 140
  130.  
  131. old_int_9       DW      ?,?     ; space for old interrupt
  132.  
  133. start:
  134.         sti
  135.         push    ax      ; push the registers we use
  136.         push    bx
  137.         push    dx
  138.         push    ds
  139.         push    es
  140.  
  141.         in      al, kb_data_port        ; let's look at the waiting key
  142.  
  143.         cmp     al, 1ah         ; is it less than "[{"?
  144.         jb      pop_out_9       ; yes, let regular int handle it
  145.         cmp     al, 1bh         ; is it less than "]}"?
  146.         jbe     special         ; yes, let's check for alt
  147.  
  148.         cmp     al, 27h         ; is it less than ";:"?
  149.         jb      pop_out_9       ; yes, let regular int handle it
  150.         cmp     al, 29h         ; is it less than "`~"?
  151.         jbe     special         ; yes, let's check for alt
  152.  
  153.         cmp     al, 33h         ; is it less than '<'?
  154.         jb      pop_out_9       ; yes, let regular int handle it
  155.         cmp     al, 35h         ; is it less than '?'?
  156.         jbe     special         ; yes, let's check for alt
  157.  
  158.         cmp     al, 47h         ; is it less than home?
  159.         jb      pop_out_9       ; yes, let regular int handle it
  160.         cmp     al, 80h         ; is it less than a break code?
  161.         jb      k1              ; yes, let's look at this key - a keypad key
  162.         ALIGN   2
  163. pop_out_9:
  164.         jmp     regular_int_9   ; default - let regular int 9 handle break codes
  165.                                 ; and other stuff
  166.  
  167. k1:
  168.         mov     dx, 0040h       ; segment of bios data area
  169.         mov     es, dx          ; put it in es
  170.         mov     dl, BYTE PTR es:kb_status  ; get shift status of alt & ctrl keys
  171.         test    dl, 0fh         ; & it with 0x0f to see if any shift keys down
  172.         jnz     k2              ; one of the shift keys is pressed - find it
  173.         mov     bx, OFFSET table        ; get offset of table
  174.         jmp     SHORT k5        ; no shift keys were down, translate normal keys
  175. k2:
  176.         test    dl, 03h                 ; are the left or right shift keys down?
  177.         jz      k3                      ; not pressed, must be a ctrl or an alt
  178.         mov     bx, OFFSET shift_table  ; get offset of shift table
  179.         jmp     SHORT k5
  180. k3:
  181.         test    dl, 04h                 ; is the control shift key down?
  182.         jz      k4                      ; not pressed, must be an alt
  183.         mov     bx, OFFSET ctrl_table   ; get offset of control table
  184.         jmp     SHORT k5
  185. k4:
  186.                                         ; the only shift key left is alt
  187.         mov     bx, OFFSET alt_table    ; get offset of alt table
  188.         ALIGN   2
  189. k5:
  190.         sub     al, 47h         ; normalize key to zero
  191.  
  192.         mov     dx, cs          ; put code segment in dx
  193.         mov     ds, dx          ; now transfer code segment to ds
  194.  
  195.         xlat                    ; table look up
  196.         cmp     al, -1          ; is it -1?
  197.         je      regular_int_9   ; yes, let regular interrupt 9 handle it
  198.  
  199.         mov     ah, al          ; put copy of character in ah
  200.         xor     al, al          ; zero out scan code - simulate extended key
  201.         jmp     SHORT k7
  202.         ALIGN   2
  203. special:
  204.         mov     dx, 0040h       ; segment of bios data area
  205.         mov     es, dx          ; put it in es
  206.         mov     dl, BYTE PTR es:kb_status  ; get shift status of alt & ctrl keys
  207.         test    dl, 08h         ; & it with 0x08 to see if the alt key is down
  208.         jnz     k6              ; alt key is down, let's do the special case
  209.         jmp     SHORT regular_int_9     ; otherwise goto regular interrupt 9
  210.         ALIGN   2
  211. k6:
  212.         mov     ah, al          ; put the scan code in ah
  213.         xor     al, al          ; zero out al
  214. ;
  215. ; We now have a key we want to emulate.  Put it in the keyboard buffer and
  216. ; end our interrupt.
  217. ;
  218. k7:
  219.         mov     bx, WORD PTR es:buffer_tail     ; get the end pointer to buffer
  220.         mov     dx, bx                          ; save in dx
  221.         inc     dx                              ; move to next word in list
  222.         inc     dx
  223.         cmp     dx, WORD PTR es:buffer_end      ; at end of buffer?
  224.         jnz     ck_full_kbd                     ; if no, continue
  225.         mov     dx, WORD PTR es:buffer_start    ; yes, reset to buffer start
  226.         ALIGN   2
  227.  
  228. ck_full_kbd:
  229.         cmp     dx, WORD PTR es:buffer_head     ; has the buffer wrapped?
  230.         jz      end_int_9       ; yes, kbd full - enable keyboard for next key
  231.         mov     WORD PTR es:[bx], ax    ; store simulated key into kbd buffer
  232.         mov     WORD PTR es:buffer_tail, dx     ; move the tail up for next key
  233.         ALIGN   2
  234.  
  235. end_int_9:
  236.         cli                     ; no interrupts now
  237.         mov     al, 20h         ; end of interrupt command
  238.         out     20h, al         ; send command to interrupt control port
  239.         sti                     ; enable interrupts - see IBM tech. ref. man.
  240.         in      al, kb_cntl_port        ; get char from control port
  241.         mov     ah, al                  ; save it in ah
  242.         or      al, 80h                 ; set bit 7
  243.         out     kb_cntl_port, al        ; output reset value
  244.         mov     al, ah                  ; send original value
  245.         jmp     SHORT $+2               ; take your time
  246.         out     kb_cntl_port, al        ; send it to enable keyboard
  247.         pop     es              ; restore registers
  248.         pop     ds
  249.         pop     dx
  250.         pop     bx
  251.         pop     ax
  252.         iret                    ; return from interrupt
  253. regular_int_9:
  254.         pop     es              ; restore registers
  255.         pop     ds
  256.         pop     dx
  257.         pop     bx
  258.         pop     ax
  259.         jmp     DWORD PTR old_int_9     ; no interrupt return - old one does it
  260.  
  261. ; ***********************************************************************
  262. ; prototype for _simulate_enh_kbd is
  263. ;
  264. ;               void far simulate_enh_kbd( int )
  265. ;
  266. ; The formal parameter is available on the stack.  Use the bp register to
  267. ; access it.
  268. ;
  269. ; Passing any non-zero value will make this function grab interrupt 9.
  270. ; Pass a zero to this function to restore the old interrupt 9.
  271. ;
  272. ; If this function were really clever, it would have a "unique" signature.
  273. ; Before "installing", it would check to see if it was already installed.
  274. ; Similarly, before "uninstalling", this function would check to make sure
  275. ; it was installed so it wouldn't uninstall the regular interrupt 9
  276. ; handler by accident.  What the hell, live dangerously.
  277. ;
  278. ; ***********************************************************************
  279.  
  280. initialize:
  281.         push    bp
  282.         mov     bp, sp
  283.  
  284.         mov     dx, [bp+6]      ; put the parameter in dx
  285.  
  286.         push    ds
  287.         ASSUME  es:_TEXT,ds:_TEXT
  288.         mov     ax, cs          ; put cs in ds
  289.         mov     es, ax
  290.         mov     ds, ax
  291.  
  292.         cmp     dx, 0           ; 'NULL' character unhooks interrupt 9
  293.         je      restore_9       ; any non NULL character grabs interrupt 9
  294. grab_9:
  295.         mov     ax, 3509h       ; get old interrupt 9 location
  296.         int     21h             ; call MSDOS to get it
  297.         mov     WORD PTR old_int_9, bx          ; save old int 9 offset
  298.         mov     WORD PTR old_int_9+2, es        ; save old int 9 segment
  299.  
  300.         mov     dx, OFFSET start        ; get new offset of int 9
  301.         mov     ax, 2509h               ; use function 25 so int 9 points
  302.         int     21h                     ;  to my routine
  303.         jmp     SHORT get_out           ; continue with editor
  304.  
  305. restore_9:
  306.         mov     dx, WORD PTR old_int_9          ; get offset of old int 9
  307.         mov     ax, WORD PTR old_int_9+2        ; get segment of old int 9
  308.         mov     ds, ax                          ;  put segment in ds
  309.         mov     ax, 2509h                       ; restore old int 9
  310.         int     21h
  311.  
  312. get_out:
  313.         pop     ds              ; clean up
  314.         pop     bp
  315.         retf
  316. _simulate_enh_kbd       endp
  317. _TEXT   ends
  318.         end
  319.