	.title	TCP/UDP Ethernet Driver

	;	DECUS C Calling Format
	;
	;	jsr	r5,csv$		;save r2,r3, and r4
	;				;r5 is parameter base
	;				;c$pmtr(r5) is first argument
	;				;c$pmtr+2(r5) is second argument
	;				;...
	;				;return args in r0
	;	...
	;	user code
	;	...
	;
	;	jmp	cret$		;restore r2-r5 and return
	;	rts	pc		;does the same (cret$ follows csv$)
	;	

	.include	"os.mac"

	.mcall	.lookup	.close	.spfun	.print

	YES	=	0		;DEBUG state
	NO	=	1

	DEBUG	=	NO		;debug mode disabled

	ERRBYT	=	52		;IO error byte

	.page
	.sbttl	Configuration Data

	.psect	c$data

.if ne sp$207				;.spfun 207 required
en0:	.rad50	/EN0EN0EN0EN0/		;temporary
tmpenu	=:	en0			;temporary unit
.iff
en7:	.rad50	/EN7EN7EN7EN7/		;temporary
tmpenu	=:	en7			;temporary unit
.endc

tmpchn	=:	14			;temporary channel

ethsts:	.word	0			;ethernet status (error)
ethadd:	.word	0,0,0			;ethernet address


	.psect	c$code


	.page
	.sbttl	Get Ethernet Address

	;
	;	engetaddr(s);	char *s
	;

engetaddr::
	jsr	r5,csv$

	.if	ne	DEBUG
	clr	errcnt
	.endc

	mov	#ethadd,r0		;check for the ethernet address
	mov	(r0)+,r1
	bis	(r0)+,r1
	bis	(r0),r1
	bne	4$			;have one !

	; Lookup the device and assign a channel

;	.lookup	#lkpdev,#tmpchn,#tmpenu
	mov	#lkpdev,r0
	emt	375
	bcc	1$

	.if	eq	DEBUG
	mov	#emsg1,r0
	jsr	pc,error
	.iff
	inc	errcnt
	.endc

.if ne sp$207				;.spfun 207 required
	; Get Physical Address

;	.spfun	#5$,#tmpchn,#207,#ethadd-2,#0,#0
1$:	mov	#5$,r0
	emt	375

	bcc	3$

	.if	eq	DEBUG
	mov	#emsg8,r0
	jsr	pc,error
	.iff
	inc	errcnt
	.endc
.iff					;no .spfun 207
	; Allocate the device

;	.spfun	#5$,#tmpchn,#200,#ethadd-2,#0,#1
1$:	mov	#5$,r0
	mov	#1,6$
	emt	375
	bcc	2$

	.if	eq	DEBUG
	mov	#emsg2,r0
	jsr	pc,error
	.iff
	inc	errcnt
	.endc

	; Deallocate the device

;	.spfun	#5$,#tmpchn,#200,#ethadd-2,#0,#0
2$:	mov	#5$,r0
	clr	6$
	emt	375
	bcc	3$

	.if	eq	DEBUG
	mov	#emsg3,r0
	jsr	pc,error
	.iff
	inc	errcnt
	.endc
.endc

	; Close the channel

3$:	.close	#tmpchn

4$:	mov	#ethadd,r0		;return the ethernet address
	mov	c$pmtr(r5),r1
	mov	(r0)+,(r1)+
	mov	(r0)+,(r1)+
	mov	(r0),(r1)

	.if	eq	DEBUG
	rts	pc
	.iff
	jmp	enexit
	.endc


.if ne sp$207				;.spfun 207 required
;	.spfun	#5$,#tmpchn,#207,#ethadd-2,#0,#0
5$:	.byte	tmpchn,32
	.word	0		;blk
	.word	ethadd-2	;buf
	.word	0		;wcnt
	.byte	377,207
	.word	0
.iff 					;no .spfun 207
;	.spfun	#5$,#tmpchn,#200,#ethadd-2,#0,(#0 or #1)
5$:	.byte	tmpchn,32
6$:	.word	0		;blk
	.word	ethadd-2	;buf
	.word	0		;wcnt
	.byte	377,200
	.word	0
