	processor 6502

	include "jmptab.inc"

#if target & pet4001
	include "include/petram34.lib"
	include "include/petrom4.lib"
#endif
#if target & pet3001
	include "include/petram34.lib"
	include "include/petrom3.lib"
#endif
#if target & (vic20 | c64 | c128)
	include "include/cbmrom.lib"
#endif

	seg code
	org prutils

entry:
	lda #0		; send ack
	jsr send_switch

loop:
	; write a file protocol:
	; C=		     other computer
	; ack (00) ->
	;		     <- <length>filename
	;		     <- device #
	;		     <- secondary address
	; st: ok (00) or error (!= 00) ->
	;		     <- <length><chksum>datablock (255 bytes max)
	; ok (80) or again (81) or stop (82) ->
	; send same or next block, accordingly
	; last block has length 0 and no checksum or data.

	jsr receive_switch	; get length of file name
	sta fnlen
	tax		; test length
	bpl noexit
	jmp exit	; re-install server
noexit:
	beq nofnam
	ldx #0		; receive file name
fnam:
	jsr receive	; preserves x but sets y to 0.
	sta filebuf,x
	inx
	cpx fnlen
	bcc fnam

nofnam:
	lda #<filebuf
	sta fnadr
	lda #>filebuf
	sta fnadr+1
	lda #0
	sta status	; clear ST

myfileno = 45
	lda #myfileno	; a hopefully unused file number
	sta la
	jsr close	; close file first just in case

	jsr receive	; receive device number
	sta fa
	jsr receive 	; secondary addr, usually 1 for file write
	sta sa
	jsr open	; now open the file
	lda status	; and test for ourselves if we must continue
	bne abort

	ldx #myfileno
	jsr chkout
	lda status
	bne abort
	jsr send_switch ; send 00 ok, going ahead code

		; loop to receive blocks from the file
nextblock:
	jsr receive_switch
	sta blklen
	tax		; set flags
	beq eof		; 0 means end of file
	jsr receive	; checksum
	sta filebuf
	ldx #0
	stx chksum	; clear checksum
recv:
	jsr receive
	sta filebuf+1,x
	clc		; update checksum
	adc chksum
	sta chksum
	inx
	cpx blklen
	bne recv

	cmp filebuf	; check checksum
	beq writeit
	lda #$81	; ask for a resend
	jsr send_switch
	sec
	bcs nextblock

writeit:
	ldx #0
write:			; write max 255 bytes from the file
	lda status	; test ST for EOI on previous byte
	bne abort
	jsr stop	; test stop key
	beq abort
	lda filebuf+1,x
	jsr chrout
	inx
	cpx blklen
	bne write

	lda #$80	; please send next block
	jsr send_switch
	sec
	bcs nextblock

abort:
	lda #$82
	jsr send_switch ; send abort code
eof:
	jsr clrchn
	lda #myfileno
	jsr close
	jmp loop

endcode = .

	seg.u bss
	org endcode

blklen:
	ds.b 1		; save block length
chksum: ds.b 1		; calculated checksum
filebuf:
	ds.b 256	; checksum followed by 255 bytes of file data

endbss = .

