home *** CD-ROM | disk | FTP | other *** search
/ Phoenix CD 2.0 / Phoenix_CD.cdr / 01e / msker301.zip / LK250.ASM < prev    next >
Assembly Source File  |  1990-01-18  |  11KB  |  264 lines

  1.         Name MSLK250
  2. ; MSLK250.ASM - A simple driver program for the DEC LK250 keyboard on IBM AT's
  3. ; Author:  Terry Kennedy, St. Peter's College, Terry@spcvxa.Bitnet.
  4. ;
  5. ; Edit history
  6. ; Last edit 17 Oct 1989
  7. ; 17 Oct 1989 Add test for pre-80286 cpu and jmp $+2 breathers. [jrd]
  8. ; 16 Oct 1989 Sync USU, SPC versions; add initialization tests. [tmk] 
  9. ;  9 Oct 1989 Add building instructions etc. [jrd]
  10. ;
  11. ; Purpose: Allow access to LK250 features without requiring the user to have
  12. ;          any DEC drivers loaded.
  13. ;
  14. ; Method:  Intercept INT 15 subfunction 4F (SysReq) and 50 (Control). If en-
  15. ;          tered via 4F, place substitute scan code in buffer if the keypress
  16. ;          was for a key we're remapping *and* we are active. If entered via
  17. ;          50, perform control function as follows:
  18. ;
  19. ;               AL=00 - Disable substitution (keyboard "Special" [IBM] mode)
  20. ;               AL=01 - Enable sunstitution (keyboard DEC mode)
  21. ;               AL=02 - Send the byte in BL to the keyboard (caution: sending
  22. ;            "random" bytes with this function can lock the key-
  23. ;            board, necessitating a reboot.
  24. ;
  25. ; Construct final file MSLK250.COM by
  26. ;  masm mslk250;        reads file mslk250.asm, writes file mslk250.obj
  27. ;  link mslk250;        expect and ignore statement about no stack segment
  28. ;  exe2bin mslk250      produces file mslk250.bin from mslk250.exe
  29. ;  ren mslk250.bin mslk250.com    rename the result to our runnable filename
  30. ;  del mslk250.exe      delete non-runnable intermediate files .exe & .obj
  31. ;  del mslk250.obj
  32. ;
  33. ;  mslk250              run mslk250.com to install the driver
  34. ;
  35. ;
  36. ; Date:    20-Aug-1989, X0.0-00 - Original version
  37. ;       26-Aug-1989, X0.0-01 - Pass Shift-PrtSc through even in DEC mode
  38. ;       16-Oct-1989, X0.0-02 - Add initialization tests suggested by jrd
  39. ;       17-Oct-1989, X0.0-03 - Add cpu test, add time between tests. jrd
  40. ;
  41. main    group   code
  42. ;
  43. data    segment at 40h
  44. ;
  45.         db      23 dup (?)
  46. shift    db    ?
  47.     db    2 dup (?)
  48. head    dw      ?
  49. tail    dw      ?
  50. buff    dw      16 dup (?)
  51.         db      66 dup (?)
  52. bstart  dw      ?
  53. bend    dw      ?
  54.         db      19 dup (?)
  55. kbflg2  db      ?
  56. ;
  57. data    ends
  58. ;
  59. code    segment public para 'code'
  60. assume  cs:main,ds:nothing
  61. ;
  62.         org     100h                    ; making a.COM file
  63. ;
  64. begin:  jmp     start                   ; program starts here
  65. ;
  66. saved15 dd      ?                       ; previous int 15 vector
  67. active  db      0                       ; are we translating?
  68. ;
  69. ; This is the new interrupt 15 routine.
  70. ;
  71. newi15  proc    far
  72.         assume  ds:data
  73.         cmp     ah,50h                  ; control function?
  74.         je      ctlfnc                  ; if so...
  75.         cmp     ah,4fh                  ; keyboard intercept?
  76.         jne     bail                    ; nope, time to leave...
  77.         cmp     active,1                ; are we active?
  78.         jne     bail                    ; no, just exit...
  79.         cmp     al,01h                  ; Esc/PF1?
  80.         je      kpf1                    ; if so
  81.         cmp     al,45h                  ; Num Lk/PF2?
  82.         je      kpf2                    ; if so
  83.         cmp     al,46h                  ; Scrl Lk/PF3?
  84.         je      kpf3                    ; if so
  85.         cmp     al,37h                  ; PrtSc / PF4?
  86.         je      kpf4                    ; if so
  87.         cmp     al,54h                  ; is it a scan we handle?
  88.         jl      bail                    ; nope, bail out...
  89.         cmp     al,69h
  90.         jg      bail                    ; likewise...
  91.         jmp     putkey                  ; otherwise go save the key...
  92. ;
  93. kpf1:   mov     al,6ah                  ; make PF1 scan 6ah
  94.         jmp     putkey
  95. ;
  96. kpf2:   mov     al,6bh                  ; make PF2 scan 6bh
  97.         jmp     putkey
  98. ;
  99. kpf3:   mov     al,6ch                  ; make PF3 scan 6ch
  100.         jmp     putkey
  101. ;
  102. kpf4:    push    ds            ; save user's [DS]
  103.     mov    ax,40h
  104.     push    ax
  105.     pop    ds
  106.     mov    al,shift        ; get shift states
  107.     pop    ds            ; restore user's [DS]
  108.     and    al,3            ; either shift state set?
  109.     jz    kpf4a            ; nope, this key gets translated
  110.     mov    al,37h            ; yes, we didn't want to translate it
  111.     jmp    bail            ; oh, this is a bad pun...
  112. ;
  113. kpf4a:    mov     al,6dh                  ; make PF4 scan 6dh
  114.         jmp     putkey
  115. ;
  116. ; stuff a scancode into the keyboard buffer
  117. ;
  118. putkey: mov     ah,al                   ; copy scan to someplace useful
  119.         mov     al,0
  120.         push    ds                      ; save user's [DS]
  121.         mov     bx,40h                  ; point to system space
  122.         push    bx
  123.         pop     ds
  124.         mov     bx,tail                 ; offset of buffer tail
  125.         mov     si,bx
  126.         inc     bx
  127.         inc     bx                      ; point to next free
  128.         cmp     bx,bend                 ; at end?
  129.         jne     nowrap                  ; if not...
  130.         mov     bx,bstart               ; else wrap buffer
  131. nowrap: cmp     bx,head                 ; buffer full?
  132.         je      bufull                  ; if so...
  133.         mov     [si],ax                 ; else store character
  134.         mov     tail,bx                 ; and update pointer
  135. bufull: pop     ds                      ; restore [DS]
  136.         clc                             ; say we did something...
  137.         iret                            ; and exit
  138. ;
  139. bail:   jmp     [saved15]
  140. ;
  141. ; control functions: enable / disable translation, set LED's, set click
  142. ; volume, set auto-repeat rate
  143. ;
  144. ctlfnc: cmp     al,0                    ; disable translation?
  145.         jne     tst1                    ; no
  146.         mov     active,al               ; else do it
  147.         mov     al,0adh                 ; set keyboard mode
  148.         call    kbsend
  149.         jmp     exit                    ; and exit
  150. ;
  151. tst1:   cmp     al,1                    ; enable translation?
  152.         jne     tst2                    ; no
  153.         mov     active,al               ; else do it
  154.         mov     al,0ach                 ; set keyboard mode
  155.         call    kbsend
  156.         jmp     exit                    ; and exit
  157. ;
  158. tst2:   cmp     al,2                    ; send to keyboard?
  159.         jne     error                   ; nope, must be an error
  160.         mov     al,bl                   ; byte to [AL] for send
  161.         call    kbsend                  ; yes, send the byte out
  162.         jmp     exit                    ; and exit
  163. ;
  164. error:  mov     ax,0                    ; say bad function
  165.         iret                            ; and exit
  166. ;
  167. exit:   mov     ax,1234h                ; say we did it
  168.         iret                            ; and exit
  169. ;
  170. newi15  endp
  171. ;
  172. ; send a byte to the keyboard controller
  173. ;
  174. kbsend  proc    near
  175.         push    ax                      ; save some regs
  176.         push    bx
  177.         push    cx
  178.         push    ds                      ; save user's [DS]
  179.         mov     bx,40h                  ; point to system space
  180.         push    bx
  181.         pop     ds
  182.         mov     bh,al                   ; copy data byte for retry
  183.         mov     bl,3                    ; set retry count
  184. sd0:    cli
  185.         and     kbflg2,0cfh             ; turn off ack, re-send bits
  186.         sub     cx,cx                   ; a nice big loop
  187. sd1:    in      al,64h
  188.     jmp    $+2            ; reduce looping rate
  189.         test    al,2
  190.         loopnz  sd1                     ; if not ready
  191.         mov     al,bh
  192.         out     60h,al                  ; send the command
  193.         sti
  194.         mov     cx,2800h                ; wait a bit
  195. sd3:    test    kbflg2,30h              ; anything happen?
  196.         jnz     sd7                     ; seems so, go handle
  197.     jmp    $+2            ; reduce looping rate
  198.         loop    sd3                     ; else wait
  199. sd5:    dec     bl                      ; call it a retry if timed out
  200.         jnz     sd0                     ; if we have another chance
  201.         or      kbflg2,80h              ; otherwise fail it
  202.         jmp     sd9                     ; and exit
  203. ;
  204. sd7:    test    kbflg2,10h              ; got a proper ack?
  205.         jz      sd5                     ; nope, re-send it
  206. sd9:    pop     ds
  207.         pop     cx
  208.         pop     bx
  209.         pop     ax
  210.         ret
  211. ;
  212. kbsend  endp
  213. ;
  214. endres  label   byte                    ; end of resident code
  215. ;
  216. ; Code after here will not remain resident
  217. ;  Cpu test uses DOS's stack [jrd]
  218. start:                    ; begin with cpu test [jrd]
  219.     push    sp            ; push DOS's SP, 8088's push old SP-2
  220.     pop    ax            ; 286's and higher push old SP
  221.     mov    dx,offset main:cpumsg    ; prepare bad news message
  222.     cmp    ax,sp            ; pre versus post push SP's
  223.     jne    start0            ; ne = an 8088, sorry 'bout that [jrd]
  224.     mov     ax,5000h                ; see if we are already loaded
  225.         int     15h                     ; look for DOS->DEC mode driver
  226.         cmp     ax,1234h                ; find marker 1234h
  227.         jne     start1                  ; ne = marker not present, no driver
  228.         mov     dx,offset main:errmsg   ; say we're already loaded
  229. start0: mov     ah,9
  230.         int     21h
  231.     int    20h            ; and bail out
  232. ;
  233. start1: mov     ax,3515h                ; get existing INT 15 vector
  234.         int     21h
  235.         mov     word ptr [saved15],bx   ; save it
  236.         mov     word ptr [saved15+2],es
  237.         mov     dx,offset main:newi15   ; set new INT 15 vector
  238.         mov     ax,2515h
  239.         int     21h                     ; set new vector from DS:DX
  240. ;
  241.         mov     dx,offset main:lodmsg   ; say we're loaded
  242.         mov     ah,9
  243.         int     21h
  244. ;
  245.         mov     ax,ds:[2ch]             ; de-allocate the environment
  246.         mov     es,ax                   ; load envirnoment segment into es
  247.         mov     ah,49h                  ; DOS function number
  248.         int     21h                     ; free the environment memory
  249. ;
  250.         mov     dx,offset main:endres   ; point to end of resident code
  251.         add     dx,0fh                  ; round up
  252.         mov     cl,4
  253.         shr     dx,cl                   ; convert to paragraphs (divide by 16)
  254.         mov     ax,3100h                ; DOS function 31h, error code=0
  255.         int     21h                     ; terminate and remain resident
  256. ;
  257. errmsg:    db    0dh,0ah,'MSLK250 is already loaded',0dh,0ah,07h,'$'
  258. lodmsg: db      0dh,0ah,'MSLK250 X0.0-03 loaded',0dh,0ah,'$'
  259. cpumsg:    db    0dh,0ah,'MSLK250 requires a 286 (AT) machine or higher'
  260.     db    0dh,0ah,'$'        ; wrong cpu type msg  [jrd]
  261. ;
  262. code    ends
  263.         end     begin                   ; start execution at BEGIN
  264.