**
** ProNET-Driver `serial'
**
** 08-05-95	Started
** 05-06-95	init: flags argument

; Format of one packet
; 2bytes	"R!" for packet recognization
; 2bytes	Length in Bytes of pure data without next two words
; 2bytes	Destination Port
; 2bytes	source Port
; xbytes	Data

		include	"A:OSmacros.i"
		include	"exec/exec.i"
		include	"devices/serial.i"
		include	"a:ProNET/include/devices/pronet.i"
		include	"exec_lib.i"

; -- Initialization routine
Init		; a0 *DriverData
		; a1 *ConfigString after driver ID
		; d0 "RST!" for Identification
		; d1 Flags
		; RETURNS d0 <>0 if everything OK, else NULL!
		movem.l	d2-d7/a2-a6,-(sp)
		move.l	a0,a4
		move.l	a1,a5
		cmp.l	#"RST!",d0		;compare ID
		bne	.error
		tst.l	d1
		bne	.error			;unknown Flags!

		bsr	StartDevice
		tst.w	d0
		beq.s	.error

		bsr	IssueReadCMD

		move.l	serialio(pc),a0
		move.l	MN_REPLYPORT(a0),a0
		move.b	MP_SIGBIT(a0),(a4)	;Read Signalbit
		move.l	#ReadQuery,2(a4)
		move.l	#Read,6(a4)
		move.l	#Write,10(a4)
		moveq	#-1,d0
		bra.s	.ende

.error		moveq	#0,d0
.ende		movem.l	(sp)+,d2-d7/a2-a6
		rts

		dc.b	"$VER: pronet-driver `serial' (05-06-95)",13,10,0
		even