.endc

	.page
	.sbttl	Get Handler Statistics

	;
	;	engetstats(*s, n)		*s an array of n elements
	;

engetstats::
.if ne sp$210				;.spfun 210 required
	jsr	r5,csv$

	.if	ne	DEBUG
	clr	errcnt
	.endc

	; Lookup the device and assign a channel

;	.lookup	#lkpdev,#tmpchn,#tmpenu
	mov	#lkpdev,r0
	emt	375
	bcc	1$

	.if	eq	DEBUG
	mov	#emsg1,r0
	jsr	pc,error
	.iff
	inc	errcnt
	.endc

	; Get Handler Statistics

;	.spfun	#3$,#tmpchn,#210,c$pmtr(r5),c$pmtr+2(r5),#0
1$:	mov	#3$,r0
	mov	c$pmtr(r5),4$
	mov	c$pmtr+2(r5),5$
	emt	375
	bcc	2$

	.if	eq	DEBUG
	mov	#emsg9,r0
	jsr	pc,error
	.iff
	inc	errcnt
	.endc

	; Close the channel

2$:	.close	#tmpchn

	.if	eq	DEBUG
	rts	pc
	.iff
	jmp	enexit
	.endc


;	.spfun	#3$,#tmpchn,#210,c$pmtr(r5),c$pmtr+2(r5),#0
3$:	.byte	tmpchn,32
	.word	0		;blk
4$:	.word	0		;buf
5$:	.word	0		;wcnt
	.byte	377,210
	.word	0

;	.lookup	#lkpdev,#tmpchn,#tmpenu
lkpdev:	.byte	tmpchn,1
	.word	tmpenu
	.word	0
.iff				;no .spfun 210
	rts	pc
.endc


	.if	ne	DEBUG
enexit:	tst	errcnt			;any errors
	beq	1$
	mov	r0,-(sp)
	.print	#iomsg
	.print	#emsg0
	mov	(sp)+,r0
1$:	rts	pc			;return
	.endc


	.if	eq	DEBUG
error:	inc	errcnt			;update error counter
	mov	r0,-(sp)
	.print	#iomsg
	mov	(sp)+,r0
	.print				;print specified error,
	.print	#iomsg
	mov	#tmpchn,r0		;channel,
	jsr	r5,twodgt
	chnerr
	movb	@#ERRBYT,r0		;ERRBYT,
	jsr	r5,twodgt
	ioerr
	mov	ethsts,r0		;and EN status
	jsr	r5,twodgt
	stserr
	.print	#errmsg
	rts	pc

twodgt:	mov	r1,-(sp)		;two octal digit converter
	mov	(r5)+,r1
	mov	r0,-(sp)
	ash	#-3,r0
	bic	#^C7,r0
	add	#'0,r0
	movb	r0,(r1)+
	mov	(sp)+,r0
	bic	#^C7,r0
	add	#'0,r0
	movb	r0,(r1)
	mov	(sp)+,r1
	rts	r5
	.endc


	.psect	c$data

errcnt:	.word	0			;error counter


	.psect	c$strn

iomsg:	.ascii	/ENDRVR-/<200>

	.if	ne	DEBUG
emsg0:	.asciz	/F-Initialization Failure/
	.iff
emsg1:	.asciz	/F-.lookup failure/
.if eq sp$207				;no .spfun 207
emsg2:	.asciz	/F-.spfun 200, unable to allocate device/
emsg3:	.asciz	/F-.spfun 200, unable to deallocate device/
.iff					;.spfun 207
emsg8:	.asciz	/F-.spfun 207, unable to get physical address/
.endc
.if ne sp$210				;.spfun 210 required
emsg9:	.asciz	/F-.spfun 210, unable to get handler statistics/
.endc
errmsg:	.ascii	/I-CHANNEL = /
chnerr:	.ascii	/00,  /
	.ascii	/ERRBYT = /
ioerr:	.ascii	/00,  /
	.ascii	/STATUS = /
stserr:	.asciz	/00/
	.endc

	.even


	.end
