
; Familiarity with the s19 format is strongly recommended
; when looking at this. the file format dictates how the
; information is handled.

; this equate is the amount of records to load before printing a star. the first
; star is printed with the first record. star_count, next, is the default
; number of records per star. there is a memory location "star_count_register"
; that this number is actuall put in. if the number in the "star_count_register"
; is modified, it will change the amount of records per star. change it to $01
; and there will be one star per record.

star_count		equ		$3



; --------------= S19 DOWNLOAD Subroutine =----------------
; puts an S19 file into memory. gets it from SCI
; ---------------------------------------------------------
***
;download_sub: "m_load.asm"
;	Used to load s19 files onto memory
;	Reg Input:
;		None
;	Reg Output
;		None
***

download_sub:
	ldy        	#ds_wait			; "waiting for S19 download"
	jsr        	print_string			; prints the string

#ifdef _STAR_
	ldaa		#1
	psha

#endif


							; wait for S
S_wait:							; it will keep looping until
	jsr        	get_char_wait_noecho		; and S character is sent
	cmpa       	#'S'				
	bne        	S_wait

#ifdef _CHECKSUM_
* additionals
	clr		tempb				; clears temporary memory space for checksum adding
* end of added
#endif
							; wait for a '1' but exit if '9'
one_wait:
	jsr        	get_char_wait_noecho		; waiting. this blocks until there is a character
	cmpa       	#'9'				; s9 seems to be sent at the end, so this signifies the last
	beq        	d_done				; record of the s19 file. d_done jumps back to monitor
	cmpa       	#'0'				; handle S0 records
	beq        	zero_header			
	cmpa       	#'1'				; must be a 1 after the S, or it keeps waiting for
	bne        	one_wait			; the 1 to show up

							; get the count and remove 3 for chksum and address
							; it is returned in A
	jsr        	get_byte			; the format dictates that after "S1" there is the number of bytes

#ifdef _CHECKSUM_
	adda		tempb				; adds A to the temporary variable, stores in a
	staa		tempb				; stores sum in the temp variable. this is checksum
#endif

#ifdef _STAR_
	pshd						; stores state of d
	
	ldab		2,sp				; loads the counter
	bne		star_skip			; checks if it is zero

							; counter is zero
	ldaa		#'*'				; loads the '*' character
	jsr		put_char			; prints it
	ldab		star_count_register		; reloads counter

star_skip:
	decb						; decrements counter
	stab		2,sp				; stores it back into stack

	puld						; restores state of d
#endif

	suba       	#3				; number of bytes that are going to be sent
							; so that number doesn't need to include the address
							; which is 2 bytes. or the checksum at the end, which
							; is one byte. I don't think that MiniIDE or HyperTerminal
							; can actually utilize the checksum value and resend a line
							; if there is an error in transmission
							; put it into B

*							* tab works here
	psha
	pulb

							; get the address (4 bytes)
							; it is returned in X
	jsr        	get_address			; the address comes after the byte count


#ifdef _CHECKSUM_
* added stuff to sum address
	pshd						; saves D
	tfr		x, d				; X => D
	aba						; adds B to A, summing the bytes of the address
	adda		tempb				; then adds the temp var to A
	staa		tempb				; stores the value in the temp var
	puld						; restores D
* added stuff ends here
#endif


d_loop1:
	jsr        	get_byte			; get the stuff!
	staa       	0,x				; store it

	adda		tempb				; adds A to the temporary variable, stores in A
	staa		tempb				; stores it in the temp variable. this is checksum

	inx						; increment X -- address
	decb						; decrement B and check if it is zero (B = num bytes to load)

#ifdef _CHECKSUM_
	beq        	check_sum			; if B is zero, then the next byte is the checksum
#endif

#ifndef _CHECKSUM_
	beq		S_wait				; if B is zero, then it is done with that record so wait for another

#endif

	bra        	d_loop1				; otherwise keep waiting on this record




#ifdef _CHECKSUM_
check_sum:
	jsr		get_byte			; this gets the checksum value
	com		tempb				; complements the value in the temporary variable
	cmpa		tempb				; compares checksum to summed and complemented value
	bne		check_sum_error			; if they aren't equal, there was a loading error.
	bra		S_wait				; otherwise, keep on loading

check_sum_error:
	ldy		#chk_sum_err
	jsr		print_string
	rts
#endif


zero_header:						; nothing is done with a zero header, so pretty much info
	jsr        	get_byte			; is just pulled from the serial port with this routine
	suba       	#3				
*							* tab can be used
        psha
        pulb
        jsr        	get_address			; the address in headers is ignored
	
zh_loop:						; content passed here in this loop
	cmpb       	#$00
	beq        	zh_done
        jsr        	get_byte			; this byte is meaningless so ignore
        decb						; decrement the counter
	bra        	zh_loop				; get more data
zh_done:
	jsr        	get_byte			; the checksum
	lbra        	S_wait				; now go back to waiting for the letter S

d_done:
	ldaa		#' '				; loads a space character
	jsr		put_char			; then prints it
	ldy        	#ds_done			; loads pointer to that message
	jsr        	print_string			; prints the pointer

							; wait for 10, which will be the end of the file
end_wait:						; it will keep looping until
	jsr        	get_char_wait_noecho		; 10 is sent
	cmpa       	#10				
	bne        	end_wait

#ifdef _STAR_
	pula						; gets return address back to top of stack
#endif

	rts						; goes back to monitor

