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

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