; | |
; This file requires NASM 0.97+ to assemble | |
; | |
; Currently used only for djgpp + DOS4GW targets | |
; | |
; these sizes MUST be equal to the sizes in PKTDRVR.H | |
; | |
%define ETH_MTU 1500 ; max data size on Ethernet | |
%define ETH_MIN 60 ; min/max total frame size | |
%define ETH_MAX (ETH_MTU+2*6+2) | |
%define NUM_RX_BUF 32 ; # of RX element buffers | |
%define RX_SIZE (ETH_MAX+6) ; sizeof(RX_ELEMENT) = 1514+6 | |
%idefine offset | |
struc RX_ELEMENT | |
.firstCount resw 1 ; # of bytes on 1st call | |
.secondCount resw 1 ; # of bytes on 2nd call | |
.handle resw 1 ; handle for upcall | |
; .timeStamp resw 4 ; 64-bit RDTSC value | |
.destinAdr resb 6 ; packet destination address | |
.sourceAdr resb 6 ; packet source address | |
.protocol resw 1 ; packet protocol number | |
.rxBuffer resb ETH_MTU ; RX buffer | |
endstruc | |
;------------------------------------------- | |
[org 0] ; assemble to .bin file | |
_rxOutOfs dw offset _pktRxBuf ; ring buffer offsets | |
_rxInOfs dw offset _pktRxBuf ; into _pktRxBuf | |
_pktDrop dw 0,0 ; packet drop counter | |
_pktTemp resb 20 ; temp work area | |
_pktTxBuf resb (ETH_MAX) ; TX buffer | |
_pktRxBuf resb (RX_SIZE*NUM_RX_BUF) ; RX structures | |
LAST_OFS equ $ | |
screenSeg dw 0B800h | |
newInOffset dw 0 | |
fanChars db '-\|/' | |
fanIndex dw 0 | |
%macro SHOW_RX 0 | |
push es | |
push bx | |
mov bx, [screenSeg] | |
mov es, bx ;; r-mode segment of colour screen | |
mov di, 158 ;; upper right corner - 1 | |
mov bx, [fanIndex] | |
mov al, [fanChars+bx] ;; get write char | |
mov ah, 15 ;; and white colour | |
cld ;; Needed? | |
stosw ;; write to screen at ES:EDI | |
inc word [fanIndex] ;; update next index | |
and word [fanIndex], 3 | |
pop bx | |
pop es | |
%endmacro | |
;PutTimeStamp | |
; rdtsc | |
; mov [si].timeStamp, eax | |
; mov [si+4].timeStamp, edx | |
; ret | |
;------------------------------------------------------------------------ | |
; | |
; This routine gets called by the packet driver twice: | |
; 1st time (AX=0) it requests an address where to put the packet | |
; | |
; 2nd time (AX=1) the packet has been copied to this location (DS:SI) | |
; BX has client handle (stored in RX_ELEMENT.handle). | |
; CX has # of bytes in packet on both call. They should be equal. | |
; A test for equality is done by putting CX in _pktRxBuf [n].firstCount | |
; and _pktRxBuf[n].secondCount, and CL on first call in | |
; _pktRxBuf[n].rxBuffer[CX]. These values are checked in "PktReceive" | |
; (PKTDRVR.C) | |
; | |
;--------------------------------------------------------------------- | |
_PktReceiver: | |
pushf | |
cli ; no distraction wanted ! | |
push ds | |
push bx | |
mov bx, cs | |
mov ds, bx | |
mov es, bx ; ES = DS = CS or seg _DATA | |
pop bx ; restore handle | |
cmp ax, 0 ; first call? (AX=0) | |
jne @post ; AX=1: second call, do post process | |
%ifdef DEBUG | |
SHOW_RX ; show that a packet is received | |
%endif | |
cmp cx, ETH_MAX ; size OK ? | |
ja @skip ; no, too big | |
mov ax, [_rxInOfs] | |
add ax, RX_SIZE | |
cmp ax, LAST_OFS | |
jb @noWrap | |
mov ax, offset _pktRxBuf | |
@noWrap: | |
cmp ax, [_rxOutOfs] | |
je @dump | |
mov di, [_rxInOfs] ; ES:DI -> _pktRxBuf[n] | |
mov [newInOffset], ax | |
mov [di], cx ; remember firstCount. | |
mov [di+4], bx ; remember handle. | |
add di, 6 ; ES:DI -> _pktRxBuf[n].destinAdr | |
pop ds | |
popf | |
retf ; far return to driver with ES:DI | |
@dump: add word [_pktDrop+0], 1 ; discard the packet on 1st call | |
adc word [_pktDrop+2], 0 ; increment packets lost | |
@skip: xor di, di ; return ES:DI = NIL pointer | |
xor ax, ax | |
mov es, ax | |
pop ds | |
popf | |
retf | |
@post: or si, si ; DS:SI->_pktRxBuf[n][n].destinAdr | |
jz @discard ; make sure we don't use NULL-pointer | |
; | |
; push si | |
; call bpf_filter_match ; run the filter here some day | |
; pop si | |
; cmp ax, 0 | |
; je @discard | |
mov [si-6+2], cx ; store _pktRxBuf[n].secondCount | |
mov ax, [newInOffset] | |
mov [_rxInOfs], ax ; update _pktRxBuf input offset | |
; call PutTimeStamp | |
@discard: | |
pop ds | |
popf | |
retf | |
_pktRxEnd db 0 ; marker for end of r-mode code/data | |
END | |