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

  1. ;  WD8003E 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.  
  18.     TITLE    NETSUPPORT -- LOW LEVEL DRIVERS FOR ETHERNET
  19. ;
  20. ;  Assembler support for interrupt-driven Ethernet I/O on the PC
  21. ;
  22. ;  Reads and writes from the 8K buffer on the WD card.
  23. ;  Started 4/11/88
  24. ;
  25. ;Microsoft EQU 1
  26. ;Lattice EQU 1
  27. ifndef Microsoft
  28.     ifndef Lattice
  29.         if2
  30.             %out
  31.             %out ERROR: You have to specify "/DMicrosoft" OR "/DLattice" on the
  32.             %out        MASM command line to determine the type of assembly.
  33.             %out
  34.         endif
  35.         end
  36.     endif
  37. endif
  38.  
  39.     NAME    NET8003
  40. ifdef MSC6
  41.     INCLUDE NET\ENET\NET8003.INC
  42. else
  43.     INCLUDE NET8003.INC
  44. endif
  45. ifdef Microsoft
  46. X    EQU    6
  47.     DOSSEG
  48.     .MODEL    LARGE
  49. else
  50.     INCLUDE    DOS.MAC
  51.     SETX
  52. endif
  53. ;
  54. ;  macros for writing to WD board
  55. ;
  56. ;***********************************************************************
  57. ;
  58. ;    Macros, from example driver
  59. ;
  60. ;***********************************************************************
  61.  
  62. ;
  63. ; MACRO rd_wd8
  64. ;   Reads port specified on macro call. Leaves byte in AL.
  65. ;
  66.  
  67. rd_wd8    MACRO    port
  68.     mov    DX, WDBASE
  69.     add    DX, port        ; DX contains address of port
  70.     in    AL, DX            ; AL contains data read from port
  71.     ENDM
  72.  
  73. ;
  74. ; MACRO wr_wd8
  75. ;   Writes byte in AL to port specified on macro call.
  76. ;
  77.  
  78. wr_wd8    MACRO    port
  79.     mov    DX, WDBASE
  80.     add    DX, port        ; DX contains address of port
  81.     out    DX, AL            ; AL contains data to be written to port
  82.     ENDM
  83.  
  84. ;
  85. ifdef Microsoft
  86. ;DGROUP    group    _DATA
  87. ;_DATA    segment    public 'DATA'
  88. ;    assume    DS:DGROUP
  89.     .data
  90. else
  91.     DSEG
  92. ;    PUBLIC    RSTAT,BUFPT,BUFORG,BUFEND,BUFREAD,BUFBIG,BUFLIM
  93. endif
  94. ;
  95. ;  The pointers below are actually DWORDs but we access them two
  96. ;  bytes at a time.
  97. ;
  98. ; STAT change to RSTAT because of name clash with MSC library routine
  99. ifdef Microsoft
  100.     EXTRN    _RSTAT:BYTE    ; last status from read
  101.     EXTRN    _BUFPT:WORD    ; current buffer pointer
  102.     EXTRN    _BUFORG:WORD    ; pointer to beginning of buffer
  103.     EXTRN    _BUFEND:WORD    ; pointer to end of buffer
  104.     EXTRN    _BUFREAD:WORD    ; pointer to where program is reading
  105.     EXTRN    _BUFBIG:WORD    ; integer, how many bytes we have
  106.     EXTRN    _BUFLIM:WORD    ; integer, max bytes we can have
  107. else
  108.     EXTRN    RSTAT:BYTE    ; last status from read
  109.     EXTRN    BUFPT:WORD    ; current buffer pointer
  110.     EXTRN    BUFORG:WORD    ; pointer to beginning of buffer
  111.     EXTRN    BUFEND:WORD    ; pointer to end of buffer
  112.     EXTRN    BUFREAD:WORD    ; pointer to where program is reading
  113.     EXTRN    BUFBIG:WORD    ; integer, how many bytes we have
  114.     EXTRN    BUFLIM:WORD    ; integer, max bytes we can have
  115. endif
  116. ;
  117. ;
  118. ;RSTAT    DB    00H         ; last status from read
  119. ;BUFBIG    DW    00H        ; buffer space used
  120. ;BUFLIM    DW    05000H        ; buffer space limit
  121. ;BUFPT    DW    00000H        ; where buffer pointer is, initialized safely
  122. ;BUFDS    DW    0a000H        ; where buffer is, ds
  123. ;BUFORG    DW    00000H        ; start of buffer space
  124. ;BUFDS2    DW    0a000H        ; another ds
  125. ;BUFEND    DW    06000H        ; end limit of allowable buffer space
  126. ;BUFDS3    DW    0a000H
  127. ;BUFREAD    DW    00000H        ; where the read pointer is
  128. ;BUFDS4    DW    0a000H
  129.  
  130. WDBASE    DW    00h        ; base ioaddr
  131. WDADD    DW    00h        ; base shared mem addr
  132. DEAF    DB    00H        ; when we can't handle any more packets
  133. OFFS    DW    00H        ; how many times the handler was turned off
  134. ;
  135. ifdef Microsoft
  136. ;_DATA    ends
  137. else
  138.     ENDDS
  139. endif
  140. ;
  141. ;
  142. ;
  143. ;   The subroutines to call from C
  144. ;
  145. ifdef Microsoft
  146. ;_TEXT    segment    public    'CODE'
  147. ;    assume CS:_TEXT
  148.     .code
  149.     PUBLIC    _WDRECV,_WDETOPEN,_WDETCLOSE,_WDGETADDR
  150. ifdef NOT_USED
  151.     PUBLIC  _WDSETADDR
  152. endif
  153.     PUBLIC  _WDXMIT,_WDETUPDATE
  154. else
  155.     PSEG
  156.     PUBLIC    WDRECV,WDETOPEN,WDETCLOSE,WDGETADDR
  157. ifdef NOT_USED
  158.     PUBLIC  WDSETADDR
  159. endif
  160.     PUBLIC  WDXMIT,WDETUPDATE
  161. endif
  162.  
  163. ;******************************************************************
  164. ;  ETOPEN
  165. ;     Initialize the Ethernet board, set receive type.
  166. ;
  167. ;  usage:  etopen(s,irq,addr,ioaddr)
  168. ;           char s[6];       ethernet address
  169. ;           int irq,addr,ioaddr;     
  170. ;                interrupt number (unused), base mem address and
  171. ;                i/o address to use
  172. ;
  173. ifdef Microsoft
  174. _WDETOPEN    PROC    FAR
  175. else
  176. WDETOPEN    PROC    FAR
  177. endif
  178.     PUSH    BP
  179.     MOV    BP,SP
  180.     mov    AX,[BP+X+8]        ; install ioaddr
  181.     mov    WDBASE,AX
  182.     mov    AX,[BP+X+6]        ; install shared mem addr
  183.     mov    WDADD,AX
  184. ;
  185. ;  put shared mem address into memory select register
  186. ;
  187.     mov    cl,9
  188.     shr    ax,cl            ; adapt for MSR reg
  189.     wr_wd8    0            ; ship it to offset 0 (MSR)
  190.  
  191. ;
  192. ;  portions adapted from WD8STAR2.ASM example driver
  193. ;  Initializations as recommended by manufacturer and National Semi
  194. ;
  195.     cld                ; Clear direction flag for movs...
  196. ;
  197. ; initial the LAN Controller register
  198. ;                    
  199.  
  200. ; program for page 0
  201.     mov    AL, MSK_PG0 + MSK_RD2
  202.     wr_wd8    CMDR
  203. ; initial DCR data configuration
  204.     mov    AL, MSK_BMS + MSK_FT10    ; select FIFO threshold = 8 bytes
  205.     wr_wd8    DCR
  206. ; clr RBCR0,1
  207.     xor    AL, AL
  208.     wr_wd8    RBCR0
  209.     wr_wd8    RBCR1
  210. ; initial RCR to monitor mode
  211.     mov    AL, MSK_MON
  212.     wr_wd8    XRCR            ; disable the rxer
  213. ; initial TCR
  214.     xor    AL, AL            
  215.     wr_wd8    TCR            ; normal operation
  216. ; initial rev buffer ring
  217.     mov    AL, STOP_PG
  218.     wr_wd8    PSTOP            ; init PSTOP
  219.     mov    AL, STRT_PG        
  220.     wr_wd8    PSTART            ; init PSTART to the 1st page of ring
  221.     wr_wd8    BNRY            ; init BNRY
  222. ; clr ISR by 1's
  223.     mov    AL, -1             ; write FF
  224.     wr_wd8    ISR
  225. ; initial IMR
  226.     mov    AL, 00h            ; ***NCSA Telnet does not
  227.                     ; ***need interrupts on
  228.  
  229.     wr_wd8    IMR            ; enable interrupt
  230. ; program for page 1
  231.     mov    AL, MSK_PG1 + MSK_RD2
  232.     wr_wd8    CMDR
  233. ; initial physical addr
  234.     mov    DX, WDBASE        ; get board io base
  235.     push    DS
  236.     mov    ax,[bp+X+2]        ; get seg from parms
  237.     mov    ds,ax
  238.  
  239.     mov    CX, BPNA        ; should be 6 for Ethernet
  240.     mov    BX, [BP+X]        ; ptr to adr in BX
  241.     add    DX, PAR0        ; i/o address of PAR0 in DX
  242. lopa:
  243.     mov    AL, [BX]        ; get 1 byte into AL
  244.     out    DX, AL            ; write to PAR
  245.     inc    BX
  246.     inc    DX
  247.     loop    lopa
  248.     pop    DS
  249.  
  250. ; initial multicast filter,  write all 0's  into MAR0 - MAR7
  251.     mov    CX, 8
  252.     mov    DX, WDBASE
  253.     add    DX, MAR0        ; i/o address of MAR0 in DX
  254.     xor    AL, AL            
  255. lopb:
  256.     out    DX, AL
  257.     inc    DX
  258.     loop    lopb                    
  259. ; initial CURR = PSTART + 1
  260.     mov    AL, STRT_PG + 1
  261.     wr_wd8    CURR
  262. ; program for page 0
  263.     mov    AL, MSK_PG0 + MSK_RD2
  264.     wr_wd8    CMDR
  265.     
  266. ; put 8390 on line
  267.     mov    AL, MSK_STA + MSK_RD2        ; activate 8390
  268.     wr_wd8    CMDR
  269. ; program RCR to normal operation (MSK_AB, no MSK_AM)
  270.     mov    AL, MSK_AB            ; accept broadcast
  271.     wr_wd8    XRCR
  272.     
  273. ;
  274.         
  275.     XOR    AX,AX
  276.     POP    BP
  277.     RET
  278. ifdef Microsoft
  279. _WDETOPEN    ENDP
  280. else
  281. WDETOPEN    ENDP
  282. endif
  283.  
  284. ifdef NOT_USED
  285. ;
  286. ;******************************************************************
  287. ;  SETADDR
  288. ;    set the Ethernet address on the board to 6 byte ID code
  289. ;
  290. ;   usage:   setaddr(s,basea,ioa);
  291. ;             char s[6];           ethernet address to use
  292. ;             int basea;           shared memory base address 
  293. ;             int ioa;             io address for board
  294. ;
  295. ifdef Microsoft
  296. _WDSETADDR    PROC    FAR
  297. else
  298. WDSETADDR    PROC    FAR
  299. endif
  300.     PUSH    BP
  301.     MOV    BP,SP
  302. ;
  303. ;  not used for this board, set during etopen
  304. ;
  305.     POP    BP
  306.     RET
  307. ifdef Microsoft
  308. _WDSETADDR    ENDP
  309. else
  310. WDSETADDR    ENDP
  311. endif
  312. endif       ; NOT_USED
  313. ;
  314. ;*******************************************************************
  315. ;  GETADDR
  316. ;     get the Ethernet address off of the board
  317. ;
  318. ;   usage:  getaddr(s,address,ioaddr);
  319. ;    char s[6];           will get six bytes from the PROM
  320. ;       int address;
  321. ;       int ioaddr;      mem address and ioaddress to use
  322. ;
  323. ifdef Microsoft
  324. _WDGETADDR    PROC    FAR
  325. else
  326. WDGETADDR    PROC    FAR
  327. endif
  328.     PUSH    BP
  329.     MOV    BP,SP
  330.     PUSH    DS
  331.     MOV    AX,[BP+X+2]    ; SEG of where to put info
  332.     MOV    DS,AX
  333.     MOV    BX,[BP+X]    ; address of where to put info
  334.     mov    cx,6
  335.     mov    dx,[BP+X+6]    ; ioaddr for board, offset 0 for PROM addr
  336.     add     dx,8        ; instruction added of WD8003e
  337.  
  338. getloop:
  339.     in    al,dx
  340.     mov    [bx],al        ; store where we want
  341.     inc    dx
  342.     inc    bx
  343.     loop    getloop
  344. ;
  345.     XOR    AX,AX
  346.     in    al,dx
  347.     sub    al,3        ; verification of board's existence
  348.     jz    noerr        ; compare went ok
  349.     mov    ax,-1        ; error return
  350. noerr:
  351.     POP    DS
  352.     POP    BP        
  353.     RET
  354. ifdef Microsoft
  355. _WDGETADDR    ENDP
  356. else
  357. WDGETADDR    ENDP
  358. endif
  359. ;
  360. ;***********************************************************************
  361. ;  ETCLOSE
  362. ;        shut it down, remove the interrupt handler
  363. ;
  364. ;  usage:  etclose();
  365. ;
  366. ;
  367. ifdef Microsoft
  368. _WDETCLOSE    PROC    FAR
  369. else
  370. WDETCLOSE    PROC    FAR
  371. endif
  372.     RET
  373. ifdef Microsoft
  374. _WDETCLOSE    ENDP
  375. else
  376. WDETCLOSE    ENDP
  377. endif
  378. ;
  379. ;************************************************************************
  380. ;   Receive
  381. ;   This is a CPU hook for boards that must be polled before we can
  382. ;   deliver packets into the receive buffer.  (i.e. no interrupts used)
  383. ;
  384. ;    usage:  recv();
  385. ;
  386. ifdef Microsoft
  387. _WDRECV    PROC    FAR
  388. else
  389. WDRECV    PROC    FAR
  390. endif
  391.     push    bp
  392.     PUSH    SI
  393.     PUSH    DI
  394.     push    es
  395. ;
  396. ;  check for data which can be read
  397. ;
  398.     mov    AL, MSK_PG1 + MSK_RD2    ; read CURR reg
  399.     wr_wd8    CMDR
  400.     rd_wd8    CURR
  401.     mov    BL, AL            ; CURR in BL 
  402.     mov    AL, MSK_PG0 + MSK_RD2        ; read BNRY reg
  403.     wr_wd8  CMDR
  404.     rd_wd8    BNRY            ; BNRY in AL
  405.     add    AL, 1            ; start page of frm in AL
  406.     cmp    AL, STOP_PG        ; check boundary
  407.     jne    go_cmp
  408.     mov    AL, STRT_PG        
  409. go_cmp:
  410.     cmp    AL, BL            
  411.     jne    gotone
  412.     jmp     end_rx            ; buff ring empty
  413. gotone:
  414. ; ring not empty
  415.     mov    BH, AL
  416.     xor    BL, BL            ; BX has the rx_frm pointer
  417.     push    BX            ; save the frm ptr
  418.         mov    AX, WDADD        ; shared mem base
  419.     mov     ES, AX            ; ES has the shr seg paragraph
  420.     mov    AL, ES:[BX]        ; AL has the status byte
  421.     test    AL, SMK_PRX        ; if rx good
  422.     jnz    readit
  423.     jmp    fd_bnry            ; rx error, drop frm by forward bnry
  424. readit:
  425. ;
  426. ;  set up to read the next packet from the net
  427. ;
  428. ;
  429. ;  get ready for next packet
  430. ;
  431.     cld            ; moves in fwd dir
  432. ;
  433. ;  check for buffer overrun or catching up with reader
  434. ;
  435. ;  implicit 64K max buffer, should stop before 64K anyway
  436. ;
  437. ifdef Microsoft
  438.     MOV    AX,_BUFBIG    ; how much stuff is in buffer
  439.     MOV    BX,_BUFLIM    ; what is our size limit?
  440. else
  441.     MOV    AX,BUFBIG    ; how much stuff is in buffer
  442.     MOV    BX,BUFLIM    ; what is our size limit?
  443. endif
  444.     CMP    AX,BX
  445.     JNA    ISROOM        ; we are ok
  446. ;
  447. ;  no room at the Inn. 
  448. ;
  449.     JMP SHORT fd_bnry     ; can't do much, we lose packets until restarted
  450.  
  451. ;
  452. ;  wrap pointer around at end, we know that we have room
  453. ;
  454. ISROOM:
  455. ifdef Microsoft
  456.     MOV    DI,word ptr [_BUFPT]     ; where buffer is
  457.     MOV    DX,word ptr [_BUFEND]    ; right before 2K safety area
  458. else
  459.     MOV    DI,word ptr [BUFPT]     ; where buffer is
  460.     MOV    DX,word ptr [BUFEND]    ; right before 2K safety area
  461. endif
  462.     CMP    DX,DI            ; see if pointer is over limit
  463.     JA    OKAYREAD        ; we are not at wrap-around
  464.  
  465. ifdef Microsoft
  466.     MOV    AX,word ptr [_BUFORG]    ; wrap to here
  467.     MOV    word ptr [_BUFPT],AX    ; wrap-around
  468. else
  469.     MOV    AX,word ptr [BUFORG]    ; wrap to here
  470.     MOV    word ptr [BUFPT],AX    ; wrap-around
  471. endif
  472.     MOV    DI,AX            ; di also
  473.  
  474. OKAYREAD:
  475. ;
  476. ;
  477. ;  start the copy of the new packet
  478. ;  pointer to the shared memory offset is in BX
  479. ;  At this offset, you will find:
  480. ;    1 byte - read status, usually 21h
  481. ;    1 byte - pointer, page # of next packet
  482. ;    2 bytes - length of data in packet, swapped for you already
  483. ;    n bytes - that many bytes of Ethernet packet spread
  484. ;       over n div 256 pages (allowing four lost bytes in first packet)
  485. ;
  486. ;
  487.     pop    si        ; get packet pointer back into si
  488.     push    si        ; restore for fd_bnry to read
  489. ;
  490. ;  save regs while moving packet to buffer
  491. ;  set up ds for buffer, even though we switch it later
  492. ;
  493.     push    es
  494.     push    ds
  495. ifdef Microsoft
  496.     MOV    AX,word ptr [_BUFPT+2]    ; buffer's ds
  497. else
  498.     MOV    AX,word ptr [BUFPT+2]    ; buffer's ds
  499. endif
  500.     mov    ds,ax
  501. ;
  502. ;  here, DS:DI contains where we want to put the packet.
  503. ;
  504. newpkt:
  505.     add    si,2        ; offset for length field
  506.     mov    dx,es:[si]    ; value of length of recd packet
  507.  
  508.     mov    ds:[di],dx        ; put the accumulated size there
  509.     inc    si
  510.     inc    si
  511.     inc    di
  512.     inc    di        ; now it is the data pointer
  513. ;
  514. ;
  515. ;  Actually move the data
  516. ;    DX has packet size in bytes
  517. ;    ES:SI has the source pointer  } need to switch
  518. ;    DS:DI has the dest pointer    } es and ds
  519. ;    Remember, 256 byte pages wrap around at STOP_PG and there
  520. ;    are max 252 bytes in the first page
  521. ;
  522.     mov    cx,dx
  523.     cmp    cx,252
  524.     jng    shrt
  525.     mov    cx,252        ; first page len
  526. shrt:
  527.     mov    ax,ds
  528.     mov    bx,es
  529.     mov    ds,bx
  530.     mov    es,ax        ; swap them
  531.  
  532.     mov    bx,dx        ; save a copy of data length
  533.  
  534. mvpg:                ; start of page move loop
  535.     sub    dx,cx
  536.     shr    cx,1        ; convert to words
  537.     jnc    iseven
  538.     movsb            ; move odd one if needed
  539. iseven:
  540.     rep    movsw        ; move all words in one page
  541.  
  542.     cmp    dx,0        ; how many left to move?
  543.     jng    donepg
  544.     mov    cx,dx
  545.     cmp    cx,256
  546.     jng    shrtr
  547.     mov    cx,256        ; one more page
  548. shrtr:
  549.     mov    ax,si        ; look at source page
  550.     cmp    ah,STOP_PG
  551.     jl    mvpg
  552.     mov    ah,STRT_PG    ; wrap around at this page boundary
  553.     mov    si,ax        ; put back in si for rest of packet
  554.     jmp    mvpg
  555.  
  556. donepg:
  557.  
  558.     pop    ds
  559.     pop    es        ; put regs back so ES is shared mem
  560.  
  561. ;
  562. ; update the pointer and length in the buffer
  563. ;  DI already points just past end of data just placed there
  564. ;
  565. ifdef Microsoft
  566.     MOV    word ptr [_BUFPT],di    ; it is here, now
  567.     MOV    AX,word ptr [_BUFBIG]    ; total amount of stuff in buffer
  568. else
  569.     MOV    word ptr [BUFPT],di    ; it is here, now
  570.     MOV    AX,word ptr [BUFBIG]    ; total amount of stuff in buffer
  571. endif
  572.     ADD    AX,BX        ; add in size of this packet
  573.     INC    AX
  574.     INC    AX        ; to cover the length value
  575. ifdef Microsoft
  576.     MOV    word ptr [_BUFBIG],AX    ; after adding in current packet size
  577. else
  578.     MOV    word ptr [BUFBIG],AX    ; after adding in current packet size
  579. endif
  580. ;
  581. ;
  582. ;  signs that something is actually happening
  583. ;
  584. ;    push    es
  585. ;    MOV    AX,0B000H       ; screen
  586. ;    MOV    ES,AX
  587. ;    MOV    DI,3998        ; lower right corner
  588. ;    INC    cs:ICNT
  589. ;    MOV    al,cs:ICNT    ; character
  590. ;    STOSB
  591. ;    pop    es
  592. ;
  593.  
  594.  
  595. ; drop bad frame by forwarding the BNRY register
  596. ;  or just normal BNRY update after frame read
  597. ;
  598. fd_bnry:                ; drop frm by forward BNRY
  599.     pop    BX            ; restore frm ptr in BX
  600.     add    BX, 1
  601.     mov    AL, ES:[BX]        ; next frm start page in AL
  602.     sub    AL, 1            ; new BNRY in AL
  603.     cmp    AL, STRT_PG        ; check boundary
  604.     jge    wrbnry
  605.     mov    AL, STOP_PG - 1
  606. wrbnry:
  607.     wr_wd8    BNRY
  608.  
  609. end_rx:
  610.     pop    es
  611.     POP    DI
  612.     POP    SI
  613.     POP    BP
  614.  
  615.     RET            ; for compatibility with other drivers
  616. ICNT    db    0
  617. ifdef Microsoft
  618. _WDRECV    ENDP
  619. else
  620. WDRECV    ENDP
  621. endif
  622. ;
  623. ;************************************************************************
  624. ;  XMIT         
  625. ;     send a packet to Ethernet
  626. ;     Is not interrupt driven, just call it when you need it.
  627. ;
  628. ;  usage:   xmit(packet,count)
  629. ;        char *packet;
  630. ;        int count;
  631. ;
  632. ;   Takes a packet raw, Ethernet packets start with destination address,
  633. ;   and puts it out onto the wire.  Count is the length of packet < 2048
  634. ;
  635. ;   checks for packets under the Ethernet size limit of 60 and handles them
  636. ;
  637. ifdef Microsoft
  638. _WDXMIT    PROC    FAR
  639. else
  640. WDXMIT    PROC    FAR
  641. endif
  642.     PUSH    BP
  643.     MOV    BP,SP
  644.     PUSH    SI
  645.     PUSH    DI
  646.     cld
  647.     push    es
  648.     PUSH    DS        ; set up proper ds for the buffer
  649. ;
  650.     mov    dx,WDADD    ; shared memory address in dx
  651.     mov    es,dx        ; use es for this
  652. ;
  653. ;
  654. ;  move packet into position, set up regs
  655. ;
  656.     MOV    AX,[BP+X+2]
  657.     MOV    DS,AX
  658.     MOV    SI,[BP+X]    ; offset for buffer
  659.  
  660.     MOV    AX,[BP+X+4]    ; count of bytes
  661.     MOV    CX,AX        ; save a copy, might be less than 60, ok
  662.  
  663.     CMP    AX,60        ; minimum length for Ether
  664.     JNB    OKLEN
  665.     MOV    AX,60        ; make sure size at least 60
  666. OKLEN:
  667. ;
  668. ;  Copy packet into transmit buffer
  669. ;  xmit buffer starts at offset zero in shared mem
  670. ;
  671.     push    ax        ; xmit size here, CX has data size
  672.     mov    di,0        ; set di to start of xmit buffer, 0 page
  673.     shr    cx,1
  674.     jnc    evenx
  675.     movsb
  676. evenx:
  677.     rep    movsw        ; copy all data into xmit buf
  678. ;
  679. ;  set up xmit length registers
  680. ;
  681.     pop    ax
  682.     pop    ds            ; get back  DS for wr_wd8 macro
  683. ; set up TBCR0,1                     
  684.     wr_wd8    TBCR0            ; lower byte to TBCR0
  685.     mov    AL, AH
  686.     wr_wd8    TBCR1            ; higher byte to TBCR1
  687.  
  688. ; set page number to page 0
  689. ;
  690.     xor    al,al            ; page number
  691.  
  692. ; set up TPSR
  693.     wr_wd8    TPSR            ; write start page into TPSR
  694.  
  695. ; issue tx command
  696.     mov    AL, MSK_TXP + MSK_RD2
  697.     wr_wd8    CMDR            ; start xmit
  698. ;
  699. ;
  700. ;  check to see if the last packet xmitted ok
  701. ;
  702.     xor    cx,cx
  703. waitxmit:
  704.     rd_wd8    CMDR        ; command register
  705.     test    al,MSK_TXP    ; xmit bit
  706.     jz    oktogo        ; xmit is finished
  707.     loop    waitxmit    ; waiting for xmit to complete
  708.     mov    ax,-1
  709.     jmp SHORT getout
  710. oktogo:
  711.     xor    ax,ax
  712. ;
  713. ; go back for more
  714. ;
  715. getout:
  716.     pop    es
  717.     POP    DI
  718.     POP    SI
  719.     POP    BP
  720.     RET
  721. ifdef Microsoft
  722. _WDXMIT    ENDP
  723. else
  724. WDXMIT    ENDP
  725. endif
  726. ;
  727. ;
  728. ;*************************************************************************
  729. ;  ETUPDATE
  730. ;      update pointers and/or restart receiver when read routine has
  731. ;      already removed the current packet
  732. ;
  733. ;   usage:  etupdate();
  734. ;
  735. ifdef Microsoft
  736. _WDETUPDATE    PROC    FAR
  737. else
  738. WDETUPDATE    PROC    FAR
  739. endif
  740.     PUSH     ES
  741. ifdef Microsoft
  742.     MOV    AX,word ptr [_BUFPT+2]    ; establish data segment to buffer
  743. else
  744.     MOV    AX,word ptr [BUFPT+2]    ; establish data segment to buffer
  745. endif
  746.     MOV    ES,AX        ; put that in es
  747. ;
  748. ifdef Microsoft
  749.     MOV    BX,_BUFREAD    ; where read pointer is now
  750. else
  751.     MOV    BX,BUFREAD    ; where read pointer is now
  752. endif
  753.     MOV    DX,ES:[BX]    ; get size of this packet
  754.     INC    DX
  755.     INC    DX        ; two more for length value
  756.  
  757.     ADD    BX,DX        ; increment bufread by size of packet
  758.  
  759. ifdef Microsoft
  760.     MOV    CX,_BUFEND    ; right before 2K safety area
  761. else
  762.     MOV    CX,BUFEND    ; right before 2K safety area
  763. endif
  764.     CMP    BX,CX        ; see if pointer is over limit
  765.     JB    NOWRAPRD    ; we are not at wrap-around
  766.     
  767. ifdef Microsoft
  768.     MOV    BX,_BUFORG    ; wrap to here
  769. NOWRAPRD:
  770.     MOV    _BUFREAD,BX    ; buffer pointer has been updated
  771. else
  772.     MOV    BX,BUFORG    ; wrap to here
  773. NOWRAPRD:
  774.     MOV    BUFREAD,BX    ; buffer pointer has been updated
  775. endif
  776.  
  777. ;
  778. ;  DECREMENT TOTAL BUFFER SIZE
  779. ;
  780.     CLI            ; keep interrupt handler from bothering dec
  781. ifdef Microsoft
  782.     MOV    CX,_BUFBIG    ; size before removing packet
  783. else
  784.     MOV    CX,BUFBIG    ; size before removing packet
  785. endif
  786.     SUB    CX,DX        ; remove size of current packet
  787. ifdef Microsoft
  788.     MOV    _BUFBIG,CX    ; put it back
  789. else
  790.     MOV    BUFBIG,CX    ; put it back
  791. endif
  792.     STI
  793. ;
  794. ;  IF RECEIVER IS ON, THEN CHECKING BUFLIM IS UNNECESSARY.
  795. ;
  796.     MOV    AL,DEAF        ; is the receiver turned off?
  797.     OR    AL,AL        ; 0 = reading, 1 = deaf
  798.     JZ    ALIVE
  799. ;
  800. ;  CHECK FOR ROOM IN THE BUFFER, IF THERE IS, TURN ON RECEIVER
  801. ;
  802. ifdef Microsoft
  803.     MOV    AX,_BUFLIM    ; what is our limit?
  804. else
  805.     MOV    AX,BUFLIM    ; what is our limit?
  806. endif
  807.     CMP    CX,AX        ; compare to limit
  808.     JA    ALIVE        ; not really alive, but can't turn on yet
  809.  
  810.     XOR    AL,AL
  811.     MOV    DEAF,AL        ; reset flag
  812.  
  813.     INC    OFFS        ; keep count how many times this happened
  814.  
  815. ;
  816. ;  turn receiver back on
  817. ;
  818.  
  819. ALIVE:
  820.     POP    ES
  821.     RET    
  822. ifdef Microsoft
  823. _WDETUPDATE    ENDP
  824. else
  825. WDETUPDATE    ENDP
  826. endif
  827.  
  828. ifdef Microsoft
  829. ;_TEXT    ends
  830. else
  831.     ENDPS
  832. endif
  833.     END
  834.