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