Home | History | Annotate | Download | only in msdos
      1 PAGE 60,132
      2 NAME PKT_RX
      3 
      4 ifdef ??version        ; using TASM
      5   masm
      6   jumps
      7 endif
      8 
      9 PUBLIC _pktDrop, _pktRxBuf, _pktTxBuf,    _pktTemp
     10 PUBLIC _rxOutOfs, _rxInOfs, _PktReceiver, _pktRxEnd
     11 
     12 ;
     13 ; these sizes MUST be equal to the sizes in PKTDRVR.H
     14 ;
     15 
     16 RX_BUF_SIZE = 1500      ; max message size on Ethernet
     17 TX_BUF_SIZE = 1500
     18 
     19 ifdef DOSX
     20  .386
     21   NUM_RX_BUF = 32       ; # of RX element buffers
     22   _TEXT   SEGMENT PUBLIC DWORD USE16 'CODE'
     23   _TEXT   ENDS
     24   _DATA   SEGMENT PUBLIC DWORD USE16 'CODE'
     25   _DATA   ENDS
     26   D_SEG   EQU <_TEXT SEGMENT>
     27   D_END   EQU <_TEXT ENDS>
     28   ASSUME  CS:_TEXT,DS:_TEXT
     29 else
     30  .286
     31   NUM_RX_BUF = 10
     32   _TEXT   SEGMENT PUBLIC DWORD 'CODE'
     33   _TEXT   ENDS
     34   _DATA   SEGMENT PUBLIC DWORD 'DATA'
     35   _DATA   ENDS
     36   D_SEG   EQU <_DATA SEGMENT>
     37   D_END   EQU <_DATA ENDS>
     38   ASSUME  CS:_TEXT,DS:_DATA
     39 endif
     40 
     41 ;-------------------------------------------
     42 
     43 D_SEG
     44 
     45 RX_ELEMENT     STRUC
     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
     53 ENDS
     54                align 4
     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
     61  LAST_OFS      = offset $
     62 
     63  screenSeg     dw  0B800h
     64  newInOffset   dw  0
     65 
     66  fanChars      db  '-\|/'
     67  fanIndex      dw  0
     68 
     69 D_END
     70 
     71 _TEXT SEGMENT
     72 
     73 
     74 SHOW_RX  MACRO
     75          push es
     76          push bx
     77          mov bx, screenSeg
     78          mov es, bx                    ;; r-mode segment of colour screen
     79          mov di, 158                   ;; upper right corner - 1
     80          mov bx, fanIndex
     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
     85          and fanIndex, 3
     86          pop bx
     87          pop es
     88 ENDM
     89 
     90 ;------------------------------------------------------------------------
     91 ;
     92 ; This macro return ES:DI to tail of Rx queue
     93 
     94 ENQUEUE  MACRO
     95          LOCAL @noWrap
     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
    101          align 4
    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
    106 
    107    ;; NOTE. rxInOfs is updated after the packet has been copied
    108    ;; to ES:DI (= DS:SI on 2nd call) by the packet driver
    109 
    110 ENDM
    111 
    112 ;------------------------------------------------------------------------
    113 ;
    114 ; This routine gets called by the packet driver twice:
    115 ;   1st time (AX=0) it requests an address where to put the packet
    116 ;
    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.
    120 ;
    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"
    124 ; (PKTDRVR.C)
    125 ;
    126 ;---------------------------------------------------------------------
    127 
    128 _PktReceiver:
    129          pushf
    130          cli                         ; no distraction wanted !
    131          push ds
    132          push bx
    133 ifdef DOSX
    134          mov bx, cs
    135 else
    136          mov bx, SEG _DATA
    137 endif
    138          mov ds, bx
    139          mov es, bx                  ; ES = DS = CS or seg _DATA
    140          pop bx                      ; restore handle
    141 
    142          cmp ax, 0                   ; first call? (AX=0)
    143          jne @post                   ; AX=1: second call, do post process
    144 
    145 ifdef DEBUG
    146          SHOW_RX                     ; show that a packet is received
    147 endif
    148          cmp cx, RX_BUF_SIZE+14      ; size OK ?
    149          ja  @skip                   ; no, packet to large for us
    150 
    151          ENQUEUE                     ; ES:DI -> _pktRxBuf[n]
    152 
    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
    156          pop ds
    157          popf
    158          retf                        ; far return to driver with ES:DI
    159 
    160          align 4
    161 @dump:   inc _pktDrop[0]             ; discard the packet on 1st call
    162          adc _pktDrop[2], 0          ; increment packets lost
    163 
    164 @skip:   xor di, di                  ; return ES:DI = NIL pointer
    165          xor ax, ax
    166          mov es, ax
    167          pop ds
    168          popf
    169          retf
    170 
    171          align 4
    172 @post:   or si, si                   ; DS:SI->_pktRxBuf[n][n].destinAdr
    173          jz @discard                 ; make sure we don't use NULL-pointer
    174 
    175          sub si, 6                   ; DS:SI -> _pktRxBuf[n].destinAdr
    176        ;
    177        ; push si
    178        ; push [si].firstCount
    179        ; call bpf_filter_match       ; run the filter here some day?
    180        ; add sp, 4
    181        ; cmp ax, 0
    182        ; je  @discard
    183 
    184          mov [si].secondCount, cx
    185          mov ax, newInOffset
    186          mov _rxInOfs, ax            ; update _pktRxBuf input offset
    187 
    188          align 4
    189 @discard:pop ds
    190          popf
    191          retf
    192 
    193 _pktRxEnd  db 0                      ; marker for end of r-mode code/data
    194 
    195 _TEXT ENDS
    196 
    197 END
    198