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