	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 & (c64 | c128 | vic20)
	include "include/cbmrom.lib"
#endif

	seg code
	org prutils

entry:
	lda #0		; send ack
	jsr send_switch

loop:
	; read a file protocol:
	; C=		     PC or Amiga
	; ack (00) ->
	;		     <- <length>filename
	;		     <- device #
	; 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
	bne noexit
	jmp exit	; reinstall server and exit.
noexit: lda #<filebuf
	sta fnadr
	lda #>filebuf
	sta fnadr+1
	ldx #0		; receive file name
	stx status	; clear ST
fnam:
	jsr receive	; preserves x but sets y to 0.
	sta filebuf,x
	inx
	cpx fnlen
	bcc fnam

	jsr receive	; receive device number
	sta fa
	lda #0		; secondary addr always 0 for file read
	sta sa

myfileno = 45
	lda #myfileno	; a hopefully unused file number
	sta la
	jsr open
	lda status	; now test for ourselves if we must continue
	bne abortst

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

		; loop to send blocks from the file
nextblock:
	ldx #0
loop2:	bne loop	; branch entry point (never branch in actual program)
	stx filebuf	; clear checksum
	inx
rd:			; read max 255 bytes from the file
	lda status	; test ST for EOI on previous byte
	bne eof
	jsr stop	; test stop key
	beq abortst
	jsr chrin
	sta filebuf,x
	clc		; add into checksum
	adc filebuf
	sta filebuf
	inx		; x ranges from 01 to max FF
	bne rd

eof:
	dex		; exclude checksum from count
	stx blklen
			; now go send the buffer
sameblock:
	lda blklen
	jsr send_switch ; send length
	lda blklen
	beq return3	; 0 length is special: we're finished.
	lda filebuf	; checksum
	jsr send
	ldx #0
snd:
	lda filebuf+1,x
	jsr send
	inx
	cpx blklen
	bne snd
			; wait for go on, repeat, or abort.
	jsr receive_switch
	cmp #$80
	beq nextblock
	cmp #$81
	beq sameblock
	bne return3	; $82 (or other values) abort

abortst:
	jsr send_switch ; send non-zero ST value
return3:
	jsr clrchn
	lda #myfileno
	jsr close

	lda #1
	bne loop2	; branch always

endcode = .

	seg.u bss
	org endcode

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

endbss = .
