*---------------------------------------------------------
*  OP-80 S-Record Loader
*---------------------------------------------------------
MPLSLOT	equ	7		;Set MP-L slot number here

PIABASE	equ	4*MPLSLOT+$8000
DATAA	equ	PIABASE+0
CSRA	equ	PIABASE+1
DATAB	equ	PIABASE+2
CSRB	equ	PIABASE+3

SYNC	equ	$DD
CONTRL	equ	$E0E3		;SWTBUG re-entry point
OUTEEE	equ	$E1D1		;output byte to console

* Locate this code above anything that will be loaded

	org	$7F80		;top of 1st 16K

* Init PIA port B

	ldaa	#$2C		;low going handshake pulse
	staa	CSRB		;  with write to PIA port B
	staa	DATAB		;clear OP80 RDA flip flop

* Outer S-record loop

rdLine	bsr	getOP80		;wait for 'S'
	cmpa	#'S
	bne	rdLine

	bsr	getOP80		;wait for '1' or '9'
	cmpa	#'9
	bne	chkS1
	jmp	CONTRL		;S9, exit to SWTBUG

chkS1	cmpa	#'1		;S1?
	bne	rdLine		;no, keep looking

* Have S1, get the line length and address

	clr	chkSum		;init checksum
	bsr	getByte		;get byte count in line
	suba	#2		;don't include address bytes
	staa	byteCnt		;  in the byte count

 	bsr	getByte		;put load address into X
 	staa	tempX		;MSB
 	bsr	getByte
 	staa	tempX+1		;LSB
 	ldx	tempX		;X=address from S-record

* Move the data bytes of an S-record to memory

datLoop	bsr	getByte		;get a data byte
	dec 	byteCnt		;all done?
	beq	valCSum		;yes, go validate the checksum
	staa	0,x		;else, store the new byte
	inx
	bra	datLoop

valCSum	inc	chkSum		;validate the checksum
	beq	rdLine		;checksum good, read next line

* Checksum error, display ? and exit to SWTBUG

	ldaa	#'?		;error
	jsr	OUTEEE
	jmp	CONTRL

* getByte - Read and convert an ASCII hex byte to an
*   actual byte in A

getByte	bsr	getNib		;get upper nibble
	asla			;put in upper nibble
	asla
	asla
	asla
	tab			;save in B

	bsr	getNib		;get lower nibble
	aba			;form result byte

	tab			;update checksum
	addb	chkSum
	stab	chkSum
	rts

* getNib - Read and convert an ASCII hex nibble to an
*   actual nibble in A

getNib	bsr	getOP80		;byte from reader
	suba	#'0		;subtract ASCII offset
	cmpa	#'9		;0-9?
	bls	nibExit
	suba	#7		;convert A-F
nibExit	rts

* getOP80 - Read and return a byte from the OP80 reader

getOP80	ldaa	CSRB		;wait for new byte
	bpl	getOP80

	ldaa	DATAB		;get new byte
	anda	#$7F		;force 7-bit ASCII
	staa	DATAB		;clear OP80 read flip-flop
	rts

* Data area

chkSum	rmb	1
byteCnt	rmb	1
tempX	rmb	2

	org	$8000
	fcb	SYNC
	end
