home *** CD-ROM | disk | FTP | other *** search
/ The Pier Shareware 6 / The_Pier_Shareware_Number_6_(The_Pier_Exchange)_(1995).iso / 024 / psi110g.zip / SCCVEC.ASM < prev    next >
Assembly Source File  |  1993-09-16  |  8KB  |  253 lines

  1. ; Modified from the PE1CHL version to work with NOS.
  2. ; This file cannot be used with the PE1CHL sources.
  3. ; 1/21/90
  4. ; Ken Mitchum, KY3B   km@speedy.cs.pitt.edu km@cadre.dsl.pitt.edu
  5. ; SCC interrupt handler for IBM-PC
  6.  
  7. ;   
  8.  
  9.  
  10. include asmglobal.h        
  11.     LOCALS
  12.     %MACS
  13.     .LALL
  14.  
  15.     extrn   Stktop,Spsave,Sssave,doret:proc,scctim:proc,eoi:proc
  16.     extrn   porg:proc
  17.     extrn   Sccvecloc,Sccpolltab,Sccmaxvec:byte
  18.  
  19. ifdef   LARGEDATA
  20.     extrn   Sccchan:dword
  21. else
  22.     extrn   Sccchan:word
  23. endif
  24.     
  25.     .CODE
  26. dbase   dw      @Data           ; save loc for ds (must be in code segment)
  27.  
  28. ; sccvec is the interrupt handler for SCC interrupts using INTACK
  29.  
  30.     public sccvec
  31.     label   sccvec  far
  32.  
  33.     cli                     ; this code is not re-entrant, so make sure it
  34.                 ; is not interrupted. some multi-taskers
  35.                 ; intercept interrupt handlers, so be careful!
  36.  
  37.  
  38.     push    ds              ; save on user stack
  39.  
  40.     mov     ds,cs:dbase
  41.  
  42.     mov     Sssave,ss       ; stash user stack context
  43.     mov     Spsave,sp
  44.  
  45.     mov     ss,cs:dbase             ; set up interrupt stack
  46.     lea     sp,Stktop
  47.  
  48.       ;  push    ax              ; save user regs on interrupt stack
  49.       ;  push    bx
  50.       ;  push    cx
  51.       ;  push    dx
  52.       ;  push    bp
  53.       ;  push    si
  54.       ;  push    di
  55.     PUSHALL
  56.     push    es
  57.     call    eoi
  58. ifndef  LARGEDATA
  59.     mov     es,ax           ; small data assumes ES == DS
  60. endif
  61.     cld                     ; in case "movsb" or "movsw" is used
  62.  
  63.  
  64. ; Read SCC interrupt vector and check it
  65.  
  66. sccint: mov     dx,Sccvecloc
  67.     out     dx,al                   ; Generate INTACK
  68.     jmp     short d1                ; Delay
  69. d1:     jmp     short d2
  70. d2:     jmp     short d3
  71. d3:     in      al,dx                   ; Read the vector
  72.     cmp     al,Sccmaxvec            ; Check for a legal vector
  73.     jnc     clrret                  ; It should not be >= the maximum
  74.                     ; If it is, ignore the interrupt
  75.  
  76. ; Extract channel number and status from vector. Determine handler address.
  77.  
  78.     mov     bl,al                   ; Copy vector (need it later for status)
  79.     shr     bl,1                    ; Discard least significant bit
  80.     jc      clrret                  ; It should not be a 1
  81.     and     bx,7ch                  ; Isolate channel number (and make word)
  82.     xor     bl,04h                  ; Toggle A/B channel bit
  83. ifdef   LARGEDATA
  84.     les     si,Sccchan[bx]  ; Read address of channel structure
  85. else
  86.     shr     bl,1                    ; Discard another bit
  87.     mov     si,Sccchan[bx]          ; Read address of channel structure
  88. endif
  89. ifdef   LARGEDATA               ; Test for NULL
  90.     push    ax
  91.     mov             ax,es
  92.     test    ax,ax
  93.     pop             ax
  94.     jne     nn0
  95. endif
  96.     test    si,si                   ; Test for NULL
  97.     je      clrret                  ; No channel struct, ignore it
  98. nn0:
  99.     and     ax,06h                  ; Isolate status info from vector
  100.     add     ax,ax                   ; Make index in FAR PTR array
  101.     mov     bx,ax                   ; It must be in BX
  102.  
  103. ; Call the handler (defined in C), with Sccchan struct as a parameter
  104.  
  105.     push    es
  106.     push    si                      ; Put channel struct as a parameter
  107. ifdef   LARGEDATA
  108.     call    dword ptr es:[bx+si]    ; Call the handler
  109. else
  110.     call    dword ptr [bx+si]       ; Call the handler
  111. endif
  112.     pop     si                      ; Get channel struct back
  113.     pop     es
  114.  
  115. ; Reset highest priority interrupt
  116.  
  117. ifdef   LARGEDATA
  118.     mov     dx,es:16[si]            ; Get control register address
  119. else
  120.     mov     dx,16[si]               ; Get control register address
  121. endif
  122.     mov     al,38h                  ; "Reset Highest IUS" opcode
  123.     out     dx,al                   ; to WR0
  124.     jmp     short d4        ; settling delay
  125. d4:     jmp     short d5
  126. d5:
  127.  
  128. ; Determine if more interrupt requests are coming in from the SCCs
  129.  
  130.     jmp     sccint                  ; keep trying until no vector returned
  131.  
  132. ; Clear the ISR bit in the PIC and return from interrupt
  133.  
  134. clrret: 
  135.         mov     ax,0            ; clear chain vector value (4/92 KA9Q)
  136.         mov     dx,0
  137.         jmp     doret                   ; execute code in pcint.asm
  138.  
  139. ;       sccvec  endproc
  140.  
  141. ; sccnovec is the interrupt handler for SCC interrupts using polling
  142.  
  143.     public sccnovec
  144.     label sccnovec far
  145.     
  146.     cli                     ; this code is not re-entrant, so make sure it
  147.                 ; is not interrupted. some multi-taskers
  148.                 ; intercept interrupt handlers, so be careful!
  149.  
  150.  
  151.     push    ds              ; save on user stack
  152.     mov     ds,cs:dbase
  153.  
  154.     mov     Sssave,ss       ; stash user stack context
  155.     mov     Spsave,sp
  156.  
  157.     mov     ss,cs:dbase             ; set up interrupt stack
  158.     lea     sp,Stktop
  159.  
  160.     ; push    ax              ; save user regs on interrupt stack
  161.     ; push    bx
  162.     ; push    cx
  163.     ; push    dx
  164.     ; push    bp
  165.     ; push    si
  166.     ; push    di
  167.     PUSHALL
  168.     push    es
  169.     call    eoi
  170. ifndef  LARGEDATA
  171.     mov     es,ax           ; small data assumes ES == DS
  172. endif
  173.  
  174.     cld                     ; in case "movsb" or "movsw" is used
  175.  
  176.  
  177. ; Find the SCC generating the interrupt by polling all attached SCCs
  178. ; reading RR3A (the interrupt pending register)
  179.  
  180. sccintnv:
  181.     lea     si,Sccpolltab           ; Point to polling table
  182. sccpoll:
  183.     mov     dx,[si]                 ; Get chan A CTRL address
  184.     inc     si
  185.     inc     si
  186.     test    dx,dx                   ; End of table without finding it
  187.     je      clrret                  ; Then return from interrupt
  188.     mov     al,3                    ; Select RR3A
  189.     out     dx,al
  190.     jmp     short d6        ; Delay
  191. d6:     jmp     short d7
  192. d7:     jmp     short d8
  193. d8:     in      al,dx
  194.     test    al,al                   ; Test if a nonzero IP here
  195.     jnz     sccip                   ; Yes, handle it
  196.     inc     si                      ; No, next A CTRL
  197.     inc     si
  198.     jmp     sccpoll
  199.  
  200. ; Read SCC interrupt vector from RR2B, it should always be correct
  201. ; Extract channel number and status from vector. Determine handler address.
  202.  
  203. sccip:  mov     dx,[si]                 ; Read B CTRL address
  204.     mov     al,2                    ; Select RR2B
  205.     out     dx,al
  206.     jmp     short d9        ; Delay
  207. d9:     jmp     short d10
  208. d10:    jmp     short d11
  209. d11:    in      al,dx           ; Read the vector
  210.     mov     bl,al                   ; Copy vector (need it later for status)
  211.     shr     bl,1                    ; Discard least significant bit
  212.     and     bx,7ch                  ; Isolate channel number (and make word)
  213.     xor     bl,04h                  ; Toggle A/B channel bit
  214. ifdef   LARGEDATA
  215.     les si,Sccchan[bx]
  216. else
  217.     shr     bl,1                    ; Discard another bit (Sccchan=words)
  218.     mov     si,Sccchan[bx]          ; Read address of channel structure
  219. endif
  220. ifdef   LARGEDATA               ; Test for NULL
  221.     push    ax
  222.     mov             ax,es
  223.     test    ax,ax
  224.     pop             ax
  225.     jne nn1
  226. endif
  227.     test    si,si                   ; Test for NULL
  228.     je      clrret                  ; No channel struct, ignore it
  229. nn1:
  230.     and     ax,06h                  ; Isolate status info from vector
  231.     add     ax,ax                   ; Make index in FAR PTR array
  232.     mov     bx,ax                   ; It must be in BX
  233.  
  234. ; Call the handler (defined in C), with Sccchan struct as a parameter
  235.  
  236.     push    es
  237.     push    si                      ; Put channel struct as a parameter
  238. ifdef   LARGEDATA
  239.     call    dword ptr es:[bx+si]    ; Call the handler
  240. else
  241.     call    dword ptr [bx+si]       ; Call the handler
  242. endif
  243.     pop     si                      ; Remove parameter from stack
  244.     pop     es
  245.  
  246. ; Check for more interrupt pending bits
  247.  
  248.     jmp     sccintnv
  249.  
  250. ;       sccnovec        endproc
  251.  
  252.     end
  253.