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

  1. ;  MICOM NI 5210 driver code
  2. ;  Tim Krauskopf
  3. ;****************************************************************************
  4. ;*                                                                          *
  5. ;*                                                                          *
  6. ;*      part of NCSA Telnet                                                 *
  7. ;*      by Tim Krauskopf, VT100 by Gaige Paulsen, Tek by Aaron Contorer     *
  8. ;*                                                                          *
  9. ;*      National Center for Supercomputing Applications                     *
  10. ;*      152 Computing Applications Building                                 *
  11. ;*      605 E. Springfield Ave.                                             *
  12. ;*      Champaign, IL  61820                                                *
  13. ;*                                                                          *
  14. ;****************************************************************************
  15. ;
  16.  
  17.     TITLE    NETSUPPORT -- LOW LEVEL DRIVERS FOR ETHERNET
  18. ;
  19. ;  Assembler support for Ethernet I/O on the PC
  20. ;
  21. ;  Tim Krauskopf
  22. ;  9/1/87  Ungermann-Bass driver started, PC bus
  23. ;  9/14/87 MICOM NI5210 driver started, PC bus
  24. ;  4/88    Modified for combined drivers, version 2.2
  25. ;  5/89    fixes for msc5.1 MAHAN
  26. ;
  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.     NAME    MNET
  43. ifdef Microsoft
  44. X    EQU    6
  45.     DOSSEG
  46.     .MODEL    LARGE
  47. else
  48.     INCLUDE    DOS.MAC
  49.     SETX
  50. endif
  51. ;
  52. ;  Equates for controlling the MICOM board
  53. ;
  54. ;  I/O addresses, writing anything in AL trips these gates
  55. ;
  56. ;  First six addresses are the EPROM board Ether address (read)
  57. ;
  58. IORESET    EQU    0        ; reset the board
  59. IOCA    EQU    1        ; execute command which is in SCB
  60. IODIS    EQU    2        ; disable network connect
  61. IOENA    EQU    3        ; enable network
  62. IOINTON    EQU    4        ; disable interrupts, '586 thinks it still ints
  63. IOINTOF    EQU    5        ; enable interrupts
  64. ;
  65. ;  Structure elements specific to the Intel 82586 chip
  66. ;
  67. BDBASE    EQU    1874        ; base address for 30 buffer descriptors
  68. BUFBASE    EQU    2174        ; base address for 30 200 byte buffers
  69. BDSTAT    EQU    0        ; status word in BD
  70. BDLINK    EQU    2        ; 16pointer to next BD
  71. BDPTR    EQU    4        ; 24pointer to actual buffer
  72. BDSIZE    EQU    8        ; size of the buffer
  73. ;
  74. SCB    EQU    10        ; system control block base
  75. SSTAT    EQU    0        ; status word for SCB
  76. SCOM    EQU    2        ; command word in SCB
  77. SCBL    EQU    4        ; 16pointer to command block list
  78. SRFA    EQU    6        ; 16pointer to receive frame list
  79. SERRS    EQU    8        ; 4 words of error counts
  80. ;
  81. FDBASE    EQU    1214        ; base addr for 30 frame descriptors
  82. FDSTAT    EQU    0        ; status word for frame
  83. FDEOL    EQU    2        ; end of FD list flag
  84. FDLINK    EQU    4        ; 16pointer to next FD
  85. FDPTR    EQU    6        ; 16pointer to list of BD's
  86. ;
  87. TSTAT    EQU    0        ; status word for xmit
  88. TCOM    EQU    2        ; command to transmit
  89. TLINK    EQU    4        ; 16pointer to next command (always ffff)
  90. TPTR    EQU    6        ; 16pointer to xmit TBD
  91. TTRIES    EQU    8        ; number of transmit retries
  92. ;
  93. SCPTR    EQU    01ff6h        ; hardwired address for SCP
  94. ISCPTR    EQU    01feeh        ; my address for ISCP, points to SCB
  95. CCBPTR    EQU    26        ; offset of configure command block
  96. TCBPTR    EQU    44        ; xmit CB offset
  97. TBDPTR    EQU    60        ; xmit BD offset
  98. TBUFPTR    EQU    68        ; xmit buffer offset
  99. ;
  100. ;  Data segment
  101. ;
  102. ifdef Microsoft
  103.     .data
  104. ;DGROUP    group    _DATA
  105. ;_DATA    segment    public 'DATA'
  106. ;    assume    DS:DGROUP
  107. else
  108.     DSEG
  109. endif
  110. ;
  111. ;  The pointers below are actually DWORDs but we access them two
  112. ;  bytes at a time.
  113. ;
  114. ; STAT change to RSTAT because of name clash with MSC library routine
  115. ifdef Microsoft
  116.     EXTRN    _RSTAT:BYTE    ; last status from read
  117.     EXTRN    _BUFPT:WORD    ; current buffer pointer
  118.     EXTRN    _BUFORG:WORD    ; pointer to beginning of buffer
  119.     EXTRN    _BUFEND:WORD    ; pointer to end of buffer
  120.     EXTRN    _BUFREAD:WORD    ; pointer to where program is reading
  121.     EXTRN    _BUFBIG:WORD    ; integer, how many bytes we have
  122.     EXTRN    _BUFLIM:WORD    ; integer, max bytes we can have
  123. else
  124.     EXTRN    RSTAT:BYTE    ; last status from read
  125.     EXTRN    BUFPT:WORD    ; current buffer pointer
  126.     EXTRN    BUFORG:WORD    ; pointer to beginning of buffer
  127.     EXTRN    BUFEND:WORD    ; pointer to end of buffer
  128.     EXTRN    BUFREAD:WORD    ; pointer to where program is reading
  129.     EXTRN    BUFBIG:WORD    ; integer, how many bytes we have
  130.     EXTRN    BUFLIM:WORD    ; integer, max bytes we can have
  131. endif
  132.  
  133.  
  134. ICNT    DB    00h
  135.  
  136. SAVECS    DW    00H        ; where to save the old interrupt ptr
  137. SAVEIP    DW    00H
  138. LFPP    DB    00h        ; Full Page pointer
  139. DEAF    DB    00H        ; when we can't handle any more packets
  140. OFFS    DW    00H        ; how many times the handler was turned off
  141. FIRSTFD    dw    FDBASE        ; start of FD queue
  142. LASTFD    DW    0        ; end of the FD chain
  143. LASTBD    DW    0        ; end of the BD chain
  144. IOADDR    DW    0360h        ; I/O address for card (jumpers)
  145. UBASE    DW      0d000h        ; base segment for board (jumper set)
  146. ;
  147. ;  data for configuring and setting up the MICOM board
  148. ;
  149. ;  chip always looks at SCP for config info which points to ISCP for the
  150. ;  pointer to the CONTROL BLOCK which handles everything from there.
  151. ;  Kind of indirect, but it works.
  152. ;
  153. SCP    DB    1        ; bus use flag
  154.     DB    5 DUP(0)    ; unused
  155.     DW    ISCPTR        ; 24pointer to ISCP offset
  156.     DW    0        ; high part
  157. ;
  158. ; Intermediate SCP
  159. ;
  160. ISCP    DW    1        ; busy flag
  161.     DW    SCB        ; 16pointer to SCB
  162.     DW    0,0        ; base for all 16 pointers, lo, hi
  163.                 ; board is hardwired to 0 for these values
  164. ;
  165. ; Configuration block for 82586, this comprises one config command
  166. ;  Parameters taken from MICOM driver
  167. ;
  168. CBCONF    DW    0        ; status word
  169.     DW    8002H        ; end of command list + configure command
  170.     DW    0ffffh        ; link to next command (not used)
  171.     DW    080CH        ; fifo=8, byte count=C
  172.     DW    2E00H        ; important! Addr (AL) not inserted on the fly!
  173.     DW    6000H        ; IFS = 60h
  174.     DW    0F200H        ; retry=F, slot time=200h
  175.     DW    0        ; flags, set to 1 for promiscuous
  176.     DW    40H        ; min frame length=40h
  177. ;
  178. ; CB for xmit, followed by BD for xmit, copied together
  179. ;
  180. TCB    DW    0        ; status word
  181.     DW    08004H        ; command word for xmit + EL
  182.     DW    0ffffh        ; no command link
  183.     DW    TBDPTR        ; 16pointer to xmit BD
  184.     DW    0,0,0,0        ; no addressing used here
  185. ;
  186. ; BD template for xmit
  187. TBD    DW    0
  188.     DW    0        ; next BD pointer, unused
  189.     DW    TBUFPTR        ; 24pointer to xmit buffer
  190.     DW    0        ; high part of pointer
  191.  
  192. ifdef Microsoft
  193. ;_DATA    ends
  194. else
  195.     ENDDS
  196. endif
  197. ;
  198. ;
  199. ;
  200. ;   The subroutines to call from C
  201. ;
  202. ifdef Microsoft
  203. ;_TEXT    segment    public    'CODE'
  204. ;    assume CS:_TEXT 
  205.     .code
  206.     PUBLIC    _M5RECV,_M5ETOPEN,_M5ETCLOSE,_M5GETADDR
  207.     PUBLIC    _M5XMIT,_M5ETUPDATE
  208. else
  209.     PSEG
  210.     PUBLIC    M5RECV,M5ETOPEN,M5ETCLOSE,M5GETADDR
  211.     PUBLIC    M5XMIT,M5ETUPDATE
  212. endif
  213.  
  214. ;******************************************************************
  215. ;  ETOPEN
  216. ;     Initialize the Ethernet board, set receive type.
  217. ;
  218. ;  usage:  etopen(s,irq,address,ioaddr)
  219. ;           char s[6];       ethernet address
  220. ;           int irq;         (unused, we don't use no interrupts)
  221. ;           int address         base mem address
  222. ;           int ioaddr       io base address
  223. ;
  224. ifdef Microsoft
  225. _M5ETOPEN    PROC    FAR
  226. else
  227. M5ETOPEN    PROC    FAR
  228. endif
  229.     PUSH    BP
  230.     MOV    BP,SP
  231.     PUSH    SI
  232.     PUSH    DI
  233.     push    es
  234.     mov    ax,[bp+X+6]    ; second parameter
  235.     mov    UBASE,ax    ; base address
  236. ;    mov    ax,UBASE    ; get a copy (temporary)
  237.     mov    es,ax        ; set to base address
  238.     mov    ax,[bp+X+8]    ; get I/O address
  239.     mov    IOADDR,ax    ; save a copy
  240. ;    mov    ax,IOADDR    ; get a copy (temporary)
  241. ;
  242. ;  check for correct EPROM location
  243. ;
  244.     mov    dx,ax        ; i/o address
  245.     add    dx,6
  246.     in    al,dx
  247.     mov    bl,al        ; assemble pattern to check
  248.     inc    dx
  249.     in    al,dx
  250.     mov    bh,al
  251.     cmp    bx,05500h    ; pattern known to be there in ROM
  252.     jz    goinit
  253.     mov    ax,-1
  254.     pop    es
  255.     POP    DI
  256.     POP    SI
  257.     pop    bp
  258.     ret
  259. goinit:
  260. ;
  261. ;  Initialize MICOM 5210
  262. ;
  263. ;  Install 8K SCP, we only use 8K bytes no matter what
  264. ;
  265.     mov    si,offset SCP    ; get pre-set values
  266.     mov    di,SCPTR
  267.     mov    cx,5        ; 5 words
  268.     rep    movsw        ; install SCP
  269. ;
  270. ;  Install 16K SCP
  271. ;
  272.     mov    si,offset SCP    ; get pre-set values
  273.     mov    di,SCPTR+02000h        ; offset for 16K board
  274.     mov    cx,5        ; 5 words
  275.     rep    movsw        ; install SCP
  276. ;
  277. ;  Intermediate SCP
  278. ;
  279.     mov    si,offset ISCP    ; addr of pre-set values
  280.     mov    di,ISCPTR
  281.     mov    cx,4        ; 4 words
  282.     rep    movsw        ; install ISCP
  283. ;
  284. ;  Turn off interrupts, I don't want them
  285. ;
  286. ;    POP    DI
  287. ;    POP    SI
  288.     mov    dx,IOADDR    ; base for IO control
  289.     add    dx,IOINTOF    ; turn ints off
  290.     out    dx,al        ; any value in ax
  291.     sub    dx,IOINTOF    ; return to base address = reset
  292.     out    dx,al        ; reset the chip
  293. ;
  294. ;  Issue a CA to initialize the chip after reset
  295. ;
  296.     inc    dx
  297.     out    dx,al        ; CA
  298. ;
  299. ;  Disconnect from network
  300.     inc    dx        ; one greater than CA
  301.     out    dx,al
  302. ;
  303. ;  configure 82586
  304. ;
  305.     mov    si,offset CBCONF    ; configure command
  306.     mov    di,CCBPTR        ; where command will reside
  307.     mov    cx,9
  308.     rep    movsw            ; copy to board
  309. ;    POP    DI
  310. ;    POP    SI
  311. ;
  312. ;  issue the configure command
  313. ;
  314.     mov    word ptr es:[SCB+SCOM],0100h    ; do-command command
  315.     mov    word ptr es:[SCB+SCBL],CCBPTR    ; where conf command is
  316.     mov    word ptr es:[SCB+SERRS],0    ; zero errs field
  317.     mov    word ptr es:[SCB+SERRS+2],0    ; zero errs field
  318.     mov    word ptr es:[SCB+SERRS+4],0    ; zero errs field
  319.     mov    word ptr es:[SCB+SERRS+6],0    ; zero errs field
  320.     mov    dx,IOADDR
  321.     add    dx,IOCA            ; CA
  322.     out    dx,al            ; send it
  323.     xor    cx,cx            ; timeout
  324. waitconf:
  325.     mov    ax,word ptr es:[CCBPTR]    ; get status word
  326.     test    ax,08000h        ; is command complete?
  327.     loopz    waitconf
  328.     jnz    confok
  329.     mov    ax,-1            ; timeout problem
  330.     pop    es
  331.     POP    DI
  332.     POP    SI
  333.     pop    bp
  334.     ret
  335. ;
  336. confok:
  337. ;
  338. ;  Next step, load our address into the board
  339. ;     reuses the space that the configure command used, with different command 
  340. ;
  341.     mov    di,CCBPTR        ; start of config command block
  342.     xor    ax,ax
  343.     stosw                ; zero status word for commmand
  344.     mov    ax,8001h        ; IA setup command + EL
  345.     stosw
  346.     xor    ax,ax
  347.     dec    ax
  348.     stosw                ; set link value to -1 (unused)
  349.  
  350. ;  move my addr onto board location inside IA command
  351. ;  es:di is already set
  352. ;
  353.     PUSH     DS        ; save my DS
  354.     MOV    AX,[BP+X+2]    ; get new one
  355.     MOV    DS,AX           ; set new one
  356.     MOV    SI,[BP+X]    ; get pointer, ds:si is ready
  357.     ;
  358.     movsw
  359.     movsw
  360.     movsw
  361.     POP    DS        ; get back DS of local data
  362. ;
  363. ;  start the IA setup command, 
  364. ;
  365.     mov    word ptr es:[SCB+SCOM],0100h    ; do-command command
  366.     mov    dx,IOADDR
  367.     add    dx,IOCA            ; CA
  368.     out    dx,al            ; send it
  369.     xor    cx,cx            ; timeout
  370. waitia:
  371.     mov    ax,word ptr es:[CCBPTR]    ; get status word
  372.     test    ax,08000h        ; is command complete?
  373.     loopz    waitia
  374.     jnz    iaok
  375.     mov    ax,-2            ; timeout problem
  376.     pop    es
  377.     POP    DI
  378.     POP    SI
  379.     pop    bp
  380.     ret
  381. ;
  382. iaok:
  383. ;
  384. ;  IA sent, setup all of the other data structures on the board
  385. ;  start with xmit command descriptors
  386. ;
  387.     mov    si,offset TCB        ; template for xmit
  388.     mov    di,TCBPTR        ; where it goes on board
  389.     mov    cx,12            ; copies CB and BD for xmit
  390.     rep    movsw
  391. ;
  392. ;  Set up frame and buffer descriptors, 30 each
  393. ;
  394.     mov    cx,30            ; # of FDs
  395.     mov    di,FDBASE        ; base addr for FDs
  396. fdloop:
  397.     xor    ax,ax
  398.     mov    bx,di            ; save pointer
  399.     stosw                ; clear status wd
  400.     stosw                ; clear EL field
  401.     add    bx,22            ; points to next one
  402.     mov    es:[di],bx        ; put in link ptr
  403.     inc    di
  404.     inc    di
  405.     dec    ax
  406.     stosw                ; clear BD ptr to -1
  407.     add    di,14
  408.     loop    fdloop
  409. ;
  410.     sub    di,20            ; point back to last EL field
  411.     mov    ax,08000h        ; end of list
  412.     stosw                ; put into last FD
  413.     sub    di,4            ; back to beginning of last FD
  414.     mov    LASTFD,di        ; save the pointer
  415.     mov    word ptr es:[di+FDLINK],FDBASE    ; make list circular, from last to first
  416.     
  417. ;
  418.     mov    ax,BDBASE        ; first BD
  419.     mov    word ptr es:[FDBASE+FDPTR],ax    ; put it in the first FD frame
  420. ;
  421. ;  now BDs
  422.     mov    cx,30
  423.     mov    di,BDBASE        ; start of BD area
  424.     mov    dx,BUFBASE        ; start of buffer area
  425. bdloop:
  426.     xor    ax,ax
  427.     mov    bx,di            ; save pointer
  428.     stosw                ; zero status field
  429.     add    bx,10            ; point to next record
  430.     mov    es:[di],bx        ; put in link ptr
  431.     inc    di
  432.     inc    di
  433.     mov    es:[di],dx        ; address of buffer, lo part
  434.     inc    di
  435.     inc    di
  436.     stosw                ; zero out high part
  437.     mov    ax,200
  438.     stosw                ; store length field    
  439.     add    dx,ax            ; add in length of buffer, updates ptr
  440.     loop    bdloop
  441. ;
  442.     sub    di,2            ; back to last BD size field
  443.     mov    ax,08000h+200        ; end of list + 200
  444.     stosw                ; mark end of list
  445.     sub    di,8            ; back to last BDLINK field
  446.     mov    ax,BDBASE
  447.     stosw                ; put link to beginning of list here
  448.     sub    di,4            ; back to beginning of last BD
  449.     mov    LASTBD,di        ; save pointer to end of list
  450. ;
  451. ;  minor detail, but important
  452. ;  Change SCB command block pointer to setup for xmit commands
  453. ;      = only commands needed when operational
  454. ;
  455.     mov    word ptr es:[SCB+SCBL],TCBPTR    ; where xmit command is
  456. ;
  457. ;  configure to connect to network
  458. ;
  459.     mov    dx,IOADDR
  460.     add    dx,IOENA        ; enable network
  461.     out    dx,al            ; any al value
  462. ;
  463. ;  Start the RU, doesn't need CB, only SCB parms.
  464. ;   command, to start receiving
  465. ;
  466.     mov    word ptr es:[SCB],0        ; clear status word
  467.     mov    word ptr es:[SCB+SRFA],FDBASE    ; set to frame descriptors
  468.     mov    word ptr es:[SCB+SCOM],010h    ; start RU
  469.     mov    dx,IOADDR
  470.     inc    dx            ; issue CA
  471.     out    dx,al
  472. ;
  473. ;  don't wait for response, we are done
  474. ;
  475.     xor    ax,ax
  476.     POP    ES
  477.     POP    DI
  478.     POP    SI
  479.     POP    BP
  480.     RET
  481. ifdef Microsoft
  482. _M5ETOPEN    ENDP
  483. else
  484. M5ETOPEN    ENDP
  485. endif
  486. ;
  487. ;
  488. ;*******************************************************************
  489. ;  GETADDR
  490. ;     get the Ethernet address off of the board
  491. ;
  492. ;   usage:  getaddr(s,address,ioaddr);
  493. ;    char s[6];           will get six bytes from the PROM
  494. ;
  495. ifdef Microsoft
  496. _M5GETADDR    PROC    FAR
  497. else
  498. M5GETADDR    PROC    FAR
  499. endif
  500.     PUSH    BP
  501.     MOV    BP,SP
  502.     PUSH    DI
  503.  
  504.     mov    dx,[BP+X+6]    ; get board's base io addr
  505. ;    mov    dx,IOADDR    ; (temporary)
  506.     PUSH     ES        ; save mine
  507.     MOV    AX,[BP+X+2]    ; get new one
  508.     MOV    ES,AX           ; set new one
  509.     MOV    DI,[BP+X]    ; get pointer, es:di is ready
  510.     ;
  511.     mov    cx,6
  512.     CLD
  513. getonee:
  514.     in    al,dx        ; get a byte of the EPROM address
  515.     STOSB            ; put it away
  516.     inc    dx        ; next register
  517.     loop getonee        ; go back for rest
  518.  
  519.     xor    ax,ax
  520.     POP     ES
  521.     POP    DI
  522.     POP    BP        
  523.     RET
  524. ifdef Microsoft
  525. _M5GETADDR    ENDP
  526. else
  527. M5GETADDR    ENDP
  528. endif
  529. ;
  530. ;***********************************************************************
  531. ;  ETCLOSE
  532. ;        shut it down if necessary
  533. ;        MICOM board never interrupts, so we can leave it running.
  534. ;        Who cares, right?
  535. ;
  536. ifdef Microsoft
  537. _M5ETCLOSE    PROC    FAR
  538. else
  539. M5ETCLOSE    PROC    FAR
  540. endif
  541.     RET
  542. ifdef Microsoft
  543. _M5ETCLOSE    ENDP
  544. else
  545. M5ETCLOSE    ENDP
  546. endif
  547. ;
  548. ;
  549. ;************************************************************************
  550. ;  XMIT         
  551. ;     send a packet to Ethernet
  552. ;     Is not interrupt driven, just call it when you need it.
  553. ;
  554. ;  usage:   xmit(packet,count)
  555. ;        char *packet;
  556. ;        int count;
  557. ;
  558. ;   Takes a packet raw, Ethernet packets start with destination address,
  559. ;   and puts it out onto the wire.  Count is the length of packet < 2048
  560. ;
  561. ;   checks for packets under the Ethernet size limit of 60 and handles them
  562. ;
  563. ifdef Microsoft
  564. _M5XMIT    PROC    FAR
  565. else
  566. M5XMIT    PROC    FAR
  567. endif
  568.     PUSH    BP
  569.     MOV    BP,SP
  570.     PUSH    SI
  571.     PUSH    DI
  572.     push    es
  573.     mov    ax,ubase
  574.     mov    es,ax        ; base for board
  575.     PUSH    DS        ; set up proper ds for the buffer
  576.     MOV    AX,[BP+X+2]
  577.     MOV    DS,AX
  578.     MOV    SI,[BP+X]    ; offset for buffer
  579.  
  580.     MOV    DX,[BP+X+4]    ; count of bytes
  581.     MOV    CX,DX        ; save a copy, might be less than 60, ok
  582.  
  583.     CMP    DX,60        ; minimum length for Ether
  584.     JNB    OKLEN
  585.     MOV    DX,60        ; make sure size at least 60
  586. OKLEN:
  587.     mov    di,TBUFPTR    ; start of xmit buffer
  588.  
  589. ;
  590. ;  check for previous xmit
  591. xwait:
  592.     mov    bx,word ptr es:[SCB+SCOM]    ; is command zeroed yet?
  593.     or    bx,bx
  594.     jnz    xwait        ; not there yet, wait for it
  595. ;
  596. ;  move the data
  597.     rep    movsb        ; copy into buffer
  598. ;
  599. ;  put the correct size into the TDB
  600. ;
  601.     or    dx,08000h    ; end of frame bit flag
  602.     mov    word ptr es:[TBDPTR],dx        ; store it
  603.     mov    word ptr es:[TCBPTR],0        ; zero status wd
  604.     mov    word ptr es:[TCBPTR+TCOM],08004h; xmit command in TCB
  605.     mov    word ptr es:[SCB+SCOM],0100h    ; execute command
  606. ;    test    bx,0100h            ; suspended?
  607. ;    jz    nosus
  608. ;    mov    word ptr es:[SCB+SCOM],0400h    ; stop command
  609. ;nosus:
  610.     pop    ds            ; get back my ds
  611.     mov    dx,IOADDR
  612.     inc    dx
  613.     out    dx,al        ; issue CA to get it going
  614.     xor     ax,ax
  615.  
  616.     pop    es
  617.     POP    DI
  618.     POP    SI
  619.     POP    BP
  620.     RET
  621. ifdef Microsoft
  622. _M5XMIT    ENDP
  623. else
  624. M5XMIT    ENDP
  625. endif
  626. ;
  627. ;
  628. ;***********************************************************************
  629. ;   Receive
  630. ;   This is a CPU hook for boards that must be polled before we can
  631. ;   deliver packets into the receive buffer.  (i.e. no interrupts used)
  632. ;
  633. ;   The 3COM 3C501 version uses interrupts, so this routine is a NOP
  634. ;   for this board.
  635. ;
  636. ;    usage:  recv();
  637. ;
  638. ;
  639. ifdef Microsoft
  640. _M5RECV    proc    far
  641. else
  642. M5RECV    proc    far
  643. endif
  644.     push    bp
  645.     PUSH    SI
  646.     PUSH    DI
  647.     push    es
  648.  
  649. ifdef Microsoft
  650.     MOV    AX,word ptr [_BUFPT+2]    ; buffer's ds
  651.     MOV    DI,_BUFPT    ; where buffer is
  652. else
  653.     MOV    AX,word ptr [BUFPT+2]    ; buffer's ds
  654.     MOV    DI,BUFPT    ; where buffer is
  655. endif
  656.     MOV    ES,AX
  657.  
  658. ;
  659. ;  check for buffer overrun or catching up with reader
  660. ;
  661. ;  implicit 64K max buffer, should stop before 64K anyway
  662. ;
  663. ifdef Microsoft
  664.     MOV    AX,_BUFBIG    ; how much stuff is in buffer
  665.     MOV    BX,_BUFLIM    ; what is our size limit?
  666. else
  667.     MOV    AX,BUFBIG    ; how much stuff is in buffer
  668.     MOV    BX,BUFLIM    ; what is our size limit?
  669. endif
  670.     CMP    AX,BX
  671.     JNA    ISROOM        ; we are ok
  672. ;
  673. ;  no room at the Inn. 
  674. ;
  675.     JMP    ENDINT        ; can't do much, we lose packets until restarted
  676.  
  677. ;
  678. ;  wrap pointer around at end, we know that we have room
  679. ;
  680. ISROOM:
  681. ifdef Microsoft
  682.     MOV    DX,_BUFEND    ; right before 2K safety area
  683. else
  684.     MOV    DX,BUFEND    ; right before 2K safety area
  685. endif
  686.     CMP    DX,DI        ; see if pointer is over limit
  687.     JA    OKAYREAD    ; we are not at wrap-around
  688.  
  689. ifdef Microsoft
  690.     MOV    AX,_BUFORG    ; wrap to here
  691.     MOV    _BUFPT,AX    ; wrap-around
  692. else
  693.     MOV    AX,BUFORG    ; wrap to here
  694.     MOV    BUFPT,AX    ; wrap-around
  695. endif
  696.     MOV    DI,AX        ; di also
  697. ;
  698. ;  here, DI contains where we want to put the packet.
  699. ;  Add 2 to allow for space to put the size value
  700. ;
  701. OKAYREAD:
  702.     inc    di
  703.     inc    di        ; room for size word
  704.     mov    bx,FIRSTFD    ; get addr of first FD in list
  705.     mov    dx,ubase    ; base for board
  706.     push    ds
  707.     mov    ds,dx
  708. ;
  709. ;  
  710. CKFRAME:
  711.     mov    ax,[bx]        ; status word of frame
  712.     test    ax,08000h    ; frame written?
  713.     jnz    IREADONE    ; yes, read it in
  714.     pop    ds
  715.     call    rust        ; restore receiver if necessary
  716.     jmp    STOPINT
  717. ;
  718. ;  we have a frame, read it in
  719. ;
  720. IREADONE:
  721.     test    ax,02000h    ; check frame OK bit
  722.     jnz    frameok        ; ok, read it
  723.     mov    cx,ds
  724.     pop    ds
  725.     call    rust        ; preserves cx, restart RU if necessary
  726.     jmp SHORT freespace   ; not OK, just free the frame
  727.  
  728. frameok:
  729.     mov    si,[bx+FDPTR]    ; get pointer to buffer descriptor
  730.  
  731. copybuf:            ; es:di is already set to receive packet
  732.     mov    dx,si        ; save a copy of current BD ptr
  733.     mov    ax,[si]        ; get status and count word for BD
  734.     push    ax        ; save for EOF bit
  735.     test    ax,04000h    ; is count field there?
  736.     jnz    okcount
  737.     pop    ax    
  738.     mov    cx,ds
  739.     pop    ds
  740.     jmp SHORT freespace   ; free the frame, etc
  741. okcount:
  742.     xor    cx,cx
  743.     mov    cl,al        ; 200 bytes is largest this can be
  744.     mov    si,[si+BDPTR]    ; get offset of data
  745.  
  746.     SHR     CL,1                ; MAKE INTO A WORD COUNT
  747.     REP     MOVSW
  748.     ADC     CL,CL               ; GET THE ODD BYTE COUNT BACK
  749.     rep movsb       ; copy the bytes from this packet segment
  750.     mov    si,dx        ; get back current BD ptr
  751.     pop    ax        ; get back EOF bit
  752.     test    ax,08000h    ; check bit
  753.     jnz    ptrupdate    ; free the frame, no more data here
  754.     mov    si,[si+BDLINK]    ; go to next BD in list
  755.     jmp    copybuf        ; copy the next buffer
  756. ;
  757. ;
  758. ptrupdate:
  759. ;
  760. ;  DI now contains updated value for BUFPT
  761. ;
  762.     mov    cx,ds        ; save board segment
  763.     pop    ds
  764. ifdef Microsoft
  765.     mov    bx,_BUFPT    ; get where size field for this packet goes
  766.     mov    ax,di        ; where pointer is now
  767.     sub    ax,bx        ; where is was then, difference is size
  768.     MOV    DX,_BUFBIG    ; total amount of stuff in buffer
  769.     ADD    DX,AX        ; add in size of this packet
  770.     MOV    _BUFBIG,DX    ; after adding in current packet size
  771. else
  772.     mov    bx,BUFPT    ; get where size field for this packet goes
  773.     mov    ax,di        ; where pointer is now
  774.     sub    ax,bx        ; where is was then, difference is size
  775.     MOV    DX,BUFBIG    ; total amount of stuff in buffer
  776.     ADD    DX,AX        ; add in size of this packet
  777.     MOV    BUFBIG,DX    ; after adding in current packet size
  778. endif
  779.  
  780.     dec    ax
  781.     dec    ax        ; account for length field
  782.     mov    ES:[bx],ax        ; put the accumulated size there
  783.  
  784. ifdef Microsoft
  785.     MOV    _BUFPT,DI    ; it is here, now
  786. else
  787.     MOV    BUFPT,DI    ; it is here, now
  788. endif
  789.  
  790. ;
  791. freespace:
  792. ;
  793. ;  we are done with the frame, do the list management
  794. ;    cx=DS for board  DS=DGROUP
  795. ;
  796.     mov    bx,FIRSTFD    ; the frame we are working with
  797.     mov    di,LASTBD    ; where end of BD list is now
  798.     mov    es,cx        ; reload board segment
  799.  
  800.     mov    si,es:[bx+FDPTR]    ; first BD in frame list
  801. nextbd:
  802.     mov    cx,es:[si]    ; count word for BD, EOF bit
  803.     test    cx,08000h    ; EOF bit, if set, save si in lastbd
  804.     jnz    dolastbd
  805.     mov    word ptr es:[si],0    ; clear status word, EOF bit
  806.     cmp    si,LASTBD        ; see if we are wrapping
  807.     jz    dolastbd        ; yes, just undo it
  808.     mov    si,es:[si+BDLINK]    ; follow link
  809.     jmp    nextbd
  810. dolastbd:
  811.     mov    LASTBD,si    ; store last known BD
  812.     mov    word ptr es:[si+BDSIZE],08000h+200    ; end of list here
  813.     mov    word ptr es:[si],0    ; clear status word, EOF bit
  814. ; size field for not end of list
  815.     mov    word ptr es:[di+BDSIZE],200    ; remove old end-of-list
  816.  
  817. ;
  818. ;  update the FD list flags, new end-of-list
  819. ;
  820.     mov    di,LASTFD    ; get old end-of-list
  821.     mov    word ptr es:[bx+FDEOL],08000h    ; store new EOL
  822.     mov    word ptr es:[bx],0        ; clear status word for frame
  823.     mov    word ptr es:[di+FDEOL],0    ; zero old one
  824.     mov    LASTFD,bx    ; update stored pointer
  825.     mov    si,es:[bx+FDLINK]        ; where next fd is
  826.     mov    FIRSTFD,si    ; store that info for next time
  827. ;    mov    bx,LASTBD    ; last of the BD list
  828. ;    mov    ax,es:[bx+BDLINK]        ; get link field from lastBD
  829. ;    mov    es:[si+FDPTR],ax        ; store into next frame
  830. ;
  831. ;  signs that something is actually happening - for debugging
  832. ;
  833. ;    MOV    AX,0B000H       ; screen
  834. ;    MOV    ES,AX
  835. ;    MOV    DI,3998        ; lower right corner
  836. ;    INC    ICNT
  837. ;    MOV    al,ICNT        ; character
  838. ;    STOSB
  839.  
  840. ;
  841. ;  set up to read the next packet from the net
  842. ;
  843. STOPINT:
  844.  
  845. ENDINT:
  846.     pop    es
  847.     POP    DI
  848.     POP    SI
  849.     POP    BP
  850.     RET
  851. ifdef Microsoft
  852. _M5RECV    ENDP
  853. else
  854. M5RECV    ENDP
  855. endif
  856.  
  857. rust    proc    near        ; re-start receiver
  858. ;
  859. ;  check to see if the receiver went off because of no resources
  860. ;  and restart receiver if necessary
  861. ;  ds=dgroup, no other requirements
  862. ;
  863.     push    es
  864.     mov    ax,ubase
  865.     mov    es,ax
  866.     mov    ax,es:[SCB]    ; status word for SCB
  867.     and    ax,070h        ; receiver status
  868.     cmp    al,020h        ; receiver has no resources
  869.     jnz    hasres
  870. ;
  871. ;  setup lists for starting the RU on the chip
  872. ;  we know that there isn't anything in the buffer that we want
  873. ;
  874.     mov    bx,FIRSTFD    ; get first FD on free list (assume free)
  875.     mov    word ptr es:[SCB+SRFA],bx    ; put into SCB
  876.     mov    si,LASTBD    ; pointer to a BD, end of chain
  877.     mov    ax,word ptr es:[si+BDLINK]    ; pointer to next BD
  878.     mov    word ptr es:[bx+FDPTR],ax    ; set to start of BDs
  879. ;
  880. ;
  881. ;  Start the RU, doesn't need CB, only SCB parms.
  882. ;   command, to start receiving again
  883. ;
  884.     mov    word ptr es:[SCB],0        ; clear status word
  885.     mov    word ptr es:[SCB+SCOM],010h    ; start RU
  886.     mov    dx,IOADDR
  887.     inc    dx            ; issue CA
  888.     out    dx,al
  889. hasres:
  890.     pop    es
  891.     ret    
  892. rust    endp
  893. ;
  894. ;*************************************************************************
  895. ;  ETUPDATE
  896. ;      update pointers and/or restart receiver when read routine has
  897. ;      already removed the current packet
  898. ;
  899. ifdef Microsoft
  900. _M5ETUPDATE    PROC    FAR
  901. else
  902. M5ETUPDATE    PROC    FAR
  903. endif
  904.     PUSH     ES
  905. ifdef Microsoft
  906.     MOV    AX,word ptr [_BUFPT+2]    ; establish data segment to buffer
  907. else
  908.     MOV    AX,word ptr [BUFPT+2]    ; establish data segment to buffer
  909. endif
  910.     MOV    ES,AX        ; put that in es
  911. ;
  912. ifdef Microsoft
  913.     MOV    BX,_BUFREAD    ; where read pointer is now
  914. else
  915.     MOV    BX,BUFREAD    ; where read pointer is now
  916. endif
  917.  
  918.     MOV    DX,ES:[BX]    ; get size of this packet
  919.     INC    DX
  920.     INC    DX        ; TWO MORE FOR LENGTH VALUE
  921.  
  922.     ADD    BX,DX        ; increment bufread by size of packet
  923.  
  924. ifdef Microsoft
  925.     MOV    CX,_BUFEND    ; right before 2K safety area
  926. else
  927.     MOV    CX,BUFEND    ; right before 2K safety area
  928. endif
  929.     CMP    BX,CX        ; see if pointer is over limit
  930.     JB    NOWRAPRD    ; we are not at wrap-around
  931.     
  932. ifdef Microsoft
  933.  
  934.     MOV    BX,_BUFORG    ; wrap to here
  935. NOWRAPRD:
  936.     MOV    _BUFREAD,BX    ; buffer pointer has been updated
  937. else
  938.  
  939.     MOV    BX,BUFORG    ; wrap to here
  940. NOWRAPRD:
  941.     MOV    BUFREAD,BX    ; buffer pointer has been updated
  942. endif
  943.  
  944. ;
  945. ;  DECREMENT TOTAL BUFFER SIZE
  946. ;
  947.     CLI            ; keep interrupt handler from bothering dec
  948. ifdef Microsoft
  949.     MOV    CX,_BUFBIG    ; size before removing packet
  950.     SUB    CX,DX        ; remove size of current packet
  951.     MOV    _BUFBIG,CX    ; put it back
  952. else
  953.     MOV    CX,BUFBIG    ; size before removing packet
  954.     SUB    CX,DX        ; remove size of current packet
  955.     MOV    BUFBIG,CX    ; put it back
  956. endif
  957.     STI
  958. ;
  959. ;  IF RECEIVER IS ON, THEN CHECKING BUFLIM IS UNNECESSARY.
  960. ;
  961.     MOV    AL,DEAF        ; is the receiver turned off?
  962.     OR    AL,AL        ; 0 = reading, 1 = deaf
  963.     JZ    ALIVE
  964. ;
  965. ;  CHECK FOR ROOM IN THE BUFFER, IF THERE IS, TURN ON RECEIVER
  966. ;
  967. ifdef Microsoft
  968.     MOV    AX,_BUFLIM    ; what is our limit?
  969. else
  970.     MOV    AX,BUFLIM    ; what is our limit?
  971. endif
  972.     CMP    CX,AX        ; compare to limit
  973.     JA    ALIVE        ; not really alive, but can't turn on yet
  974.  
  975.     XOR    AL,AL
  976.     MOV    DEAF,AL        ; reset flag
  977.  
  978.     INC    OFFS        ; keep count how many times this happened
  979.  
  980. ALIVE:
  981.     POP    ES
  982.     RET    
  983. ifdef Microsoft
  984. _M5ETUPDATE    ENDP
  985. else
  986. M5ETUPDATE    ENDP
  987. endif
  988.  
  989. ifdef Microsoft
  990. ;_TEXT    ends
  991. else
  992.     ENDPS
  993. endif
  994.     END
  995.