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

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