home *** CD-ROM | disk | FTP | other *** search
/ Reverse Code Engineering RCE CD +sandman 2000 / ReverseCodeEngineeringRceCdsandman2000.iso / RCE / Library / Manuels & Misc / Assembly / AOA.ZIP / CH20 / LEDSHOW.ASM < prev    next >
Encoding:
Assembly Source File  |  1994-07-23  |  5.3 KB  |  235 lines

  1. ; LEDSHOW.ASM
  2. ;
  3. ; This short TSR creates a light show on the keyboard's LEDs.  For space
  4. ; reasons, this code does not implement a multiplex handler nor can you
  5. ; remove this TSR once installed.  See the chapter on resident programs
  6. ; for details on how to do this.
  7. ;
  8. ; cseg and EndResident must occur before the standard library segments!
  9.  
  10. cseg        segment    para public 'code'
  11. cseg        ends
  12.  
  13. ; Marker segment, to find the end of the resident section.
  14.  
  15. EndResident    segment    para public 'Resident'
  16. EndResident    ends
  17.  
  18.         .xlist
  19.         include     stdlib.a
  20.         includelib    stdlib.lib
  21.         .list
  22.  
  23.  
  24. byp        equ    <byte ptr>
  25.  
  26. cseg        segment    para public 'code'
  27.         assume    cs:cseg, ds:cseg
  28.  
  29.  
  30.  
  31.  
  32.  
  33.  
  34. ; SetCmd-    Sends the command byte in the AL register to the 8042
  35. ;        keyboard microcontroller chip (command register at
  36. ;        port 64h).
  37.  
  38. SetCmd        proc    near
  39.         push    cx
  40.         push    ax        ;Save command value.
  41.         cli            ;Critical region, no ints now.
  42.  
  43. ; Wait until the 8042 is done processing the current command.
  44.  
  45.         xor    cx, cx        ;Allow 65,536 times thru loop.
  46. Wait4Empty:    in    al, 64h        ;Read keyboard status register.
  47.         test    al, 10b        ;Input buffer full?
  48.         loopnz    Wait4Empty    ;If so, wait until empty.
  49.  
  50. ; Okay, send the command to the 8042:
  51.  
  52.         pop    ax        ;Retrieve command.
  53.         out    64h, al
  54.         sti            ;Okay, ints can happen again.
  55.         pop    cx
  56.         ret
  57. SetCmd        endp
  58.  
  59.  
  60.  
  61.  
  62. ; SendCmd-    The following routine sends a command or data byte to the
  63. ;        keyboard data port (port 60h).
  64.  
  65. SendCmd        proc    near
  66.         push    ds
  67.         push    bx
  68.         push    cx
  69.         mov    cx, 40h
  70.         mov    ds, cx
  71.         mov    bx, ax        ;Save data byte
  72.  
  73.         mov    al, 0ADh        ;Disable kbd for now.
  74.         call    SetCmd
  75.  
  76.         cli            ;Disable ints while accessing HW.
  77.  
  78. ; Wait until the 8042 is done processing the current command.
  79.  
  80.         xor    cx, cx            ;Allow 65,536 times thru loop.
  81. Wait4Empty:    in    al, 64h            ;Read keyboard status register.
  82.         test    al, 10b            ;Input buffer full?
  83.         loopnz    Wait4Empty        ;If so, wait until empty.
  84.  
  85. ; Okay, send the data to port 60h
  86.  
  87.         mov    al, bl
  88.         out    60h, al
  89.  
  90.         mov    al, 0AEh        ;Reenable keyboard.
  91.         call    SetCmd
  92.         sti                ;Allow interrupts now.
  93.  
  94.         pop    cx
  95.         pop    bx
  96.         pop    ds
  97.         ret
  98. SendCmd        endp
  99.  
  100.  
  101. ; SetLEDs-    Writes the value in AL to the LEDs on the keyboard.
  102. ;        Bits 0..2 correspond to scroll, num, and caps lock,
  103. ;        respectively.
  104.  
  105. SetLEDs        proc    near
  106.         push    ax
  107.         push    cx
  108.  
  109.         mov    ah, al            ;Save LED bits.
  110.  
  111.         mov    al, 0EDh        ;8042 set LEDs cmd.
  112.         call    SendCmd            ;Send the command to 8042.
  113.         mov    al, ah            ;Get parameter byte
  114.         call    SendCmd            ;Send parameter to the 8042.
  115.  
  116.         pop    cx
  117.         pop    ax
  118.         ret
  119. SetLEDs        endp
  120.  
  121.  
  122.  
  123. ; MyInt1C-    Every 1/4 seconds (every 4th call) this routine
  124. ;        rotates the LEDs to produce an interesting light show.
  125.  
  126. CallsPerIter    equ    4
  127. CallCnt        byte    CallsPerIter
  128. LEDIndex    word    LEDTable
  129. LEDTable    byte    111b, 110b, 101b, 011b,111b, 110b, 101b, 011b
  130.         byte    111b, 110b, 101b, 011b,111b, 110b, 101b, 011b
  131.         byte    111b, 110b, 101b, 011b,111b, 110b, 101b, 011b
  132.         byte    111b, 110b, 101b, 011b,111b, 110b, 101b, 011b
  133.  
  134.         byte    000b, 100b, 010b, 001b, 000b, 100b, 010b, 001b
  135.         byte    000b, 100b, 010b, 001b, 000b, 100b, 010b, 001b
  136.         byte    000b, 100b, 010b, 001b, 000b, 100b, 010b, 001b
  137.         byte    000b, 100b, 010b, 001b, 000b, 100b, 010b, 001b
  138.  
  139.         byte    000b, 001b, 010b, 100b, 000b, 001b, 010b, 100b
  140.         byte    000b, 001b, 010b, 100b, 000b, 001b, 010b, 100b
  141.         byte    000b, 001b, 010b, 100b, 000b, 001b, 010b, 100b
  142.         byte    000b, 001b, 010b, 100b, 000b, 001b, 010b, 100b
  143.  
  144.                 byte    010b, 001b, 010b, 100b, 010b, 001b, 010b, 100b
  145.         byte    010b, 001b, 010b, 100b, 010b, 001b, 010b, 100b
  146.         byte    010b, 001b, 010b, 100b, 010b, 001b, 010b, 100b
  147.         byte    010b, 001b, 010b, 100b, 010b, 001b, 010b, 100b
  148.  
  149.         byte    000b, 111b, 000b, 111b, 000b, 111b, 000b, 111b
  150.         byte    000b, 111b, 000b, 111b, 000b, 111b, 000b, 111b
  151.         byte    000b, 111b, 000b, 111b, 000b, 111b, 000b, 111b
  152.         byte    000b, 111b, 000b, 111b, 000b, 111b, 000b, 111b
  153. TableEnd    equ    this byte
  154.  
  155. OldInt1C    dword    ?
  156.  
  157. MyInt1C        proc    far
  158.         assume    ds:cseg
  159.  
  160.         push    ds
  161.         push    ax
  162.         push    bx
  163.  
  164.         mov    ax, cs
  165.         mov    ds, ax
  166.  
  167.         dec    CallCnt
  168.         jne    NotYet
  169.         mov    CallCnt, CallsPerIter    ;Reset call count.
  170.         mov    bx, LEDIndex
  171.         mov    al, [bx]
  172.         call    SetLEDs
  173.         inc    bx
  174.         cmp    bx, offset TableEnd
  175.         jne    SetTbl
  176.         lea    bx, LEDTable
  177. SetTbl:        mov    LEDIndex, bx
  178. NotYet:        pop    bx
  179.         pop    ax
  180.         pop    ds
  181.         jmp    cs:OldInt1C
  182. MyInt1C        endp
  183.  
  184.  
  185. Main        proc
  186.  
  187.         mov    ax, cseg
  188.         mov    ds, ax
  189.  
  190.         print
  191.         byte    "LED Light Show",cr,lf
  192.         byte    "Installing....",cr,lf,0
  193.  
  194. ; Patch into the INT 9 and INT 16 interrupt vectors.  Note that the
  195. ; statements above have made cseg the current data segment,
  196. ; so we can store the old INT 9 and INT 16 values directly into
  197. ; the OldInt9 and OldInt16 variables.
  198.  
  199.         cli                ;Turn off interrupts!
  200.         mov    ax, 0
  201.         mov    es, ax
  202.         mov    ax, es:[1Ch*4]
  203.         mov    word ptr OldInt1C, ax
  204.         mov     ax, es:[1Ch*4 + 2]
  205.         mov    word ptr OldInt1C+2, ax
  206.         mov    es:[1Ch*4], offset MyInt1C
  207.         mov    es:[1Ch*4+2], cs
  208.         sti                ;Okay, ints back on.
  209.  
  210.  
  211. ; We're hooked up, the only thing that remains is to terminate and
  212. ; stay resident.
  213.  
  214.         print
  215.         byte    "Installed.",cr,lf,0
  216.  
  217.         mov    ah, 62h            ;Get this program's PSP
  218.         int    21h            ; value.
  219.  
  220.         mov    dx, EndResident        ;Compute size of program.
  221.         sub    dx, bx
  222.         mov    ax, 3100h        ;DOS TSR command.
  223.         int    21h
  224. Main        endp
  225. cseg        ends
  226.  
  227. sseg        segment    para stack 'stack'
  228. stk        db    1024 dup ("stack   ")
  229. sseg        ends
  230.  
  231. zzzzzzseg    segment    para public 'zzzzzz'
  232. LastBytes    db    16 dup (?)
  233. zzzzzzseg    ends
  234.         end    Main
  235.