*******************************************************************
*
*  BINLOAD.ASM
*    Binary loader for loading through the console port. Uses
*    the same data record sync and jump record sync bytes as
*    the 8800 format tapes. Delays three seconds after end of
*    tape before jumping to the loaded program to give the
*    operator time to switch from reader back to console with
*    an A/B port switch.
*
*    Mike Douglas, Nov 23, 2023
*
*******************************************************************
OUTCH	equ	$FF81		;display char from B (in monitor)
SIOSR	equ	$F000		;UART status register
SIODR	equ	$F001		;data register

DATAREC	equ	$3C		;flag that a data record follows
JUMPREC	equ	$78		;flag that a jump record follows

*----------------------------------------------------------------
*  The loader is located at $3F00 at the top of the 1st
*  16K RAM board. 
*----------------------------------------------------------------
	org	$3F00		;loader at top of 1st 16K
	
main	bsr	conRead		;look for a sync byte
	cmpb	#DATAREC	;data record?
	beq	loadRec		;yes
	
	cmpb	#JUMPREC	;jump record?
	bne	main		;no, keep looking

	bsr	getAddr		;get jump-to address in X
	bsr	delay3		;give time to switch A/B switch
	ldx	saveX		;X=start adddress
	jmp	0,x		;jump to loaded code
	
* loadRec - Load a data record

loadRec	bsr	getAddr		;get pointer in X for data	
	bsr	conRead		;get byte count to read
	stab	byteCnt
	clra			;init checksum
	
loadLp	bsr	conRead		;load, save, and verify byte
	stab	0,x
	cmpb	0,x
	bne	memErr
	
	aba			;update checksum
	inx
	dec	byteCnt
	bne	loadLp
	
	bsr	conRead		;read checksum
	sba
	bne	csumErr		;didn't match
	
	bra	main		;else, look for next record

* getAddr - Read two byte address from the cassette interface
*   and return it in X

getAddr	bsr	conRead		;get MSB
	stab	saveX
	bsr	conRead		;get LSB
	stab	saveX+1
	ldx	saveX		;X contains the address
	rts

* csumErr, memErr - Die in a loop displaying the error code

csumErr	ldab	#'C		;display C for checksum errors
	bra	dieLoop
	
memErr	ldab	#'M		display M for memory errors

dieLoop	jsr	OUTCH		;die here sending error code
	bra	dieLoop

* conRead - Read a byte from the console serial port into B

conRead	ldab	SIOSR		;wait for new byte
	rorb
	bcc	conRead

	ldab	SIODR		;load and return byte
	rts

* delay3 - Three second delay

delay3	ldaa	#3		;delay 3 seconds
oneSec	ldx	#62500		;1s = 62500*16us
delay	dex			;8us
	bne	delay		;8us
	deca
	bne	oneSec
	rts

* Data area

saveX	rmb	2
byteCnt	rmb	1

	end
