; Micro-X -- an X server for DOS
; Copyright (C) 1993 StarNet Communications Corp.

; This program is free software; you can redistribute it and/or
; modify it under the terms of the GNU General Public License
; as published by the Free Software Foundation; either version 2
; of the License, or (at your option) any later version.

; This program is distributed in the hope that it will be useful,
; but WITHOUT ANY WARRANTY; without even the implied warranty of
; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
; GNU General Public License for more details.

; You should have received a copy of the GNU General Public License
; along with this program; if not, write to the Free Software
; Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.

; StarNet Communications Corp.
; 550 Lakeside Dr. #3
; Sunnyvale CA 94086 US
; http://www.starnet.com
; x-dos@starnet.com

	TITLE	EVENT
	NAME	EVENT

	.286p

	INCLUDE	struct.inc

X	equ	4		; for near calls
;X	equ	6		; for far calls

_DATA	SEGMENT PARA PUBLIC 'DATA'
_DATA	ENDS
_BSS	SEGMENT PARA PUBLIC 'BSS'
_BSS	ends
_TEXT	SEGMENT  para PUBLIC 'CODE'
_TEXT	ENDS

DGROUP	GROUP	_DATA,_BSS

	ASSUME	cs:_TEXT, ds:DGROUP, es:nothing, ss:nothing

	extrn	@ipinterpret:near, @arpinterpret:near
	extrn	_tcptick:near
	extrn	_mbfree:word
	extrn	_mbprocess:word
	extrn	_mbnext:word
	extrn	_eb:byte
	extrn	_slip_mode:byte
	extrn	@pkxmit:near
	extrn	_innet:byte
	extrn	_iptype:word, _arptype:word, _rarptype:word

_TEXT	segment
	ASSUME	cs:_TEXT, ds:DGROUP

	public	_netsleep
_netsleep proc NEAR
	test	_innet,0ffh
	jz	$A1
	mov	ah,2
	mov	dl,'!'
	int	21h
	ret
$A1:
	push	si
	push	di

	mov	si,_mbprocess
	or	si,si
	jnz	more
	jmp	$A2
more:
	cli
	mov	bx,[si].next
	mov	_mbprocess,bx
	or	bx,bx
	jnz	$A4
	mov	_mbnext,offset DGROUP:_mbprocess
$A4:
	sti
	mov	bx,[si].dptr
	; in slip mode, ignore packet type since it is always ip
	test	_slip_mode,0ffh
	jnz	ip
	; get packet type
	mov	ax,12[bx]
	cmp	ax,_iptype
	je	ip
	cmp	ax,_arptype
	je	arp
	cmp	ax,_rarptype
	jne	$A11
arp:
	mov	ax,[si].len		; do arp
	call	@arpinterpret
	jmp	short $A11
ip:
	mov	ax,[si].len
	call	@ipinterpret
$A11:
	mov	ax,ds
	mov	es,ax
	ASSUME	es:DGROUP

	mov	bx,[si].dptr		; bx = start of data
	mov	dx,[si].len
	add	dx,bx			; dx = byte past end of buffer
	mov	di,offset DGROUP:_eb
	cli
$A3:
	mov	cx,[di].count
	jcxz	$A6			; slot is not used
	mov	ax,[di].start_addr
	cmp	ax,dx
	je	$A6			; fix address and count
	ja	$A5			; move slot down
	add	ax,cx
	cmp	ax,bx
	je	$A7			; fix count only
	add	di,size ebuf		; point to next entry
	cmp	di,offset DGROUP:_eb + 32 * size ebuf
	jb	$A3			; are we done?
$AXX:
	sub	bx,bx			; joe code!!!
	mov	ax,0e13h
	int	10h
	jmp short $A9
$A5:
	push	di
	push	si
	mov	si,di			; si = current ebuf
$A30:
	add	di,size ebuf		; point to next ebuf
	mov	cx,[di].count		; get count
	jcxz	$A31
	cmp	di,offset DGROUP:_eb + 31 * size ebuf
					; are we at the last ebuf?
	jb	$A30
	jmp short $AXX			; joe code!!
$A31:
	mov	cx,di			; count = new ebuf - original ebuf
	sub	cx,si
	shr	cx,1			; make it words
	dec	di
	dec	di
	mov	si,di			; point to end of real data
	add	di,size ebuf
	std
	rep	movsw
	cld

	pop	si
	pop	di
	mov	[di].start_addr,bx
	mov	ax,[si].len
	mov	[di].count,ax
	jmp short $A9
$A6:
	mov	[di].start_addr,bx
	add	dx,cx
	mov	ax,dx
	sub	dx,bx
	mov	[di].count,dx
	cmp	di,offset DGROUP:_eb
	jbe	$A9
	sub	di,size ebuf
	jmp short $A8
$A7:
	mov	ax,dx
	add	dx,cx			; add in original ebuf count
	sub	dx,bx			; restore the count
	mov	[di].count,dx
$A8:					; check for continuous ebufs
	cmp	ax,[di + size ebuf].start_addr
	jne	$A9
	add	dx,[di + size ebuf].count
	mov	[di].count,dx		; add in next ebuf's count
	add	di,size ebuf
	cmp	di,offset DGROUP:_eb + 31 * size ebuf
	jae	$A9
	push	si
	mov	si,di
	add	si,size ebuf
$A81:
	movsw				; copy in start_addr
	lodsw				; get count
	stosw				; save it
	or 	ax,ax
	jnz	$A81
	pop	si
$A9:	
	mov	bx,_mbfree
	mov	[si].next,bx
	mov	_mbfree,si
	sti
	mov	si,_mbprocess
	or	si,si
	jz	$A2
	jmp	more
$A2:
	call	_tcptick
	pop	di
	pop	si
	ret
_netsleep endp

_TEXT	ends
	end
