home *** CD-ROM | disk | FTP | other *** search
/ BCI NET 2 / BCI NET 2.iso / archives / networking / misc / parpc04.lha / hardware / src / PARVEC.ASM < prev    next >
Encoding:
Assembly Source File  |  1993-08-13  |  6.1 KB  |  235 lines

  1. ; PARnet interrupt handler
  2. ; 03-JUN-93 <S.A.Pechler@bdk.tue.nl>
  3.  
  4.     .MODEL    MEMMOD,C
  5.     %MACS
  6.  
  7.         if @Datasize NE 0
  8.            extrn   parint:far,maskoff:far,maskon:far
  9.         else
  10.            extrn   parint:near,maskoff:near,maskon:near
  11.         endif
  12.  
  13.     .DATA
  14. Isat    dw      0
  15. int_no  dw      7               ; IRQ level used (=printer IRQ)
  16. savess    dw    ?        ; saved SS during the stack swap.
  17. savesp    dw    ?        ; saved SP
  18. Intstk  dw      512 dup(?)      ; Interrupt working stack
  19. Stktop  equ     $               ; SP set here when entering interrupt
  20.  
  21.     .CODE
  22. dbase   dw      @Data           ;to get the right DS
  23.  
  24. eoi     PROC
  25.         cmp     Isat,1
  26.         jne     @@1             ; Only one 8259, so skip this stuff
  27.         mov     al,0bh          ; read in-service register from
  28.         out     0a0h,al         ; secondary 8259
  29.         nop                     ; settling delay
  30.         nop
  31.         nop
  32.         in      al,0a0h         ; get it
  33.         or      al,al           ; Any bits set?
  34.         jz      @@1             ; nope, not a secondary interrupt
  35.         mov     al,20h          ; Get EOI instruction
  36.         out     0a0h,al         ; Secondary 8259 (PC/AT only)
  37. @@1:    mov     al,20h          ; 8259 end-of-interrupt command
  38.         out     20h,al          ; Primary 8259
  39.         ret
  40. eoi     ENDP
  41.  
  42.     public parisr
  43.         if @Datasize NE 0
  44.         label parisr far
  45.         else
  46.         label parisr near
  47.         endif
  48.  
  49.         push    ds
  50. ; Now switch stacks, push remaining registers, and do remaining interrupt work.
  51.         mov     ds,cs:dbase        ; establish interrupt data segment
  52.  
  53.         mov     savesp,sp
  54.     mov    savess,ss
  55.  
  56.     mov    ss,cs:dbase    ; stack segment = data segment
  57.         mov     sp,offset Stktop; initalize stacktop
  58.     cld
  59.  
  60.         push    ax
  61.     push    bx
  62.     push    cx
  63.         push    dx
  64.     push    si
  65.     push    di
  66.     push    bp
  67.     push    es
  68.  
  69. ; The following comment is wrong in that we now do a specific EOI command,
  70. ; and because we don't enable interrupts (even though we should).
  71.  
  72. ; Chips & Technologies 8259 clone chip seems to be very broken.  If you
  73. ; send it a Non Specific EOI command, it clears all In Service Register
  74. ; bits instead of just the one with the highest priority (as the Intel
  75. ; chip does and clones should do).  This bug causes our interrupt
  76. ; routine to be reentered if: 1. we reenable processor interrupts;
  77. ; 2. we reenable device interrupts; 3. a timer or other higher priority
  78. ; device interrupt now comes in; 4. the new interrupting device uses
  79. ; a Non Specific EOI; 5. our device interrupts again.  Because of
  80. ; this bug, we now completely mask our interrupts around the call
  81. ; to "parint", the real device interrupt handler.  This allows us
  82. ; to send an EOI instruction to the 8259 early, before we actually
  83. ; reenable device interrupts.  Since the interrupt is masked, we
  84. ; are still guaranteed not to get another interrupt from our device
  85. ; until the interrupt handler returns.  This has another benefit:
  86. ; we now no longer prevent other devices from interrupting while our
  87. ; interrupt handler is running.  This is especially useful if we have
  88. ; other (multiple) packet drivers trying to do low-latency transmits.
  89.         mov     ax,int_no       ; Disable further device interrupts
  90.         push    ax
  91.         call    maskoff
  92.         inc     sp
  93.         inc     sp
  94.  
  95.         call    eoi
  96.  
  97.         sti                             ; Interrupts are now completely safe
  98.         mov  ax,0
  99.         push ax
  100.         call    parint                  ; user interrupt routine
  101.         inc sp
  102.         inc sp
  103.  
  104.     cli                ;interrupts *must* be off between
  105.                     ;here and the stack restore, because
  106.                     ;if we have one of our interrupts
  107.                     ;pending, we would trash our stack.
  108.         mov     ax,int_no       ; Now reenable device interrupts
  109.         push    ax
  110.         call    maskon
  111.         inc     sp
  112.         inc     sp
  113.  
  114.     pop    es
  115.     pop    bp
  116.     pop    di
  117.     pop    si
  118.         pop     dx
  119.     pop    cx
  120.     pop    bx
  121.         pop     ax
  122.  
  123.     mov    ss,savess
  124.     mov    sp,savesp
  125.  
  126.     pop    ds
  127.     iret
  128.  
  129. ; Convert 32-bit int in network order to host order (dh, dl, ah, al)
  130. ; Called from C as
  131. ; int32 get32(char *cp);
  132.  
  133.     public    get32
  134. get32    proc
  135.     arg    cp:ptr
  136.     if    @Datasize NE 0
  137.         uses    ds,si
  138.         lds    si,cp    ; ds:si = cp
  139.     else
  140.         uses    si
  141.         mov    si,cp    ; ds:si = cp (ds already set)
  142.     endif
  143.  
  144.     cld
  145.     lodsw
  146.     mov    dh,al    ; high word to dx, a-swapping as we go
  147.     mov    dl,ah
  148.     lodsw
  149.     xchg    al,ah    ; low word stays in ax, just swap
  150.     ret
  151. get32    endp
  152.  
  153. ; Convert 16-bit int in network order to host order (ah, al)
  154. ; Called from C as
  155. ; int16 get16(char *cp);
  156.  
  157.     public    get16
  158. get16    proc
  159.     arg    cp:ptr
  160.     if    @Datasize NE 0
  161.         uses    ds,si
  162.         lds    si,cp    ; ds:si = cp
  163.     else
  164.         uses    si
  165.         mov    si,cp    ; ds:si = cp (ds already set)
  166.     endif
  167.  
  168.     lodsw        ; note: direction flag is don't-care
  169.     xchg    al,ah    ; word stays in ax, just swap
  170.     ret
  171. get16    endp
  172.  
  173. ; Convert 32-bit int to network order, returning new pointer
  174. ; Called from C as
  175. ; char *put32(char *cp,int32 x);
  176.  
  177.     public    put32
  178. put32    proc
  179.     arg    cp:ptr,x:dword
  180.     if    @Datasize NE 0
  181.         uses    ds,di
  182.         les    di,cp    ; es:di = cp
  183.         mov    ax,ss    ; our parameter is on the stack, and ds might not
  184.         mov    ds,ax    ;   be pointing to ss.
  185.     else
  186.         uses    di
  187.         mov    di,cp    ; es:di = cp
  188.         mov    ax,ds    ; point es at data segment
  189.         mov    es,ax
  190.     endif
  191.  
  192.     cld
  193.     mov    ax,word ptr (x+2)    ; read high word of machine version
  194.     xchg    ah,al            ; swap bytes
  195.     stosw                ; output in network order
  196.     mov    ax,word ptr x        ; read low word of machine version
  197.     xchg    ah,al            ; swap bytes
  198.     stosw                ; put in network order
  199.  
  200.     mov    ax,di    ; return incremented output pointer
  201.     if    @Datasize NE 0
  202.         mov    dx,es    ; upper half of pointer
  203.     endif
  204.     ret
  205. put32    endp
  206.  
  207. ; Convert 16-bit int to network order, returning new pointer
  208. ; Called from C as
  209. ; char *put16(char *cp,int16 x);
  210.  
  211.     public    put16
  212. put16    proc
  213.     arg    cp:ptr,x:word
  214.     uses    di
  215.     if    @Datasize NE 0
  216.         les    di,cp    ;es:di = cp
  217.     else
  218.         mov    di,cp    ; es:di = cp
  219.         mov    ax,ds
  220.         mov    es,ax
  221.     endif
  222.     cld
  223.     mov    ax,x    ; fetch source word in machine order
  224.     xchg    ah,al    ; swap bytes
  225.     stosw        ; save in network order
  226.     mov    ax,di    ; return new output pointer to user
  227.     if    @Datasize NE 0
  228.         mov    dx,es    ; upper half of pointer
  229.     endif
  230.     ret
  231. put16   endp
  232.  
  233.  
  234.     end
  235.