home *** CD-ROM | disk | FTP | other *** search
/ Programmer 7500 / MAX_PROGRAMMERS.iso / INFO / NCSATELN / TEL23SRC.ZIP / NET / ENET / NETATT10.ASM < prev    next >
Encoding:
Assembly Source File  |  1991-05-15  |  32.5 KB  |  975 lines

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