;	------------------------------------------------------------------------------
;	Project JAGUAR:	JAGUAR PROTOCOLE COMMUNICATIONS.
;	LOW LEVEL CODE FOR TOS MACHINE VIA CARTRIDGE AND SERIAL PORT.
;
;	File:		JProto.s
;	Author:		FAVARD Laurent
;	Date:		20 January 1998
;	Release:	23 June 1998
;	Language:	HISOFT DEVPAC 3-680x0
;
;	Funship - Atari Jaguar France / Copyright 1997-1998
;	------------------------------------------------------------------------------

						include		".\JProtolo.inc"

; ---------------------------------------------------------------------------
;	Export symboles

						XDEF		GetPack
						XDEF		SendPack
						XDEF		GetByte
						XDEF		SendByte
                        XDEF		SetPort
                        XDEF		GetPort
						XDEF		CheckJaguar
						XDEF		ClearBuffer
						
; ---------------------------------------------------------------------------
;	Import symboles


						TEXT

; ---------------------------------------------------------------------------
;		long cdecl GetPack(void *Buffer, int Expected)
;
;		Get a block from the input buffer which the lenght will be of 'Expected'
;		bytes.
;
;		return the count of bytes received or zero if no bytes.
; ---------------------------------------------------------------------------

OFF_BLOCKGET			equ			4+2*4
OFF_EXPECBLKGET			equ			8+2*4


GetPack:				movem.l		d1/a0,-(sp)
						move.l		OFF_BLOCKGET(sp),a0

;	Check if one byte is ready at least (If < 0 then no bytes)

						jsr			GetByte
						tst.l		d0											;	d0 < 0 ?
						blt.s		.EndWithError								;	yes => no byte

						move.b		d0,(a0)+									;	store the byte
						move.l		#1,d1										;	one byte received

;	Sending loop

.loop:					cmp.w		OFF_EXPECBLKGET(sp),d1						;	check the count expected
						bge.s		.EndNoError									;	too bytes received

						jsr			GetByte
						tst.l		d0
						blt.s		.EndNoError									;	no more bytes, finish

						move.b		d0,(a0)+									;	store the byte
						addq.l		#1,d1										;	one more byte received

						bra.s		.loop

.EndNoError:			
						move.l		d1,d0										;	return count of bytes
						movem.l		(sp)+,d1/a0
						rts

.EndWithError:			movem.l		(sp)+,d1/a0
						move.l		#0,d0										;	0 bytes received
						rts

; ---------------------------------------------------------------------------
;		long cdecl SendPack(void *Buffer, int Lenght)
;
;		Send the contains of the buffer to the output buffer. 'Lenght' bytes
;		will be send.
;
;		return TRUE if all bytes could been send or FALSE else.
; ---------------------------------------------------------------------------

OFF_BLOCKSEND			equ			4+2*4
OFF_LENBLKSEND			equ			8+2*4


SendPack:				movem.l		d1/a0,-(sp)
						move.l		OFF_BLOCKSEND(sp),a0
						move.w		OFF_LENBLKSEND(sp),d1

;	Sending loop

.loop:					tst.w		d1											;	while d1 > 0
						beq.s		.EndNoError									;	d1 = 0 terminate

						move.b		(a0)+,d0									;	get byte to send
						andi.l		#$FF,d0

						move.w		d0,-(sp)
						jsr			SendByte
						addq.l		#2,sp										;	clear stack

						tst.w		d0
						beq.s		.EndWithError

						subi.w		#1,d1
						bra.s		.loop
						
.EndNoError:			movem.l		(sp)+,d1/a0
						move.l		#TRUE,d0
						rts

.EndWithError:			movem.l		(sp)+,d1/a0
						move.l		#FALSE,d0
						rts

; ---------------------------------------------------------------------------

GetByte:                cmpi.w		#PORT_SERIE,G_PORT							;	cartridge port ?
						bne.s		.GetBoard									;	yes

;	Get a byte from the serial port	(For debug and test mode)

						movem.l		d1-d2/a0-a2,-(sp)

