home *** CD-ROM | disk | FTP | other *** search
/ Programmer 7500 / MAX_PROGRAMMERS.iso / INFO / NCSATELN / TEL23SRC.ZIP / NET / ENET / NET5210.ASM < prev    next >
Encoding:
Assembly Source File  |  1991-05-15  |  24.5 KB  |  990 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.     pop    es
  616.     POP    DI
  617.     POP    SI
  618.     POP    BP
  619.     RET
  620. ifdef Microsoft
  621. _M5XMIT    ENDP
  622. else
  623. M5XMIT    ENDP
  624. endif
  625. ;
  626. ;
  627. ;***********************************************************************
  628. ;   Receive
  629. ;   This is a CPU hook for boards that must be polled before we can
  630. ;   deliver packets into the receive buffer.  (i.e. no interrupts used)
  631. ;
  632. ;   The 3COM 3C501 version uses interrupts, so this routine is a NOP
  633. ;   for this board.
  634. ;
  635. ;    usage:  recv();
  636. ;
  637. ;
  638. ifdef Microsoft
  639. _M5RECV    proc    far
  640. else
  641. M5RECV    proc    far
  642. endif
  643.     push    bp
  644.     PUSH    SI
  645.     PUSH    DI
  646.     push    es
  647.  
  648. ifdef Microsoft
  649.     MOV    AX,word ptr [_BUFPT+2]    ; buffer's ds
  650.     MOV    DI,_BUFPT    ; where buffer is
  651. else
  652.     MOV    AX,word ptr [BUFPT+2]    ; buffer's ds
  653.     MOV    DI,BUFPT    ; where buffer is
  654. endif
  655.     MOV    ES,AX
  656.  
  657. ;
  658. ;  check for buffer overrun or catching up with reader
  659. ;
  660. ;  implicit 64K max buffer, should stop before 64K anyway
  661. ;
  662. ifdef Microsoft
  663.     MOV    AX,_BUFBIG    ; how much stuff is in buffer
  664.     MOV    BX,_BUFLIM    ; what is our size limit?
  665. else
  666.     MOV    AX,BUFBIG    ; how much stuff is in buffer
  667.     MOV    BX,BUFLIM    ; what is our size limit?
  668. endif
  669.     CMP    AX,BX
  670.     JNA    ISROOM        ; we are ok
  671. ;
  672. ;  no room at the Inn. 
  673. ;
  674.     JMP    ENDINT        ; can't do much, we lose packets until restarted
  675.  
  676. ;
  677. ;  wrap pointer around at end, we know that we have room
  678. ;
  679. ISROOM:
  680. ifdef Microsoft
  681.     MOV    DX,_BUFEND    ; right before 2K safety area
  682. else
  683.     MOV    DX,BUFEND    ; right before 2K safety area
  684. endif
  685.     CMP    DX,DI        ; see if pointer is over limit
  686.     JA    OKAYREAD    ; we are not at wrap-around
  687.  
  688. ifdef Microsoft
  689.     MOV    AX,_BUFORG    ; wrap to here
  690.     MOV    _BUFPT,AX    ; wrap-around
  691. else
  692.     MOV    AX,BUFORG    ; wrap to here
  693.     MOV    BUFPT,AX    ; wrap-around
  694. endif
  695.     MOV    DI,AX        ; di also
  696. ;
  697. ;  here, DI contains where we want to put the packet.
  698. ;  Add 2 to allow for space to put the size value
  699. ;
  700. OKAYREAD:
  701.     inc    di
  702.     inc    di        ; room for size word
  703.     mov    bx,FIRSTFD    ; get addr of first FD in list
  704.     mov    dx,ubase    ; base for board
  705.     push    ds
  706.     mov    ds,dx
  707. ;
  708. ;  
  709. CKFRAME:
  710.     mov    ax,[bx]        ; status word of frame
  711.     test    ax,08000h    ; frame written?
  712.     jnz    IREADONE    ; yes, read it in
  713.     pop    ds
  714.     call    rust        ; restore receiver if necessary
  715.     jmp    STOPINT
  716. ;
  717. ;  we have a frame, read it in
  718. ;
  719. IREADONE:
  720.     test    ax,02000h    ; check frame OK bit
  721.     jnz    frameok        ; ok, read it
  722.     mov    cx,ds
  723.     pop    ds
  724.     call    rust        ; preserves cx, restart RU if necessary
  725.     jmp SHORT freespace   ; not OK, just free the frame
  726.  
  727. frameok:
  728.     mov    si,[bx+FDPTR]    ; get pointer to buffer descriptor
  729.  
  730. copybuf:            ; es:di is already set to receive packet
  731.     mov    dx,si        ; save a copy of current BD ptr
  732.     mov    ax,[si]        ; get status and count word for BD
  733.     push    ax        ; save for EOF bit
  734.     test    ax,04000h    ; is count field there?
  735.     jnz    okcount
  736.     pop    ax    
  737.     mov    cx,ds
  738.     pop    ds
  739.     jmp SHORT freespace   ; free the frame, etc
  740. okcount:
  741.     xor    cx,cx
  742.     mov    cl,al        ; 200 bytes is largest this can be
  743.     mov    si,[si+BDPTR]    ; get offset of data
  744.     rep    movsb        ; copy the bytes from this packet segment
  745.     mov    si,dx        ; get back current BD ptr
  746.     pop    ax        ; get back EOF bit
  747.     test    ax,08000h    ; check bit
  748.     jnz    ptrupdate    ; free the frame, no more data here
  749.     mov    si,[si+BDLINK]    ; go to next BD in list
  750.     jmp    copybuf        ; copy the next buffer
  751. ;
  752. ;
  753. ptrupdate:
  754. ;
  755. ;  DI now contains updated value for BUFPT
  756. ;
  757.     mov    cx,ds        ; save board segment
  758.     pop    ds
  759. ifdef Microsoft
  760.     mov    bx,_BUFPT    ; get where size field for this packet goes
  761.     mov    ax,di        ; where pointer is now
  762.     sub    ax,bx        ; where is was then, difference is size
  763.     MOV    DX,_BUFBIG    ; total amount of stuff in buffer
  764.     ADD    DX,AX        ; add in size of this packet
  765.     MOV    _BUFBIG,DX    ; after adding in current packet size
  766. else
  767.     mov    bx,BUFPT    ; get where size field for this packet goes
  768.     mov    ax,di        ; where pointer is now
  769.     sub    ax,bx        ; where is was then, difference is size
  770.     MOV    DX,BUFBIG    ; total amount of stuff in buffer
  771.     ADD    DX,AX        ; add in size of this packet
  772.     MOV    BUFBIG,DX    ; after adding in current packet size
  773. endif
  774.  
  775.     dec    ax
  776.     dec    ax        ; account for length field
  777.     mov    ES:[bx],ax        ; put the accumulated size there
  778.  
  779. ifdef Microsoft
  780.     MOV    _BUFPT,DI    ; it is here, now
  781. else
  782.     MOV    BUFPT,DI    ; it is here, now
  783. endif
  784.  
  785. ;
  786. freespace:
  787. ;
  788. ;  we are done with the frame, do the list management
  789. ;    cx=DS for board  DS=DGROUP
  790. ;
  791.     mov    bx,FIRSTFD    ; the frame we are working with
  792.     mov    di,LASTBD    ; where end of BD list is now
  793.     mov    es,cx        ; reload board segment
  794.  
  795.     mov    si,es:[bx+FDPTR]    ; first BD in frame list
  796. nextbd:
  797.     mov    cx,es:[si]    ; count word for BD, EOF bit
  798.     test    cx,08000h    ; EOF bit, if set, save si in lastbd
  799.     jnz    dolastbd
  800.     mov    word ptr es:[si],0    ; clear status word, EOF bit
  801.     cmp    si,LASTBD        ; see if we are wrapping
  802.     jz    dolastbd        ; yes, just undo it
  803.     mov    si,es:[si+BDLINK]    ; follow link
  804.     jmp    nextbd
  805. dolastbd:
  806.     mov    LASTBD,si    ; store last known BD
  807.     mov    word ptr es:[si+BDSIZE],08000h+200    ; end of list here
  808.     mov    word ptr es:[si],0    ; clear status word, EOF bit
  809. ; size field for not end of list
  810.     mov    word ptr es:[di+BDSIZE],200    ; remove old end-of-list
  811.  
  812. ;
  813. ;  update the FD list flags, new end-of-list
  814. ;
  815.     mov    di,LASTFD    ; get old end-of-list
  816.     mov    word ptr es:[bx+FDEOL],08000h    ; store new EOL
  817.     mov    word ptr es:[bx],0        ; clear status word for frame
  818.     mov    word ptr es:[di+FDEOL],0    ; zero old one
  819.     mov    LASTFD,bx    ; update stored pointer
  820.     mov    si,es:[bx+FDLINK]        ; where next fd is
  821.     mov    FIRSTFD,si    ; store that info for next time
  822. ;    mov    bx,LASTBD    ; last of the BD list
  823. ;    mov    ax,es:[bx+BDLINK]        ; get link field from lastBD
  824. ;    mov    es:[si+FDPTR],ax        ; store into next frame
  825. ;
  826. ;  signs that something is actually happening - for debugging
  827. ;
  828. ;    MOV    AX,0B000H       ; screen
  829. ;    MOV    ES,AX
  830. ;    MOV    DI,3998        ; lower right corner
  831. ;    INC    ICNT
  832. ;    MOV    al,ICNT        ; character
  833. ;    STOSB
  834.  
  835. ;
  836. ;  set up to read the next packet from the net
  837. ;
  838. STOPINT:
  839.  
  840. ENDINT:
  841.     pop    es
  842.     POP    DI
  843.     POP    SI
  844.     POP    BP
  845.     RET
  846. ifdef Microsoft
  847. _M5RECV    ENDP
  848. else
  849. M5RECV    ENDP
  850. endif
  851.  
  852. rust    proc    near        ; re-start receiver
  853. ;
  854. ;  check to see if the receiver went off because of no resources
  855. ;  and restart receiver if necessary
  856. ;  ds=dgroup, no other requirements
  857. ;
  858.     push    es
  859.     mov    ax,ubase
  860.     mov    es,ax
  861.     mov    ax,es:[SCB]    ; status word for SCB
  862.     and    ax,070h        ; receiver status
  863.     cmp    al,020h        ; receiver has no resources
  864.     jnz    hasres
  865. ;
  866. ;  setup lists for starting the RU on the chip
  867. ;  we know that there isn't anything in the buffer that we want
  868. ;
  869.     mov    bx,FIRSTFD    ; get first FD on free list (assume free)
  870.     mov    word ptr es:[SCB+SRFA],bx    ; put into SCB
  871.     mov    si,LASTBD    ; pointer to a BD, end of chain
  872.     mov    ax,word ptr es:[si+BDLINK]    ; pointer to next BD
  873.     mov    word ptr es:[bx+FDPTR],ax    ; set to start of BDs
  874. ;
  875. ;
  876. ;  Start the RU, doesn't need CB, only SCB parms.
  877. ;   command, to start receiving again
  878. ;
  879.     mov    word ptr es:[SCB],0        ; clear status word
  880.     mov    word ptr es:[SCB+SCOM],010h    ; start RU
  881.     mov    dx,IOADDR
  882.     inc    dx            ; issue CA
  883.     out    dx,al
  884. hasres:
  885.     pop    es
  886.     ret    
  887. rust    endp
  888. ;
  889. ;*************************************************************************
  890. ;  ETUPDATE
  891. ;      update pointers and/or restart receiver when read routine has
  892. ;      already removed the current packet
  893. ;
  894. ifdef Microsoft
  895. _M5ETUPDATE    PROC    FAR
  896. else
  897. M5ETUPDATE    PROC    FAR
  898. endif
  899.     PUSH     ES
  900. ifdef Microsoft
  901.     MOV    AX,word ptr [_BUFPT+2]    ; establish data segment to buffer
  902. else
  903.     MOV    AX,word ptr [BUFPT+2]    ; establish data segment to buffer
  904. endif
  905.     MOV    ES,AX        ; put that in es
  906. ;
  907. ifdef Microsoft
  908.     MOV    BX,_BUFREAD    ; where read pointer is now
  909. else
  910.     MOV    BX,BUFREAD    ; where read pointer is now
  911. endif
  912.  
  913.     MOV    DX,ES:[BX]    ; get size of this packet
  914.     INC    DX
  915.     INC    DX        ; TWO MORE FOR LENGTH VALUE
  916.  
  917.     ADD    BX,DX        ; increment bufread by size of packet
  918.  
  919. ifdef Microsoft
  920.     MOV    CX,_BUFEND    ; right before 2K safety area
  921. else
  922.     MOV    CX,BUFEND    ; right before 2K safety area
  923. endif
  924.     CMP    BX,CX        ; see if pointer is over limit
  925.     JB    NOWRAPRD    ; we are not at wrap-around
  926.     
  927. ifdef Microsoft
  928.  
  929.     MOV    BX,_BUFORG    ; wrap to here
  930. NOWRAPRD:
  931.     MOV    _BUFREAD,BX    ; buffer pointer has been updated
  932. else
  933.  
  934.     MOV    BX,BUFORG    ; wrap to here
  935. NOWRAPRD:
  936.     MOV    BUFREAD,BX    ; buffer pointer has been updated
  937. endif
  938.  
  939. ;
  940. ;  DECREMENT TOTAL BUFFER SIZE
  941. ;
  942.     CLI            ; keep interrupt handler from bothering dec
  943. ifdef Microsoft
  944.     MOV    CX,_BUFBIG    ; size before removing packet
  945.     SUB    CX,DX        ; remove size of current packet
  946.     MOV    _BUFBIG,CX    ; put it back
  947. else
  948.     MOV    CX,BUFBIG    ; size before removing packet
  949.     SUB    CX,DX        ; remove size of current packet
  950.     MOV    BUFBIG,CX    ; put it back
  951. endif
  952.     STI
  953. ;
  954. ;  IF RECEIVER IS ON, THEN CHECKING BUFLIM IS UNNECESSARY.
  955. ;
  956.     MOV    AL,DEAF        ; is the receiver turned off?
  957.     OR    AL,AL        ; 0 = reading, 1 = deaf
  958.     JZ    ALIVE
  959. ;
  960. ;  CHECK FOR ROOM IN THE BUFFER, IF THERE IS, TURN ON RECEIVER
  961. ;
  962. ifdef Microsoft
  963.     MOV    AX,_BUFLIM    ; what is our limit?
  964. else
  965.     MOV    AX,BUFLIM    ; what is our limit?
  966. endif
  967.     CMP    CX,AX        ; compare to limit
  968.     JA    ALIVE        ; not really alive, but can't turn on yet
  969.  
  970.     XOR    AL,AL
  971.     MOV    DEAF,AL        ; reset flag
  972.  
  973.     INC    OFFS        ; keep count how many times this happened
  974.  
  975. ALIVE:
  976.     POP    ES
  977.     RET    
  978. ifdef Microsoft
  979. _M5ETUPDATE    ENDP
  980. else
  981. M5ETUPDATE    ENDP
  982. endif
  983.  
  984. ifdef Microsoft
  985. ;_TEXT    ends
  986. else
  987.     ENDPS
  988. endif
  989.     END
  990.