	name	pkglue
	include	dos.mac
	.286p

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

ebuf	STRUC
start_addr	dw	?
count		dw	?
ebuf	ENDS

mbuf	STRUC
dp	dw	?
next	dw	?
len	dw	?
mbuf	ENDS

packet_info	STRUC
version	dw	?
class	dw	?
pktype	dw	?
ifnum	dw	?
pkname	dd	?
extend	dw	?
packet_info	ENDS

	extrn	_eb:byte
	extrn	_arpbuffer:byte
	extrn	_mbfree:word
	extrn	_mbnext:word

	public	innet
LIBTCP_DATA	segment
innet	dw	0
LIBTCP_DATA	ends

LIBTCP_TEXT	segment

	ASSUME	cs: nothing, ds: nothing
	even
return_err proc far
	mov	dh,11		; bad command error
	push	bp
	mov	bp,sp
	or	word ptr [bp+6],1	; point to PSW, and set carry flag
	pop	bp
	iret
return_err endp

	ASSUME	cs :LIBTCP_TEXT, ds: nothing, es: nothing
	even
do_int	proc near
	pushf
	cli
	db	9ah		; call far ptr
packet_vector	dd	return_err
	ret
do_int	endp

	ASSUME	cs: LIBTCP_TEXT, ds: LIBTCP_DATA, es: nothing

	extrn	_arpinterpret:near
	public	_arp_receiver
	even
_arp_receiver	proc	far
	push	ds
	push	bx

	mov	bx,LIBTCP_DATA_GROUP
	mov	ds,bx
	ASSUME	ds: LIBTCP_DATA_GROUP

	or	ax,ax
	jz	$A0

	cld
	push	es
	push	dx
	push	cx
	call	_arpinterpret
	pop	cx
	pop	dx
	pop	es
	jmp short $A99
$A0:
	cmp	cx,96		; arp packet must be <= 96 bytes
	jbe	$A1
	mov	di,ax
	mov	es,ax
	jmp short $A99
$A1:
	mov	di,offset _arpbuffer
	mov	es,bx
$A99:
	pop	bx
	pop	ds
	ASSUME	ds: nothing
	ret
_arp_receiver	endp

        public	_pkt_receiver
	even
_pkt_receiver   proc    far
	push	ds
	push	bx

	mov	bx,LIBTCP_DATA_GROUP
	mov	ds,bx
	ASSUME	ds: LIBTCP_DATA_GROUP

	or	ax,ax
	jz	$B0

	mov	innet,0
	jmp	$B99
$B23:
	cli
	mov	bx,_mbfree		; restore mbuf onto free list
	mov	[di].next,bx
	mov	_mbfree,di
	sti
$B1:
	sub	ax,ax			; drop packet
	mov	innet,ax
	mov	di,ax
	mov	es,ax
	jmp	$B99
$B0:
	mov	es,bx
	ASSUME	es: LIBTCP_DATA_GROUP

	cld
	mov	innet,1
	mov	di,_mbfree
	or	di,di
	jz	$B1			; drop packet
	cli
	mov	bx,[di].next
	mov	_mbfree,bx
	mov	[di].next,ax		; on entry ax = 0
	sti

	mov	ax,cx			; ax = length of packet in bytes
	add	ax,007fh
	and	ax,0ff80h
	mov	si,offset _eb		; find a free buffer to put data into
$B5:
	mov	cx,[si].count
	jcxz	$B23			; display dropped packet
	sub	cx,ax
	jge	$B4			; if cx >= ax then branch
	add	si,size ebuf
	cmp	si,offset _eb + 32 * size ebuf
					; NEBUFS * sizeof(struct ebuf)
	jb	$B5
	jmp short $B23			; drop packet, no non-fragged storage
$B4:
	mov	[si].count,cx
	mov	dx,[si].start_addr
	mov	[di].dp,dx
	mov	[di].len,ax
	jcxz	$B80
	add	ax,dx
	mov	[si].start_addr,ax
$B80:
					; put in mbprocess queue
	mov	bx,_mbnext		; *mbnext = di
	mov	[bx],di
	add	di,offset next		; di -> &[di].next
	mov	_mbnext,di		; mbnext = &[di].next
	or	cx,cx
	jnz	$B97

	cmp	si,offset _eb + 31 * size ebuf
	jae	$B97
	mov	di,si
	add	si,size ebuf		; si -> next entry
	; figure out how many structures to copy
	mov	cx,offset _eb + 32 * size ebuf
	sub	cx,si
	shr	cx,1			; convert to words
	rep	movsw			;
	mov	[di].count,cx		; 0 last count
