Initialize Tizen 2.3
[external/libpcap.git] / msdos / pkt_rx0.asm
1 PAGE 60,132\r
2 NAME PKT_RX\r
3 \r
4 ifdef ??version        ; using TASM\r
5   masm\r
6   jumps\r
7 endif\r
8 \r
9 PUBLIC _pktDrop, _pktRxBuf, _pktTxBuf,    _pktTemp\r
10 PUBLIC _rxOutOfs, _rxInOfs, _PktReceiver, _pktRxEnd\r
11 \r
12 ;\r
13 ; these sizes MUST be equal to the sizes in PKTDRVR.H\r
14 ;\r
15 \r
16 RX_BUF_SIZE = 1500      ; max message size on Ethernet\r
17 TX_BUF_SIZE = 1500\r
18 \r
19 ifdef DOSX\r
20  .386\r
21   NUM_RX_BUF = 32       ; # of RX element buffers\r
22   _TEXT   SEGMENT PUBLIC DWORD USE16 'CODE'\r
23   _TEXT   ENDS\r
24   _DATA   SEGMENT PUBLIC DWORD USE16 'CODE'\r
25   _DATA   ENDS\r
26   D_SEG   EQU <_TEXT SEGMENT>\r
27   D_END   EQU <_TEXT ENDS>\r
28   ASSUME  CS:_TEXT,DS:_TEXT\r
29 else\r
30  .286\r
31   NUM_RX_BUF = 10\r
32   _TEXT   SEGMENT PUBLIC DWORD 'CODE'\r
33   _TEXT   ENDS\r
34   _DATA   SEGMENT PUBLIC DWORD 'DATA'\r
35   _DATA   ENDS\r
36   D_SEG   EQU <_DATA SEGMENT>\r
37   D_END   EQU <_DATA ENDS>\r
38   ASSUME  CS:_TEXT,DS:_DATA\r
39 endif\r
40 \r
41 ;-------------------------------------------\r
42 \r
43 D_SEG\r
44 \r
45 RX_ELEMENT     STRUC\r
46    firstCount  dw  0                          ; # of bytes on 1st call\r
47    secondCount dw  0                          ; # of bytes on 2nd call\r
48    handle      dw  0                          ; handle for upcall\r
49    destinAdr   db  6           dup (0)        ; packet destination address\r
50    sourceAdr   db  6           dup (0)        ; packet source address\r
51    protocol    dw  0                          ; packet protocol number\r
52    rxBuffer    db  RX_BUF_SIZE dup (0)        ; RX buffer\r
53 ENDS\r
54                align 4\r
55 _rxOutOfs      dw  offset _pktRxBuf           ; ring buffer offsets\r
56 _rxInOfs       dw  offset _pktRxBuf           ; into _pktRxBuf\r
57 _pktDrop       dw  0,0                        ; packet drop counter\r
58 _pktTemp       db  20                dup (0)  ; temp work area\r
59 _pktTxBuf      db  (TX_BUF_SIZE+14)  dup (0)  ; TX buffer\r
60 _pktRxBuf      RX_ELEMENT NUM_RX_BUF dup (<>) ; RX structures\r
61  LAST_OFS      = offset $\r
62 \r
63  screenSeg     dw  0B800h\r
64  newInOffset   dw  0\r
65 \r
66  fanChars      db  '-\|/'\r
67  fanIndex      dw  0\r
68 \r
69 D_END\r
70 \r
71 _TEXT SEGMENT\r
72 \r
73 \r
74 SHOW_RX  MACRO\r
75          push es\r
76          push bx\r
77          mov bx, screenSeg\r
78          mov es, bx                    ;; r-mode segment of colour screen\r
79          mov di, 158                   ;; upper right corner - 1\r
80          mov bx, fanIndex\r
81          mov al, fanChars[bx]          ;; get write char\r
82          mov ah, 15                    ;;  and white colour\r
83          stosw                         ;; write to screen at ES:EDI\r
84          inc fanIndex                  ;; update next index\r
85          and fanIndex, 3\r
86          pop bx\r
87          pop es\r
88 ENDM\r
89 \r
90 ;------------------------------------------------------------------------\r
91 ;\r
92 ; This macro return ES:DI to tail of Rx queue\r
93 \r
94 ENQUEUE  MACRO\r
95          LOCAL @noWrap\r
96          mov ax, _rxInOfs              ;; DI = current in-offset\r
97          add ax, SIZE RX_ELEMENT       ;; point to next _pktRxBuf buffer\r
98          cmp ax, LAST_OFS              ;; pointing past last ?\r
99          jb  @noWrap                   ;; no - jump\r
100          lea ax, _pktRxBuf             ;; yes, point to 1st buffer\r
101          align 4\r
102 @noWrap: cmp ax, _rxOutOfs             ;; in-ofs = out-ofs ?\r
103          je  @dump                     ;; yes, queue is full\r
104          mov di, _rxInOfs              ;; ES:DI -> buffer at queue input\r
105          mov newInOffset, ax           ;; remember new input offset\r
106 \r
107    ;; NOTE. rxInOfs is updated after the packet has been copied\r
108    ;; to ES:DI (= DS:SI on 2nd call) by the packet driver\r
109 \r
110 ENDM\r
111 \r
112 ;------------------------------------------------------------------------\r
113 ;\r
114 ; This routine gets called by the packet driver twice:\r
115 ;   1st time (AX=0) it requests an address where to put the packet\r
116 ;\r
117 ;   2nd time (AX=1) the packet has been copied to this location (DS:SI)\r
118 ;   BX has client handle (stored in RX_ELEMENT.handle).\r
119 ;   CX has # of bytes in packet on both call. They should be equal.\r
120 ;\r
121 ; A test for equality is done by putting CX in _pktRxBuf [n].firstCount\r
122 ; and _pktRxBuf[n].secondCount, and CL on first call in\r
123 ; _pktRxBuf[n].rxBuffer[CX]. These values are checked in "PktReceive"\r
124 ; (PKTDRVR.C)\r
125 ;\r
126 ;---------------------------------------------------------------------\r
127 \r
128 _PktReceiver:\r
129          pushf\r
130          cli                         ; no distraction wanted !\r
131          push ds\r
132          push bx\r
133 ifdef DOSX\r
134          mov bx, cs\r
135 else\r
136          mov bx, SEG _DATA\r
137 endif\r
138          mov ds, bx\r
139          mov es, bx                  ; ES = DS = CS or seg _DATA\r
140          pop bx                      ; restore handle\r
141 \r
142          cmp ax, 0                   ; first call? (AX=0)\r
143          jne @post                   ; AX=1: second call, do post process\r
144 \r
145 ifdef DEBUG\r
146          SHOW_RX                     ; show that a packet is received\r
147 endif\r
148          cmp cx, RX_BUF_SIZE+14      ; size OK ?\r
149          ja  @skip                   ; no, packet to large for us\r
150 \r
151          ENQUEUE                     ; ES:DI -> _pktRxBuf[n]\r
152 \r
153          mov [di].firstCount, cx     ; remember the first count.\r
154          mov [di].handle, bx         ; remember the handle.\r
155          add di, 6                   ; ES:DI -> _pktRxBuf[n].destinAdr\r
156          pop ds\r
157          popf\r
158          retf                        ; far return to driver with ES:DI\r
159 \r
160          align 4\r
161 @dump:   inc _pktDrop[0]             ; discard the packet on 1st call\r
162          adc _pktDrop[2], 0          ; increment packets lost\r
163 \r
164 @skip:   xor di, di                  ; return ES:DI = NIL pointer\r
165          xor ax, ax\r
166          mov es, ax\r
167          pop ds\r
168          popf\r
169          retf\r
170 \r
171          align 4\r
172 @post:   or si, si                   ; DS:SI->_pktRxBuf[n][n].destinAdr\r
173          jz @discard                 ; make sure we don't use NULL-pointer\r
174 \r
175          sub si, 6                   ; DS:SI -> _pktRxBuf[n].destinAdr\r
176        ;\r
177        ; push si\r
178        ; push [si].firstCount\r
179        ; call bpf_filter_match       ; run the filter here some day?\r
180        ; add sp, 4\r
181        ; cmp ax, 0\r
182        ; je  @discard\r
183 \r
184          mov [si].secondCount, cx\r
185          mov ax, newInOffset\r
186          mov _rxInOfs, ax            ; update _pktRxBuf input offset\r
187 \r
188          align 4\r
189 @discard:pop ds\r
190          popf\r
191          retf\r
192 \r
193 _pktRxEnd  db 0                      ; marker for end of r-mode code/data\r
194 \r
195 _TEXT ENDS\r
196 \r
197 END\r