home *** CD-ROM | disk | FTP | other *** search
/ Programmer 7500 / MAX_PROGRAMMERS.iso / INFO / NCSATELN / TEL23SRC.ZIP / NET / ENET / 503BAK.ASM next >
Encoding:
Assembly Source File  |  1991-05-15  |  22.3 KB  |  1,090 lines

  1. ;  3C503 Driver
  2. ;
  3. ;    Kurt Mahan ( based on WD8003 by Tim Krauskopf )
  4. ;
  5. ;****************************************************************************
  6. ;*                                                                          *
  7. ;*                                                                          *
  8. ;*      part of NCSA Telnet                                                 *
  9. ;*      by Tim Krauskopf, VT100 by Gaige Paulsen, Tek by Aaron Contorer     *
  10. ;*        neat other things by Kurt Mahan
  11. ;*                                                                          *
  12. ;*      National Center for Supercomputing Applications                     *
  13. ;*      152 Computing Applications Building                                 *
  14. ;*      605 E. Springfield Ave.                                             *
  15. ;*      Champaign, IL  61820                                                *
  16. ;*                                                                          *
  17. ;*                                                                          *
  18. ;****************************************************************************
  19. ;
  20.  
  21.     TITLE    NETSUPPORT -- LOW LEVEL DRIVERS FOR ETHERNET
  22. ;
  23. ;  Assembler support for interrupt-driven Ethernet I/O on the PC
  24. ;
  25. ;  Reads and writes from the 8K buffer on the WD card.
  26. ;  Started 4/11/88
  27. ;
  28. ;Microsoft EQU 1
  29. ;Lattice EQU 1
  30.   ifndef Microsoft
  31.     ifndef Lattice
  32.       if2
  33.         %out
  34.         %out ERROR: You have to specify "/DMicrosoft" OR "/DLattice" on the
  35.         %out        MASM command line to determine the type of assembly.
  36.         %out
  37.       endif
  38.       end
  39.     endif
  40.   endif
  41.  
  42. ifdef Microsoft
  43. X    EQU    6
  44.     DOSSEG
  45.     .MODEL    LARGE
  46. else
  47.         NAME    NET503
  48.       INCLUDE    DOS.MAC
  49.       SETX
  50. endif
  51.  
  52. ;
  53. ;    EQUATES for the 3C503 board
  54. ;
  55.  
  56. CMDR    equ    00h              ; ports on the 8390 ( page 0 )
  57. PSTART    equ    01h
  58. PSTOP    equ    02h
  59. BNRY    equ    03h
  60. TPSR    equ    04h
  61. TBCR0    equ    05h
  62. TBCR1    equ    06h
  63. ISR    equ    07h
  64. RSAR0    equ    08h
  65. RSAR1    equ    09h
  66. RBCR0    equ    0ah
  67. RBCR1    equ    0bh
  68. XRCR    equ    0ch
  69. TCR    equ    0dh
  70. DCR    equ    0eh
  71. IMR    equ    0fh
  72.  
  73. PAR0    equ    01h              ; ports on the 8390 ( page 1 )
  74. PAR1    equ    02h
  75. PAR2    equ    03h
  76. PAR3    equ    04h
  77. PAR4    equ    05h
  78. PAR5    equ    06h
  79. CURR    equ    07h
  80. MAR0    equ    08h
  81. MAR1    equ    09h
  82. MAR2    equ    0ah
  83. MAR3    equ    0bh
  84. MAR4    equ    0ch
  85. MAR5    equ    0dh
  86. MAR6    equ    0eh
  87. MAR7    equ    0fh
  88.  
  89. PSTR    equ    400h              ; ports on the gate array
  90. PSPR    equ    401h
  91. DQTR    equ    402h
  92. BCFR    equ    403h
  93. PCFR    equ    404h
  94. GACFR    equ    405h
  95. CTRL    equ    406h
  96. STREG    equ    407h
  97. IDCFR    equ    408h
  98. DAMSB    equ    409h
  99. DALSM    equ    40ah
  100. VPTR2    equ    40bh
  101. VPTR1    equ    40ch
  102. VPTR0    equ    40dh
  103. RFMSB    equ    40eh
  104. RFLSB    equ    40fh
  105.  
  106. STRT_PG    equ    26h              ; start at page 6
  107. STOP_PG    equ    40h              ; end at page 31
  108. TSTRT_PG equ    20h              ; transmit start page
  109.  
  110. ;
  111. ;  macros for writing to NET503 board
  112. ;
  113. ;***********************************************************************
  114. ;
  115. ;    Macros, from example driver
  116. ;
  117. ;***********************************************************************
  118.  
  119. ;
  120. ; MACRO rd_wd8
  121. ;   Reads port specified on macro call. Leaves byte in AL.
  122. ;
  123.  
  124. rd_wd8    MACRO    port
  125.     push    dx
  126.     mov    DX, WDBASE
  127.     add    DX, port        ; DX contains address of port
  128.     in    AL, DX            ; AL contains data read from port
  129.     pop    dx
  130.     ENDM
  131.  
  132. ;
  133. ; MACRO wr_wd8
  134. ;   Writes byte in AL to port specified on macro call.
  135. ;
  136.  
  137. wr_wd8    MACRO    port
  138.     push    dx
  139.     mov    DX, WDBASE
  140.     add    DX, port        ; DX contains address of port
  141.     out    DX, AL            ; AL contains data to be written to port
  142.     pop    dx
  143.     ENDM
  144.  
  145. ;
  146. ifdef Microsoft
  147. ;DGROUP    group    _DATA
  148. ;_DATA    segment    public 'DATA'
  149. ;    assume    DS:DGROUP
  150.     .data
  151. else
  152.     DSEG
  153. endif
  154. ;    PUBLIC    STAT,BUFPT,BUFORG,BUFEND,BUFREAD,BUFBIG,BUFLIM,OFFS
  155. ;
  156. ;  The pointers below are actually DWORDs but we access them two
  157. ;  bytes at a time.
  158. ;
  159. ; STAT change to RSTAT because of name clash with MSC library routine
  160. ifdef Microsoft
  161.     EXTRN    _RSTAT:BYTE    ; last status from read
  162.     EXTRN    _BUFPT:WORD    ; current buffer pointer
  163.     EXTRN    _BUFORG:WORD    ; pointer to beginning of buffer
  164.     EXTRN    _BUFEND:WORD    ; pointer to end of buffer
  165.     EXTRN    _BUFREAD:WORD    ; pointer to where program is reading
  166.     EXTRN    _BUFBIG:WORD    ; integer, how many bytes we have
  167.     EXTRN    _BUFLIM:WORD    ; integer, max bytes we can have
  168. else
  169.     EXTRN    RSTAT:BYTE    ; last status from read
  170.     EXTRN    BUFPT:WORD    ; current buffer pointer
  171.     EXTRN    BUFORG:WORD    ; pointer to beginning of buffer
  172.     EXTRN    BUFEND:WORD    ; pointer to end of buffer
  173.     EXTRN    BUFREAD:WORD    ; pointer to where program is reading
  174.     EXTRN    BUFBIG:WORD    ; integer, how many bytes we have
  175.     EXTRN    BUFLIM:WORD    ; integer, max bytes we can have
  176. endif
  177.  
  178. WDBASE    DW    00h        ; base ioaddr
  179. WDADD    DW    00h        ; base shared mem addr
  180. DEAF    DB    00H        ; when we can't handle any more packets
  181. OFFS    DW    00H        ; how many times the handler was turned off
  182. WIRE    DB    02h        ; thin as the default
  183. ;
  184. ifdef Microsoft
  185. ;_DATA    ends
  186. else
  187.     ENDDS
  188. endif
  189. ;
  190. ;   The subroutines to call from C
  191. ;
  192. ifdef Microsoft
  193. ;_TEXT    segment    public    'CODE'
  194. ;    assume CS:_TEXT
  195.     .code
  196.     PUBLIC    _E4RECV,_E4ETOPEN,_E4ETCLOSE,_E4GETADDR
  197.     PUBLIC    _E4SETADDR,_E4XMIT,_E4ETUPDATE
  198.     PUBLIC _E4SETWIRE
  199. else
  200.     PSEG
  201.     PUBLIC    E4RECV,E4ETOPEN,E4ETCLOSE,E4GETADDR
  202.     PUBLIC    E4SETADDR,E4XMIT,E4ETUPDATE, E4SETWIRE
  203. endif
  204.  
  205.  
  206. ;*****************************************************************
  207. ;
  208. ; E4SETWIRE
  209. ;
  210. ; WHAT TYPE OF WIRE ARE WE USING?  THIN OR THICK
  211. ;
  212. ; USAGE: E4SETWIRE(INT WIRE)
  213. ;
  214.  
  215. ifdef Microsoft
  216. _E4SETWIRE    PROC FAR
  217. else
  218. E4SETWIRE    PROC FAR
  219. endif
  220.  
  221.     PUSH BP
  222.     MOV  BP,SP
  223.     push ds
  224.     mov  ax,seg WIRE
  225.     mov  ds,ax
  226.     XOR  AX,AX
  227.     MOV  AL,[BP+X]        ; GET WIRE TYPE
  228.     MOV  WIRE,AL         ; STORE IT!
  229.     pop  ds
  230.     POP  BP
  231.     RET
  232.  
  233. ifdef    Microsoft
  234. _E4SETWIRE    ENDP
  235. else
  236. E4SETWIRE    ENDP
  237. endif
  238.  
  239.  
  240. ;******************************************************************
  241. ;  ETOPEN
  242. ;     Initialize the Ethernet board, set receive type.
  243. ;
  244. ;  usage:  etopen(s,irq,addr,ioaddr)
  245. ;           char s[6];       ethernet address
  246. ;           int irq,addr,ioaddr;     
  247. ;                interrupt number (unused), base mem address and
  248. ;                i/o address to use
  249. ;
  250. ifdef    Microsoft
  251. _E4ETOPEN    PROC    FAR
  252. else
  253. E4ETOPEN    PROC    FAR
  254. endif
  255. ;
  256. ;    init addresses and things
  257. ;
  258.  
  259.     PUSH    BP
  260.     MOV    BP,SP
  261.     mov    AX,[BP+X+8]        ; install ioaddr
  262.     mov    WDBASE,AX
  263.     mov    AX,[BP+X+6]        ; install shared mem addr
  264.     mov    WDADD,AX
  265. ;
  266. ;    initialize the gate array
  267. ;
  268.     push    ds
  269.     mov    ax,seg WIRE
  270.     mov    ds,ax
  271.     mov    al,1            ; reset the board -- onboard xcvr
  272.     or     al,WIRE
  273.     wr_wd8    CTRL
  274.     mov    al,0            ; done with reset -- still onboard xcvr
  275.     or    al,WIRE
  276.     wr_wd8    CTRL
  277.     wr_wd8    CTRL
  278.     pop    ds
  279. ;
  280. ;    set the vector pointers ( VPTR0 - VPTR2 ) so that the shared memory
  281. ;    won't go byebye on us accidentally ( point to ffff00h )
  282. ;
  283.     mov    al,0ffh
  284.     wr_wd8    VPTR2
  285.     wr_wd8    VPTR1
  286.     xor    al,al
  287.     wr_wd8    VPTR0
  288. ;
  289. ;    lookup the shared memory address ( such a neat card, huh -- we can
  290. ;    actually read it up from the gate array )
  291. ;
  292. ;    PCFR : high bits = ( 7 .. 0 )
  293. ;                bit 7 = dc00
  294. ;                bit 6 = d800
  295. ;                bit 5 = cc00
  296. ;                bit 4 = c800
  297. ;
  298. ;
  299.     rd_wd8    PCFR            ; read prom config register
  300.     test    al,80h            ; dc00?
  301.     jz    eto100
  302.     mov    WDADD,0da00h
  303.     jmp    etok
  304. eto100:    test    al,40h            ; d800?
  305.     jz    eto200
  306.     mov    WDADD,0d600h
  307.     jmp    etok
  308. eto200:    test    al,20h            ; cc00?
  309.     jz    eto300
  310.     mov    WDADD,0ca00h
  311.     jmp    etok
  312. eto300:    test    al,10h            ; c800?
  313.     jz    eto400
  314.     mov    WDADD,0c600h
  315.     jmp    etok
  316. ;
  317. eto400:    mov    ax,-1            ; mem not enabled
  318.     pop    bp
  319.     ret
  320. ;
  321. ;    ok, WDBASE is setup as the base memory address
  322. ;
  323. etok :    mov    al,0c9h            ; dis ints, ram sel, bank 0
  324.     wr_wd8    GACFR
  325. ;
  326. ;    setup the start/stop pages 
  327. ;
  328.     mov    al,STRT_PG        ; starting page
  329.     wr_wd8    PSTR
  330.     mov    al,STOP_PG        ; ending page
  331.     wr_wd8    PSPR
  332. ;
  333. ;    setup the interrupt and dma request stuff
  334. ;
  335.     xor    al,10h            ; no ints, no dma channels
  336.     wr_wd8    IDCFR            ; interrupt/dma channel ctrl
  337. ;
  338. ;    set DRQ timer to 8
  339. ;
  340.     mov    al,8
  341.     wr_wd8    DQTR
  342. ;
  343. ;    set dma msb to 20h
  344. ;
  345.     mov    al,TSTRT_PG        ; transmit start page
  346.     wr_wd8    DAMSB
  347.     xor    al,al            ; 0
  348.     wr_wd8    DALSM
  349. ;
  350.     cld
  351. ;
  352. ; initialize the LAN Controller register
  353. ;                    
  354.     push    ds
  355.     mov    ax,seg WIRE
  356.     mov    ds,ax
  357.     mov    al,0
  358.     or    al,WIRE
  359.     wr_wd8    CTRL            ; make sure its switched in
  360.     pop    ds
  361. ;
  362. ; program for page 0
  363. ;
  364.     mov    AL, 21h              ; page 0, abort any pending dma
  365.     wr_wd8    CMDR
  366. ;
  367. ;    clear interrupt regs
  368. ;
  369.     mov    al, 0ffh
  370.     wr_wd8    ISR
  371. ;
  372. ; initial DCR data configuration
  373. ;
  374.     mov    AL, 48h               ; burst dma, fifo thresh = 8 bytes
  375.     wr_wd8    DCR
  376. ;
  377. ; initial TCR
  378. ;
  379.     xor    AL, AL            
  380.     wr_wd8    TCR            ; normal operation
  381. ;
  382. ; initial RCR to monitor mode
  383. ;
  384.     mov    AL, 20h                ; monitor mode
  385.     wr_wd8    XRCR
  386. ;
  387. ; set page start/page stop/ boundary
  388. ;
  389.     mov    AL,STRT_PG
  390.     wr_wd8    PSTART
  391.     mov    al,STOP_PG
  392.     wr_wd8    PSTOP
  393.     mov    al,STRT_PG        ; go with the WD style of things
  394.     wr_wd8    BNRY
  395. ;
  396. ; program for page 1
  397. ;
  398.     mov    AL, 60h               ; page 1, abort any pending dma
  399.     wr_wd8    CMDR
  400. ;
  401. ; initial physical addr
  402. ;
  403.     mov    DX, WDBASE        ; get board io base
  404.     push    DS
  405.     mov    ax,[bp+X+2]        ; get seg from parms
  406.     mov    ds,ax
  407.  
  408.     mov    CX, 6            ; should be 6 for Ethernet
  409.     mov    BX, [BP+X]        ; ptr to adr in BX
  410.     add    DX, PAR0        ; i/o address of PAR0 in DX
  411. lopa:
  412.     mov    AL, [BX]        ; get 1 byte into AL
  413.     out    DX, AL            ; write to PAR
  414.     inc    BX
  415.     inc    DX
  416.     loop    lopa
  417.     pop    DS
  418. ;
  419. ; initial multicast filter,  write all 0's  into MAR0 - MAR7
  420. ;
  421.     mov    CX, 8
  422.     mov    DX, WDBASE
  423.     add    DX, MAR0        ; i/o address of MAR0 in DX
  424.     xor    AL, AL            
  425. lopb:
  426.     out    DX, AL
  427.     inc    DX
  428.     loop    lopb                    
  429. ;
  430. ;    set CURR page
  431. ;
  432.     mov    al,STRT_PG+1
  433.     wr_wd8    CURR
  434. ;
  435. ; program for page 0
  436. ;
  437.     mov    al,21h            ; page 0, stop any dma stuff
  438.     wr_wd8    CMDR
  439. ;
  440. ; initial IMR
  441. ;
  442.     xor    al,al            ; ***NCSA Telnet does not need interrupts
  443.     wr_wd8    IMR            ; enable interrupt
  444.     mov    al,0ffh
  445.     wr_wd8    ISR
  446. ;
  447. ;    clear byte counts
  448. ;
  449.     xor    AL, AL
  450.     wr_wd8    RBCR0
  451.     wr_wd8    RBCR1
  452. ;    
  453. ; put 8390 on line
  454. ;
  455.     mov    al,22h            ; start up the 8390
  456.     wr_wd8    CMDR
  457. ;
  458. ; program RCR to normal operation (MSK_AB, no MSK_AM)
  459. ;
  460.     mov    al,4                ; accept broadcast packets
  461.     wr_wd8    XRCR
  462. ;
  463.     mov    al,0c9h
  464.     wr_wd8    GACFR
  465. ;
  466. ;    I'm happy to keep GACFR at c9 ( no interrupts )
  467. ;
  468. ;    return NO ERROR
  469. ;
  470.     XOR    AX,AX
  471.     POP    BP
  472.     RET
  473. ;
  474. ifdef    Microsoft
  475. _E4ETOPEN    ENDP
  476. else
  477. E4ETOPEN    ENDP
  478. endif
  479. ;
  480. ;******************************************************************
  481. ;  SETADDR
  482. ;    set the Ethernet address on the board to 6 byte ID code
  483. ;
  484. ;   usage:   setaddr(s,basea,ioa);
  485. ;             char s[6];           ethernet address to use
  486. ;             int basea;           shared memory base address 
  487. ;             int ioa;             io address for board
  488. ;
  489. ifdef    Microsoft
  490. _E4SETADDR    PROC    FAR
  491. else
  492. E4SETADDR    PROC    FAR
  493. endif
  494.  
  495.     PUSH    BP
  496.     MOV    BP,SP
  497. ;
  498. ;  not used for this board, set during etopen
  499. ;
  500.     POP    BP
  501.     RET
  502. ifdef    Microsoft
  503. _E4SETADDR    ENDP
  504. else
  505. E4SETADDR    ENDP
  506. endif
  507. ;
  508. ;*******************************************************************
  509. ;  GETADDR
  510. ;     get the Ethernet address off of the board
  511. ;
  512. ;   usage:  getaddr(s,address,ioaddr);
  513. ;    char s[6];           will get six bytes from the PROM
  514. ;       int address;
  515. ;       int ioaddr;      mem address and ioaddress to use
  516. ;
  517. ifdef    Microsoft
  518. _E4GETADDR    PROC    FAR
  519. else
  520. E4GETADDR    PROC    FAR
  521. endif
  522.  
  523.     PUSH    BP
  524.     MOV    BP,SP
  525.     PUSH    DS
  526.     MOV    AX,[BP+X+2]    ; SEG of where to put info
  527.     MOV    DS,AX
  528.     MOV    BX,[BP+X]    ; address of where to put info
  529.     mov    cx,6
  530.     mov    dx,[BP+X+6]    ; ioaddr for board
  531. ;
  532. ;    set the gate array to look at the lower 16 bytes of the prom
  533. ;
  534.     push    ds
  535.     mov    ax,seg WIRE
  536.     mov    ds,ax
  537.     mov    al,1
  538.     or    al,WIRE
  539.     pop    ds
  540.     push    dx
  541.     add    dx,CTRL
  542.     out    dx,al
  543.     mov    al,2
  544.     out    dx,al
  545.     mov    al,6
  546.     out    dx,al
  547.     
  548.     pop    dx
  549.     push    dx
  550. ;
  551. getloop:
  552.     in    al,dx
  553.     mov    [bx],al        ; store where we want
  554.     inc    dx
  555.     inc    bx
  556.     loop    getloop
  557. ;
  558. ;    reset the gate array to normal mapping
  559. ;
  560.     pop    dx
  561.     push    ds
  562.     mov    ax,seg WIRE
  563.     mov    ds,ax
  564.     mov    al,0        ; still onboard xcvr 
  565.     or    al,WIRE
  566.     pop    ds
  567.     add    dx,CTRL
  568.     out    dx,al
  569.     POP    DS
  570.     POP    BP        
  571.     RET
  572. ifdef    Microsoft
  573. _E4GETADDR    ENDP
  574. else
  575. E4GETADDR    ENDP
  576. endif
  577.  
  578. ;
  579. ;***********************************************************************
  580. ;  ETCLOSE
  581. ;        shut it down, remove the interrupt handler
  582. ;
  583. ;  usage:  etclose();
  584. ;
  585. ;
  586. ifdef    Microsoft
  587. _E4ETCLOSE    PROC    FAR
  588. else
  589. E4ETCLOSE    PROC    FAR
  590. endif
  591.  
  592.     RET
  593. ifdef    Microsoft
  594. _E4ETCLOSE    ENDP
  595. else
  596. E4ETCLOSE    ENDP
  597. endif
  598. ;
  599. ;************************************************************************
  600. ;   Receive
  601. ;   This is a CPU hook for boards that must be polled before we can
  602. ;   deliver packets into the receive buffer.  (i.e. no interrupts used)
  603. ;
  604. ;    usage:  recv();
  605. ;
  606. ifdef    Microsoft
  607. _E4RECV    PROC    FAR
  608. else
  609. E4RECV    PROC    FAR
  610. endif
  611.  
  612.     push    bp
  613.     push    es
  614. ;
  615. ;  check for data which can be read
  616. ;
  617.     rd_wd8    XRCR            ; read the Rx Status Register
  618.     and    al,01h            ; check for a packet
  619.     jnz    snore            ; none -- go onto something else
  620.     jmp    end_rx
  621. snore:
  622. ;
  623. ;    ok, the chip thinks we have a packet to read
  624. ;
  625.     mov    AL, 61h            ; page 1
  626.     wr_wd8    CMDR
  627.     rd_wd8    CURR
  628.     mov    BL, AL            ; CURR in BL 
  629. ;
  630.     mov    AL, 20h            ; page 0
  631.     wr_wd8  CMDR
  632.     rd_wd8    BNRY            ; BNRY in AL
  633. ;
  634.     add    AL, 1            ; start page of frm in AL
  635.     cmp    AL, STOP_PG        ; check boundary
  636.     jne    go_cmp
  637.     mov    AL, STRT_PG        
  638. go_cmp:
  639.     cmp    AL, BL            
  640.     jne    gotone
  641.     jmp     end_rx            ; buff ring empty
  642. gotone:
  643. ;
  644. ; ring not empty
  645. ;
  646.     mov    BH, AL
  647.     xor    BL, BL            ; BX has the rx_frm pointer
  648.     push    BX            ; save the frm ptr
  649.         mov    AX, WDADD        ; shared mem base
  650.     mov     ES, AX            ; ES has the shr seg paragraph
  651.     mov    AL, ES:[BX]        ; AL has the status byte
  652. ;    test    AL, SMK_PRX        ; if rx good
  653.     test    al,1
  654.     jnz    readit
  655.     jmp    fd_bnry            ; rx error, drop frm by forward bnry
  656. readit:
  657. ;
  658. ;  set up to read the next packet from the net
  659. ;
  660. ;
  661. ;  get ready for next packet
  662. ;
  663.     cld            ; moves in fwd dir
  664. ;
  665. ;  check for buffer overrun or catching up with reader
  666. ;
  667. ;  implicit 64K max buffer, should stop before 64K anyway
  668. ;
  669. ifdef    Microsoft
  670.     MOV    AX,_BUFBIG    ; how much stuff is in buffer
  671.     MOV    BX,_BUFLIM    ; what is our size limit?
  672. else
  673.     MOV    AX,BUFBIG    ; how much stuff is in buffer
  674.     MOV    BX,BUFLIM    ; what is our size limit?
  675. endif
  676.     CMP    AX,BX
  677.     JNA    ISROOM        ; we are ok
  678. ;
  679. ;  no room at the Inn. 
  680. ;
  681.     JMP    fd_bnry        ; can't do much, we lose packets until restarted
  682.  
  683. ;
  684. ;  wrap pointer around at end, we know that we have room
  685. ;
  686. ISROOM:
  687. ifdef    Microsoft
  688.     MOV    DI,word ptr [_BUFPT]     ; where buffer is
  689.     MOV    DX,word ptr [_BUFEND]    ; right before 2K safety area
  690. else
  691.     MOV    DI,word ptr [BUFPT]     ; where buffer is
  692.     MOV    DX,word ptr [BUFEND]    ; right before 2K safety area
  693. endif
  694.  
  695.     CMP    DX,DI            ; see if pointer is over limit
  696.     JA    OKAYREAD        ; we are not at wrap-around
  697.  
  698. ifdef    Microsoft
  699.     MOV    AX,word ptr [_BUFORG]    ; wrap to here
  700.     MOV    word ptr [_BUFPT],AX    ; wrap-around
  701. else
  702.     MOV    AX,word ptr [BUFORG]    ; wrap to here
  703.     MOV    word ptr [BUFPT],AX    ; wrap-around
  704. endif
  705.     MOV    DI,AX            ; di also
  706.  
  707. OKAYREAD:
  708. ;
  709. ;
  710. ;  start the copy of the new packet
  711. ;  pointer to the shared memory offset is in BX
  712. ;  At this offset, you will find:
  713. ;    1 byte - read status, usually 21h
  714. ;    1 byte - pointer, page # of next packet
  715. ;    2 bytes - length of data in packet, swapped for you already
  716. ;    n bytes - that many bytes of Ethernet packet spread
  717. ;       over n div 256 pages (allowing four lost bytes in first packet)
  718. ;
  719. ;
  720.     pop    si        ; get packet pointer back into si
  721.     push    si        ; restore for fd_bnry to read
  722. ;
  723. ;  save regs while moving packet to buffer
  724. ;  set up ds for buffer, even though we switch it later
  725. ;
  726.     push    es
  727.     push    ds
  728. ifdef    Microsoft
  729.     MOV    AX,word ptr [_BUFPT+2]    ; buffer's ds
  730. else
  731.     MOV    AX,word ptr [BUFPT+2]    ; buffer's ds
  732. endif
  733.     mov    ds,ax
  734. ;
  735. ;  here, DS:DI contains where we want to put the packet.
  736. ;
  737. newpkt:
  738.     add    si,2        ; offset for length field
  739.     mov    dx,es:[si]    ; value of length of recd packet
  740.  
  741.     mov    [di],dx        ; put the accumulated size there
  742.     inc    si
  743.     inc    si
  744.     inc    di
  745.     inc    di        ; now it is the data pointer
  746. ;
  747. ;
  748. ;  Actually move the data
  749. ;    DX has packet size in bytes
  750. ;    ES:SI has the source pointer  } need to switch
  751. ;    DS:DI has the dest pointer    } es and ds
  752. ;    Remember, 256 byte pages wrap around at STOP_PG and there
  753. ;    are max 252 bytes in the first page
  754. ;
  755.     mov    cx,dx
  756.     cmp    cx,252
  757.     jng    shrt
  758.     mov    cx,252        ; first page len
  759. shrt:
  760.     mov    ax,ds
  761.     mov    bx,es
  762.     mov    ds,bx
  763.     mov    es,ax        ; swap them
  764.  
  765.     mov    bx,dx        ; save a copy of data length
  766.  
  767. mvpg:                ; start of page move loop
  768.     sub    dx,cx
  769.     shr    cx,1        ; convert to words
  770.     jnc    iseven
  771.     movsb            ; move odd one if needed
  772. iseven:
  773.     rep    movsw        ; move all words in one page
  774.  
  775.     cmp    dx,0        ; how many left to move?
  776.     jng    donepg
  777.     mov    cx,dx
  778.     cmp    cx,256
  779.     jng    shrtr
  780.     mov    cx,256        ; one more page
  781. shrtr:
  782.     mov    ax,si        ; look at source page
  783.     cmp    ah,STOP_PG
  784.     jl    mvpg
  785.     mov    ah,STRT_PG    ; wrap around at this page boundary
  786.     mov    si,ax        ; put back in si for rest of packet
  787.     jmp    mvpg
  788.  
  789. donepg:
  790.  
  791.     pop    ds
  792.     pop    es        ; put regs back so ES is shared mem
  793.  
  794. ;
  795. ; update the pointer and length in the buffer
  796. ;  DI already points just past end of data just placed there
  797. ;
  798. ifdef    Microsoft
  799.     MOV    word ptr [_BUFPT],di    ; it is here, now
  800.     MOV    AX,word ptr [_BUFBIG]    ; total amount of stuff in buffer
  801. else
  802.     MOV    word ptr [BUFPT],di    ; it is here, now
  803.     MOV    AX,word ptr [BUFBIG]    ; total amount of stuff in buffer
  804. endif
  805.     ADD    AX,BX        ; add in size of this packet
  806.     INC    AX
  807.     INC    AX        ; to cover the length value
  808. ifdef    Microsoft
  809.     MOV    word ptr [_BUFBIG],AX    ; after adding in current packet size
  810. else
  811.     MOV    word ptr [BUFBIG],AX    ; after adding in current packet size
  812. endif
  813. ;
  814. ;
  815. ;  signs that something is actually happening
  816. ;
  817. ;    push    es
  818. ;    MOV    AX,0B000H       ; screen
  819. ;    MOV    ES,AX
  820. ;    MOV    DI,3998        ; lower right corner
  821. ;    INC    cs:ICNT
  822. ;    MOV    al,cs:ICNT    ; character
  823. ;    STOSB
  824. ;    pop    es
  825. ;
  826.  
  827.  
  828. ; drop bad frame by forwarding the BNRY register
  829. ;  or just normal BNRY update after frame read
  830. ;
  831. fd_bnry:                ; drop frm by forward BNRY
  832.     pop    BX            ; restore frm ptr in BX
  833.     add    BX, 1
  834.     mov    AL, ES:[BX]        ; next frm start page in AL
  835.     sub    AL, 1            ; new BNRY in AL
  836.     cmp    AL, STRT_PG        ; check boundary
  837.     jge    wrbnry
  838.     mov    AL, STOP_PG - 1
  839. wrbnry:
  840.     wr_wd8    BNRY
  841.  
  842. end_rx:
  843.     pop    es
  844.     POP    BP
  845.  
  846.     RET            ; for compatibility with other drivers
  847. ICNT    db    0
  848. ifdef    Microsoft
  849. _E4RECV    ENDP
  850. else
  851. E4RECV    ENDP
  852. endif
  853.  
  854. ;
  855. ;************************************************************************
  856. ;  XMIT         
  857. ;     send a packet to Ethernet
  858. ;     Is not interrupt driven, just call it when you need it.
  859. ;
  860. ;  usage:   xmit(packet,count)
  861. ;        char *packet;
  862. ;        int count;
  863. ;
  864. ;   Takes a packet raw, Ethernet packets start with destination address,
  865. ;   and puts it out onto the wire.  Count is the length of packet < 2048
  866. ;
  867. ;   checks for packets under the Ethernet size limit of 60 and handles them
  868. ;
  869. ifdef    Microsoft
  870. _E4XMIT    PROC    FAR
  871. else
  872. E4XMIT    PROC    FAR
  873. endif
  874.  
  875.     PUSH    BP
  876.     MOV    BP,SP
  877.     push    es
  878.     PUSH    DS        ; set up proper ds for the buffer
  879. ;
  880. ;    ok, let's hangout here waiting for the transmitter
  881. ;
  882.     mov    bx,8000h    ; adequate timeout
  883. twait:    rd_wd8    CMDR        ; read up the command reg
  884.     and    al,04h        ; xmit flag
  885.     jz        tfree
  886.     dec    bx
  887.     jnz    twait        ; keep going till timeout
  888.     mov    ax,-1        ; bummer, it hates me
  889.     pop    ds
  890.     pop    es
  891.     pop    bp
  892.     ret
  893. tfree:
  894.     cld
  895. ;
  896.     mov    al,0c9h
  897.     wr_wd8    GACFR
  898. ;
  899.     mov    ax,WDADD    ; shared memory address in ax
  900.     mov    es,ax        ; use es for this
  901. ;
  902. ;  move packet into position, set up regs
  903. ;
  904.     MOV    AX,[BP+X+2]    ; get data ds
  905.     MOV    DS,AX
  906.     MOV    SI,[BP+X]    ; DS:SI points to data buffer
  907.  
  908.     MOV        CX,[BP+X+4]    ; count of bytes
  909.     CMP    CX,60        ; minimum length for Ether
  910.     JNB    OKLEN
  911.     MOV    CX,60        ; make sure size at least 60
  912. OKLEN:
  913. ;
  914. ;  Copy Packet : 
  915. ;
  916. ;    DS:SI = real data
  917. ;    ES    = shared memory address
  918. ;    CX    = number of bytes
  919. ;
  920.     mov    al,0c9h        ; reset the gate array
  921.     wr_wd8    GACFR
  922. ;
  923.     push    cx        ; save xmit length
  924.     xor    ax,ax
  925.     mov    ah,TSTRT_PG    ; starting page number
  926.     mov    di,ax        ; ES:DI = shared mem buff start
  927.     shr    cx,1        ; gonna do 16 bits
  928.     jnc    evenx
  929.     movsb            ; pick up odd byte
  930. evenx:
  931.     rep    movsw        ; copy all data into xmit buf
  932. ;
  933.     mov    al,0
  934.     wr_wd8    TCR
  935. ;
  936. ;  set up xmit length registers
  937. ;
  938.     pop    cx        ; len restored in cx
  939.     pop    ds
  940.     mov    al,cl        ; length
  941.     wr_wd8    TBCR0            ; lower byte to TBCR0
  942.     mov    al,ch
  943.     wr_wd8    TBCR1            ; higher byte to TBCR1
  944. ;
  945. ; set page number
  946. ;
  947.     mov    al,TSTRT_PG
  948.     wr_wd8    TPSR            ; write start page into TPSR
  949. ;
  950. ; issue tx command
  951. ;
  952.     mov    al,24h
  953.     wr_wd8    CMDR            ; start xmit
  954. ;
  955. ;  check to see if the last packet xmitted ok
  956. ;
  957.     xor    cx,cx            ; set a timeout
  958. ;
  959. waitxmit:
  960. ;
  961.     rd_wd8    CMDR        ; command register
  962.     and    al,4        ; xmit bit
  963.     jz    oktogo        ; xmit is finished
  964.     loop    waitxmit    ; waiting for xmit to complete
  965.     mov    ax,-1
  966.     jmp    getout
  967. oktogo:
  968.     xor    ax,ax
  969. ;
  970. ; go back for more
  971. ;
  972. getout:
  973.     pop    es
  974.     POP    BP
  975.     RET
  976. ifdef    Microsoft
  977. _E4XMIT    ENDP
  978. else
  979. E4XMIT    ENDP
  980. endif
  981.  
  982. ;
  983. ;
  984. ;*************************************************************************
  985. ;  ETUPDATE
  986. ;      update pointers and/or restart receiver when read routine has
  987. ;      already removed the current packet
  988. ;
  989. ;   usage:  etupdate();
  990. ;
  991. ifdef    Microsoft
  992. _E4ETUPDATE    PROC    FAR
  993. else
  994. E4ETUPDATE    PROC    FAR
  995. endif
  996.  
  997.     PUSH     ES
  998. ifdef    Microsoft
  999.     MOV    AX,word ptr [_BUFPT+2]    ; establish data segment to buffer
  1000. else
  1001.     MOV    AX,word ptr [BUFPT+2]    ; establish data segment to buffer
  1002. endif
  1003.     MOV    ES,AX        ; put that in es
  1004. ;
  1005. ifdef    Microsoft
  1006.     MOV    BX,_BUFREAD    ; where read pointer is now
  1007. else
  1008.     MOV    BX,BUFREAD    ; where read pointer is now
  1009. endif
  1010.     MOV    DX,ES:[BX]    ; get size of this packet
  1011.     INC    DX
  1012.     INC    DX        ; two more for length value
  1013.  
  1014.     ADD    BX,DX        ; increment bufread by size of packet
  1015.  
  1016. ifdef    Microsoft
  1017.     MOV    CX,_BUFEND    ; right before 2K safety area
  1018. else
  1019.     MOV    CX,BUFEND    ; right before 2K safety area
  1020. endif
  1021.     CMP    BX,CX        ; see if pointer is over limit
  1022.     JB    NOWRAPRD    ; we are not at wrap-around
  1023.  
  1024. ifdef    Microsoft    
  1025.     MOV    BX,_BUFORG    ; wrap to here
  1026. NOWRAPRD:
  1027.     MOV    _BUFREAD,BX    ; buffer pointer has been updated
  1028. else
  1029.     MOV    BX,BUFORG    ; wrap to here
  1030. NOWRAPRD:
  1031.     MOV    BUFREAD,BX    ; buffer pointer has been updated
  1032. endif
  1033.  
  1034. ;
  1035. ;  DECREMENT TOTAL BUFFER SIZE
  1036. ;
  1037.     CLI            ; keep interrupt handler from bothering dec
  1038. ifdef    Microsoft
  1039.     MOV    CX,_BUFBIG    ; size before removing packet
  1040.     SUB    CX,DX        ; remove size of current packet
  1041.     MOV    _BUFBIG,CX    ; put it back
  1042. else
  1043.     MOV    CX,BUFBIG    ; size before removing packet
  1044.     SUB    CX,DX        ; remove size of current packet
  1045.     MOV    BUFBIG,CX    ; put it back
  1046. endif
  1047.     STI
  1048. ;
  1049. ;  IF RECEIVER IS ON, THEN CHECKING BUFLIM IS UNNECESSARY.
  1050. ;
  1051.     MOV    AL,DEAF        ; is the receiver turned off?
  1052.     OR    AL,AL        ; 0 = reading, 1 = deaf
  1053.     JZ    ALIVE
  1054. ;
  1055. ;  CHECK FOR ROOM IN THE BUFFER, IF THERE IS, TURN ON RECEIVER
  1056. ;
  1057. ifdef    Microsoft
  1058.     MOV    AX,_BUFLIM    ; what is our limit?
  1059. else
  1060.     MOV    AX,BUFLIM    ; what is our limit?
  1061. endif
  1062.     CMP    CX,AX        ; compare to limit
  1063.     JA    ALIVE        ; not really alive, but can't turn on yet
  1064.  
  1065.     XOR    AL,AL
  1066.     MOV    DEAF,AL        ; reset flag
  1067.  
  1068.     INC    OFFS        ; keep count how many times this happened
  1069.  
  1070. ;
  1071. ;  turn receiver back on
  1072. ;
  1073.  
  1074. ALIVE:
  1075.     POP    ES
  1076.     RET    
  1077.  
  1078. ifdef    Microsoft
  1079. _E4ETUPDATE    ENDP
  1080. else
  1081. E4ETUPDATE    ENDP
  1082. endif
  1083.  
  1084. ifdef Microsoft
  1085. ;_TEXT    ends
  1086. else
  1087.     ENDPS
  1088. endif
  1089.     END
  1090.