4 ifdef
??version
; using TASM
9 PUBLIC _pktDrop
, _pktRxBuf
, _pktTxBuf
, _pktTemp
10 PUBLIC _rxOutOfs
, _rxInOfs
, _PktReceiver
, _pktRxEnd
13 ; these sizes MUST be equal to the sizes in PKTDRVR.H
16 RX_BUF_SIZE
= 1500 ; max message size on Ethernet
21 NUM_RX_BUF
= 32 ; # of RX element buffers
22 _TEXT
SEGMENT PUBLIC DWORD USE16
'CODE'
24 _DATA
SEGMENT PUBLIC DWORD USE16
'CODE'
26 D_SEG
EQU <_TEXT
SEGMENT>
27 D_END
EQU <_TEXT
ENDS>
28 ASSUME CS:_TEXT
,DS:_TEXT
32 _TEXT
SEGMENT PUBLIC DWORD 'CODE'
34 _DATA
SEGMENT PUBLIC DWORD 'DATA'
36 D_SEG
EQU <_DATA
SEGMENT>
37 D_END
EQU <_DATA
ENDS>
38 ASSUME CS:_TEXT
,DS:_DATA
41 ;-------------------------------------------
46 firstCount
dw 0 ; # of bytes on 1st call
47 secondCount
dw 0 ; # of bytes on 2nd call
48 handle
dw 0 ; handle for upcall
49 destinAdr
db 6 dup
(0) ; packet destination address
50 sourceAdr
db 6 dup
(0) ; packet source address
51 protocol
dw 0 ; packet protocol number
52 rxBuffer
db RX_BUF_SIZE dup
(0) ; RX buffer
55 _rxOutOfs
dw offset _pktRxBuf
; ring buffer offsets
56 _rxInOfs
dw offset _pktRxBuf
; into _pktRxBuf
57 _pktDrop
dw 0,0 ; packet drop counter
58 _pktTemp
db 20 dup
(0) ; temp work area
59 _pktTxBuf
db (TX_BUF_SIZE
+14) dup
(0) ; TX buffer
60 _pktRxBuf RX_ELEMENT NUM_RX_BUF dup
(<>) ; RX structures
78 mov es, bx ;; r-mode segment of colour screen
79 mov di, 158 ;; upper right corner - 1
81 mov al, fanChars
[bx] ;; get write char
82 mov ah, 15 ;; and white colour
83 stosw ;; write to screen at ES:EDI
84 inc fanIndex
;; update next index
90 ;------------------------------------------------------------------------
92 ; This macro return ES:DI to tail of Rx queue
96 mov ax, _rxInOfs
;; DI = current in-offset
97 add ax, SIZE RX_ELEMENT
;; point to next _pktRxBuf buffer
98 cmp ax, LAST_OFS
;; pointing past last ?
99 jb @noWrap ;; no - jump
100 lea ax, _pktRxBuf
;; yes, point to 1st buffer
102 @noWrap: cmp ax, _rxOutOfs
;; in-ofs = out-ofs ?
103 je @dump ;; yes, queue is full
104 mov di, _rxInOfs
;; ES:DI -> buffer at queue input
105 mov newInOffset
, ax ;; remember new input offset
107 ;; NOTE. rxInOfs is updated after the packet has been copied
108 ;; to ES:DI (= DS:SI on 2nd call) by the packet driver
112 ;------------------------------------------------------------------------
114 ; This routine gets called by the packet driver twice:
115 ; 1st time (AX=0) it requests an address where to put the packet
117 ; 2nd time (AX=1) the packet has been copied to this location (DS:SI)
118 ; BX has client handle (stored in RX_ELEMENT.handle).
119 ; CX has # of bytes in packet on both call. They should be equal.
121 ; A test for equality is done by putting CX in _pktRxBuf [n].firstCount
122 ; and _pktRxBuf[n].secondCount, and CL on first call in
123 ; _pktRxBuf[n].rxBuffer[CX]. These values are checked in "PktReceive"
126 ;---------------------------------------------------------------------
130 cli ; no distraction wanted !
139 mov es, bx ; ES = DS = CS or seg _DATA
140 pop bx ; restore handle
142 cmp ax, 0 ; first call? (AX=0)
143 jne @post ; AX=1: second call, do post process
146 SHOW_RX
; show that a packet is received
148 cmp cx, RX_BUF_SIZE
+14 ; size OK ?
149 ja @skip ; no, packet to large for us
151 ENQUEUE
; ES:DI -> _pktRxBuf[n]
153 mov [di].firstCount
, cx ; remember the first count.
154 mov [di].handle
, bx ; remember the handle.
155 add di, 6 ; ES:DI -> _pktRxBuf[n].destinAdr
158 retf ; far return to driver with ES:DI
161 @dump: inc _pktDrop
[0] ; discard the packet on 1st call
162 adc _pktDrop
[2], 0 ; increment packets lost
164 @skip: xor di, di ; return ES:DI = NIL pointer
172 @post: or si, si ; DS:SI->_pktRxBuf[n][n].destinAdr
173 jz @discard ; make sure we don't use NULL-pointer
175 sub si, 6 ; DS:SI -> _pktRxBuf[n].destinAdr
178 ; push [si].firstCount
179 ; call bpf_filter_match ; run the filter here some day?
184 mov [si].secondCount
, cx
186 mov _rxInOfs
, ax ; update _pktRxBuf input offset
193 _pktRxEnd
db 0 ; marker for end of r-mode code/data