
	TITLE	sleep

	.386p

	include	data.inc

_BSS	segment dword public use32 'BSS'
_BSS	ends

_DATA	segment dword public use32 'DATA'
	PUBLIC	_insleep
_insleep	db	0
_DATA	ends

DGROUP	group _BSS,_DATA

	extrn	ipinterpret_:near
	extrn	tcptick_:near
	extrn	send_pkt_:near
	extrn	_pkshared:word

_TEXT	segment	dword public use32 'CODE'
	ASSUME	cs:_TEXT, ds: DGROUP

	public	netsleep_
netsleep_ proc near
	push	eax
	cli
	mov	al,_insleep
	or	al,al
	jz	ins1
	sti
	pop	eax
	ret
ins1:
	inc	al
	mov	_insleep,al
	sti
	push	esi
	push	edi
	push	edx
	push	ecx
	push	ebx

	mov	gs,_pkshared+4

	cli
	movzx	eax,gs:innet
	or	eax,eax
	jnz	$A1

	movzx	esi,gs:mbprocess

	or	esi,esi
	jz	$A0

more:
	movzx	ebx,gs:[esi].next
	mov	gs:mbprocess,bx
	or	ebx,ebx
	jnz	short $A4
	mov	gs:mbnext,offset mbprocess
$A4:
	sti
	movzx	ebx,gs:[esi].len
	mov	dx,gs
	movzx	eax,gs:[esi].dptr
	push	gs
	call	ipinterpret_
	pop	gs

	; start of code to free buffer
	cli
	push	ds
	mov	ax,gs
	mov	ds,ax
	ASSUME	ds: nothing

	movzx	ebx,[esi].dptr	; bx = start of data
	movzx	edx,[esi].len
	add	edx,ebx			; dx = byte past end of buffer
	mov	edi,offset eb
$A3:
	movzx	ecx,[edi].count
	jecxz	short $Free_slot		; slot is not used
	movzx	eax,[edi].start_addr
	add	ecx,eax			; ecx points to end of buffer
	cmp	ecx,ebx
	je	short $Fix_count
	cmp	eax,edx
	je	short $Fix_both		; fix address and count
	ja	short $Insert			; move slot down
	add	edi,size ebuf		; point to next entry
	jmp	short $A3

$Free_slot:
	mov	[edi].start_addr,bx
	sub	edx,ebx
	mov	[edi].count,dx
	jmp	short $A9

$Fix_both:
	sub	ecx,ebx			; len
	mov	[edi].start_addr,bx
	mov	[edi].count,cx
	jmp	short $A9

$Insert:
	push	esi
	mov	esi,offset eb + (NEBUFS - 2) * size ebuf
	mov	ecx,esi
	sub	ecx,edi
	mov	edi,offset eb + (NEBUFS - 1) * size ebuf
	shr	ecx,2
	inc	ecx
	std
	rep	movsd
	cld
	pop	esi

	mov	[edi].start_addr,bx
	sub	edx,ebx
	mov	[edi].count,dx
	jmp short $A9

$Fix_count:
	mov	ecx,edx
	sub	edx,eax			; count = end - start
	mov	[edi].count,dx

					; check for continuous ebufs
	cmp	cx,[edi + size ebuf].start_addr
	jne	short $A9
	movzx	ecx,[edi + size ebuf].count
	jecxz	short $A9
	add	edx,ecx
	mov	[edi].count,dx		; add in next ebuf's count
	add	edi,size ebuf
$A81:
	mov	eax,[edi + size ebuf]
	stosd
	shr	eax,16
	jnz	short $A81
$A9:	
	movzx	ebx,ds:mbfree
	mov	[esi].next,bx
	mov	ds:mbfree,si

	movzx	esi,ds:mbprocess

	pop	ds
	ASSUME	ds:DGROUP

	or	esi,esi
	jnz	more			; process more packets
$A0:
	mov	al,gs:arpqueued
	or	al,al
	jz	short $A1
	inc	al			; make it 2
	mov	gs:arpqueued,al
	mov	eax,60
	push	gs
	call	send_pkt_
	pop	gs
	mov	gs:arpqueued,0
$A1:
	sti

;	movzx	eax,gs:mbprocess
;	or	eax,eax
;	jnz	short $A2		; don't call tcptick if more packets
;	call	tcptick_

;$A2:
	call	tcptick_
	xor	al,al
	mov	_insleep,al
	pop	ebx
	pop	ecx
	pop	edx
	pop	edi
	pop	esi
	pop	eax

	ret
netsleep_ endp

_TEXT	ends
	end
