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