;
; ******************************************
; *                                        *
; *  TAPE SAVE AND LOAD FOR APPLE 1 BASIC  *
; *                                        *
; ******************************************
;
; By Dave Hassler for the PAL-1 6502 hobby computer, 2022.
;
; Apple BASIC by Steve Wozniak, 1976.
; Apple 1 BASIC (A1B) patched for PAL-1 by Jim B. McClanahan, 2021.
;
; USAGE:
;	SAVE - As currently located, from within A1B (at $8000)
; type CALL-25600 in immediate mode, as a command.  Answer the
; prompts.  Type a 'G' after a successful save.  The first time,
; this saves the necessary Zero Page locations and takes you back
; to the save/load to save the main program part.  When it's done,
; type 'G' again to go back to Apple BASIC.  You may have to type
; a few <RET>s to get the '>' prompt back.
;	LOAD - similar to above.
;	RETURN - do nothing and go back to A1B.
;
; NOTES:
;	Apple 1 BASIC requires Zero Page memory from
; $4A to $FF to be saved, in addition to the BASIC program,
; itself.  This is not a big problem if your program nearly
; fills the available RAM $0300 to $13FF - just save it all in 
; one shot.  But for a small program (or, more importantly, a 
; big program in expanded memory above $2000), the gap between
; Zero Page and the beginning of the user program would mean
; glacial load times from cassette: a 5K single file instead of
; 1.25K-worth in two files, for example. Hence, two saves for 
; one program.
;	One of the weird things about Apple BASIC is that the 
; user program is stored backwards: line 10 is *higher* in memory
; than line 100.  That doesn't matter to a memory dump, of course,
; and the original Apple Cassette Interface is quite similar to
; the KIM-1 monitor, functionally.
;	This code is easily relocated anywhere there's room; just
; change the origin address.  Also, a good modification is to change
; the JMP $1800 instructions in the SAVE section to point to
; Hypertape, wherever you may have it (which I've done in this
; version).
; 	The MSG/TXT routine style is modeled after Jim Butterfield.
; ... we stand on the shoulders of giants...   DHH
;

* = $9400

	
TITLE2	LDX #TXT1-TXTBAS    ; display init msg
        JSR SNDTXT
	

GETCMD	JSR $1E5A	; GET A KEYSTROKE
	CMP #$53	; IS IT S?
	BEQ SAVE	; YES, GO TO SAVE SECTION
	CMP #$4C	; IS IT L?
	BEQ LOAD	; YES, GO TO LOAD SECTION
TESTR	CMP #$52	; IS IT R?
	BEQ EXIT2	; YES, RTS
	BNE GETCMD	; ... TRY AGAIN

EXIT2	RTS		; back to A1B after SAVE or RETURN

; SAVE SECTION, ZERO PAGE REQUIREMENTS FIRST

SAVE	LDA #$4C	; JMP to SAVE2 after a successful
	STA $00		; ZP save to store the main 
	LDA #<SAVE2	; program
	STA $01
	LDA #>SAVE2
	STA $02

	LDA #$4A	; set up a save from $4A to $FF
	STA $17F5	; KIM-1 start addr for DUMPT
	LDA #$FF
	STA $17F7	; KIM-1 end addr for DUMPT
	LDA #$00
	STA $17F6
	STA $17F8
	LDA #$AA	; 'AA': S=$53 + W=$57 -- Steve Wozniak
	STA $17F9	; make $AA the tape file ID
	LDX #TXT2-TXTBAS    ; display START REC msg
        JSR SNDTXT
CHRGET	JSR $1E5A	; call GETCH
	CMP #$0D	; is it <RET>?
	BNE CHRGET	; no? Try again
	LDA #$00
	STA $F1		; clear all proc flags for DUMPT
	JMP $9100	; to DUMPT (or Hypertape, somewhere else)

SAVE2	LDA #$4C	; to A1B warm start after a successful
	STA $00		; save of main program 
	LDA #$B3	; by typing 'G' at addr $0000
	STA $01
	LDA #$82
	STA $02

	LDA $CA		; get and store program start addr for save
	LDX $CB		; This is "end of user program" pointer
	STA $17F5	; in A1B, at *BOTTOM* of program
	STX $17F6
	LDA $4C		; get and store program end addr for save
	LDX $4D		; this is A1B HIMEM, top of program.
	STA $17F7	; ... yes, it's upside-down.
	STX $17F8
	LDA #$AA	; set file ID # and store
	STA $17F9
	LDX #TXT3-TXTBAS    ; display START REC for prog msg
        JSR SNDTXT
CHGET1	JSR $1E5A	; call GETCH
	CMP #$0D	; is it <RET>?
	BNE CHGET1	; no? Try again
	LDA #$00
	STA $F1		; clear all proc flags for DUMPT
	JMP $9100	; to DUMPT (or Hypertape, somewhere else)

; LOAD SECTION
	

LOAD	LDA #$4C	; JMP to A1B warm start after a successful
	STA $00		; save of main program 
	LDA #<LOAD2
	STA $01
	LDA #>LOAD2
	STA $02

	LDA #$AA	; set file ID and store
	STA $17F9	
	LDX #TXT4-TXTBAS    ; display START REC msg for Z Pg
        JSR SNDTXT
CHGET2	JSR $1E5A	; call GETCH
	CMP #$0D	; is it <RET>?
	BNE CHGET2	; no? Try again
	LDA #$00
	STA $F1		; clear all proc flags for LOADT
	JMP $1873	; jump to LOADT

LOAD2	LDA #$4C	; Back to A1B after a 
	STA $00		; successful load of main program 
	LDA #$B3	; by typing 'G' at addr $0000
	STA $01
	LDA #$82
	STA $02


	LDA #$AA	; set file ID and store
	STA $17F9	
	LDX #TXT5-TXTBAS    ; display START REC for main prog msg
        JSR SNDTXT
CHGET3	JSR $1E5A	; call GETCH
	CMP #$0D	; is it <RET>?
	BNE CHGET3	; no? Try again
	LDA #$00
	STA $F1		; clear all proc flags for LOADT
	JMP $1873	; jump to LOADT



; display message from table

SNDTXT	LDA TXTBAS,X
	BEQ RETRN2	
	JSR $1EA0	; call OUTCH
	INX
	BNE SNDTXT
RETRN2	RTS



TXTBAS  = *

TXT1			; 41 bytes
.BYTE 	$0A $0D
.BYTE	"Apple BASIC: (S)ave, (L)oad, (R)eturn?"
.BYTE 	$00

TXT2			; 47 bytes
.BYTE	$0A $0D 
.BYTE	"Set device to REC, hit <RET> to save Z-Pg."
.BYTE 	$0A $0D $00

TXT3			; 48 bytes
.BYTE	$0A $0D 
.BYTE	"Save program: set device to REC, hit <RET>."
.BYTE 	$0A $0D $00


; =====================

TXT4			; 50 bytes
.BYTE	$0A $0D 
.BYTE	"Hit <RET>, press PLAY on device to load Z-Pg."
.BYTE 	$0A $0D $00

TXT5			; 51 bytes
.BYTE	$0A $0D 
.BYTE	"Load program: hit <RET>, press PLAY on device."
.BYTE 	$0A $0D $00
