pkt_rx0.asm 6.0 KB

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