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