home *** CD-ROM | disk | FTP | other *** search
/ Power CD-ROM!! 7 / POWERCD7.ISO / prgmming / keys / keys.asm < prev    next >
Assembly Source File  |  1994-01-21  |  24KB  |  692 lines

  1. TITLE           STACKKEY
  2.  
  3. ;INITIAL VALUES :       CS:IP   0000:0100
  4. ;                       SS:SP   0000:FFFE
  5.  
  6. com_segment     SEGMENT
  7.                 ASSUME  cs:com_segment, es:com_segment 
  8.                 assume  ss:com_segment, ds:com_segment
  9.  
  10.                 org     $+80h
  11. keybuffer       equ     $
  12. parmbuffer      equ     $
  13.                 ORG     $+80h
  14.  
  15. bufptr          equ     $
  16. maxkeys         equ     255
  17. keybuflen       equ     (2*maxkeys)
  18.  
  19. ; WARNING: the code and data below is EXACTLY the right length to
  20. ; be consumed by the keybuffer starting at 080h
  21.  
  22. epoint:
  23.                 MOV     SI, parmbuffer
  24.                 LODSB
  25.                 CBW
  26.                 MOV     BX, AX
  27.                 MOV     BYTE PTR [BX+SI], 0     ; null terminate cmd line
  28. look_for_slash:
  29.                 LODSB
  30.                 OR      AL, AL
  31.                 JZ      no_more_parms
  32.                 CMP     AL, '/'
  33.                 jz      found_slash
  34.                 cmp     al, ' '
  35.                 JZ      look_for_slash
  36.                 jmp     do_parms
  37. found_slash:
  38.                 LODSB
  39.                 CMP     AL, 'I'
  40.                 JZ      do_install
  41.                 CMP     AL, 'i'
  42.                 JZ      do_install
  43.                 cmp     al, 'f'
  44.                 jz      do_file_parms
  45.                 cmp     al, 'F'
  46.                 jz      do_file_parms
  47.                 JMP     look_for_slash
  48.  
  49.                 ; if no parms, print installation check results
  50. no_more_parms:
  51.                 MOV     AX, 0D44Fh
  52.                 XOR     BX, BX
  53.                 INT     2Fh     ; install check
  54.                 CMP     AX, 44DDh
  55.                 JNZ     not_installed
  56.                 MOV     DX, offset fdosalready
  57.                 jz      print_and_exit
  58. not_installed:
  59.                 mov     dx, offset fdosnoload
  60. print_and_exit:
  61.                 MOV     AH, 9
  62.                 INT     21h
  63.                 MOV     AX, 4C01h
  64.                 INT     21h     ; exit normally, exit code 1
  65.  
  66. fdosinstalled   db      'KEYS installed.', 0dh, 0ah, '$'
  67. fdosnoload      db      'KEYS not installed.', 0dh, 0ah, '$'
  68.                 
  69. ; WARNING: the above code and data is EXACTLY the right length to
  70. ; be consumed by the keybuffer starting at 080h
  71.  
  72. terminator      dw      -1
  73.  
  74. ; betcha $ is at 0100h right here !!!
  75.  
  76. skeycnt         dw      0
  77. curkeyp         dw      0
  78. delaydur        dw      0
  79. startticks      dw      0
  80.  
  81. oldint16        dw      0
  82.                 dw      0
  83.  
  84. oldint2f        dw      0
  85.                 dw      0
  86.  
  87. resident        proc    near
  88.                 assume  cs:com_segment
  89.                 assume  ds:nothing, es:nothing, ss:nothing
  90. fwdint16:
  91.                 JMP     dword ptr [oldint16]
  92. newint16:
  93.                 sti
  94.                 CMP     [skeycnt], 0
  95.                 jz      fwdint16  ; if no stacked keys, get out quick
  96.                 test    ah, 0eeh  ; this weirdness is a quick check for
  97.                                   ; 0h, 1h, 10h, and 11h.
  98.                                   ; All other calls are always forwarded.
  99.                 jnz     fwdint16
  100.  
  101. int16around:
  102.                 PUSH    SI
  103.                 PUSH    DS
  104.                 push    ax
  105.  
  106.                 PUSH    CS
  107.                 POP     DS
  108.                 assume  ds:com_segment
  109.  
  110.                 mov     si, [curkeyp]
  111.  
  112.                 CLD
  113.                 test    ah, 1 ; check vs. get
  114.                 jnz     just_checking
  115.  
  116. must_get_key:
  117.                 cmp     [delaydur], 0
  118.                 jz      get_key_now
  119.                 call    delay_check
  120.                 jmp     short must_get_key
  121.  
  122. just_checking:
  123.                 cmp     [delaydur], 0
  124.                 jz      check_now
  125.                 call    delay_check
  126. check_now:
  127.                 xor     ax, ax
  128.                 cmp     [delaydur], ax
  129.                 jnz     check_exit
  130.                 lodsw
  131.                 cmp     ax, -1
  132.                 jnz     is_key
  133.                 call    delay_setup
  134.                 xor     ax, ax
  135.                 jmp     short check_exit
  136. is_key:
  137.                 or      ax, ax
  138.                 jnz     check_exit
  139.                 dec     [skeycnt]       ; zero means fake out the check
  140.                 mov     [curkeyp], si   ; but consume the fake out indicator
  141. check_exit:
  142.                 or      ax, ax
  143.                 pop     si      ; old ax value
  144.                 pop     ds
  145.                 pop     si
  146.                 retf    2
  147.  
  148. get_key_now:
  149.                 lodsw
  150.                 cmp     ax, -1
  151.                 jnz     not_a_delay
  152.                 call    delay_setup
  153.                 jmp     must_get_key
  154. not_a_delay:
  155.                 dec     [skeycnt]
  156.                 or      ax, ax
  157.                 jz      get_key_now
  158.  
  159.                 mov     [curkeyp], si
  160.                 pop     si      ; old ax value
  161.                 pop     ds
  162.                 assume  ds:nothing
  163.                 pop     si
  164.                 iret
  165.                 assume  ds:com_segment
  166.  
  167.                 ; set up new delay if appropriate
  168. delay_setup:
  169.                 DEC     [skeycnt]       ; adjust for the -1 flag
  170.                 LODSW                   ; fetch the delay parameter
  171.                 MOV     [delaydur], AX
  172.                 CALL    getticks
  173.                 MOV     [startticks], AX
  174.  
  175.                 DEC     [skeycnt]       ; adjust for the delay parameter
  176.                 mov     [curkeyp], si
  177.                 cmp     [skeycnt], 0
  178.                 jl      found_terminator        ; negative count remaining
  179.  
  180.                 ret
  181.  
  182. found_terminator:
  183.                 pop     ax ; throw away return IP from call to delay_setup
  184.                 mov     [skeycnt], 0
  185.                 pop     ax
  186.                 pop     ds
  187.                 assume  ds:nothing
  188.                 pop     si
  189.                 jmp     fwdint16
  190.                 assume  ds:com_segment
  191.  
  192. getticks:
  193.                 PUSH    ES
  194.                 MOV     AX, 40h
  195.                 MOV     ES, AX
  196.                 MOV     AX, es:[6Ch]    ; low word of ticks since midnight
  197.                 POP     ES
  198.                 RET
  199.  
  200. delay_check:
  201.                 CALL    getticks
  202.                 SUB     AX, [startticks]
  203.                 CMP     AX, [delaydur]
  204.                 JB      moredelay
  205.                 MOV     [delaydur], 0
  206. moredelay:
  207.                 RET
  208.  
  209.                 assume  ds:nothing, es:nothing, ss:nothing
  210. fwdint2f:       JMP     dword ptr [oldint2f]
  211.  
  212. newint2f:       CMP     AX, 0D44Fh
  213.                 JNZ     fwdint2f        ; we only recognize 1 op-code
  214.                 MOV     AX, 44DDh       ; we always do this for grins
  215.                 OR      BX, BX          ; here's the real op-code
  216.                 JZ      done2f
  217.  
  218.                 ; here's the code to load in the new keystrokes
  219.                 STI
  220.                 PUSH    DI
  221.                 PUSH    SI
  222.                 CLD
  223.  
  224.                 PUSH    CS
  225.                 POP     ES
  226.                 assume  es:com_segment
  227.                 MOV     DI, keybuffer
  228.                 MOV     [curkeyp], DI
  229.                 xor     ch, ch  ; bounds check cx
  230.                 MOV     [skeycnt], cx
  231.                 MOV     [delaydur], 0
  232.                 MOV     SI, DX
  233.  
  234.                 REPZ    MOVSW
  235.                 dec     cx
  236.                 mov     word ptr es:[di], cx   ; end with -1
  237.  
  238.                 POP     SI
  239.                 POP     DI
  240.                 XOR     AX, AX
  241.  
  242. done2f:         IRET
  243.                 assume  es:nothing
  244.  
  245. endres          equ     $
  246. resident        endp
  247.  
  248. nonres          proc    near
  249.                 ASSUME  cs:com_segment, es:com_segment 
  250.                 assume  ss:com_segment, ds:com_segment
  251.  
  252. do_install:     MOV     AX, cs:[2Ch] ; get environment segment
  253.                 OR      AX, AX
  254.                 JZ      noenvironment
  255.                 assume  es:nothing
  256.                 MOV     ES, AX
  257.                 MOV     AH, 49h
  258.                 INT     21h     ; return environment block
  259. noenvironment:
  260.                 MOV     AX, 3516h
  261.                 INT     21h     ; get vector for INT 16h
  262.                 MOV     [oldint16], BX
  263.                 MOV     [oldint16+2], ES
  264.                 MOV     AX, 2516h
  265.                 MOV     DX, newint16
  266.                 INT     21h
  267.                 MOV     AX, 352Fh
  268.                 INT     21h     ; get vector for INT 2fh
  269.                 MOV     [oldint2f], BX
  270.                 MOV     [oldint2f+2], ES
  271.                 MOV     AX, 252Fh
  272.                 MOV     DX, newint2f
  273.                 INT     21h
  274.                 MOV     AH, 9
  275.                 MOV     DX, offset fdosinstalled
  276.                 INT     21h
  277.                 MOV     DX, offset endres + 15
  278.                 MOV     CX, 4
  279.                 SHR     DX, CL
  280.                 MOV     AX, 3100h
  281.                 INT     21h
  282.  
  283.                 ASSUME  cs:com_segment, es:com_segment 
  284.                 assume  ss:com_segment, ds:com_segment
  285. do_parms:
  286.                 MOV     SI, offset parmbuffer
  287.                 LODSB
  288.                 CBW
  289.                 jmp     do_common
  290. do_file_parms:
  291.                 mov     ah, 3fh
  292.                 mov     bx, 1
  293.                 mov     cx, 32767
  294.                 mov     dx, offset filebuf
  295.                 int     21h
  296.                 mov     si, dx
  297. do_common:
  298.                 ; at this point, si points to buffer, ax is count
  299.                 MOV     BP, AX  ; save count
  300.                 mov     bx, ax
  301.                 mov     ax, 0d44fh
  302.                 add     bx, si
  303.                 CLD
  304.                 mov     byte ptr [bx], 0        ; null terminate the input
  305.                 mov     bx, 0h
  306.                 int     2fh     ; check if KEYS is installed
  307.                 cmp     ax, 044ddh
  308.                 je      installed
  309. exitpoint:
  310.                 ret     ; not installed, exit quietly
  311.  
  312. installed:
  313.                 MOV     DI, OFFSET bufptr
  314.                 xor     cx, cx
  315.                 dec     cl      ; initialize initial scan code value
  316.                 or      bp, bp  ; any buffer to process ?
  317.                 jz      exitpoint
  318.                 call    parsemain
  319.                 mov     ax, 0d44fh
  320.                 mov     bx, 1h
  321.                 mov     cx, [numentries]
  322.                 mov     dx, offset bufptr
  323.                 int     2fh
  324.                 ret
  325. nonres          endp
  326.  
  327.                 align   2
  328.  
  329. numentries      dw      0
  330. SOFAR           dw      0
  331. BASEVAL         dw      0AH
  332.  
  333. parse           proc    near
  334. ; in remainder of code, the following register assignments are generally used
  335. ; BP count of command line bytes remaining (yes, this usage is unusual)
  336. ; BX is used as a temporary scratch register; often to a lookup table
  337. ; DH is quoted string delimiter during quoted string operations
  338. ; DL is a temporary save register during scan code lookup, and putchar ops
  339. ; AH generally contains the scan code of interest
  340. ; AL generally contains the ASCII code of interest, or the current input byte
  341. ; DS:SI points to the input stream
  342. ; ES:DI points to the output stream
  343. ; CL contains the global scan code (initially 255)
  344.  
  345. parsemain:
  346.                 XOR     AX, AX
  347.                 call    obtchar
  348.                 call    chkspace
  349.                 OR      BP, BP
  350.                 JnZ     parsemain ; loop until all characters used
  351.                 ret
  352.  
  353. chkspace:       ; ' ' and all control characters are ignored
  354.                 cmp     al, ' '
  355.                 jg      chkpound
  356.                 ret
  357.  
  358. CHKPOUND:       ; '#' introduces a scancode value.  Once set, it is
  359.                 ; used for all subsequent keystrokes.  Initially 255.
  360.                 ; The value of 255 causes a lookup of the "real" scancode.
  361.                 CMP     AL, '#'
  362.                 JNZ     CHKAT
  363.                 CALL    GETNUM
  364.                 MOV     CL, AL
  365.                 ret
  366.  
  367. CHKAT:          ; '@' introduces a number used as an Extended ASCII code.
  368.                 ; Hence, the ASCII value is set to zero, and the number
  369.                 ; specified is used as the scancode.  This is independent
  370.                 ; of the scancode used for subsequent ASCII codes, however.
  371.                 CMP     AL, '@'
  372.                 JNZ     CHKPCT
  373.                 CALL    GETNUM
  374.                 MOV     AH, AL
  375.                 MOV     AL, 0
  376.                 CALL    PUTCHAR
  377.                 ret
  378.  
  379. CHKPCT:         ; '%' introduces a number used as an Enhanced keyboard
  380.                 ; Extended ASCII code.  Hence, the ASCII value is set to
  381.                 ; E0, and the number specified is used as the scancode.
  382.                 ; This is independent of the scancode used for subsequent
  383.                 ; ASCII codes, however.
  384.                 cmp     al, '%'
  385.                 jnz     chkhat
  386.                 call    getnum
  387.                 mov     ah, al
  388.                 mov     al, 0e0h
  389.                 call    putchar
  390.                 ret
  391.  
  392. chkhat:         ; '^' introduces a letter used for a control code.
  393.                 ; It must be an uppercase letter, or one of '@[\]^_'.
  394.                 ; Also acceptable, are lowercase letters, or one of '`{|}~'.
  395.                 ; Actually, any character is acceptable, and only the low
  396.                 ; 5 bits of the character code are used.
  397.                 cmp     al, '^'
  398.                 jnz     chkbang
  399.                 call    obtchar
  400.                 and     al, 1fh
  401.                 call    xlatchar
  402.                 call    putchar
  403.                 ret
  404.  
  405. chkbang:        cmp     al, '!'
  406.                 jnz     chkamp
  407.                 mov     ax, 0d44fh
  408.                 mov     bx, 1h
  409.                 xor     cx, cx
  410.                 mov     dx, offset bufptr
  411.                 int     2fh
  412.                 jmp     short startflush
  413.  
  414. flushloop:
  415.                 mov     ah, 0
  416.                 int     16h     ; eat a character
  417. startflush:
  418.                 mov     ah, 01h
  419.                 int     16h     ; is there a character
  420.                 jnz     flushloop
  421.                 ret
  422.  
  423. chkamp:         ; '&' introduces a letter used for an ALT code.
  424.                 ; It must be a letter.
  425.                 ; Actually, any character is acceptable, that letter's
  426.                 ; scan code is determined from the table, and used as
  427.                 ; and extended code.
  428.                 cmp     al, '&'
  429.                 jnz     chkstr
  430.                 call    obtchar
  431.                 call    xlatspec
  432.                 mov     al, 0
  433.                 call    putchar
  434. doret:
  435.                 ret
  436.  
  437. CHKSTR:
  438.                 CMP     AL, '"'
  439.                 JZ      ISSTR
  440.                 CMP     AL, "'"
  441.                 JZ      ISSTR
  442.                 CMP     AL, '~'
  443.                 JNZ     CHKDASH
  444. ISSTR:
  445.                 MOV     DH, AL
  446. MORESTR:
  447.                 xor     ax, ax
  448.                 CALL    OBTCHAR
  449.                 CMP     AL, DH
  450.                 JZ      doret
  451.                 CALL    xlatchar
  452.                 CALL    PUTCHAR
  453.                 JMP     SHORT MORESTR
  454.  
  455. CHKDASH:
  456.                 CMP     AL, '-'
  457.                 JNZ     CHKR
  458.                 MOV     AX, 0
  459.                 CALL    PUTCHAR
  460.                 ret
  461.  
  462. CHKR:
  463.                 CMP     AL, 'r'
  464.                 JZ      DOENTER
  465.                 CMP     AL, 'R'
  466.                 JZ      DOENTER
  467.                 CMP     AL, 'e'
  468.                 JZ      DOENTER
  469.                 CMP     AL, 'E'
  470.                 JNZ     CHKF
  471. DOENTER:
  472.                 MOV     AL, 0DH
  473.                 CALL    XLATCHAR
  474.                 CALL    PUTCHAR
  475.                 ret
  476.  
  477. nochkw:
  478.                 call    unobtchar
  479.                 ret
  480.  
  481. CHKSLASH:
  482.                 CMP     AL, '/'
  483.                 JNZ     CHKDIGIT
  484. CHKW:
  485.                 CALL    OBTCHAR
  486.                 CMP     AL, 'w'
  487.                 JZ      DOWAIT
  488.                 CMP     AL, 'W'
  489.                 JNZ     nochkw
  490.  
  491. DOWAIT:
  492.                 CALL    GETNUM
  493.                 push    ax
  494.                 mov     ax, -1
  495.                 call    putchar
  496.                 pop     ax
  497.                 shl     ax, 1
  498.                 call    putchar
  499.                 ret
  500.  
  501. CHKF:
  502.                 CMP     AL, 'f'
  503.                 JZ      DOFUNC
  504.                 CMP     AL, 'F'
  505.                 JNZ     CHKSLASH
  506.  
  507. DOFUNC:
  508.                 CALL    OBTCHAR
  509.                 mov     bx, offset afunckey
  510.                 CMP     AL, 'A'
  511.                 JZ      DOFUNCNUM
  512.                 CMP     AL, 'a'
  513.                 JZ      DOFUNCNUM
  514.                 mov     bx, offset cfunckey
  515.                 CMP     AL, 'C'
  516.                 JZ      DOFUNCNUM
  517.                 CMP     AL, 'c'
  518.                 JZ      DOFUNCNUM
  519.                 mov     bx, offset sfunckey
  520.                 CMP     AL, 'S'
  521.                 JZ      DOFUNCNUM
  522.                 CMP     AL, 's'
  523.                 JZ      DOFUNCNUM
  524.                 mov     bx, offset rfunckey
  525.                 CALL    UNOBTCHAR
  526. DOFUNCNUM:
  527.                 CALL    GETNUM  ; should be in range of 1-12
  528.                 sub     ax, 1   ; put in range of 1-11
  529.                 cmp     ax, 11  ; compare to the max
  530.                 JA      nofunc  ; bad number
  531.                 xlat
  532.                 mov     ah, al
  533.                 MOV     AL, 0
  534.                 CALL    PUTCHAR
  535. nofunc:
  536.                 ret
  537.  
  538. CHKDIGIT:
  539.                 CMP     AL, '0'
  540.                 JB      nochkdigit
  541.                 CMP     AL, '9'
  542.                 JA      nochkdigit
  543.                 CALL    UNOBTCHAR
  544.                 CALL    GETNUM
  545.                 CALL    XLATCHAR
  546.                 CALL    PUTCHAR
  547. nochkdigit:
  548.                 ret
  549.  
  550. fdosalready     db      'KEYS already installed.', 0dh, 0ah, '$'
  551.  
  552. parse           endp
  553.  
  554. xlatchar        PROC    NEAR
  555.                 cmp     ah, 0
  556.                 jnz     regnoxlat ; fastest way out, if scan code pre-set
  557.                 MOV     AH, CL
  558.                 cmp     ah, 255
  559.                 jnz     regnoxlat ; 2nd fastest way out, if scan code pre-spec
  560.                 cmp     dh, '~' ; what kind of scan code do you want
  561.                 jnz     xlatspec
  562.                 mov     bx, offset numscan
  563.                 jmp     short xlatact
  564. xlatspec:
  565.                 mov     bx, offset regscan
  566. xlatact:
  567.                 MOV     DL, AL
  568.                 XLAT
  569.                 MOV     AH, AL
  570.                 MOV     AL, DL
  571. regnoxlat:
  572.                 RET
  573. xlatchar        ENDP
  574.  
  575. OBTCHAR         PROC    NEAR
  576.                 LODSB
  577.                 DEC     BP
  578.                 RET
  579. OBTCHAR         ENDP
  580.  
  581. UNOBTCHAR       PROC
  582.                 INC     BP
  583.                 DEC     SI
  584.                 RET
  585. UNOBTCHAR       ENDP
  586.  
  587. GETNUM          PROC    NEAR
  588.                 PUSH    AX
  589.                 MOV     BYTE PTR SOFAR, 0
  590. CHKCHAR:
  591.                 CALL    OBTCHAR
  592.                 CMP     AL, '0'
  593.                 JB      BADCHAR
  594.                 CMP     AL, '9'
  595.                 JA      BADCHAR
  596.                 SUB     AL, '0'
  597.                 xor     ah, ah
  598.                 XCHG    ax, SOFAR
  599.                 MUL     BYTE PTR BASEVAL
  600.                 ADD     SOFAR, ax
  601.                 JMP     SHORT CHKCHAR
  602.  
  603. BADCHAR:
  604.                 CALL    UNOBTCHAR
  605.                 POP     AX
  606.                 MOV     AX, SOFAR
  607.                 RET
  608. GETNUM          ENDP
  609.  
  610. PUTCHAR         PROC    NEAR
  611.                 mov     bx, [numentries]
  612.                 cmp     bx, maxkeys
  613.                 ja      noputchar
  614.                 STOSW
  615.                 INC     bx
  616.                 mov     [numentries], bx
  617. noputchar:
  618.                 RET
  619. PUTCHAR         ENDP
  620.  
  621.           DB      'Function Key Lookup Table'
  622.           ;    F1   F2   F3   F4   F5   F6   F7   F8   F9  F10  F11  F12
  623. RFUNCKEY  DB  3bh, 3ch, 3dh, 3eh, 3fh, 40h, 41h, 42h, 43h, 44h, 91h, 92h
  624. SFUNCKEY  DB  54h, 55h, 56h, 57h, 58h, 59h, 5ah, 5bh, 5ch, 5dh, 93h, 94h
  625. CFUNCKEY  DB  5eh, 5fh, 60h, 61h, 62h, 63h, 64h, 65h, 66h, 67h, 95h, 96h
  626. AFUNCKEY  DB  68h, 69h, 6ah, 6bh, 6ch, 6dh, 6eh, 6fh, 70h, 71h, 97h, 98h
  627.  
  628.                 DB      'Scancode Lookup Table'
  629. regscan         DB      03H     ; zero (control @)
  630.                         ; control A-Z
  631.                 DB      1EH, 30H, 2EH, 20H, 12H, 21H, 22H, 0EH, 0FH
  632.                 DB      24H, 25H, 26H, 1CH, 31H, 18H, 19H, 10H, 13H
  633.                 DB      1FH, 14H, 16H, 2FH, 11H, 2DH, 15H, 2CH
  634.                         ; control [ | ] ^ _
  635.                 DB      01H, 2BH, 1BH, 07H, 0CH, 39H
  636.                         ; special characters ! " # $ % & ' ( ) * +, - . /
  637.                 DB      02H, 28H, 04H, 05H, 06H, 08H, 28H, 0AH, 0BH, 09H, 0DH
  638.                 DB      33H, 0CH, 34H, 35H
  639.                         ; digits 0-9
  640.                 DB      0BH, 02H, 03H, 04H, 05H, 06H, 07H, 08H, 09H, 0AH
  641.                         ; special characters : ; < = > ? @
  642.                 DB      27H, 27H, 33H, 0DH, 34H, 35H, 03H
  643.                         ; A-Z
  644.                 DB      1EH, 30H, 2EH, 20H, 12H, 21H, 22H, 23H, 17H
  645.                 DB      24H, 25H, 26H, 32H, 31H, 18H, 19H, 10H, 13H
  646.                 DB      1FH, 14H, 16H, 2FH, 11H, 2DH, 15H, 2CH
  647.                         ; special characters [ \ ] ^ _ `
  648.                 DB      1AH, 2BH, 1BH, 07H, 0CH, 39H, 29H
  649.                         ; a-z
  650.                 DB      1EH, 30H, 2EH, 20H, 12H, 21H, 22H, 23H, 17H
  651.                 DB      24H, 25H, 26H, 32H, 31H, 18H, 19H, 10H, 13H
  652.                 DB      1FH, 14H, 16H, 2FH, 11H, 2DH, 15H, 2CH
  653.                         ; special characters { | } ~
  654.                 DB      1AH, 2BH, 1BH, 29H
  655.                         ; Alt numeric key entry only
  656.                 DB      129 DUP(0)
  657. numscan         DB      03H     ; zero
  658.                         ; control A-Z
  659.                 DB      1EH, 30H, 2EH, 20H, 12H, 21H, 22H, 0EH, 0FH
  660.                 DB      24H, 25H, 26H, 1CH, 31H, 18H, 19H, 10H, 13H
  661.                 DB      1FH, 14H, 16H, 2FH, 11H, 2DH, 15H, 2CH
  662.                         ; control [ | ] ^ _
  663.                 DB      01H, 2BH, 1BH, 07H, 0CH, 39H
  664.                         ; special characters ! " # $ % & ' ( ) * +, - . /
  665.                 DB      02H, 28H, 04H, 05H, 06H, 08H, 28H, 0AH, 0BH, 37H, 4EH
  666.                 DB      33H, 4AH, 53H, 35H
  667.                         ; digits 0-9
  668.                 DB      52H, 4FH, 50H, 51H, 4BH, 4CH, 4DH, 47H, 48H, 49H
  669.                         ; special characters : ; < = > ? @
  670.                 DB      27H, 27H, 33H, 0DH, 34H, 35H, 03H
  671.                         ; A-Z
  672.                 DB      1EH, 30H, 2EH, 20H, 12H, 21H, 22H, 23H, 17H
  673.                 DB      24H, 25H, 26H, 32H, 31H, 18H, 19H, 10H, 13H
  674.                 DB      1FH, 14H, 16H, 2FH, 11H, 2DH, 15H, 2CH
  675.                         ; special characters [ \ ] ^ _ `
  676.                 DB      1AH, 2BH, 1BH, 07H, 0CH, 39H, 29H
  677.                         ; a-z
  678.                 DB      1EH, 30H, 2EH, 20H, 12H, 21H, 22H, 23H, 17H
  679.                 DB      24H, 25H, 26H, 32H, 31H, 18H, 19H, 10H, 13H
  680.                 DB      1FH, 14H, 16H, 2FH, 11H, 2DH, 15H, 2CH
  681.                         ; special characters { | } ~
  682.                 DB      1AH, 2BH, 1BH, 29H
  683.                         ; Alt numeric key entry only
  684.                 DB      129 DUP(0)
  685.  
  686.                 align   2
  687.  
  688. filebuf         equ     $
  689.  
  690. com_segment   ends
  691. end     epoint
  692.