.WaitToGet:				move.w		#DEV_AUX,-(sp)								;	A byte is ready ?
						move.w		#BCONSTAT,-(sp)
						trap		#BIOS
						addq.l		#4,sp

						tst.w		d0											;	d0 = 0 => no byte
						beq.s		.EndWithError

						move.w		#DEV_AUX,-(sp)								;	Yes, get it
						move.w		#BCONIN,-(sp)
						trap		#BIOS
						addq.l		#4,sp

.EndNoError:			movem.l		(sp)+,d1-d2/a0-a2
						andi.l		#$FF,d0
						rts

.EndWithError:			movem.l		(sp)+,d1-d2/a0-a2
						move.l		#-1,d0
						rts

;	get a byte from the cartridge port

.GetBoard:              btst.b		#RBUF_EMPTY,STATUS_BUFFER					;	FIFO empty ?
						beq.s		.NoByte										;	no bytes so wait

						move.b		RECEIVE_BUFFER,d0
						andi.l		#$FF,d0
						rts

.NoByte:                move.l		#-1,d0
						rts

; ---------------------------------------------------------------------------
;		long cdecl SendByte(int byte)
;
;		Wait and send a byte to the output buffer as soon as possible.
;
;		return always TRUE because it wait to send the byte.
; ---------------------------------------------------------------------------

OFF_SBYTE				equ			4+5*4										;	when via serial port
BYTE					equ			8											;	when via cartridge

SendByte:               cmpi.w		#PORT_SERIE,G_PORT							;	cartridge port ?
						bne.s		.SendBoard									;	yes

;	Send the byte with the serial port	(For debug and test mode)

						movem.l		d1-d2/a0-a2,-(sp)

.WaitToSend:			move.w		#DEV_AUX,-(sp)								;	ready to send ?
						move.w		#BCOSTAT,-(sp)
						trap		#BIOS
						addq.l		#4,sp

						tst.w		d0											;	not ready ?
						beq.s		.WaitToSend									;	so wait to send

						move.w		OFF_SBYTE(sp),-(sp)							;	get the byte
						move.w		#DEV_AUX,-(sp)
						move.w		#BCONOUT,-(sp)
						trap		#BIOS
						addq.l		#6,sp

				IF	MODE == DEBUG

						move.l		#7,d1
.Slow1:					move.l		#$FFFFFFFF,d0
.Slow2:					dbra		d0,.Slow2
						dbra		d1,.Slow1
						
				ENDIF
               
.EndNoError:			movem.l		(sp)+,d1-d2/a0-a2
						move.l		#TRUE,d0
						rts

;	Send the byte with the cartridge port

.SendBoard:             move.l		a0,-(sp)

.WaitSendBoard:			btst.b		#SBUF_FULL,STATUS_BUFFER					;	test status register
						beq.s		.WaitSendBoard								;	FIFO full, wait

						movea.l		#SEND_BUFFER,a0								;	a0 <- Send register
						moveq.l		#0,d0										;	d0 <- 0.l
						move.w		BYTE(sp),d0									;	d0 <- data.w
						move.b		0(a0,d0.w),d0								;	d0 <- Read(a0 OR d0)

						move.l		(sp)+,a0
                        move.l		#TRUE,d0
						rts

; ---------------------------------------------------------------------------
;		int cdecl GetPort(void)

GetPort:				move.w		G_PORT,d0
						rts
; ---------------------------------------------------------------------------
;		void cdecl SetPort(int Port)

PORT					equ			4

SetPort:				move.w		PORT(sp),G_PORT
						rts
; ---------------------------------------------------------------------------

CheckJaguar:			move.b		STATUS_BUFFER,d0
						btst.b		#CARTDRIDGE_SET,d0
						beq.s		.Detected
						
						move.w		#FALSE,d0
						rts
.Detected:				move.w		#TRUE,d0
						rts
; ---------------------------------------------------------------------------

ClearBuffer:			move.l		d0,-(sp)

.Clear:					jsr			GetByte
						tst.l		d0											;	d0 < 0 ?
						bge.s		.Clear
						
						move.l		(sp)+,d0
						rts

; ---------------------------------------------------------------------------

						DATA
						EVEN

G_PORT:					dc.w		PORT_SERIE									;	contents current port to use

						END
