Blame msdos/pkt_rx1.s

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