*----------------------------------------------------------
* PUNCH.ASM
*    Punch a range of memory to paper tape. Located in 
*    the top 128 bytes of the 1K onboard RAM. User should
*    put start address top punch at $60,$61 and last
*    address to punch at $62,$63
*----------------------------------------------------------
 
* Monitor equates

MON	equ	$FFAB		;return to monitor
OUTHEX	equ	$FF6D		;output 8 bit hex value
OUTCH	equ	$FF81		;outout a character

* ASCII equates

CR	equ	$0D
LF	equ	$0A
DC2	equ	$12		;punch on
DC4	equ	$14		;punch off

* Data is on page zero

	org	$60
	
memPtr	rmb	2		;start address to save
endPtr	rmb	2		;last address to save
count	rmb	1		;line byte counter
chkSum	rmb	1		;checksum on line
atEnd	rmb	1		;0=end reached		

* Start of program

	org	$0380

* Punch the S-records

	ldab	#DC2		;turn on punch
	jsr	OUTCH
	ldaa	#30		;punch 30 nulls
	bsr	nulls

doLine	ldx	#mS113		;CR/LF S113
	jsr	punMsg

	ldx	memPtr		;point to memory to punch
	ldaa	#17		;punch 16 bytes +1 address byte
	staa	count
	staa	atEnd		;cleared to zero if end reached

	ldaa	#19		;total byte count on line
	adda	memPtr		;init checksum with 1st two bytes
	staa	chkSum
	
	ldaa	memPtr		;punch first address byte
	jsr	OUTHEX
	ldaa	memPtr+1	;punch 2nd address byte 
	bra	punchA

* punch the bytes within a line

doByte	ldaa	0,x		;A=next byte to punch
	inx
punchA	tab			;update checksum
	addb	chkSum
	stab	chkSum
	jsr	OUTHEX		;punch the byte
	cpx	endPtr		;reach end?
	bne	nxtByte		;no
	clr	atEnd		;else, indicate we're done
nxtByte	dec	count
	bne	doByte		;punch full 16 byte line

	ldaa	chkSum		;punch the checksum
	eora	#$FF		;1s compliment
	jsr	OUTHEX

	stx	memPtr		;save current memory address
	ldaa	atEnd		;did we reach the end?
	bne	doLine		;no

* Punch S9 and a trailer of nulls

	ldx	#mS9		;end
	jsr	punMsg

	ldaa	#10		;10 trailing nulls
	bsr	nulls		;punch trailer
	ldab	#DC4		;punch off
	jsr	OUTCH
	jmp	MON		;return to monitor

* nulls - Punch the number of nulls in A
		
nulls	clrb
	jsr	OUTCH
	deca
	bne	nulls
return	rts

* punMsg - Punch null terminated message

punMsg	ldab	0,x		;next character
	beq	return
	jsr	OUTCH		;punch the character
	inx
	bra	punMsg

* Messages and data

mS113	fcb	CR,LF,$08	;$08 give more time for CR
	fcc	'S113'
	fcb	0

mS9	fcc	'S9'
	fcb	0

	end