$B97:
	mov	di,dx			; set up buffer for packet
$B99:
	pop	bx
	pop	ds
	ASSUME	ds: nothing, es: nothing
        ret
_pkt_receiver endp

	public	_patch_vec
	even
_patch_vec proc near
	push	bp
	mov	bp,sp
	ASSUME	ds: LIBTCP_DATA_GROUP
	mov	ax,[bp+X]
	mov	word ptr cs:packet_vector,ax
	mov	ax,[bp+X+2]
	mov	word ptr cs:packet_vector+2,ax
	ASSUME	ds: nothing
	pop	bp
	ret
_patch_vec endp

	public	_driver_info
	even
_driver_info proc near
	push	bp
	mov	bp,sp
	push	ds
	push	si
	push	di
	ASSUME	ds: LIBTCP_DATA_GROUP

	mov	ax,01ffh
	sub	bx,bx
	call	do_int
	ASSUME	ds: nothing
	mov	ah,0
	jc	$C0
	cmp	al,0ffh
	jne	$C1
$C0:
	sub	ax,ax
	not	ax
	jmp short $C99
$C1:
	les	di,[bp+X]
	ASSUME	es: nothing
	mov	es:[di].version,bx
	mov	es:[di].pktype,dx
	cmp	al,2
	je	$C2
	mov	al,1
$C2:
	mov	es:[di].extend,ax
	mov	al,ch
	mov	es:[di].class,ax
	mov	al,cl
	mov	es:[di].ifnum,ax
	mov	word ptr es:[di].pkname,si
	mov	word ptr es:[di].pkname+2,ds
	sub	ax,ax
$C99:
	pop	di
	pop	si
	pop	ds
	ASSUME	ds: LIBTCP_DATA_GROUP
	pop	bp
	ret
_driver_info endp

	public	_access_type
	even
_access_type proc near
	push	bp
	mov	bp,sp
	push	ds
	push	si
	push	di

	mov	ax,[bp+X]
	mov	bx,[bp+X+2]
	mov	dl,[bp+X+4]
	lds	si,[bp+X+6]
	ASSUME	ds: nothing
	mov	cx,[bp+X+10]
	les	di,[bp+X+12]
	mov	ah,2
	call	do_int
	jnc	$D99
	mov	ah,0
	mov	al,dh
	neg	ax
$D99:
	pop	di
	pop	si
	pop	ds
	ASSUME	ds: LIBTCP_DATA_GROUP
	pop	bp
	ret
_access_type endp

	public	_release_type
	even
_release_type proc near
	push	bp
	mov	bp,sp

	mov	bx,[bp+X]
	mov	ah,3
	call	do_int
	mov	ax,0
	jnc	$E99
	mov	al,dh
	neg	ax
$E99:
	pop	bp
	ret
_release_type endp

	public	_send_pkt
	even
_send_pkt proc near
	push	bp
	mov	bp,sp
	push	ds
	push	si

	lds	si,[bp+X]
	ASSUME	ds: nothing
	mov	cx,[bp+X+4]
	mov	ah,4
	call	do_int
	mov	ax,0
	jnc	$F99
	mov	al,dh
	neg	ax
$F99:
	pop	si
	pop	ds
	ASSUME	ds: LIBTCP_DATA_GROUP
	pop	bp
	ret
_send_pkt endp

	public	_terminate
	even
_terminate proc near
	ret
_terminate endp

	public	_get_address
	even
_get_address proc near
	push	bp
	mov	bp,sp
	push	di

	mov	bx,[bp+X]
	les	di,[bp+X+2]
	ASSUME	ds: LIBTCP_DATA_GROUP, es: nothing
	mov	cx,[bp+X+6]
	mov	ah,6
	call	do_int
	mov	ax,cx
	jnc	$I99
	mov	al,dh
	neg	al
	cbw
$I99:
	pop	di
	ASSUME	ds: LIBTCP_DATA_GROUP
	pop	bp
	ret
_get_address endp

	public	_reset_interface
	even
_reset_interface proc near
	ret
_reset_interface endp

	public	_set_rcv_mode
	even
_set_rcv_mode proc near
	push	bp
	mov	bp,sp
	ASSUME	ds: LIBTCP_DATA_GROUP

	mov	ah,20h
	mov	bx,[bp+X]
	mov	cx,[bp+X+2]
	call	do_int
	mov	ax,0
	jnc	$J99
	mov	al,dh
	neg	ax
$J99:
	pop	bp
	ret
_set_rcv_mode endp

	public	_get_rcv_mode
	even
_get_rcv_mode proc near
	ret
_get_rcv_mode endp
LIBTCP_TEXT	ends
        end