; -- Start the right `serial.device'
StartDevice	move.l	4.w,a6

		moveq	#IOEXTSER_SIZE,d0
		bsr	GetIORequest
		move.l	d0,serialio
		beq	noiorequest

		moveq	#IOEXTSER_SIZE,d0
		bsr	GetIORequest
		move.l	d0,serialiow
		beq	noiorequest2

		move.l	serialio(pc),a2
		move.b	#SERF_7WIRE,IO_SERFLAGS(a2)

		move.l	a5,a0			;device name
.0		move.b	(a0)+,d0
		cmp.b	#" ",d0
		bhi.s	.0
		clr.b	-1(a0)

		bsr	dec2long
		move.l	d1,d5			;unit
		bsr	dec2long
		move.l	d1,d6			;baudrate

		move.l	a5,a0
		move.l	d5,d0
		move.l	a2,a1
		moveq	#0,d1
		LIBCALL	OpenDevice
		tst.b	d0
		bne.s	nodevice

		move.w	#SDCMD_SETPARAMS,IO_COMMAND(a2)
		move.b	#SERF_XDISABLED^SERF_RAD_BOOGIE^SERF_7WIRE,IO_SERFLAGS(a2)
		move.l	d6,IO_BAUD(a2)
		move.l	#32768,IO_RBUFLEN(a2)
		clr.l	IO_EXTFLAGS(a2)
		move.b	#8,IO_READLEN(a2)
		move.b	#8,IO_WRITELEN(a2)
		move.b	#1,IO_STOPBITS(a2)
		move.l	a2,a1
		LIBCALL	DoIO
		tst.b	d0
		bne.s	noparams

		move.l	a2,a0
		move.l	serialiow(pc),a1
		move.l	a1,a2
		move.l	MN_REPLYPORT(a2),d2
		moveq	#IOEXTSER_SIZE,d0
		LIBCALL	CopyMem
		move.l	d2,MN_REPLYPORT(a2)

		moveq	#-1,d0
		rts

noparams	move.l	a2,a1
		LIBCALL	CloseDevice
nodevice	move.l	serialiow(pc),a0
		bsr	FreeIORequest
noiorequest2	move.l	serialio(pc),a0
		bsr	FreeIORequest
noiorequest	moveq	#0,d0
		rts

; -- Put Out An 8 Bytes Read Command
IssueReadCMD	move.l	4.w,a6
		moveq	#0,d0
		moveq	#0,d1
		move.l	serialio(pc),a0
		move.l	MN_REPLYPORT(a0),a0
		move.b	MP_SIGBIT(a0),d2
		bset	d2,d1
		LIBCALL	SetSignal
		move.l	serialio(pc),a2
		move.w	#CMD_READ,IO_COMMAND(a2)
		clr.b	IO_FLAGS(a2)
		move.l	#buffer-2,IO_DATA(a2)
		move.l	#8,IO_LENGTH(a2)
		move.l	a2,a1
		LIBJMP	SendIO

; -- Read Query routine
ReadQuery	; RETURNS d0 length of pure data to come or NULL
		;         d1 destport
		;         d2 sourceport
		movem.l	d3-d7/a2-a6,-(sp)
		move.l	serialio(pc),a0
		move.l	MN_REPLYPORT(a0),a0
		move.l	4.w,a6
		LIBCALL	GetMsg
		tst.l	d0
		beq.s	.nope
		move.w	buffer-2(pc),d0
		cmp.w	#"R!",d0
		beq.s	.ok0

		bsr	ReadEmpty
		bsr	IssueReadCMD
.nope		clr.w	buffer

.ok0		movem.w	buffer(pc),d0-d2
		movem.l	(sp)+,d3-d7/a2-a6
		rts

; -- Read routine
Read		; a0 *destination
		movem.l	d2-d7/a2-a6,-(sp)
		move.l	4.w,a6
		move.l	serialio(pc),a1
		move.l	a0,IO_DATA(a1)
		moveq	#0,d0
		move.w	buffer(pc),d0
		move.l	d0,IO_LENGTH(a1)
		move.w	#CMD_READ,IO_COMMAND(a1)
		LIBCALL	DoIO
		bsr	IssueReadCMD
		movem.l	(sp)+,d2-d7/a2-a6
		rts

; -- Write routine
Write		; a0 *data1
		; d0.l datalength1 (even)
		; a1 *data2
		; d1.l datalength2 (even)
		; d2 Destination Port
		; d3 Source Port
		; d0+d1 <= $4000
		; d1=0 --> only first chunk is sent, else second is appended
		;          to first one and sent as one chunk!
		; RETURNS d0 <>0 on error, else NULL
		movem.l	d2-d7/a2-a6,-(sp)
		move.l	serialiow(pc),a2
		move.l	4.w,a6
		lea	buffer(pc),a5
		movem.l	d0/d1/a0/a1,6(a5)

		move.w	d0,d4
		add.w	d1,d4
		move.w	d4,(a5)
		move.w	d2,2(a5)
		move.w	d3,4(a5)
		lea	-2(a5),a0
		move.w	#"R!",(a0)
		move.l	a0,IO_DATA(a2)
		move.l	#8,IO_LENGTH(a2)
		move.w	#CMD_WRITE,IO_COMMAND(a2)
		move.l	a2,a1
		LIBCALL	DoIO

		move.w	#CMD_WRITE,IO_COMMAND(a2)
		move.l	14(a5),IO_DATA(a2)
		move.l	6(a5),IO_LENGTH(a2)
		move.l	a2,a1
		LIBCALL	DoIO

		move.w	#CMD_WRITE,IO_COMMAND(a2)
		move.l	18(a5),IO_DATA(a2)
		move.l	10(a5),IO_LENGTH(a2)
		beq.s	.0
		move.l	a2,a1
		LIBCALL	DoIO

.0		moveq	#0,d0
		movem.l	(sp)+,d2-d7/a2-a6
		rts

		dc.w	0
buffer		ds.b	64

; -- A received message did not contain the "R!" string (probably
; -- the BaudBandit.device startup message), so clear it!
ReadEmpty	move.l	serialio(pc),a2			* CMD_CLEAR
		move.l	4.w,a6				* does not help!
.loop		move.w	#SDCMD_QUERY,IO_COMMAND(a2)	* so we have to read
		move.l	a2,a1				* it out!
		LIBCALL	DoIO
		move.l	IO_ACTUAL(a2),d0
		beq.s	.ende
		cmp.l	#64,d0
		bcs.s	.ok0
		moveq	#64,d0
.ok0		move.l	d0,IO_LENGTH(a2)
		move.l	#buffer,IO_DATA(a2)
		move.w	#CMD_READ,IO_COMMAND(a2)
		move.l	a2,a1
		LIBCALL	DoIO
		bra.s	.loop
.ende		rts


dec2long	; konvertiert Dezimalstring ab (a0) zu Longword in D1 !!
		moveq	#0,d1
.loop		moveq	#0,d0
		move.b	(a0)+,d0
		sub.b	#"0",d0
		cmp.b	#9,d0
		bhi.s	.oki
		move.l	d1,d2
		lsl.l	#3,d1
		add.l	d2,d1
		add.l	d2,d1
		add.l	d0,d1
		bra.s	.loop
.oki		rts

serialio	dc.l	0
serialiow	dc.l	0


		include	"A:ProNET/source/devio.s"
