home *** CD-ROM | disk | FTP | other *** search
/ Power Programming / powerprogramming1994.iso / progtool / microcrn / issue_40.arc / SCANNER.ARC / SCAN.ASM < prev    next >
Assembly Source File  |  1988-01-11  |  9KB  |  246 lines

  1. ;           Code from Pascal column in Micro Cornucopia Issue #39
  2. ;
  3. ;           SCAN.ASM
  4. ;
  5. ;
  6. ;           Document scanner resident data capture software.
  7. ;           This software intercepts the real time clock interrupt
  8. ;           with a high speed data capture routine and also installs
  9. ;           a routine at interrupt vector 60H to provide scanning
  10. ;           functions to other programs.
  11. ;
  12. ;           Since this software incorporates itself into the real time
  13. ;           clock processing, it has the potential of interfering with
  14. ;           other resident software.  It is highly recommended that
  15. ;           the absolute minimum of other resident software be installed.
  16. ;
  17. ;           The software does NOT check for previous use of INT 60H.
  18. ;
  19. ;           Written for Eric Isaacson's A86 assembler.
  20. ;
  21. ;           CONST
  22. ;              joystick = 201H;
  23. ;              tickconst = 1024;
  24. ;
  25. joystick    equ     201h
  26. tickconst   equ     1024
  27. ;
  28. code        segment                     ; both code and data in same segment
  29. ;
  30.             jmp     init
  31. ;
  32. ;           VAR
  33. ;              count : CARDINAL;
  34. ;              counter : CARDINAL;
  35. ;              rasterPtr : POINTER TO raster;
  36. ;              scaning : BOOLEAN;
  37. ;              dosclk : ADDRESS;
  38. ;              tickcount : BYTE;
  39. ;              tickinc : BYTE;
  40. ;
  41. count       dw      ?
  42. counter     dw      ?
  43. ;
  44. raster_ofs  dw
  45. rasterPtr   dd      ?                   ; double word for far data
  46. scanning    db      0                   ; FALSE
  47. ;
  48. dosclk_ip   dw
  49. dosclk      dd      ?                   ; double word for far calls
  50. ;
  51. tickcount   dw      ?                   ; how many counter cycles?
  52. tickinc     dw      tickconst           ;  fast clock divisor default value
  53. ;
  54. ;           Restore/Set hardware clock chip
  55. ;
  56. restore_clock: xor  ax,ax               ; normal time constant = 0
  57. setclk:     push    ax
  58.             mov     al,36h              ; control register
  59.             out     43h,al
  60.             pop     ax
  61.             out     40h,al              ; count low byte
  62.             xchg    ah,al
  63.             out     40h,al              ; and high byte
  64.             ret
  65. ;
  66. ;           New clock routine, includes data capture from scanner
  67. ;
  68. fastclock:  push    ax                  ; interrupt routine, save registers
  69.             push    ds
  70.             push    es
  71.             push    cs                  ; make ds = cs
  72.             pop     ds
  73. ;
  74.             mov     al,scanning         ; are we scanning?
  75.             or      al,al
  76.             jz      notscanning         ; if z, no
  77. ;
  78.             push    bx                  ; scanning, save additional regs
  79.             push    cx
  80.             push    dx
  81. ;
  82.             mov     bx,raster_ofs       ; data address offset
  83.             mov     ax,raster_ofs+2     ;  and segment previously set
  84.             mov     es,ax               ;  when scan initiated.
  85. ;
  86.             mov     dx,joystick         ; input data address
  87.             in      al,dx               ;  get the data
  88.             mov     cl,4                ; then shift to low order nybble
  89.             ror     al,cl
  90.             and     al,0fh
  91. ;
  92.             push    si
  93.             mov     si,counter
  94. es          mov  b  [bx+si],al          ; store the data where M2 needs it
  95.             pop     si
  96.             inc     w counter           ; bump the count
  97.             mov     ax,count            ; done yet?
  98.             cmp     ax,counter
  99.             jnz     notdone             ; not done yet
  100. ;
  101.             xor     al,al               ; done, flip flag
  102.             mov     scanning,al
  103.             call    restore_clock       ; reset hardware
  104.             mov     tickcount,0         ; ready for next time
  105.             pop     dx
  106.             pop     cx
  107.             pop     bx
  108.             jmp     clkexit
  109. ;
  110. notdone:    pop     dx
  111.             pop     cx
  112.             pop     bx
  113. ;
  114.             mov     ax,tickcount
  115.             add     ax,tickinc          ; bump tick counter
  116.             mov     tickcount,ax
  117.             jnc     clkexit             ; if no overflow, not time for DOS
  118. ;
  119. notscanning:pushf                       ; simulate software interrupt
  120.             call    dosclk              ;  with pushf and far call
  121.             jmp     clkxit2             ; skip eoi to 8259 since dos does it
  122. ;
  123. clkexit:    mov     al,20h              ; end of interrupt command
  124.             out     20h,al              ; to 8259 interrupt controller
  125. clkxit2:    pop     es                  ; restore registers
  126.             pop     ds
  127.             pop     ax
  128.             iret
  129.  
  130. ;
  131. ;           Modula-2 activates the functions in this resident
  132. ;           software with an int 60H instruction.  The parameters
  133. ;           needed are passed in the registers AL, BX, CX, and DX.
  134. ;           AL = function #
  135. ;           BX = data (raster) offset
  136. ;           DX = data segment
  137. ;           CX = number of data points to capture or time constant
  138. ;
  139. ;           The functions currently supported are:
  140. ;           0 : report address of 'scanning' flag byte (DX:BX)
  141. ;           1 : restore original clock routine
  142. ;           2 : capture a scan line of data
  143. ;           3 : set fast clock speed 
  144. ;
  145. dispatch:                               ; M2 call has saved all regs
  146.             or      al,al               ;  report flag address?
  147.             jz      rprt_addr
  148. ;
  149.             cmp     al,1                ; restore clock to normal?
  150.             jz      killfast
  151. ;
  152.             cmp     al,2                ; get data
  153.             jz      capture
  154. ;
  155.             cmp     al,3                ; set fast clock divisor
  156.             jz      setfast
  157. ;
  158.             iret                        ; unrecognized function, ignore
  159. ;
  160. rprt_addr:  push    ds
  161.             push    cs                  ; data in code segment
  162.             pop     dx                  ;  segment address
  163.             mov     bx, offset scanning ; and offset
  164.             pop     ds                  ;  that's all it takes
  165.             iret
  166. ;
  167. setfast:    push    ds                  ; set fast clock divisor
  168.             push    cs
  169.             pop     ds
  170.             mov     tickinc,cx          ; simple isn't it?
  171.             pop     ds
  172.             iret
  173. ;
  174. killfast:   push    ds
  175.             push    cs
  176.             pop     ds
  177.             call    restore_clock       ; reset hardware
  178.             mov     dx,dosclk_ip        ; old offset value
  179.             mov     ds,dosclk_ip+2      ; and old segment
  180.             mov     ah,25h
  181.             mov     al,8
  182.             sti                         ; can we do an int if disabled?
  183.             int     21h
  184.             pop     ds
  185.             iret
  186. ;
  187. ;       Capture a line of data by setting scanning to TRUE
  188. ;       and activating the fast clock.
  189. ;
  190. capture:    push    ds
  191.             push    cs
  192.             pop     ds
  193.             mov     counter,0           ; data point counter
  194.             mov     count,cx            ;  # points to capture
  195.             mov     raster_ofs,bx       ; data destination offset
  196.             mov     raster_ofs+2,dx     ;  and segment
  197.             mov     scanning,0ffh       ; set scanning to TRUE
  198. ;
  199. ;
  200.             mov     ax,tickinc          ; set clock to fast rate
  201.             call    setclk
  202.             mov     tickcount,0         ; reset tick counter
  203.             pop     ds                  ; return to M2
  204.             iret
  205. ;
  206. ;
  207. ;           Install function dispatch routine 
  208. ;
  209. init:       mov     ah,25h              ; install interrupt function
  210.             mov     al,60H              ;  can only use 60 - 67
  211.             mov     dx, offset dispatch
  212.             push    cs
  213.             pop     ds
  214.             int     21h
  215. ;
  216. ;           Get and save old clock vector
  217. ;
  218.             push    es
  219.             mov     ah,35h              ; get vector function
  220.             mov     al,8h               ; clock vector #
  221.             int     21h
  222.             mov     dosclk_ip,bx        ; save the long address
  223.             mov     dosclk_ip+2,es
  224.             pop     es
  225. ;
  226. ;           Install new clock routine
  227. ;
  228.             push    ds
  229.             mov     ah,25h              ; install interrupt fxn
  230.             mov     al,8h
  231.             mov     dx, offset fastclock
  232.             push    cs
  233.             pop     ds
  234.             int     21h
  235.             pop     ds
  236. ;
  237. ;
  238. ;           exit to dos, remain resident
  239. ;
  240.             mov     dx,offset init
  241.             int     27h                 ; terminate but stay resident
  242. ;
  243. code        ends
  244.             end
  245.  
  246.