	name pkglue

	.286p

	include	data.inc

_TEXT	SEGMENT  para PUBLIC 'CODE'
_TEXT	ENDS

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

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

_DATA	SEGMENT  WORD PUBLIC 'DATA'

m_slip	db	'S=', '$'
	extrn	_shared:byte
	extrn	_arpbuffer:byte

_DATA	ENDS

DGROUP	GROUP	_DATA

_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:_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:_TEXT, ds:nothing, es: nothing

	extrn	_arpinterpret:near
	public	_arp_receiver
	even
_arp_receiver	proc	far
	push	ds
	push	bx
	mov	bx,DGROUP
	mov	ds,bx
	ASSUME	ds:DGROUP

	or	ax,ax
	jz	$A0

	sti
	push	es
	push	dx
	push	cx
	call	_arpinterpret
	pop	cx
	pop	dx
	pop	es
	jmp short $A99
$A0:
	cmp	cx,128		; arp packet must be <= 128 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
	push	dx
	mov	bx,DGROUP
	mov	ds,bx
	mov	es,bx
	ASSUME	ds: DGROUP, es:DGROUP

	or	ax,ax
	jz	$B0

	mov	_shared.innet,0
	jmp	$B99
$B23:
	mov	bx,_shared.mbfree		; restore mbuf onto free list
	mov	[di].next,bx
	mov	_shared.mbfree,di
$B1:
	sub	ax,ax			; drop packet
	mov	_shared.innet,ax
	mov	di,ax
	mov	es,ax
	jmp	$B99
$B0:
	mov	_shared.innet,1
	mov	di,_shared.mbfree
	or	di,di
	jz	$B1			; drop packet
	mov	bx,[di].next
	mov	_shared.mbfree,bx
	mov	[di].next,ax		; on entry ax = 0

	mov	ax,_shared.slip_mode
	or	ax,ax
	jz	$B7
	add	cx,size ether		; add fake Ethernet header
$B7:
	mov	ax,cx			; ax = length of packet in bytes
	add	ax,007fh		; len += 127
	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
	jae	$B4			; if cx >= ax then branch
	add	si,size ebuf

	jmp	short $B5
;	cmp	si,offset _shared.eb + NEBUFS * 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].dptr,dx		; [di].next has been zeroed
	mov	[di].len,ax
	add	ax,dx
	mov	[si].start_addr,ax
					; put in mbprocess queue
	mov	bx,_shared.mbnext	; *mbnext = di
	mov	[bx],di
	add	di,offset mbuf.next	; di -> &[di].next
	mov	_shared.mbnext,di	; mbnext = &[di].next
	or	cx,cx
	jnz	$B98
	mov	di,si
	add	si,size ebuf		; si -> next entry
	cld				; make sure it's forward
$B90:
	movsw
	lodsw
	stosw
	or	ax,ax
	jnz	$B90
$B98:
	mov	di,dx			; set up buffer for packet
	mov	ax,_shared.slip_mode
	or	ax,ax
	jz	$B99
	add	di,size ether
$B99:
	pop	dx
	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
	mov	ax,[bp+X]
	mov	word ptr cs:packet_vector,ax
	mov	ax,[bp+X+2]
	mov	word ptr cs:packet_vector+2,ax
	pop	bp
	ret
_patch_vec endp

	public	_driver_info
	even
_driver_info proc near
	ASSUME	ds:DGROUP
	push	bp
	mov	bp,sp
	push	ds
	push	si
	push	di
	mov	ax,ds
	mov	es,ax
	ASSUME	es:DGROUP

	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:
	mov	di,[bp+X]
	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:DGROUP
	pop	bp
	ret
_driver_info endp

	ASSUME	es:nothing

	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]
	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
	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	@pkxmit
	even
@pkxmit proc near
	push	si

	mov	si,bx		; Hack: leave ds alone.  It already is right
	mov	cx,ax
	mov	ax,_shared.slip_mode
	or	ax,ax
	jnz	slip
	cmp	cx,60		; minimum packet size is 60 bytes
	jge	no_slip
	mov	cx,60
	jmp	short no_slip
slip:
	sub	cx,size ether
	add	si,size ether
no_slip:
	mov	ah,4
	call	do_int
	mov	ax,0
	jnc	$F99
	mov	al,dh
	neg	ax
$F99:
	pop	si
	ret
@pkxmit 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]
	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
	pop	bp
	ret
_get_address endp

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

	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

_TEXT	ends
        end
