home *** CD-ROM | disk | FTP | other *** search
/ Super Net 1 / SUPERNET_1.iso / PC / OTROS / MSDOS / NCSA / TEL2307S.ZIP / NET / ENET / NET3COM.ASM < prev    next >
Encoding:
Assembly Source File  |  1991-10-20  |  25.5 KB  |  1,024 lines

  1. ;  3COM 3C501 driver code
  2. ;  Tim Krauskopf
  3. ;
  4. ;  This version is virtually unused, replaced by the driver version 
  5. ;  which handles all of the different ioaddrs and interrupts.
  6. ;
  7. ;****************************************************************************
  8. ;*                                                                          *
  9. ;*                                                                          *
  10. ;*      part of NCSA Telnet                                                 *
  11. ;*      by Tim Krauskopf, VT100 by Gaige Paulsen, Tek by Aaron Contorer     *
  12. ;*                                                                          *
  13. ;*      National Center for Supercomputing Applications                     *
  14. ;*      152 Computing Applications Building                                 *
  15. ;*      605 E. Springfield Ave.                                             *
  16. ;*      Champaign, IL  61820                                                *
  17. ;*                                                                          *
  18. ;*                                                                          *
  19. ;****************************************************************************
  20. ;
  21.  
  22.     TITLE    NETSUPPORT -- LOW LEVEL DRIVERS FOR ETHERNET
  23. ;
  24. ;  Assembler support for interrupt-driven Ethernet I/O on the PC
  25. ;
  26. ;  Will read and write packets from the 2K packet buffer on the
  27. ;  Etherlink card.  Provides hooks for higher layer protocols.
  28. ;
  29. ;Microsoft EQU 1
  30. ;Lattice EQU 1
  31. ifndef Microsoft
  32.     ifndef Lattice
  33.         if2
  34.             %out
  35.             %out ERROR: You have to specify "/DMicrosoft" OR "/DLattice" on the
  36.             %out        MASM command line to determine the type of assembly.
  37.             %out
  38.         endif
  39.         end
  40.     endif
  41. endif
  42.  
  43. ifdef Microsoft
  44. X    EQU    6
  45.     DOSSEG
  46.     .MODEL    LARGE
  47. else
  48.     INCLUDE    DOS.MAC
  49.     SETX
  50. endif
  51.     NAME    NET
  52. ;
  53. ;  Equates for controlling the 3COM board
  54. ;
  55. ICTRL    EQU    020H        ; 8259 interrupt control register
  56. IMASK    EQU    021H        ; 8259 interrupt mask register
  57. BASEA    EQU    300H        ; Base I/O address on PC I/O bus
  58. ENDOFI    EQU    020H        ; end-of-interrupt
  59. ;
  60. ;  Controller registers
  61. ;
  62. EADDR    EQU    BASEA+0H    ; Network address for hardware checking
  63. ;   takes six bytes, this is the address that the Ethernet board will
  64. ;   match to find packets on the net.  (0-5h)
  65. ;
  66. EREC    EQU    BASEA+6H    ; Receive status (read)
  67.                 ; Receive command (write)
  68. ESEND    EQU    BASEA+7H    ; Transmit status (read)
  69.                 ; Transmit command (write)
  70. EGLOW    EQU    BASEA+8H    ; General purpose pointer for R/W to 
  71.                 ; packet buffer, low byte
  72. EGHI    EQU    BASEA+9H    ; high byte, total of 11 bits for 2K buffer
  73. ERLOW    EQU    BASEA+0AH    ; Receive pointer, set by board (read) low byte
  74.                 ; Receive buffer pointer clear (write)
  75. ERHI    EQU    BASEA+0BH    ; high byte of Receive pointer
  76. EPROM    EQU    BASEA+0CH    ; PROM window address
  77.         ;     DH ??
  78. EAUX    EQU    BASEA+0EH    ; Auxiliary Status (read)
  79.                 ; Aux Command (write)
  80. EBUF    EQU    BASEA+0FH    ; Buffer window (where to I/O to net)
  81. ;
  82. ;  Transmit command options
  83. ;     what conditions we wish to be interrupted on after transmit
  84. ;
  85. EDTUNDER  EQU    01H        ; Detect underflow (bad CRC), not used
  86. EDTCOLL    EQU    02H        ; Detect collision on xmit
  87. EDTC16    EQU    04H        ; Detect 16 consecutive collisions (net down)
  88. EDTOK    EQU    08H        ; Detect successful transmission
  89.                 ; other 4 bits unused in this reg
  90. EXMITNORM  EQU    00H        ; Normal use for interrupt-driven XMIT
  91. ;
  92. ;  Transmit status results
  93. ;
  94. ;  Use same values as commands, 08h means OK to xmit again
  95. ;
  96. ;*****************************
  97. ;  Receive Command Options
  98. ;
  99. ;    If something is not detected for, the receiver automatically discards
  100. ;        those packets.
  101. ;
  102. EDTOVER    EQU    01H        ; Detect Overflow condition
  103. EDTFCS    EQU    02H        ; Detect FCS error, bad CRC on packet
  104. EDTDRB    EQU    04H        ; Detect dribble errors and accept them
  105. EDTSHORT EQU    08H        ; Detect short frames (< 60 bytes)
  106. EDTEOF    EQU    10H        ; Detect no overflow (end-of-frame found)
  107. EGOOD    EQU    20H        ; Accept good frames 
  108. ; four values legal for the last two bits:
  109. ECLOSE    EQU    00H        ; Turn off receiver
  110. EGETALL    EQU    40H        ; Get all packets, no matter what address
  111. EBROAD    EQU    80H        ; get those for me or for broadcast
  112. EMULTI    EQU    0C0H        ; get those for me or for multicast
  113. EWANT    EQU    0A0h        ; EGOOD OR EBROAD
  114.                 ; which packets we will look for on net
  115. ;
  116. ;  Receive Status results
  117. ;
  118. ;  errors are not detected unless asked for...otherwise the board just
  119. ;  won't take bad packets off of the net.
  120. ;
  121. ERROVER    EQU    01H        ; overflow error
  122. ERRFCS    EQU    02H        ; FCS (checksum) error
  123. ERRDRB    EQU    04H        ; Dribble error
  124. ERRSHORT  EQU    08H        ; Short frame error
  125. ENOOVER    EQU    10H        ; Received without overflow error 
  126.                 ; means that we didn't miss any by being slow
  127. ;EGOOD    EQU    20H        ; as above, we received a valid frame
  128. ; undefined 40h
  129. ESTALE    EQU    80H        ; stale receive condition, already read me
  130. ;
  131. ;  Aux command register
  132. ;
  133. EIRE    EQU    01H        ; interrupt request enable (no DMA) new boards
  134. EBADFCS    EQU    02H        ; create bad checksum for testing only
  135. ;
  136. ;  Next two bits tell who has access to packet buffer
  137. ;
  138. EBUS    EQU    00H        ; System bus has control of buffer
  139. EXMIT    EQU    04H        ; Transmit packet in buffer, auto kick
  140.                 ; back to recieve status
  141. EGETEM    EQU    08H        ; Receive state, look for packets
  142. ELOOP    EQU    0CH        ; Transmit and loopback into xmit buffer
  143. ;  10H  unused
  144. EDMA    EQU    20H        ; Starts a DMA xfer
  145. ERIDE    EQU    40H        ; Interrupt and DMA enable
  146. ERESET    EQU    80H        ; Reset the Ethernet board
  147. ;
  148. ;  Aux status register
  149. ;
  150. ERBUSY    EQU    01H        ; Receive busy, receiver looking for packets
  151. ;               02H        ; echos command status EBADFCS
  152. ;               04,08h        ; echos command status for EXMIT,EGETEM,EBUS
  153. EDMADONE  EQU    10H        ; goes to one when DMA finishes
  154. ;               20H        ; echos DMA request bit
  155. ;               40h        ; echos RIDE bit
  156. EXBUSY    EQU    80H        ; for polled xmit, goes to 0 when xmit is done
  157. ;
  158. ;
  159. ;  Macros for in and out
  160. ;
  161. MOUT    MACRO    REG,STUFF       ; one byte to the given I/O register
  162.     MOV    DX,REG
  163.     MOV    AL,STUFF
  164.     OUT    DX,AL
  165.     ENDM
  166. ;
  167. MOUTW    MACRO    REG,LO,HI      ; two bytes to the I/O double port
  168.     MOV    DX,REG
  169.     MOV    AL,LO
  170.     OUT    DX,AL
  171.     INC    DX
  172.     MOV    AL,HI
  173.     OUT    DX,AL
  174.     ENDM
  175. ;
  176. MIN    MACRO    REG             ; get one byte to al
  177.     MOV    DX,REG
  178.     IN    AL,DX
  179.     ENDM
  180.  
  181. ifdef Microsoft
  182. ;DGROUP    group    _DATA
  183. ;_DATA    segment    public 'DATA'
  184. ;    assume    DS:DGROUP
  185.     .data
  186. else
  187.     DSEG
  188. endif
  189. ;
  190. ;  The pointers below are actually DWORDs but we access them two
  191. ;  bytes at a time.
  192. ;
  193. ifdef Microsoft
  194.     PUBLIC  _RSTAT,_BUFPT,_BUFORG,_BUFEND,_BUFREAD,_BUFBIG,_BUFLIM
  195. ifdef OLD_WAY
  196.     PUBLIC  OFFS
  197. endif
  198. _RSTAT    DB    00H         ; last status from read
  199. _BUFBIG    DW    00H        ; buffer space used
  200. _BUFLIM    DW    05000H        ; buffer space limit
  201. _BUFPT    DW    00000H        ; where buffer pointer is, initialized safely
  202. _BUFDS    DW    0a000H        ; where buffer is, ds
  203. _BUFORG    DW    00000H        ; start of buffer space
  204. _BUFDS2    DW    0a000H        ; another ds
  205. _BUFEND    DW    06000H        ; end limit of allowable buffer space
  206. _BUFDS3    DW    0a000H
  207. _BUFREAD    DW    00000H        ; where the read pointer is
  208. _BUFDS4    DW    0a000H
  209. else
  210.     EXTRN    RSTAT:BYTE    ; last status from read
  211.     EXTRN    BUFPT:WORD    ; current buffer pointer
  212.     EXTRN    BUFORG:WORD    ; pointer to beginning of buffer
  213.     EXTRN    BUFEND:WORD    ; pointer to end of buffer
  214.     EXTRN    BUFREAD:WORD    ; pointer to where program is reading
  215.     EXTRN    BUFBIG:WORD    ; integer, how many bytes we have
  216.     EXTRN    BUFLIM:WORD    ; integer, max bytes we can have
  217. endif
  218.  
  219. SAVECS    DW    00H        ; where to save the old interrupt ptr
  220. SAVEIP    DW    00H
  221. OLDMASK    DB    00H        ; save interrupt controller mask
  222. DEAF    DB    00H        ; when we can't handle any more packets
  223. ifdef OLD_WAY
  224. OFFS    DW    00H        ; how many times the handler was turned off
  225. endif
  226. ;
  227. ;  use variables to access IRQ3 or IRQ5
  228. ;  3 is COM2, 5 is LPT2
  229. ;
  230. ;WHICHINT  EQU    4*0Bh        ; Interrupt for interrupt I/O on IRQ3
  231. ;WHICHINT  EQU    4*0Dh        ; Interrupt for interrupt I/O on IRQ5
  232. ;TURNOFF  EQU      08H          ; IRQ3 bit mask for 8259 controller (1<<3)
  233. ;TURNOFF  EQU      020H            ; IRQ5 bit mask for 8259 controller (1<<5)
  234. ;TURNON    EQU    0F7H        ; IRQ3 enable bit mask for 8259 controller
  235. ;TURNON    EQU    0DFH        ; IRQ5 enable bit mask for 8259 controller
  236. INTNUM    DB    0BH        ; Defaults to IRQ3, interrupt handler 0bh
  237. WHICHINT  DW    4*0BH        ; ETOPEN can change these values
  238. TURNOFF    DB    08H
  239. TURNON    DB    0F7H
  240. ifdef Microsoft
  241. ;_DATA    ends
  242. else
  243.     ENDDS
  244. endif
  245. ;
  246. ;
  247. ;
  248. ;   The subroutines to call from C
  249. ;
  250. ifdef Microsoft
  251. ;_TEXT    segment    public    'CODE'
  252. ;    assume CS:_TEXT
  253.     .code
  254.     PUBLIC  _E3RECV,_E3ETOPEN,_E3ETCLOSE,_E3GETADDR
  255. ifdef NOT_USED
  256.     PUBLIC  _E3SETADDR
  257. endif
  258.     PUBLIC  _E3XMIT,_E3ETUPDATE
  259. else
  260.     PSEG
  261.     PUBLIC    E3RECV,E3ETOPEN,E3ETCLOSE,E3GETADDR
  262. ifdef NOT_USED
  263.     PUBLIC  E3SETADDR
  264. endif
  265.     PUBLIC  E3XMIT,E3ETUPDATE
  266. endif
  267.  
  268. ;******************************************************************
  269. ;  ETOPEN
  270. ;     Initialize the Ethernet board, set receive type.
  271. ;
  272. ;  usage:  etopen(s,irq,addr,ioaddr)
  273. ;           char s[6];       ethernet address
  274. ;           int irq,addr,ioaddr;     
  275. ;                interrupt number, base mem address (unused) and
  276. ;                i/o address to use (currently unused)
  277. ;
  278. ;
  279. ifdef Microsoft
  280. _E3ETOPEN    PROC    FAR
  281. else
  282. E3ETOPEN    PROC    FAR
  283. endif
  284.     PUSH    BP
  285.     MOV    BP,SP
  286.     PUSH    SI
  287.     MOUT    EAUX,ERESET    ; reset the board
  288.     MOUT    EAUX,0          ; Clear the reset bit, otherwise keeps resetting
  289. ;
  290. ;  check the parameters for interrupt and dma
  291. ;
  292.     MOV    AX,[BP+X+4]    ; interrupt number
  293.     CMP    AL,5        ; If not 5, then use 3
  294.     JNZ    USE3
  295.     MOV    INTNUM,0DH    ; Interrupt # for handler for IRQ5
  296.     MOV    WHICHINT,4*0DH    ; Interrupt handler location in vector table
  297.     MOV    TURNOFF,020H    ; mask for interrupt controller for IRQ5
  298.     MOV    TURNON,0DFH    ; opposite mask, for interrupt controller
  299. USE3:
  300.     MOV    AX,[BP+X+6]    ; dma channel to use
  301.     CMP    AL,3        ; if not 3, then use 1
  302.     JNZ    USE1
  303. ;
  304. ; Add DMA values for channel 3 here later
  305. ;  probably never going to use DMA for this board - unreliable so far
  306. ;
  307. USE1:
  308. ;
  309. ;  install the interrupt handler
  310. ;
  311.     CALL    IINST        ; do the patching of the interrupt table
  312. ;
  313. ;  set up the net address
  314. ;
  315.     PUSH     DS        ; save mine
  316.     MOV    AX,[BP+X+2]    ; get new one
  317.     MOV    DS,AX           ; set new one
  318.     MOV    SI,[BP+X]    ; get pointer, ds:si is ready
  319.     ;
  320.     MOV    CX,6
  321.     MOV    DX,EADDR    ; get base i/o reg for setting address
  322.     CLD
  323. SADDR:
  324.     LODSB            ; get next one
  325.     OUT    DX,AL        ; send it
  326.     INC    DX        ; next position
  327.     LOOP    SADDR        ; do 6 times
  328.  
  329.     POP    DS        ; get back DS of local data
  330. ;
  331. ;  enable interrupts here with interrupt handler 
  332. ;  already set up.
  333. ;
  334.     MOUT    ESEND,0        ; xmit command = 0 for no interrupts
  335.     IN    AL,DX
  336.  
  337.     MOUT    EREC,EWANT    ; Set receiver for which packets we want
  338.     IN    AL,DX        ; reset 'stale'
  339.  
  340.     MOUT    ERLOW,0        ; Clear the receive buffer pointer
  341.  
  342.     CLI
  343.     MOUT    EAUX,EGETEM+ERIDE    ; Set for receive, interrupts
  344.  
  345.     MIN    IMASK        ; get current int enable mask
  346.     MOV    BL,AL        ; save a copy
  347.     AND    AL,TURNON    ; force bit for etherlink board off
  348.     OUT    DX,AL        ; put back the byte, IRQ enabled
  349.  
  350.     STI
  351.     AND    BL,TURNOFF    ; isolate this bit only from oldmask
  352.     MOV    OLDMASK,BL    ; save it
  353. ;
  354.     POP    SI
  355.     POP    BP
  356.     XOR    AX,AX
  357.     RET
  358. ifdef Microsoft
  359. _E3ETOPEN    ENDP
  360. else
  361. E3ETOPEN    ENDP
  362. endif
  363.  
  364. ifdef NOT_USED
  365. ;
  366. ;******************************************************************
  367. ;  SETADDR
  368. ;    set the Ethernet address on the board to 6 byte ID code
  369. ;
  370. ;   usage:   setaddr(s,basea,ioa);
  371. ;             char s[6];           ethernet address to use
  372. ;             int basea;           shared memory base address (unused)
  373. ;             int ioa;             io address for board (unused)
  374. ;
  375. ifdef Microsoft
  376. _E3SETADDR    PROC    FAR
  377. else
  378. E3SETADDR    PROC    FAR
  379. endif
  380.     PUSH    BP
  381.     MOV    BP,SP
  382.     PUSH    DS
  383.     PUSH    SI
  384.     MOV    AX,[BP+X+2]
  385.     MOV    DS,AX
  386.     MOV    SI,[BP+X]    ; address of buffer to read
  387. ;
  388.     MOV    CX,6
  389.     MOV    DX,EADDR    ; get base i/o reg for setting address
  390.     CLD
  391. SADDR2:
  392.     LODSB            ; get next one
  393.     OUT    DX,AL        ; send it
  394.     INC    DX        ; next position
  395.     LOOP    SADDR2        ; do 6 times
  396.  
  397.     POP    SI
  398.     POP    DS
  399.     POP    BP
  400.     RET
  401. ifdef Microsoft
  402. _E3SETADDR    ENDP
  403. else
  404. E3SETADDR    ENDP
  405. endif
  406. endif       ; NOT_USED
  407. ;
  408. ;*******************************************************************
  409. ;  GETADDR
  410. ;     get the Ethernet address off of the board
  411. ;
  412. ;   usage:  getaddr(s,address,ioaddr);
  413. ;    char s[6];           will get six bytes from the PROM
  414. ;       int address;
  415. ;       int ioaddr;     (unused here) mem address and ioaddress to use
  416. ;
  417. ifdef Microsoft
  418. _E3GETADDR    PROC    FAR
  419. else
  420. E3GETADDR    PROC    FAR
  421. endif
  422.     PUSH    BP
  423.     MOV    BP,SP
  424.     PUSH    DI
  425.     PUSH     ES        ; save mine
  426.     MOV    AX,[BP+X+2]    ; get new one
  427.     MOV    ES,AX           ; set new one
  428.     MOV    DI,[BP+X]    ; get pointer, es:di is ready
  429.     ;
  430.     MOV    BX,0            ; start location 
  431.     MOV    CX,EPROM    ; address window
  432. GADDR:
  433.     CLD
  434.     MOUTW    EGLOW,BL,BH      ; set gp to the right value
  435.     MIN    CX        ; get value from prom address window
  436.     STOSB                   ; put into given buffer
  437.     INC    BX        ; next position
  438.     CMP    BX,6
  439.     JNZ     GADDR          ; do 6 times
  440.     POP     ES
  441.     POP    DI
  442.     POP    BP        
  443.     RET
  444. ifdef Microsoft
  445. _E3GETADDR    ENDP
  446. else
  447. E3GETADDR    ENDP
  448. endif
  449. ;
  450. ;***********************************************************************
  451. ;  ETCLOSE
  452. ;        shut it down, remove the interrupt handler
  453. ;
  454. ;  usage:  etclose();
  455. ;
  456. ;
  457. ifdef Microsoft
  458. _E3ETCLOSE    PROC    FAR
  459. else
  460. E3ETCLOSE    PROC    FAR
  461. endif
  462.     CLI
  463.     MOUT    EAUX,ERESET    ; Turn off all pendings, cause reset
  464.     MOUT    EAUX,0          ; Turn off reset
  465. ;
  466. ;
  467. ;  mask out IRQ on interrupt controller
  468. ;
  469.     MIN    IMASK        ; get current mask
  470.     OR    AL,TURNOFF    ; force that bit on
  471.     OUT    DX,AL        ; send it back to controller
  472.     STI
  473.  
  474.     CALL    DEINST        ; restore old interrupt handler
  475.  
  476.     MOV    BL,OLDMASK    ; get back saved setting of irq
  477.     NOT    BL        ; flip it
  478.     CLI
  479.     MIN    IMASK
  480.     AND    AL,BL        ; restore setting of that bit
  481.     OUT    DX,AL
  482.     STI    
  483.     RET
  484. ifdef Microsoft
  485. _E3ETCLOSE    ENDP
  486. else
  487. E3ETCLOSE    ENDP
  488. endif
  489. ;
  490. ;************************************************************************
  491. ;   Receive
  492. ;   This is a CPU hook for boards that must be polled before we can
  493. ;   deliver packets into the receive buffer.  (i.e. no interrupts used)
  494. ;
  495. ;   The 3COM 3C501 version uses interrupts, so this routine is a NOP
  496. ;   for this board.
  497. ;
  498. ;    usage:  recv();
  499. ;
  500. ifdef Microsoft
  501. _E3RECV    PROC    FAR
  502. else
  503. E3RECV    PROC    FAR
  504. endif
  505.     RET            ; for compatibility with other drivers
  506. ifdef Microsoft
  507. _E3RECV    ENDP
  508. else
  509. E3RECV    ENDP
  510. endif
  511. ifdef unused_code
  512. ;      This version is unused.  It is a polled receive which is nearly
  513. ;      useless with this board.  It hasn't been debugged yet, either.
  514. ;             char *where;      at least 2048 bytes of room
  515. ;             returns # bytes in packet, -1 if no packet available
  516.     PUSH    BP
  517.     MOV    BP,SP
  518.     PUSH    ES
  519.     MOV    AX,[BP+X+2]    ; get new es value
  520.     MOV    ES,AX
  521.     MOV    DI,[BP+X]    ; set di for later movement
  522.     ;
  523.     MOV    CX,10        ; give it a few tries
  524.  
  525. FINDONE:
  526.     MIN    EAUX        ; get status to al
  527.     MOV    STAT,AL
  528.     AND    AL,ERBUSY    ; is it still in receive state or done?
  529.     JZ    READONE        ; done, can read it
  530.     LOOP    FINDONE
  531.  
  532.     MOV    AX,-1        ; no packet yet, return
  533.     POP    ES
  534.     POP    BP
  535.     RET
  536. ;
  537. READONE:
  538.     MOUT    EAUX,EBUS    ; turn off receive, give buffer to bus
  539.     MOUTW    EGLOW,0,0    ; clear general purpose pointer for read
  540.  
  541.     MOV    DX,ERLOW    ; receive buffer pointer
  542.     IN    AL,DX
  543.     MOV    CL,AL        ; save low byte
  544.     INC    DX
  545.     IN    AL,DX
  546.     MOV    CH,AL        ; save high byte
  547.  
  548.     MOV    BX,CX           ; save another copy of the length
  549.  
  550.     MOV    DX,EBUF        ; window to the data
  551.  
  552. DOBYTES:
  553.     IN    AL,DX        ; get a byte
  554.     STOSB            ; save it to es:di
  555.     LOOP     DOBYTES
  556.  
  557.     MIN    EREC        ; get status to al, clears read
  558.     MOV    STAT,AL        ; KEEP LAST STATUS BYTE
  559. ;
  560. ;  set up to read the next packet from the net
  561. ;
  562.     MOUT    ERLOW,0        ; clear receive buffer pointer
  563.     MOUT    EAUX,EGETEM+ERIDE    ; set receive bit in aux
  564.  
  565.     MOV    AX,BX        ; return value is # of bytes
  566.     POP    ES
  567.     POP    BP
  568.     RET
  569. ifdef Microsoft
  570. _E3RECV    ENDP
  571. else
  572. E3RECV    ENDP
  573. endif
  574. endif
  575. ;
  576. ;************************************************************************
  577. ;  XMIT         
  578. ;     send a packet to Ethernet
  579. ;     Is not interrupt driven, just call it when you need it.
  580. ;
  581. ;  usage:   xmit(packet,count)
  582. ;        char *packet;
  583. ;        int count;
  584. ;
  585. ;   Takes a packet raw, Ethernet packets start with destination address,
  586. ;   and puts it out onto the wire.  Count is the length of packet < 2048
  587. ;
  588. ;   checks for packets under the Ethernet size limit of 60 and handles them
  589. ;
  590. ifdef Microsoft
  591. _E3XMIT    PROC    FAR
  592. else
  593. E3XMIT    PROC    FAR
  594. endif
  595.     PUSH    BP
  596.     MOV    BP,SP
  597.     PUSH    SI
  598.     PUSH    DI
  599.     PUSH    DS        ; set up proper ds for the buffer
  600.     MOV    AX,[BP+X+2]
  601.     MOV    DS,AX
  602.     MOV    SI,[BP+X]    ; offset for buffer
  603.  
  604.     MOV    AX,[BP+X+4]    ; count of bytes
  605.     MOV    CX,AX        ; save a copy, might be less than 60, ok
  606.  
  607.     CMP    AX,60        ; minimum length for Ether
  608.     JNB    OKLEN
  609.     MOV    AX,60        ; make sure size at least 60
  610. OKLEN:
  611.     MOV    BX,2048        ; total length of buffer
  612.     SUB    BX,AX        ; offset of for buffer pointer to start
  613.     MOV    DI,BX        ; save a copy of the buffer pointer
  614. ;
  615. ;  TAKE CONTROL OF THE INPUT BUFFER
  616. ;
  617.     MOUT    EAUX,EBUS+ERIDE    ; take buffer away from receiver
  618.     MOUT    ERLOW,0        ; clear receive pointer for next read
  619.     MOUTW    EGLOW,BL,BH    ; set the general purpose pointer
  620.  
  621.     MOV    DX,EBUF        ; window to packet buffer
  622.     CLD
  623. FILLBUF:
  624.     LODSB            ; get value to go into buffer
  625.     OUT    DX,AL        ; put it into buffer (autoincrement)
  626.     LOOP    FILLBUF        ; do whole count
  627.  
  628.     POP    DS
  629. ;
  630. ;  packet is in buffer, ready to be sent
  631. ;
  632. TRYAGAIN:
  633.     MOV    BX,DI        ; retrieve copy of offset pointer
  634.     MOUTW    EGLOW,BL,BH    ; set the general purpose pointer (again)
  635. ;
  636.     MOUT    EAUX,EXMIT+ERIDE    ; tell the board to send it and start receiving
  637.     
  638. NOTDONEX:
  639.     MIN    EAUX        ; waiting for transmit to finish
  640.     AND    AL,EXBUSY    ; is it done yet?
  641.     JNZ    NOTDONEX    ; no, wait some more
  642.  
  643.     MOV    CX,0        ; return value, ok
  644.     MIN    ESEND        ; get xmit status
  645.     MOV    BL,AL        ; save status
  646.     AND    AL,EDTOK    ; was it ok?
  647.     JNZ    DONEX        ; yes, successful xmit
  648. ;
  649. ;  handle the possible errors, return 1 on coll16
  650. ;     coll16 generally means that the network has failed
  651. ;
  652.     MOV    AL,BL        ; get copy of status back
  653.     AND    AL,EDTC16    ; check collision 16
  654.     JNZ    RET16        ; yes, network probably down
  655.     MOV    AL,BL        ; get copy back again
  656.     AND    AL,EDTCOLL    ; check for collision status
  657.     JZ    UNK        ; no, unknown problem
  658.     MOUT    EAUX,EBUS+ERIDE        ; collision, reset buffer control
  659.     JMP    TRYAGAIN    ; go for it
  660. UNK:
  661.     MOV    CX,2        ; unknown problem return code
  662.     JMP SHORT DONEX
  663. RET16:
  664.     MOV    CX,1        ; failure return
  665. DONEX:
  666.     MOUT    EREC,EWANT    ; reset receive register filter necessary
  667.     MIN    EAUX    
  668.     AND    AL,ERBUSY    ; is it still in receive state or done?
  669.     JNZ    DONEMIT        ; not ready now, return instead
  670.  
  671.     MOV    AL,INTNUM
  672.     CMP    AL,0BH        ; two choices of int to call
  673.     JNZ    TRYNINT
  674.     INT    0BH        ; we do have a packet, read it
  675.     JMP SHORT DONEMIT
  676. TRYNINT:
  677.     CMP    AL,0DH
  678.     JNZ    DONEMIT
  679.     INT    0DH
  680.  
  681. DONEMIT:
  682.     MOV    AX,CX        ; put return in ax
  683.     POP    DI
  684.     POP    SI
  685.     POP    BP
  686.     RET
  687. ifdef Microsoft
  688. _E3XMIT    ENDP
  689. else
  690. E3XMIT    ENDP
  691. endif
  692. ;
  693. ;*************************************************************************
  694. ;  Interrupt Handler
  695. ;  installation and deinstallation
  696. ;
  697. ;     the handler takes the receive packet out of the input buffer
  698. ;
  699. DEINST    PROC    NEAR
  700.     MOV    CX,SAVEIP    ; get old ip from save spot
  701.     MOV    DX,SAVECS    ; get old cs from save spot
  702.     MOV    BX,WHICHINT    ; interrupt in table for 3com board
  703.     PUSH    DS
  704.     XOR    AX,AX        ; system interrupt table
  705.     MOV    DS,AX        
  706.     CLI
  707.     MOV    [BX],CX        ; store old ip into the table
  708.     INC    BX
  709.     INC    BX        ; move pointer in interrupt table
  710.     MOV    [BX],DX        ; store old cs into the table
  711.     STI
  712.     POP    DS
  713.     RET
  714. DEINST    ENDP
  715. ;
  716. IINST    PROC    NEAR
  717.     MOV    CS:MYDS,DS    ; store for use by handler
  718.     MOV    BX,WHICHINT    ; interrupt in table for 3com board
  719.     PUSH    DS
  720.     XOR    AX,AX        ; system interrupt table
  721.     MOV    DS,AX        
  722.     MOV    AX,OFFSET IHAND    ; where the handler is
  723.     CLI
  724.     MOV    DX,[BX]        ; keep copy of the ip
  725.     MOV    [BX],AX        ; store ip into the table
  726.     INC    BX
  727.     INC    BX        ; move pointer in interrupt table
  728.     MOV    CX,[BX]        ; keep copy of the cs, too
  729.     MOV    AX,CS
  730.     MOV    [BX],AX        ; store new cs into the table
  731.     STI
  732.     POP    DS
  733.     MOV    SAVEIP,DX    ; store them away
  734.     MOV    SAVECS,CX
  735.     RET
  736. MYDS    DW    00H        ; the data segment for this assembly code
  737. ICNT    DB      00H
  738. IHAND:                       ; not a public name, only handles ints
  739.     STI
  740.     PUSH    DS
  741.     PUSH     ES
  742.     PUSH    AX
  743.     PUSH    BX
  744.     PUSH    CX
  745.     PUSH    DX
  746.     PUSH    DI
  747.     CLD            ; all moves will be forward
  748. ;
  749. ;  SET UP CORRECT DS
  750. ;
  751.     MOV    DS,CS:MYDS        ; get correct ds
  752. ifdef Microsoft
  753.     MOV    AX,word ptr [_BUFPT+2]    ; buffer's ds
  754.     MOV DI,_BUFPT       ; where buffer is
  755. else
  756.     MOV    AX,word ptr [BUFPT+2]    ; buffer's ds
  757.     MOV DI,BUFPT        ; where buffer is
  758. endif
  759.     MOV    ES,AX
  760. ;
  761. ;  check for buffer overrun or catching up with reader
  762. ;
  763. ;  implicit 64K max buffer, should stop before 64K anyway
  764. ;
  765. ifdef Microsoft
  766.     MOV    AX,_BUFBIG    ; how much stuff is in buffer
  767. else
  768.     MOV    AX,BUFBIG    ; how much stuff is in buffer
  769. endif
  770. ifdef Microsoft
  771.     MOV    BX,_BUFLIM    ; what is our size limit?
  772. else
  773.     MOV    BX,BUFLIM    ; what is our size limit?
  774. endif
  775.     CMP    AX,BX
  776.     JNA    ISROOM        ; we are ok
  777. ;
  778. ;  no room at the Inn.  turn off receiver
  779. ;
  780.     MOUT    EAUX,EBUS+ERIDE    ; refuse to read more packets until restarted
  781.  
  782.     MIN    EREC        ; must clear interrupt
  783.  
  784.     MOV    AL,1        ; set flag
  785.     MOV    DEAF,AL        ; we are now deaf, read routine must restart
  786.  
  787.     JMP SHORT ENDINT      ; can't do much, we lose packets until restarted
  788.  
  789. ;
  790. ;  wrap pointer around at end, we know that we have room
  791. ;
  792. ISROOM:
  793. ifdef Microsoft
  794.     MOV    DX,_BUFEND    ; right before 2K safety area
  795. else
  796.     MOV    DX,BUFEND    ; right before 2K safety area
  797. endif
  798.     CMP    DX,DI        ; see if pointer is over limit
  799.     JA    OKAYREAD    ; we are not at wrap-around
  800.  
  801. ifdef Microsoft
  802.     MOV    AX,_BUFORG    ; wrap to here
  803. else
  804.     MOV    AX,BUFORG    ; wrap to here
  805. endif
  806. ifdef Microsoft
  807.     MOV    _BUFPT,AX    ; wrap-around
  808. else
  809.     MOV    BUFPT,AX    ; wrap-around
  810. endif
  811.     MOV    DI,AX        ; di also
  812. ;
  813. ;  here, DI contains where we want to put the packet.
  814. ;
  815. OKAYREAD:
  816.  
  817. ;    MOV    CX,10        ; give it a few tries
  818.  
  819. IFINDONE:
  820. ;    MIN    EAUX        ; get status to al
  821. ;    AND    AL,ERBUSY    ; is it still in receive state or done?
  822. ;    JZ    IREADONE    ; done, can read it
  823. ;    LOOP    IFINDONE
  824. ;    MIN    EREC
  825. ;    AND    AL,ESTALE
  826. ;    JZ    IREADONE
  827. ;    jmp    ireadone
  828.  
  829. ;    MOV    AX,0        ; no packet yet, spurious int, return
  830. ;    STOSB
  831.  
  832. ;    MIN    EREC        ; clear interrupt condition
  833. ;    MIN    ESEND        ; in case it was an xmit spurious int
  834. ;    JMP    STOPINT
  835. ;
  836. IREADONE:
  837.     MOUT    EAUX,EBUS+ERIDE    ; turn off receive, give buffer to bus
  838.     MOUTW    EGLOW,0,0    ; clear general purpose pointer for read
  839.     MIN    EREC        ; get status to al, clears read
  840.  
  841.     MOV    DX,ERLOW    ; receive buffer pointer
  842.     IN    AL,DX
  843.     MOV    CL,AL        ; save low byte
  844.     INC    DX
  845.     IN    AL,DX
  846.     MOV    CH,AL        ; save high byte
  847.  
  848.     MOV    BX,CX           ; save another copy of the length
  849.     OR    BX,BX        ; check for non-zero
  850.     JZ    STOPINT        ; no packet
  851.     
  852.     MOV    AX,BX        ; save length in buffer, before packet
  853.     STOSW
  854.  
  855.     MOV    DX,EBUF        ; window to the data
  856.  
  857. IDOBYTES:
  858.     IN    AL,DX        ; get a byte
  859.     STOSB            ; save it to es:di
  860.     LOOP     IDOBYTES
  861. ;
  862. ;
  863. ;  DI now contains updated value for BUFPT, BX contains size of packet
  864. ;
  865. ifdef Microsoft
  866.     MOV    _BUFPT,DI    ; it is here, now
  867. else
  868.     MOV    BUFPT,DI    ; it is here, now
  869. endif
  870.  
  871. ifdef Microsoft
  872.     MOV    AX,_BUFBIG    ; total amount of stuff in buffer
  873. else
  874.     MOV    AX,BUFBIG    ; total amount of stuff in buffer
  875. endif
  876.     ADD    AX,BX
  877.     INC    AX
  878.     INC    AX        ; to cover the length value
  879. ifdef Microsoft
  880.     MOV    _BUFBIG,AX    ; after adding in current packet size
  881. else
  882.     MOV    BUFBIG,AX    ; after adding in current packet size
  883. endif
  884. ;
  885. ;  signs that something is actually happening - used for debugging
  886. ;
  887. ;    MOV    AX,0B000H       ; screen
  888. ;    MOV    ES,AX
  889. ;    MOV    DI,3998        ; lower right corner
  890. ;    INC    CS:ICNT
  891. ;    MOV    Al,CS:ICNT    ; character
  892. ;    STOSB
  893.  
  894. ;
  895. ;  set up to read the next packet from the net
  896. ;
  897. STOPINT:
  898.     MOUT    ERLOW,0        ; clear receive buffer pointer
  899.     MOUT    EAUX,EGETEM+ERIDE    ; set receive bit in aux
  900.  
  901. ENDINT:
  902.  
  903.     MOUT    ICTRL,ENDOFI    ; signal end of interrupt
  904.     POP    DI
  905.     POP    DX
  906.     POP    CX
  907.     POP    BX
  908.     POP    AX
  909.     POP    ES
  910.     POP    DS
  911.     IRET
  912. IINST    ENDP
  913.  
  914. ;
  915. ;*************************************************************************
  916. ;  ETUPDATE
  917. ;      update pointers and/or restart receiver when read routine has
  918. ;      already removed the current packet
  919. ;
  920. ;   usage:  etupdate();
  921. ;
  922. ifdef Microsoft
  923. _E3ETUPDATE    PROC    FAR
  924. else
  925. E3ETUPDATE    PROC    FAR
  926. endif
  927.     PUSH     ES
  928. ifdef Microsoft
  929.     MOV    AX,word ptr [_BUFPT+2]    ; establish data segment to buffer
  930. else
  931.     MOV    AX,word ptr [BUFPT+2]    ; establish data segment to buffer
  932. endif
  933.     MOV    ES,AX        ; put that in es
  934. ;
  935. ifdef Microsoft
  936.     MOV    BX,_BUFREAD    ; where read pointer is now
  937. else
  938.     MOV    BX,BUFREAD    ; where read pointer is now
  939. endif
  940.     MOV    DX,ES:[BX]    ; get size of this packet
  941.     INC    DX
  942.     INC    DX        ; two more for length value
  943.  
  944.     ADD    BX,DX        ; increment bufread by size of packet
  945.  
  946. ifdef Microsoft
  947.     MOV    CX,_BUFEND    ; right before 2K safety area
  948. else
  949.     MOV    CX,BUFEND    ; right before 2K safety area
  950. endif
  951.     CMP    BX,CX        ; see if pointer is over limit
  952.     JB    NOWRAPRD    ; we are not at wrap-around
  953.     
  954. ifdef Microsoft
  955.     MOV    BX,_BUFORG    ; wrap to here
  956. else
  957.     MOV    BX,BUFORG    ; wrap to here
  958. endif
  959. NOWRAPRD:
  960. ifdef Microsoft
  961.     MOV    _BUFREAD,BX    ; buffer pointer has been updated
  962. else
  963.     MOV    BUFREAD,BX    ; buffer pointer has been updated
  964. endif
  965.  
  966. ;
  967. ;  DECREMENT TOTAL BUFFER SIZE
  968. ;
  969.     CLI            ; keep interrupt handler from bothering dec
  970. ifdef Microsoft
  971.     MOV    CX,_BUFBIG    ; size before removing packet
  972. else
  973.     MOV    CX,BUFBIG    ; size before removing packet
  974. endif
  975.     SUB    CX,DX        ; remove size of current packet
  976. ifdef Microsoft
  977.     MOV    _BUFBIG,CX    ; put it back
  978. else
  979.     MOV    BUFBIG,CX    ; put it back
  980. endif
  981.     STI
  982. ;
  983. ;  IF RECEIVER IS ON, THEN CHECKING BUFLIM IS UNNECESSARY.
  984. ;
  985.     MOV    AL,DEAF        ; is the receiver turned off?
  986.     OR    AL,AL        ; 0 = reading, 1 = deaf
  987.     JZ    ALIVE
  988. ;
  989. ;  CHECK FOR ROOM IN THE BUFFER, IF THERE IS, TURN ON RECEIVER
  990. ;
  991. ifdef Microsoft
  992.     MOV    AX,_BUFLIM    ; what is our limit?
  993. else
  994.     MOV    AX,BUFLIM    ; what is our limit?
  995. endif
  996.     CMP    CX,AX        ; compare to limit
  997.     JA    ALIVE        ; not really alive, but can't turn on yet
  998.  
  999.     XOR    AL,AL
  1000.     MOV    DEAF,AL        ; reset flag
  1001.  
  1002. ifdef OLD_WAY
  1003.     INC    OFFS        ; keep count how many times this happened
  1004. endif
  1005.  
  1006.     MOUT    ERLOW,0        ; reset receive buffer ptr
  1007.     MOUT    EAUX,EGETEM+ERIDE    ; turn on receiver
  1008.  
  1009. ALIVE:
  1010.     POP    ES
  1011.     RET    
  1012. ifdef Microsoft
  1013. _E3ETUPDATE    ENDP
  1014. else
  1015. E3ETUPDATE    ENDP
  1016. endif
  1017.  
  1018. ifdef Microsoft
  1019. ;_TEXT    ends
  1020. else
  1021.     ENDPS
  1022. endif
  1023.     END
  1024.