home *** CD-ROM | disk | FTP | other *** search
/ GRIPS 2: Government Rast…rocessing Software & Data / GRIPS_2.cdr / dos / ncsa_tel / contribu / 3c505_dr < prev    next >
Encoding:
Text File  |  1990-12-29  |  61.2 KB  |  1,710 lines

  1.  
  2. Changes to pctools.c
  3. -----------------------------------------------------------------
  4. extern int E4etopen(),E4getaddr(),E4setaddr(),E4recv(),E4xmit(),E4etupdate();
  5. extern int E4etclose(),E4etdma();
  6.  
  7.  
  8. -----------------------------------------
  9. and these lines were add to "netconfig".
  10. -----------------------------------------
  11.     else if (!strncmp(s,"3c505",5) || !strncmp(s,"505",3)) {
  12.         etopen = E4etopen;
  13.         xmit = E4xmit;
  14.         recv = E4recv;
  15.         getaddr = E4getaddr;
  16.         etupdate = E4etupdate;
  17.         etclose = E4etclose;
  18.     }
  19.  
  20. -----------------------------------------------------------------
  21. ;-------net505.asm------
  22.           page     55,132
  23.           title     Driver routines for 3C505 Ethernet board
  24. ;
  25. ; Driver routines for 3C505 Ethernet board
  26. ;
  27. ; Bruce Orchard
  28. ; Waisman Center on Mental Retardation and Human Development
  29. ; University of Wisconsin-Madison
  30. ;
  31. ; April 7, 1988
  32. ;  2/9/89      Changed to make compatible with Telnet 2.2 - Warren Van Houten
  33. ;  3/17/89     Changed to make compatible with msc 5.0
  34. ;  7/14/89     Fixed getting ether address (far/near mismatch) - krus@diku.dk
  35. ;
  36. ;Microsoft EQU 1
  37. ;Lattice EQU 1
  38.   ifndef Microsoft
  39.     ifndef Lattice
  40.       if2
  41.         %out
  42.         %out ERROR: You have to specify "/DMicrosoft" OR "/DLattice" on the
  43.         %out        MASM command line to determine the type of assembly.
  44.         %out
  45.       endif
  46.       end
  47.     endif
  48.   endif
  49.  
  50. ifdef Microsoft
  51. x          equ     6              ; Offset to parameters (skip bp, ip, cs)
  52. else
  53.         NAME    NET
  54.       INCLUDE    DOS.MAC
  55.       SETX
  56. endif
  57.  
  58. ;  3C505 control register bit definitions
  59.  
  60. EC_ATTENTION             equ     0200q     ; Attention
  61. EC_FLUSH_DATA            equ     0100q     ; Flush data register
  62. EC_DMA_ENABLE            equ     0040q     ; DMA enable
  63. EC_TO_HOST               equ     0020q     ; Direction:  To host
  64. EC_TERMINAL_COUNT_ENABLE equ     0010q     ; Terminal count interrupt enable
  65. EC_COMMAND_ENABLE        equ     0004q     ; Command intterupt enable
  66. EC_FLAG2                 equ     0002q     ; Host status flag 2
  67. EC_FLAG1                 equ     0001q     ; Host status flag 1
  68.  
  69. ;  3C505 status register bit definitions
  70.  
  71. ES_DATA_READY            equ     0200q     ; Data register ready
  72. ES_HOST_COMMAND_EMPTY    equ     0100q     ; Host command register empty
  73. ES_ADAPTER_COMMAND_FULL  equ     0040q     ; Adapter command register full
  74. ES_TO_HOST               equ     0020q     ; Direction:  To host
  75. ES_DMA_DONE              equ     0010q     ; DMA done
  76. ES_FLAG3                 equ     0004q     ; Adapter status flag 3
  77. ES_FLAG2                 equ     0002q     ; Adapter status flag 2
  78. ES_FLAG1                 equ     0001q     ; Adapter status flag 1
  79.  
  80. ;  3C505 aux DMA control register bit definitions
  81.  
  82. EA_BURST                 equ     0001q     ; Burst mode DMA
  83.  
  84. ; 8259 equates
  85.  
  86. IOCWR1        equ     20h          ; Command register address 1
  87. IMR1          equ     21h          ; Interrupt mask register address 1
  88. VEC1          equ     8            ; First vector for 8259 1
  89. IOCWR2        equ     0a0h         ; Command register address 2
  90. IMR2          equ     0a1h         ; Interrupt mask register address 2
  91. VEC2          equ     70h          ; First vector for 8259 2
  92. EOI           equ     60h          ; End of interrupt command
  93.  
  94. ; Time out values (1/18 second ticks)
  95.  
  96. SECOND          EQU     18          ; Ticks in 1 second
  97. RESDEL          EQU     3           ; Delay before checking reset status
  98. RESTO           EQU     15*SECOND   ; Time out for reset completion
  99. CMDBTO          EQU     3           ; Time out for command byte to be accepted
  100. CMDCTO          EQU     3           ; Time out for command to be accepted
  101. RETRYDELAY      EQU     3           ; Command retry delay
  102. RCMDTO          EQU     3           ; Incoming command time out
  103. RESPTO          EQU     3           ; Response time out
  104.  
  105.  
  106.  
  107. ; BIOS data area
  108.  
  109. bios_data      segment     at 40h
  110. org 06Ch
  111. timer_low        dw        ?         ; BIOS timer counter
  112. timer_high       dw        ?
  113. timer_ofl        dw        ?
  114. bios_data       ends
  115.  
  116. ifdef Microsoft
  117. DGROUP    group    _DATA
  118. _DATA    segment    public 'DATA'
  119.  
  120. ;    PUBLIC    STAT,BUFPT,BUFORG,BUFEND,BUFREAD,BUFBIG,BUFLIM,OFFS
  121. ;
  122. ;  The pointers below are actually DWORDs but we access them two
  123. ;  bytes at a time.
  124. ;
  125. ; STAT change to RSTAT because of name clash with MSC library routine
  126. ;   EXTRN   _RSTAT:BYTE       ; last status from read
  127.     EXTRN   _BUFPT:WORD       ; current buffer pointer
  128.     EXTRN   _BUFORG:WORD      ; pointer to beginning of buffer
  129.     EXTRN   _BUFEND:WORD      ; pointer to end of buffer
  130.     EXTRN   _BUFREAD:WORD     ; pointer to where program is reading
  131.     EXTRN   _BUFBIG:WORD      ; integer, how many bytes we have
  132.     EXTRN   _BUFLIM:WORD      ; integer, max bytes we can have
  133.  
  134.           public     _c5_droptot
  135.           public     _c5_wrapct
  136.           public     _c5_nocmd     
  137.           public     _c5_cmdito
  138.  
  139. _c5_droptot    dw     0          ; total buffers dropped
  140. _c5_wrapct     dw     0          ; buffer wraparounds
  141. _c5_nocmd      dw     0          ; interrupt with command register empty
  142. _c5_cmdito     dw     0          ; incoming command timeout
  143.     assume    DS:seg _c5_droptot
  144.  
  145. else
  146.     DSEG
  147.  
  148. ;   EXTRN   RSTAT:BYTE    ; last status from read
  149.     EXTRN   BUFPT:WORD    ; current buffer pointer
  150.     EXTRN   BUFORG:WORD    ; pointer to beginning of buffer
  151.     EXTRN   BUFEND:WORD    ; pointer to end of buffer
  152.     EXTRN   BUFREAD:WORD    ; pointer to where program is reading
  153.     EXTRN   BUFBIG:WORD    ; integer, how many bytes we have
  154.     EXTRN   BUFLIM:WORD    ; integer, max bytes we can have
  155.  
  156.           public     c5_droptot
  157.           public     c5_wrapct
  158.           public     c5_nocmd     
  159.           public     c5_cmdito
  160.  
  161. c5_droptot    dw     0          ; total buffers dropped
  162. c5_wrapct     dw     0          ; buffer wraparounds
  163. c5_nocmd      dw     0          ; interrupt with command register empty
  164. c5_cmdito     dw     0          ; incoming command timeout
  165.     assume    DS:seg c5_droptot
  166.  
  167. endif
  168.  
  169. ksegbios     dw     ?          ; bios data segment
  170. ksegdata     dw     ?          ; DATA segment - might be different
  171.                                ; from seg c5_drop
  172. kseghere     dw     ?          ; segment for the begining of this data
  173.                                ; group.
  174. irq          dw     ?          ; Interrupt request level
  175. ioadr        dw     ?          ; IO address
  176. dma          dw     ?          ; DMA request level
  177.  
  178. ecommand     dw     ?          ; 3C505 command address
  179. estatus      dw     ?          ; 3C505 status address
  180. edata        dw     ?          ; 3C505 data address
  181. econtrol     dw     ?          ; 3C505 control address
  182. eauxdma      dw     ?          ; 3C505 aux DMA control address
  183.  
  184. eoi1         dw     ?          ; End of interrupt command for 8259 1
  185. eoi2         dw     ?          ; End of interrupt command for 8259 2
  186.  
  187. imr          dw     ?          ; Interrupt mask register address
  188. vec          dw     ?          ; Vector number
  189. oldioff      dw     ?          ; Original interrupt offset
  190. oldiseg      dw     ?          ; Original interrupt segment
  191.  
  192. pcblen       dw     ?          ; PCB length
  193. pcbad        dw     ?          ; PCB address
  194.  
  195. cmdlen       dw     ?          ; Incoming command length
  196.  
  197. rbufct       dw     ?          ; receive buffer counter
  198. rdropnew     dw     ?          ; receive buffers just dropped
  199. newstart     dw     ?          ; number of receives to start
  200.  
  201. savemask     db     ?          ; Original interrupt mask
  202. maskbit      db     ?          ; Interrupt mask bit
  203. lastcon      db     ?          ; Last control to board
  204.  
  205. CBSH         equ     50        ; half of incoming command buffer
  206. CBS          equ     CBSH*2    ; incoming command buffer size
  207.  
  208. icmdb        db     CBS dup (?)    ; Incoming command buffer
  209. icmd         db     CBSH dup (?)   ; incoming command
  210.  
  211. fconc        db     0          ; Flag:  Configure 82586
  212. fgeth        db     0          ; Flag:  Get Ethernet address
  213. fseth        db     0          ; Flag:  Set Ethernet address
  214. fxmit        db     0          ; Flag:  Transmit packet
  215. fadin        db     0          ; Flag:  Adapter info
  216. fstat        db     0          ; Flag:  Statistics
  217.  
  218.           even
  219.  
  220. cconc          db     02h        ; Command:  Configure 82586
  221.                db     2          ; -- 2 more bytes
  222.                dw     1          ; -- receive broadcasts
  223.  
  224. rconc          db  2 dup (?)     ; Response:  Configure 82586
  225. rconc_st       dw     ?          ; -- status
  226.  
  227.  
  228. cgeth          db     03h        ; Command:  Get Ethernet address
  229.                db     00         ; 0 more bytes
  230.  
  231. rgeth          db  2 dup (?)     ; Response:  Get Ethernet address
  232. rgeth_ad       db  6 dup (?)     ; -- address
  233.  
  234.  
  235. cseth          db     10h        ; Command:  Set Ethernet address
  236.                db     06         ; 6 more bytes
  237. cseth_ad       db  6 dup (?)     ; -- address
  238. rseth          db  2 dup (?)     ; Response:  Set Ethernet address
  239. rseth_status   dw     ?          ; -- status
  240.  
  241. cxmit          db     09h        ; Command:  Transmit packet
  242.                db     06         ; 6 more bytes
  243. cx_offset      dw     ?          ; -- buffer offset
  244. cx_segment     dw     ?          ; -- buffer segment
  245. cx_length      dw     ?          ; -- buffer length
  246.  
  247. rxmit          db  2 dup (?)     ; Response:  Transmit packet
  248. rx_offset      dw     ?          ; -- buffer offset
  249. rx_segment     dw     ?          ; -- buffer segment
  250. rx_status      dw     ?          ; -- completion status
  251. rx_cstatus     dw     ?          ; -- 82586 status
  252.  
  253. cr             db     08h        ; Command:  Receive
  254.                db     08         ; 8 more bytes
  255. cr_offset      dw     ?          ; -- buffer offset
  256. cr_segment     dw     ?          ; -- buffer segment
  257. cr_length      dw     ?          ; -- buffer length
  258. cr_timeout     dw     ?          ; -- timeout
  259.  
  260. rr             db  2 dup (?)     ; Response:  Receive
  261. rr_offset      dw     ?          ; -- buffer offset
  262. rr_segment     dw     ?          ; -- buffer segment
  263. rr_dmalen      dw     ?          ; -- bytes to dma
  264. rr_length      dw     ?          ; -- actual length
  265. rr_status      dw     ?          ; -- completion status
  266. rr_rstatus     dw     ?          ; -- 82586 receive status
  267. rr_time        dd     ?          ; -- time tag
  268.  
  269. cadin          db     11h        ; Command:  Adapter info
  270.                db     0          ; 0 more bytes
  271. radin          db  2 dup (?)     ; Response:  Adapter info
  272.  
  273. ra_rom         dw     ?          ; -- ROM version
  274. ra_cs          dw     ?          ; -- ROM checksum
  275. ra_mem         dw     ?          ; -- RAM memory size
  276. ra_freeoff     dw     ?          ; -- Free memory offset
  277. ra_freeseg     dw     ?          ; -- Free memory segment
  278.  
  279. cstat          db     0ah        ; Command:  Network statistics
  280.                db     0          ; 0 more bytes
  281.  
  282. rstat          db  2 dup (?)     ; Response:  Network statistics
  283. rs_rec         dd     ?          ; -- Packets received
  284. rs_tran        dd     ?          ; -- Packets sent
  285. rs_crc         dw     ?          ; -- CRC error counter
  286. rs_align       dw     ?          ; -- Alignment error counter
  287. rs_nors        dw     ?          ; -- No resources error counter
  288. rs_or          dw     ?          ; -- Overrun error counter
  289.  
  290. TURNOFF        db     08h
  291. TURNON         db     0F7h
  292. ifdef Microsoft
  293. _DATA    ends
  294. else
  295.     ENDDS
  296. endif
  297. ;
  298. ;
  299. ;  Macros for in and out
  300. ;
  301. MOUT     MACRO     REG,STUFF       ; one byte to the given I/O register
  302.      MOV  DX, REG
  303.      MOV  AL, STUFF
  304.      OUT  DX, AL
  305.      ENDM
  306. ;
  307. MOUTW     MACRO     REG, LO, HI     ; two bytes to the I/O double port
  308.      MOV  DX, REG
  309.      MOV  AL, LO
  310.      OUT  DX, AL
  311.      INC  DX
  312.      MOV  AL, HI
  313.      OUT  DX, AL
  314.      ENDM
  315. ;
  316. MIN MACRO  REG              ; get one byte to al
  317.     MOV DX, REG
  318.     IN  AL, DX
  319.     ENDM
  320.  
  321.  
  322. ;
  323. ;
  324. ;
  325. ;   The subroutines to call from C
  326. ;
  327. ifdef Microsoft
  328. _TEXT  segment  public  'CODE'
  329.     
  330.     assume CS:_TEXT, ES:bios_data
  331.     
  332.     PUBLIC  _E4RECV, _E4ETOPEN, _E4ETCLOSE, _E4GETADDR
  333.     PUBLIC  _E4SETADDR, _E4XMIT, _E4ETUPDATE, _E4ETDMA
  334.     public  _c5_get_adapter_info, _c5_get_statistics
  335. else
  336.     PSEG
  337.     PUBLIC  E4RECV, E4ETOPEN, E4ETCLOS, E4GETADD
  338.     PUBLIC  E4SETADD, E4XMIT, E4ETUPDA, E4ETDMA
  339.     public  c5getada, c5getsta
  340. endif
  341.  
  342.  
  343.  
  344.           subttl     _E4etopen:  Initialize board
  345.           page     +
  346. ;******************************************************************
  347. ;  ETOPEN
  348. ;     Initialize the Ethernet board, set receive type.
  349. ;
  350. ;  usage:  etopen(s,irq,addr,ioaddr)
  351. ;           char s[6];       ethernet address
  352. ;           int irq,addr,ioaddr;     
  353. ;                interrupt number, base mem address (unused) and
  354. ;                i/o address to use
  355. ;
  356. ;  _c5_init
  357. ;    Initialize the board, etc.
  358. ;
  359. ;  Arguments:
  360. a_ethadr   equ     x             ; ethernet address
  361. a_irq      equ     a_ethadr+4    ; Interrupt request level (int)
  362. a_seg      equ     a_irq+2       ; Shared segment address (int)
  363. a_ioadr    equ     a_seg+2       ; IO address (int)
  364. ;
  365. ifdef Microsoft
  366. _E4etopen  proc   far
  367. else
  368. E4ETOPEN    PROC    FAR
  369. endif
  370.           push     bp          ; save bp
  371.           mov     bp,sp          ; bp -> return, parameters
  372.           push     ds          ; save ds
  373.           push     es          ; save es
  374.           push     si          ; save si
  375.           push     di          ; save di
  376. ifdef Microsoft
  377.           mov     ax, seg _c5_droptot     ; ax -> data segment
  378. else
  379.           mov     ax, seg c5_droptot      ; ax -> data segment
  380. endif
  381.           mov     ds, ax                  ; ds -> data segment
  382.           mov     kseghere, ax
  383.           
  384.           mov     ax, seg _DATA
  385.           mov     ksegdata, ax
  386.           
  387.           mov     ax, seg bios_data
  388.           mov     ksegbios, ax
  389.           
  390.           mov     es, ksegbios            ; es -> bios data segment
  391.  
  392.           mov     ax, [bp+a_irq]          ; interrupt level -> ax
  393.           mov     irq, ax                 ; save interrupt level
  394.  
  395.           mov     ax, [bp+a_ioadr]        ; IO address -> ax
  396.           mov     ioadr, ax               ; save IO address
  397.           mov     ax, ioadr               ; 3C505 IO address -> ax
  398.           mov     ecommand, ax            ; save command address
  399.  
  400.           add     ax, 2                   ; status address -> ax
  401.           mov     estatus, ax             ; save status address
  402.  
  403.           mov     eauxdma, ax             ; save aux dma address
  404.           
  405.           add     ax, 2                   ; data address -> ax
  406.           mov     edata, ax               ; save data address
  407.  
  408.           add     ax, 2                   ; control address -> ax
  409.           mov     econtrol, ax            ; save control address
  410.  
  411.           cli                             ; disable interrupts
  412.  
  413. ; Set up the 8259 interrupt controller chip to what the 3c505 board is 
  414. ; set at.
  415.  
  416.           
  417.           mov     ax, irq                 ; interrupt level -> ax
  418.           cmp     ax, 8                   ; which 8259?
  419.           jge     o_1                     ; 8259 2
  420.           
  421.           mov     bx, ax                  ; irq -> bx
  422.           or      ax, EOI                 ; 8259 1: make first EOI command
  423.           mov     eoi1, ax                ; save first EOI command
  424.           mov     eoi2, 0                 ; no second EOI command
  425.           mov     imr, IMR1               ; mask is in IMR1
  426.           add     bx, VEC1                ; interrupt vector number -> bx
  427.           mov     vec, bx                 ; save vector number
  428.           jmp     o_2                     ; skip 8259 2 case
  429.  
  430.        ; 8259 2: just keep low 8 bits of interrupt number
  431. o_1:
  432.           and     ax, 07Q
  433.           mov     bx, ax                  ; interrupt on 8259 -> bx
  434.           or      ax, EOI                 ; put in EOI command
  435.           mov     eoi2, ax                ; save second EOI command
  436.           mov     eoi1, EOI+2             ; first EOI releases second
  437.           mov     imr, IMR2               ; mask is in IMR2
  438.           add     bx, VEC2                ; interrupt vector number -> bx
  439.           mov     vec, bx                 ; save vector number
  440.           mov     dx, IOCWR2              ; dx -> command register 2
  441.           out     dx, al                  ; do EOI 2 just in case
  442.  
  443. o_2:
  444.           mov     ax, eoi1                ; EOI 1 command -> ax
  445.           mov     dx, IOCWR1              ; dx -> command register 1
  446.           out     dx, al                  ; do EOI 1 just in case
  447.           mov     ax, vec                 ; vector number -> ax
  448.  
  449. ; Install the interrupt handler.
  450.  
  451.           call    IINST
  452.           
  453. ; Save the old interrupt mask of the 8259 chip and then turn it on.
  454.  
  455.           mov     cx, irq                 ; interrupt level -> cx
  456.           and     cx, 07q                 ; just keep level on 8259
  457.           mov     ax, 1                   ; 1 -> ax
  458.           shl     ax, cl                  ; make interrupt mask
  459.           mov     maskbit, al             ; save mask bit
  460.           mov     dx, imr                 ; mask register address -> dx
  461.           in      al, dx                  ; get old mask
  462.           mov     savemask, al            ; save mask
  463.           mov     bl, maskbit             ; our interrupt bit -> bl
  464.           not     bl                      ; want to unmask it
  465.           and     al, bl                  ; combine with other interrupts
  466.           out     dx, al                  ; unmask our interrupt
  467.           sti                            ; turn interrupts on
  468.           
  469.  
  470. ;  Reset the 3c505 board - this takes about 15-20 seconds.
  471.  
  472.           mov     al, EC_ATTENTION OR EC_FLUSH_DATA; Master reset command -> al
  473.  
  474.           mov     dx, econtrol            ; dx -> control register
  475.           out     dx, al                  ; do reset
  476.           mov     ax, timer_low           ; current timer -> ax
  477.           add     ax, RESDEL              ; + time to wait
  478.  
  479. wlp1:
  480.           cmp     ax, timer_low           ; compare to current time
  481.           ja      wlp1                    ; wait for reset to propagate
  482.  
  483.           mov     al, EC_COMMAND_ENABLE   ; command interrupt enable -> al
  484.           mov     lastcon, al             ; save last command
  485.           out     dx, al                  ; release reset
  486.           mov     ax, timer_low           ; current timer -> ax
  487.           add     ax, RESDEL              ; + time to wait
  488.  
  489. wlp2:
  490.           cmp     ax, timer_low           ; compare to current time
  491.           ja      wlp2                    ; wait for CPU to start reset
  492.           mov     bx, timer_low           ; current timer -> ax
  493.           add     bx, RESTO               ; + time out
  494.  
  495. wlp3:
  496.           call     getstat                     ; get status
  497.  
  498.           and     ax, ES_FLAG1 OR ES_FLAG2     ; just keep flags
  499.           cmp     ax, ES_FLAG1 OR ES_FLAG2     ; both on?
  500.           jne     resdone                      ; no:  reset completed
  501.  
  502.           cmp     bx, timer_low                ; have we waited too long?
  503.           ja      wlp3                         ; no
  504.           jmp     openfail                     ; yes:  open failed
  505.  
  506. resdone:  
  507.  
  508. ; Set up the receive buffers.
  509.  
  510.           mov     rbufct, 0                ; clear buffer counter
  511.           mov     cr_length, 1600          ; buffer length:  1600
  512.  
  513. irb1:
  514.           mov     ax, rbufct               ; buffer counter -> ax
  515.           mov     cr_offset, ax            ; use buffer number for offset
  516.           inc     ax                       ; count buffer
  517.           mov     rbufct, ax               ; store buffer number
  518.           mov     ax, 10                   ; pcb length -> ax
  519.           mov     si, offset cr            ; si -> request
  520.  
  521.           call    outpcb                   ; pass pcb
  522.  
  523.           mov     ax, rbufct               ; buffer counter -> ax
  524.           cmp     ax, 10                   ; start 10 receives
  525.           jl     irb1                      ; loop if more buffers
  526.           
  527.           ; We use the same character string pointer for both of the
  528.           ; next two calls, so we don't adjust the stack pointer
  529.           ; until we're done.
  530.           
  531.           mov    ax, [bp+a_ethadr+2]
  532.           push   ax
  533.           mov    ax, [bp+a_ethadr]
  534.           push   ax
  535.  
  536. ; Get the hardware ethernet address.
  537.           
  538.           call   far ptr get_eth_addr
  539.           or     ax, ax
  540.           jz     callset
  541.           add    sp,4
  542.           jmp    openfail
  543. callset:          
  544.  
  545. ;  Set the 3c505 board to use that address
  546.  
  547.           call   far ptr _e4setaddr
  548.           add    sp, 4
  549.           or     ax, ax
  550.           jnz    openfail
  551.  
  552. ; Tell the 3c505 board to start receiving packets.
  553.  
  554.           
  555.           CALL    E4OPEN
  556. ;    ax = 0 e4open OK, ax = -1 then e4open failed
  557.           jmp     openx                    ; go return
  558.  
  559. openfail:
  560.           mov     ax, -1                   ; -1 -> ax, fail
  561.  
  562. openx:
  563.           pop     di                      ; restore di
  564.           pop     si                      ; restore si
  565.           pop     es                      ; restore es
  566.           pop     ds                      ; restore ds
  567.           pop     bp                      ; restore bp
  568.           ret
  569. ifdef Microsoft
  570. _E4etopen     endp
  571. else
  572. E4ETOPEN    ENDP
  573. endif
  574.  
  575.  
  576.  
  577.           subttl     _E4etDMA:  DMA request level.
  578.           page     +
  579.  
  580. ;******************************************************************
  581. ;  ETDMA
  582. ;     Initialize the DMA request level.
  583. ;
  584. ;  not needed at this time
  585. ;
  586. a_dma      equ     a_ioadr+2     ; DMA request level
  587. ;
  588. ifdef Microsoft
  589. _E4etdma  proc   far
  590. else
  591. E4ETDMA  PROC  FAR
  592. endif
  593.  
  594.           push     bp          ; save bp
  595.           mov     bp,sp          ; bp -> return, parameters
  596.  
  597.           push     ds                     ; save ds
  598. ifdef Microsoft
  599.           mov     ax, seg _c5_droptot           ; ax -> data segment
  600. else
  601.           mov     ax, seg c5_droptot           ; ax -> data segment
  602. endif
  603.           mov     ds, ax
  604.           
  605.           mov     ax, seg bios_data
  606.           mov     ksegbios, ax
  607.  
  608.           mov     ax, [bp+a_dma]          ; DMA level -> ax
  609.           mov     dma, ax                 ; save IO address
  610.  
  611.           xor     ax, ax
  612.  
  613.           pop     ds                      ; restore ds
  614.  
  615.           pop     bp                      ; restore bp
  616.           ret
  617. ifdef Microsoft
  618. _E4etdma     endp
  619. else
  620. E4ETDMA   ENDP
  621. endif
  622.  
  623.  
  624.  
  625.  
  626.           subttl     open:  Open
  627.           page     +
  628. ;  This routine turns tells the 3c505 board to start receiving packets.
  629.  
  630. e4open     proc     near
  631.  
  632.           push     bp                     ; save bp
  633.           mov     bp, sp                  ; bp -> return, parameters
  634.           push     ds                     ; save ds
  635.           push     es                     ; save es
  636.           push     si                     ; save si
  637.           push     di                     ; save di
  638.                                           
  639. ifdef Microsoft
  640.           mov     ax, seg _c5_droptot           ; ax -> data segment
  641. else
  642.           mov     ax, seg c5_droptot           ; ax -> data segment
  643. endif
  644.           mov     ds, ax                  ; ds -> data segment
  645.           mov     es, ksegbios            ; es -> bios data segment
  646.           mov     si, offset cconc        ; si -> configure 82586 request
  647.           mov     ax, 4                   ; request length -> ax
  648.           mov     fconc, 0                ; clear response received flag
  649.           call    outpcb                  ; send the pcb
  650.  
  651.           mov     ax, timer_low           ; current time -> ax
  652.           add     ax, RESTO               ; + wait time
  653. op_1:
  654.           test    fconc, 0ffh             ; answered yet?
  655.           jnz     op_2                    ; yes
  656.  
  657.           cmp     ax, timer_low           ; expired?
  658.           ja      op_1                    ; no
  659.  
  660.           mov     ax, -1                  ; return fail
  661.           jmp     op_x                    ; go return
  662. op_2:
  663.           mov     ax, 0                   ; 0 -> ax, success
  664.  
  665. op_x:
  666.           pop     di                      ; restore di
  667.           pop     si                      ; restore si
  668.           pop     es                      ; restore es
  669.           pop     ds                      ; restore ds
  670.           pop     bp                      ; restore bp
  671.           ret               ; Just return
  672. E4open        endp
  673.  
  674.  
  675.           subttl     _E4etclose:  Close board
  676.           page     +
  677.  
  678. ;***********************************************************************
  679. ;  ETCLOSE
  680. ;        shut it down, remove the interrupt handler
  681. ;
  682. ;  usage:  etclose();
  683. ;
  684. ;
  685. ifdef Microsoft
  686. _E4ETCLOSE     PROC     FAR
  687. else
  688. E4ETCLOS     PROC     FAR
  689. endif
  690.      CLI
  691. ;
  692. ;
  693. ;  mask out IRQ on interrupt controller
  694. ;
  695.      push ds
  696. ifdef Microsoft
  697.           mov     ax, seg _c5_droptot           ; ax -> data segment
  698. else
  699.           mov     ax, seg c5_droptot           ; ax -> data segment
  700. endif
  701.      mov  ds, ax
  702.      MIN  imr                  ; get current mask
  703.      OR   AL, TURNOFF          ; force that bit on
  704.      OUT  DX, AL               ; send it back to controller
  705.      STI
  706.  
  707.      CALL  DEINST              ; restore old interrupt handler
  708.  
  709.      MOV   BL, savemask        ; get back saved setting of irq
  710.      NOT   BL                  ; flip it
  711.      
  712.      CLI
  713.      MIN   imr
  714.      AND   AL, BL              ; restore setting of that bit
  715.      OUT   DX, AL
  716.      STI     
  717.      
  718.      xor   ax, ax
  719.      pop   ds
  720.      RET
  721. ifdef Microsoft
  722. _E4ETCLOSE     ENDP
  723. else
  724. E4ETCLOS     ENDP
  725. endif
  726.  
  727.  
  728.           subttl     _c5_getaddr:  Get Ethernet address
  729.           page     +
  730.  
  731. ;*******************************************************************
  732. ;  GETADDR
  733. ;     get the Ethernet address off of the board (This gets called 
  734. ;       before E4etopen)
  735. ;
  736. ;   usage:  getaddr(s,address,ioaddr);
  737. ;    char s[6];           will get six bytes from the PROM
  738. ;       int address;    (unused here)
  739. ;       int ioaddr;     mem address and ioaddress to use
  740. ;
  741. ; _E4getaddr
  742. ;    Get Ethernet address
  743. ;
  744. ; Arguments:
  745.  
  746. a_eadr          equ     x          ; Ethernet address (far char *)
  747. ag_ioadr        equ     a_eadr + 6
  748. ifdef Microsoft
  749. _E4getaddr     proc     far
  750. else
  751. E4GETADD    PROC    FAR
  752. endif
  753.  
  754. ret
  755.  
  756. ifdef Microsoft
  757. _E4getaddr     endp
  758. else
  759. E4GETADD    ENDP
  760. endif
  761.  
  762.  
  763. get_eth_addr   proc far
  764. ;
  765. ; This was the old getaddr routine.  But, to advoid changing the Telnet
  766. ; source code i moved it here.  The interrupt handler has to be installed
  767. ; before this routine is used.
  768. ;
  769.           push     bp
  770.           mov     bp, sp                  ; bp -> return, parameters
  771.           push     ds
  772.           push     es
  773.           push     si
  774.           push     di
  775.  
  776. ifdef Microsoft
  777.           mov     ax, seg _c5_droptot           ; ax -> data segment
  778. else
  779.           mov     ax, seg c5_droptot           ; ax -> data segment
  780. endif
  781.           mov     ds, ax                  ; ds -> data segment
  782.           mov     es, ksegbios            ; es -> bios data segment
  783.  
  784.           mov     si, offset cgeth        ; si -> request ethernet address
  785.           mov     ax, 2                   ; request length -> ax
  786.           mov     fgeth, 0                ; clear response received flag
  787.  
  788.           call    outpcb                  ; send the pcb
  789.  
  790.           mov     ax, timer_low           ; current time -> ax
  791.           add     ax, RESTO               ; + wait time
  792. ga_1:
  793.           test    fgeth, 0ffh             ; answered yet?
  794.           jnz     ga_2                    ; yes
  795.  
  796.           cmp     ax, timer_low           ; expired?
  797.           ja      ga_1                    ; no;
  798.  
  799.           mov     ax, -1                  ; return fail
  800.           jmp     ga_x                    ; go return
  801.  
  802. ga_2:
  803.           cld
  804.           mov     di, [bp+a_eadr]         ; di -> destination offset
  805.           push    es                      ; save es
  806.           mov     es, [bp+a_eadr+2]       ; es -> destination segment
  807.           mov     si, offset rgeth_ad     ; si -> response
  808.           mov     cx, 6                   ; address length -> cx
  809.  
  810.           rep movsb                       ; return address
  811.  
  812.           pop     es
  813.           mov     ax, 0                   ; 0 -> ax, success
  814. ga_x:
  815.           pop     di
  816.           pop     si
  817.           pop     es
  818.           pop     ds
  819.           pop     bp
  820.           ret
  821.  
  822. get_eth_addr   endp
  823.           subttl     _c5_setaddr:  Set Ethernet address
  824.           page     +
  825.  
  826. ;******************************************************************
  827. ;  SETADDR
  828. ;    set the Ethernet address on the board to 6 byte ID code
  829. ;
  830. ;   usage:   setaddr(s,basea,ioa);
  831. ;             char s[6];           ethernet address to use
  832. ;             int basea;           shared memory base address (unused)
  833. ;             int ioa;             io address for board (unused)
  834. ;
  835. ; _c5_setaddr
  836. ; _E4setaddr
  837. ;    Set Ethernet address
  838. ;
  839. ; Arguments:
  840.  
  841. a_eadr          equ     x          ; Ethernet address (far char *)
  842.  
  843. ifdef Microsoft
  844. _E4setaddr     proc     far
  845. else
  846. E4SETADD    PROC    FAR
  847. endif
  848.  
  849.           push     bp
  850.           mov     bp, sp                  ; bp -> return, parameters
  851.           push     ds
  852.           push     es
  853.           push     si
  854.           push     di
  855.  
  856. ifdef Microsoft
  857.           mov     ax, seg _c5_droptot           ; ax -> data segment
  858. else
  859.           mov     ax, seg c5_droptot           ; ax -> data segment
  860. endif
  861.           mov     ds, ax                  ; ds -> data segment
  862.           mov     es, ksegbios            ; es -> bios data segment
  863.           push    es
  864.  
  865.           mov     di, offset cseth_ad     ; si -> command
  866.           mov     ax, seg cseth_ad        ; ax -> command segment
  867.           mov     es, ax                  ; es -> command segment
  868.           push    ds
  869.  
  870.           mov     si, [bp+a_eadr]         ; di -> destination offset
  871.           mov     ds, [bp+a_eadr+2]       ; es -> destination segment
  872.           mov     cx, 6                   ; address length -> cx
  873.  
  874.           rep movsb                       ; return address
  875.  
  876.           pop     ds
  877.           pop     es
  878.  
  879.           mov     si, offset cseth        ; si -> request ethernet address
  880.           mov     ax, 8                   ; request length -> ax
  881.           mov     fseth, 0                ; clear response received flag
  882.  
  883.           call    outpcb                  ; send the pcb
  884.  
  885.           mov     ax, timer_low           ; current time -> ax
  886.           add     ax, RESTO               ; + wait time
  887. sa_1:
  888.           test     fgeth, 0ffh            ; answered yet?
  889.           jnz     sa_2                    ; yes
  890.           
  891.           cmp     ax, timer_low           ; expired?
  892.           ja      sa_1                    ; no
  893.           
  894.           mov     ax, -1                  ; return fail
  895.           jmp     sa_x                    ; go return
  896. sa_2:
  897.           mov     ax,0                    ; 0 -> ax, success
  898. sa_x:
  899.           pop     di
  900.           pop     si
  901.           pop     es
  902.           pop     ds
  903.           pop     bp
  904.           ret
  905. ifdef Microsoft
  906. _E4setaddr     endp
  907. else
  908. E4SETADD    ENDP
  909. endif
  910.  
  911.  
  912.           subttl     _c5_get_adapter_info:  Get adapter information
  913.           page     +
  914.           
  915. ; I don't have the information to use this routine
  916. ;
  917. ; _c5_get_adapter_info
  918. ;    Get adapter information
  919. ;
  920. ; Arguments:
  921.  
  922. a_adin    equ     x        ; Adapter information (far struct r_adapter_info *)
  923.  
  924. _c5_get_adapter_info     proc     far
  925.  
  926.           push     bp                     ; save bp
  927.           mov     bp, sp                  ; bp -> return, parameters
  928.           push     ds                     ; save ds
  929.           push     es                     ; save es
  930.           push     si                     ; save si
  931.           push     di                     ; save di
  932.           
  933. ifdef Microsoft
  934.           mov     ax, seg _c5_droptot           ; ax -> data segment
  935. else
  936.           mov     ax, seg c5_droptot           ; ax -> data segment
  937. endif
  938.           mov     ds, ax                  ; ds -> data segment
  939.           mov     es, ksegbios            ; es -> bios data segment
  940.           mov     si, offset cadin        ; si -> request adapter information
  941.           mov     ax, 2                   ; request length -> ax
  942.           mov     fadin, 0                ; clear response received flag
  943.  
  944.           call    outpcb                  ; send the pcb
  945.  
  946.           mov     ax, timer_low           ; current time -> ax
  947.           add     ax, RESTO               ; + wait time
  948. ai_1:     
  949.           test     fadin, 0ffh            ; answered yet?
  950.           jnz     ai_2                    ; yes
  951.  
  952.           cmp     ax, timer_low           ; expired?
  953.           ja      ai_1                    ; no
  954.  
  955.           mov     ax, -1                  ; return fail
  956.           jmp     ai_x                    ; go return
  957. ai_2:     
  958.           mov     di, [bp+a_adin]         ; di -> destination offset
  959.           push     es                     ; save es
  960.           mov     es, [bp+a_adin+2]       ; es -> destination segment
  961.           mov     si, offset radin        ; si -> response
  962.           mov     cx, 12                  ; address length -> cx
  963.  
  964.           rep movsb                       ; return address
  965.  
  966.           pop     es                      ; restore es
  967.           mov     ax, 0                   ; 0 -> ax, success
  968. ai_x:     
  969.           pop     di                      ; restore di
  970.           pop     si                      ; restore si
  971.           pop     es                      ; restore es
  972.           pop     ds                      ; restore ds
  973.           pop     bp                      ; restore bp
  974.           ret                           ; return
  975. _c5_get_adapter_info     endp
  976.  
  977.  
  978.           subttl     _c5_get_statistics:  Get statistics
  979.           page     +
  980.  
  981. ; I don't have the information to use this routine
  982. ;
  983. ; _c5_get_statistics
  984. ;    Get network statistics
  985. ;
  986. ; Arguments:
  987.  
  988. a_stat          equ     x          ; Statistics (far struct r_statistics *)
  989.  
  990. _c5_get_statistics     proc     far
  991.  
  992.           push     bp                     ; save bp
  993.           mov     bp, sp                  ; bp -> return, parameters
  994.           push     ds                     ; save ds
  995.           push     es                     ; save es
  996.           push     si                     ; save si
  997.           push     di                     ; save di
  998.           
  999. ifdef Microsoft
  1000.           mov     ax, seg _c5_droptot           ; ax -> data segment
  1001. else
  1002.           mov     ax, seg c5_droptot           ; ax -> data segment
  1003. endif
  1004.           mov     ds, ax                  ; ds -> data segment
  1005.           mov     es, ksegbios            ; es -> bios data segment
  1006.           mov     si, offset cstat        ; si -> request statistics
  1007.           mov     ax, 2                   ; request length -> ax
  1008.           mov     fstat, 0                ; clear response received flag
  1009.           
  1010.           call    outpcb                  ; send the pcb
  1011.           
  1012.           mov     ax, timer_low           ; current time -> ax
  1013.           add     ax, RESTO               ; + wait time
  1014. st_1:
  1015.           test     fstat, 0ffh            ; answered yet?
  1016.           jnz     st_2                    ; yes
  1017.           
  1018.           cmp     ax, timer_low           ; expired?
  1019.           ja      st_1                    ; no
  1020.           
  1021.           mov     ax, -1                  ; return fail
  1022.           jmp     st_x                    ; go return
  1023. st_2:
  1024.           mov     di, [bp+a_stat]         ; di -> destination offset
  1025.           push     es                     ; save es
  1026.           mov     es, [bp+a_stat+2]       ; es -> destination segment
  1027.           mov     si, offset rstat        ; si -> response
  1028.           mov     cx, 18                  ; statistics length -> cx
  1029.  
  1030.           rep movsb                       ; return address
  1031.  
  1032.           pop     es                      ; restore es
  1033.           mov     ax, 0                   ; 0 -> ax, success
  1034. st_x:
  1035.           pop     di                      ; restore di
  1036.           pop     si                      ; restore si
  1037.           pop     es                      ; restore es
  1038.           pop     ds                      ; restore ds
  1039.           pop     bp                      ; restore bp
  1040.           ret                           ; return
  1041. _c5_get_statistics     endp
  1042.  
  1043.  
  1044.           subttl     _E4recv:  Receive message
  1045.           page     +
  1046.  
  1047. ;************************************************************************
  1048. ;   Receive
  1049. ;   This is a CPU hook for boards that must be polled before we can
  1050. ;   deliver packets into the receive buffer.  (i.e. no interrupts used)
  1051. ;
  1052. ;   The 3COM 3C505 version uses interrupts, so this routine is a NOP
  1053. ;   for this board.
  1054. ;
  1055. ;    usage:  recv();
  1056. ;
  1057. ifdef Microsoft
  1058. _E4RECV    PROC    FAR
  1059. else
  1060. E4RECV    PROC    FAR
  1061. endif
  1062.  
  1063.     RET            ; for compatibility with other drivers
  1064.  
  1065. ifdef Microsoft
  1066. _E4RECV    ENDP
  1067. else
  1068. E4RECV    ENDP
  1069. endif
  1070.  
  1071.  
  1072.  
  1073.  
  1074.           subttl     _c5_xmit:  Transmit message
  1075.           page     +
  1076.  
  1077. ;************************************************************************
  1078. ;  XMIT         
  1079. ;     send a packet to Ethernet
  1080. ;     Is not interrupt driven, just call it when you need it.
  1081. ;
  1082. ;  usage:   xmit(packet,count)
  1083. ;        char *packet;
  1084. ;        int count;
  1085. ;
  1086. ;   Takes a packet raw, Ethernet packets start with destination address,
  1087. ;   and puts it out onto the wire.  Count is the length of packet < 2048
  1088. ;
  1089. ;   checks for packets under the Ethernet size limit of 60 and handles them
  1090. ;
  1091. ; _c5_xmit
  1092. ; _E4xmit
  1093. ;    Transmit message
  1094. ;
  1095. ; Arguments:
  1096.  
  1097. a_xaddr          equ     x          ; Pointer to buffer (far char *--must beeven)
  1098. a_xlength     equ     a_xaddr+4     ; Length in bytes (int)
  1099.  
  1100. ifdef Microsoft
  1101. _E4xmit     proc     far
  1102. else
  1103. E4XMIT    PROC    FAR
  1104. endif
  1105.  
  1106.           push     bp
  1107.           mov     bp, sp                  ; bp -> return, parameters
  1108.           push     ds
  1109.           push     es
  1110.           push     si
  1111.           push     di
  1112.  
  1113. ifdef Microsoft
  1114.           mov     ax, seg _c5_droptot           ; ax -> data segment
  1115. else
  1116.           mov     ax, seg c5_droptot           ; ax -> data segment
  1117. endif
  1118.           mov     ds, ax                  ; ds -> data segment
  1119.           mov     es, ksegbios            ; es -> bios data segment
  1120.           mov     ax, [bp+a_xaddr]        ; ax -> buffer offset
  1121.           mov     cx_offset, ax           ; put in request
  1122.           mov     ax, [bp+a_xaddr+2]      ; ax -> buffer segment
  1123.           mov     cx_segment, ax          ; put in request
  1124.  
  1125.           mov     ax, [bp+a_xlength]      ; message length -> ax
  1126.           cmp     ax, 60                  ; is buffer too short?
  1127.           jg      xm_4                    ; no
  1128.  
  1129.           mov     ax, 60                  ; yes:  pad with garbage
  1130. xm_4:
  1131.           inc     ax                      ; round up
  1132.           sar     ax, 1                   ; divide by 2
  1133.           shl     ax, 1                   ; multiply by 2
  1134.           mov     cx_length, ax           ; put in request
  1135.           mov     fxmit, 0                ; clear transmit done flag
  1136.           mov     si, offset cxmit        ; si -> request
  1137.           mov     ax, 8                   ; request length -> ax
  1138.  
  1139.           call    outpcb                  ; send command
  1140.  
  1141.           mov     bx, estatus             ; bx -> status register
  1142.           mov     dx, edata               ; dx -> data register
  1143.           mov     cx, cx_length           ; length -> cx
  1144.           sar     cx, 1                   ; convert to words
  1145.           mov     si, cx_offset           ; offset -> si
  1146.           push     ds
  1147.           mov     ds, cx_segment          ; segment -> ds
  1148. xm_1:
  1149.           lodsw                           ; next word -> ax
  1150.           out     dx, ax                  ; output it
  1151.           xchg    dx, bx                  ; dx -> status register
  1152. xm_2:
  1153.           in      al, dx                  ; get status
  1154.           test    al, ES_DATA_READY       ; ready for next word?
  1155.           jz      xm_2                    ; no
  1156.           
  1157.           xchg    dx, bx                  ; dx -> data register
  1158.           dec     cx                      ; count word
  1159.           jnz     xm_1                    ; loop through buffer
  1160.           
  1161.           pop     ds
  1162. xm_3:
  1163.           test    fxmit, 0ffh             ; has transmit completed?
  1164.           jz      xm_3                    ; no
  1165.           
  1166.           mov     ax, rx_status           ; return status
  1167. xm_x:
  1168.           pop     di
  1169.           pop     si
  1170.           pop     es
  1171.           pop     ds
  1172.           pop     bp
  1173.           ret
  1174. ifdef Microsoft
  1175. _E4xmit     endp
  1176. else
  1177. E4XMIT    ENDP
  1178. endif
  1179.  
  1180.  
  1181.           subttl     _c5_update:  Update receive buffer pointer
  1182.           page     +
  1183.  
  1184.  
  1185. ;*************************************************************************
  1186. ;  ETUPDATE
  1187. ;      update pointers and/or restart receiver when read routine has
  1188. ;      already removed the current packet
  1189. ;
  1190. ;   usage:  etupdate();
  1191. ;
  1192. ; _c5_update
  1193. ; _E4etupdate
  1194. ;    Update receive buffer pointer
  1195. ;
  1196. ;************  needs much more work to use with Lattice C
  1197. ;
  1198. ifdef Microsoft
  1199. _E4etupdate     proc     far
  1200. else
  1201. E4ETUPDA    PROC    FAR
  1202. endif
  1203.           
  1204.           push     bp
  1205.           mov     bp, sp                  ; bp -> return, parameters
  1206.           push     ds
  1207.           push     es
  1208.           push     si
  1209.           push     di
  1210.           push     cx
  1211.           
  1212. ifdef Microsoft
  1213.           mov     ax, seg _c5_droptot           ; ax -> data segment
  1214. else
  1215.           mov     ax, seg c5_droptot         ; ax -> data segment
  1216. endif
  1217.           mov     ds, ax
  1218.           mov     es, ksegbios               ; es -> bios data segment
  1219.           push    es                         ; save es
  1220.           
  1221.           mov     ds, ksegdata          
  1222.           les     di, dword ptr _bufread     ; es/di -> start of message
  1223.           mov     ax, es:[di]                ; message length -> ax
  1224.           pop     es
  1225.           add     di, ax                     ; advance by message length
  1226.           add     di, 2                      ; + 2 for message length
  1227.           cmp     di, _bufend                ; passed end?
  1228.           jb      up_1                       ; no
  1229.           
  1230.           mov     di, _buforg             ; yes:  start over
  1231.           inc     _c5_wrapct              ; count wraparound
  1232. up_1:     
  1233.           mov     _bufread, di         ; store pointer
  1234.           
  1235.           cli                             ; protect bufbig
  1236.           mov     bx, _bufbig          ; amount of buffer in use -> bx
  1237.           sub     bx, ax                  ; - size just released
  1238.           sub     bx, 2                   ; - 2 for message size
  1239.           mov     _bufbig, bx          ; store size left
  1240.           sti                             ; release bufbig
  1241.           
  1242.           cli                             ; protect drop count
  1243.           mov     ax, rdropnew            ; messages dropped recently -> ax
  1244.           mov     rdropnew, 0             ; clear drop count
  1245.           sti                             ; release interrupts
  1246.           
  1247.           inc     ax                      ; + 1 for buffer released
  1248.           mov     ax, newstart            ; = number to start
  1249. up_2:
  1250.           mov     ax, rbufct              ; buffer counter -> ax
  1251.           mov     cr_offset, ax           ; use buffer number for offset
  1252.           inc     ax                      ; count buffer
  1253.           mov     rbufct, ax              ; store buffer number
  1254.           mov     ax, 10                  ; pcb length -> ax
  1255.           mov     si, offset cr           ; si -> request
  1256.           
  1257.           call     outpcb                 ; pass pcb
  1258.           
  1259.           dec     newstart                ; count receive started
  1260.           jg     up_2                     ; loop if more buffers
  1261. up_x:
  1262.           pop     cx
  1263.           pop     di
  1264.           pop     si
  1265.           pop     es
  1266.           pop     ds
  1267.           pop     bp
  1268.           ret
  1269. ifdef Microsoft
  1270. _E4etupdate     endp
  1271. else
  1272. E4ETUPDA    ENDP
  1273. endif
  1274.  
  1275.  
  1276.           subttl     getstat:  Get board status
  1277.           page     +
  1278. ; Get board status, waiting for it to become stable
  1279. ;
  1280. ; Return:
  1281. ;   al = status
  1282.  
  1283. getstat          proc     near
  1284.  
  1285.           push     bx
  1286.           push     dx
  1287.           
  1288.           mov     dx, estatus             ; dx -> status register
  1289. gs_1:
  1290.           in     al, dx                   ; status -> al
  1291.           mov     bl, al                  ; status -> bl
  1292.           in      al, dx                  ; status -> al
  1293.           cmp     al, bl                  ; same both times?
  1294.           jne     gs_1                    ; No:  try again
  1295.           
  1296.           pop     dx
  1297.           pop     bx
  1298.           ret
  1299. getstat          endp
  1300.  
  1301.  
  1302.  
  1303.           subttl     outpcb:  Send PCB to board
  1304.           page     +
  1305. ; Send pcb to board, retry until accepted
  1306. ;
  1307. ; Entry:
  1308. ;   ax = number of bytes in pcb
  1309. ;   si = address of pcb
  1310.  
  1311. outpcb          proc     near
  1312.  
  1313.           mov     pcblen, ax                   ; save pcb length
  1314.           mov     pcbad, si                    ; save pcb address
  1315.  
  1316. ob_1:
  1317.           mov     cx, pcblen                   ; length -> cx
  1318.           mov     si, pcbad                    ; address -> si
  1319.           
  1320.           cli                                      ; Protect last command
  1321.           mov     al, lastcon                      ; last command -> ax
  1322.           and     al, NOT (EC_FLAG1 OR EC_FLAG2)   ; clear flags
  1323.           mov     lastcon, al                      ; save lastcom
  1324.           sti                                      ; enable interrupts
  1325.           
  1326.           mov     dx, econtrol                 ; dx -> control register
  1327.           out     dx, al                       ; send control
  1328.           mov     dx, ecommand                 ; dx -> command register
  1329.           
  1330. ob_2:
  1331.           mov     al, [si]                     ; next command byte -> al
  1332.           out     dx, al                       ; send command byte
  1333.           mov     bx, timer_low                ; current timer -> ax
  1334.           add     bx, CMDBTO                   ; + time out
  1335.           
  1336. wlp4:
  1337.           call     getstat                     ; get status
  1338.           
  1339.           and     al, ES_HOST_COMMAND_EMPTY    ; has command been taken?
  1340.           jne     ob_3                         ; yes:  go on
  1341.           
  1342.           cmp     bx, timer_low                ; have we waited too long?
  1343.           ja     wlp4                          ; no
  1344.           
  1345.           jmp     cmdretry                     ; go retry command
  1346.           
  1347.           
  1348. ob_3:
  1349.           inc     si                           ; increment source pointer
  1350.           dec     cx                           ; count byte
  1351.           jg     ob_2                          ; loop if more bytes
  1352.           
  1353.           mov     dx, econtrol                 ; dx -> control register
  1354.           
  1355.           cli                                  ; disable interrupts
  1356.           mov     al, lastcon                  ; last control -> al
  1357.           or     al, (EC_FLAG1 OR EC_FLAG2)    ; set end of command
  1358.           mov     lastcon, al                  ; save lastcon
  1359.           out     dx, al                       ; send flag bits
  1360.           
  1361.           mov     dx, ecommand                 ; dx -> command register
  1362.           mov     ax, pcblen                   ; pcb length -> ax
  1363.           out     dx, al                       ; send pcb length
  1364.           sti                                  ; enable interrupts
  1365.           
  1366.           
  1367.           mov     bx, timer_low                ; current time -> bx
  1368.           add     bx, CMDCTO            ; + time out for command to be accepted
  1369. wlp5:
  1370.           call     getstat                     ; get status
  1371.           
  1372.           and     al, (ES_FLAG1 OR ES_FLAG2)   ; just keep status flags
  1373.           cmp     al, 1                        ; accepted?
  1374.           je     cmdaccept                     ; yes
  1375.           
  1376.           cmp     al, 2                        ; rejected?
  1377.           je     cmdretry                      ; yes
  1378.           
  1379.           cmp     bx, timer_low                ; have we waited too long?
  1380.           ja     wlp5                          ; no
  1381.           
  1382. cmdretry:
  1383.           mov     ax, timer_low                ; current time -> ax
  1384.           add     ax, RETRYDELAY               ; + retry delay
  1385. wlp6:
  1386.           cmp     ax, timer_low                ; have we waited long enough?
  1387.           ja     wlp6                          ; no
  1388.           
  1389.           jmp     ob_1                         ; go do retry
  1390.           
  1391. cmdaccept:
  1392.           cli                                    ; protect last control
  1393.           mov     al, lastcon                    ; last control -> al
  1394.           and     al, NOT (EC_FLAG1 OR EC_FLAG2) ; turn off end of command flag
  1395.           mov     lastcon, al                    ; save last control
  1396.           sti                                    ; reenable interrupts
  1397.           
  1398.           mov     dx, econtrol                 ; dx -> control register
  1399.           out     dx, al                       ; pass control byte
  1400.           mov     ax, 0                        ; return 0, success
  1401.           ret
  1402. outpcb          endp
  1403.  
  1404.  
  1405.           subttl     Interrupt routine
  1406.           page     +
  1407.  
  1408. ;*************************************************************************
  1409. ;  Interrupt Handler
  1410. ;  installation and deinstallation
  1411. ;
  1412. ;     the handler takes the receive packet out of the input buffer
  1413. ;
  1414. DEINST     PROC     NEAR
  1415.      push ds
  1416.      
  1417.      MOV  ax, vec                  ; interrupt in table for 3com board
  1418.      MOV  dx, oldioff              ; get old ip from save spot
  1419.      MOV  ds, oldiseg              ; get old cs from save spot
  1420.      mov  ah, 25h
  1421.      int  21h
  1422.  
  1423.      POP  DS
  1424.      RET
  1425. DEINST     ENDP
  1426.  
  1427.  
  1428. ;
  1429. IINST     PROC     NEAR
  1430.  
  1431.      MOV  CS:MYDS, DS              ; store for use by handler
  1432.  
  1433.      PUSH DS
  1434.      push es
  1435.      push bx
  1436.      
  1437.      mov  ax, vec                  ; get the current interupt vector
  1438.      mov  ah, 35h                  ; that we are using.
  1439.      int  21h
  1440.      
  1441.      mov  oldioff, bx              ; save the vector for later
  1442.      mov  oldiseg, es
  1443.      
  1444.      mov  dx, offset IHAND         ; set our interupt vector
  1445.      mov  ax, vec
  1446.      MOV  BX, CS
  1447.      MOV  DS, BX
  1448.      mov  ah, 25h
  1449.      int  21h
  1450.      
  1451.      pop  bx
  1452.      pop  es
  1453.      POP  DS
  1454.  
  1455.      RET
  1456.      
  1457. MYDS  DW 00H                     ; the data segment for this assembly code
  1458. ICNT  DB 00H
  1459.  
  1460. IHAND:                           ; not a public name, only handles ints
  1461.  
  1462.           push     ds
  1463.           push     es
  1464.           push     si
  1465.           push     di
  1466.           push     bp
  1467.           push     ax
  1468.           push     bx
  1469.           push     cx
  1470.           push     dx
  1471.           
  1472.           sti                             ; let other interrupts come in
  1473.           cld                             ; increment
  1474.  
  1475. ifdef Microsoft
  1476.           mov     ax, seg _c5_droptot           ; ax -> data segment
  1477. else
  1478.           mov     ax, seg c5_droptot           ; ax -> data segment
  1479. endif
  1480.           mov     ds, ax                  ; ds -> data segment
  1481.  
  1482.  
  1483. ; Check to see if we have a command in the command register
  1484.  
  1485. icmdc:
  1486.           mov     dx, estatus                   ; dx -> status register
  1487.           in      al, dx                        ; status -> al
  1488.           and     al, ES_ADAPTER_COMMAND_FULL   ; command register full?
  1489.           jnz     icmd0                         ; yes
  1490.           
  1491.           inc     _c5_nocmd              ; count no command
  1492.           jmp     ir_y                   ; no:  no more commands this interrupt
  1493.           
  1494. ; Yes we may have something.  Clear the flags and then check to see if 
  1495. ; we really have something.
  1496.  
  1497. icmd0:
  1498.           mov     bx, timer_low                    ; current time -> bx
  1499.           add     bx, RCMDTO                       ; + time to wait
  1500.           mov     al, lastcon                      ; last control -> ax
  1501.           and     al, NOT (EC_FLAG1 OR EC_FLAG2)   ; clear flags
  1502.           mov     lastcon, al                      ; save last control
  1503.           mov     dx, econtrol                     ; dx -> control register
  1504.           out     dx, al                      ; clear flags in control register
  1505.  
  1506. ;----------------------------------------------------------------------------
  1507. ; This loop stores the command from the 3c505 board into the icmdb buffer.
  1508. ;
  1509.           mov   di, offset icmdb               ; di -> incoming command buffer
  1510. icmd1:    
  1511.           mov   dx, estatus                    ; dx -> status register
  1512.           in    al, dx                         ; status -> al
  1513.           mov   cx, ax                         ; status -> cx
  1514.           test  al, ES_ADAPTER_COMMAND_FULL    ; command register full?
  1515.           jnz   icmd2                          ; yes
  1516.           
  1517.           cmp   bx, timer_low                  ; have we waited too long?
  1518.           ja    icmd1                          ; no
  1519.           
  1520.           inc   _c5_cmdito                     ; count time out
  1521.           jmp   ir_x                           ; yes:  give up
  1522.           
  1523. ;      Yes we REALLY do have a command waiting from the 3c505 board.
  1524. icmd2:
  1525.           mov     dx, ecommand               ; dx -> command register
  1526.           in      al, dx                     ; get command byte
  1527.           and     cl, ES_FLAG1 OR ES_FLAG2   ; just keep flags
  1528.           cmp     cl, ES_FLAG1 OR ES_FLAG2   ; are both on?
  1529.           je      icmd3                      ; yes:  end of command
  1530.           
  1531.           mov     [di], al                   ; save byte
  1532.           inc     di                         ; increment pointer
  1533.           mov     ax, di                     ; current pointer -> ax
  1534.           sub     ax, offset icmdb           ; - start of buffer
  1535.           cmp     ax, CBS                    ; full?
  1536.           jl      icmd1                      ; no
  1537.           
  1538.           mov     si, (offset icmdb) + CBSH  ; si -> middle of buffer
  1539.           mov     di, offset icmdb           ; di -> start of buffer
  1540.           mov     cx, CBSH                   ; size of half buffer -> cx
  1541.           PUSH    ds
  1542.           POP     es
  1543.           rep movsb                          ; move buffer up
  1544.           jmp     icmd1                      ; loop for another byte
  1545.  
  1546. ;-------------------------------------------------------------------------
  1547. ; We've gotten the command from the board.
  1548.           
  1549. icmd3:    
  1550.           push    ds
  1551.           pop     es                      ; es -> segment of command area
  1552.           mov     ah, 0                   ; clear high byte of length
  1553.           mov     cmdlen, ax              ; save command length
  1554.           mov     si, di                  ; si -> command buffer
  1555.           sub     si, cmdlen              ; back up to start of command
  1556.           mov     di, offset icmd         ; di -> command area
  1557.           mov     cx, cmdlen              ; command length -> cx
  1558.           
  1559.           rep movsb                       ; move command
  1560.           
  1561.           mov     al, icmd                ; first byte of command -> al
  1562.           cmp     al, 32h                 ; configure 82586?
  1563.           je     ic_conc                  ; yes
  1564.           
  1565.           cmp     al, 33h                 ; get Ethernet address?
  1566.           je     ic_geth                  ; yes
  1567.           
  1568.           cmp     al, 38h                 ; receive complete?
  1569.           je     ic_rec                   ; yes
  1570.           
  1571.           cmp     al, 39h                 ; transmit complete?
  1572.           je      ic_xmit                 ; yes
  1573.           
  1574.           cmp     al, 3ah                 ; statistics response?
  1575.           je     ic_stat                  ; yes
  1576.           
  1577.           cmp     al, 40h                 ; set Ethernet address complete?
  1578.           jne     ic_j4                   ; no
  1579.           
  1580.           jmp     ic_seth                 ; yes
  1581.           
  1582. ic_j4:    
  1583.           cmp     al, 41h                 ; adapter information response?
  1584.           jne     ic_j5                   ; no
  1585.           
  1586.           jmp     ic_adin                 ; yes
  1587.           
  1588. ic_j5:    
  1589.           jmp     ir_x                    ; other:  just ignore it
  1590.           
  1591. ic_conc:  
  1592.           push    ds
  1593.           pop     es                   ; es -> configure 82586 response segment
  1594.           mov     si, offset icmd      ; si -> command received
  1595.           mov     di, offset rconc     ; di -> configure 82586 response
  1596.           mov     cx, 2                ; response length -> cx
  1597.           
  1598.           rep movsw                    ; move response
  1599.           
  1600.           mov     fconc, 1             ; flag response received
  1601.           jmp     ir_x                 ; go return from interrupt
  1602.           
  1603. ic_geth:  
  1604.           push    ds
  1605.           pop     es                  ; es -> Ethernet address response segment
  1606.           mov     si, offset icmd     ; si -> command received
  1607.           mov     di, offset rgeth    ; di -> Ethernet address response
  1608.           mov     cx, 4               ; response length -> cx
  1609.           
  1610.           rep movsw                   ; move response
  1611.           
  1612.           mov     fgeth, 1            ; flag response received
  1613.           jmp     ir_x                ; go return from interrupt
  1614.           
  1615. ic_xmit:  
  1616.           push    ds
  1617.           pop     es                      ; es -> transmit response segment
  1618.           mov     si, offset icmd         ; si -> command received
  1619.           mov     di, offset rxmit        ; di -> transmit response
  1620.           mov     cx, 5                   ; response length -> cx
  1621.           
  1622.           rep movsw                       ; move response
  1623.           
  1624.           mov     fxmit, 1                ; flag response received
  1625.           jmp     ir_x                    ; go return from interrupt
  1626.           
  1627. ic_stat:  
  1628.           push    ds
  1629.           pop     es                      ; es -> statistics response segment
  1630.           mov     si, offset icmd         ; si -> command received
  1631.           mov     di, offset rstat        ; di -> statistics response
  1632.           mov     cx, 5                   ; response length -> cx
  1633.           
  1634.           rep movsw                       ; move response
  1635.           
  1636.           mov     fstat, 1                ; flag response received
  1637.           jmp     ir_x                    ; go return from interrupt
  1638.           
  1639. ic_rec:   
  1640.           push    ds
  1641.           pop     es                      ; es -> receive response segment
  1642.           mov     si, offset icmd         ; si -> command received
  1643.           mov     di, offset rr           ; di -> receive response
  1644.           mov     cx, 9                   ; response length -> cx
  1645.           
  1646.           rep movsw                       ; move response
  1647.           
  1648.           push    ds
  1649.           mov     ds, ksegdata
  1650.           mov     ax, _buflim             ; buffer size -> ax
  1651.           sub     ax, _bufbig             ; - amount in use
  1652.           pop     ds
  1653.           sub     ax, rr_dmalen              ; - size of new message
  1654.           jl      ir_drop                    ; no room--drop it
  1655.           
  1656.           push    ds
  1657.           mov     ds, ksegdata
  1658.           les     di, dword ptr _bufpt    ; es/di -> buffer position
  1659.           cmp     di, _bufend             ; have we passed restart point
  1660.           jb      icr_2                      ; no     
  1661.           
  1662.           mov     di, _buforg             ; yes:  start over
  1663. icr_2:    
  1664.           pop     ds
  1665.           mov     ax, rr_dmalen               ; message size -> ax
  1666.           inc     ax                          ; + 1 to round up
  1667.           shr     ax, 1                       ; convert to words
  1668.           shl     ax, 1                       ; convert back to characters
  1669.           mov     rr_dmalen, ax               ; use it to update bufbig
  1670.           stosw                      ; store message length at front of message
  1671.           mov     cx, ax                      ; message length -> cx
  1672.           shr     cx, 1                       ; convert to words
  1673.           mov     al, lastcon                 ; last control -> al
  1674.           or      al, EC_TO_HOST OR EC_FLAG1  ; set direction and acknowledge 
  1675.                                                      ; response
  1676.           mov     lastcon, al                 ; save last control
  1677.           mov     dx, econtrol                ; dx -> control register
  1678.           out     dx, al                      ; pass direction
  1679.           
  1680.           mov     dx, estatus              ; dx -> status register
  1681.           mov     bx, edata                ; bx -> data register
  1682. icr_1:    
  1683.           in      al, dx                   ; get status
  1684.           test    al, ES_DATA_READY        ; is data ready?
  1685.           jz      icr_1                    ; no
  1686.           xchg    dx, bx                   ; dx -> data register
  1687.           in      ax, dx                   ; data word -> ax
  1688.           stosw                            ; store word in buffer
  1689.           xchg    dx, bx                   ; dx -> status register
  1690.           dec     cx                       ; count word
  1691.           jnz     icr_1                    ; loop if more words
  1692.           
  1693.           mov     al, lastcon                      ; last control -> al
  1694.           and     al, NOT (EC_TO_HOST OR EC_FLAG1) ; change direction to output
  1695.           mov     lastcon, al                      ; save last control
  1696.           mov     dx, econtrol                     ; dx -> control register
  1697.           out     dx, al                  ; send control
  1698.           
  1699.           mov     ax, rr_dmalen           ; data length-> ax
  1700.           push    ds
  1701.           mov     ds, ksegdata
  1702.           mov     _bufpt, di              ; store pointer
  1703.           add     ax, _bufbig             ; + bytes in buffer 
  1704.           add     ax, 2                   ; + 2 for size
  1705.           mov     _bufbig, ax             ; save buffer in use
  1706.           pop     ds
  1707.           jmp     ir_x                    ; go return from interrupt
  1708. ir_drop:
  1709.           inc     _c5_droptot             ; count dropped message
  1710.           inc     rdropnew