The quickest and easiest way to save the program is to do this …
Type LIST but not the return ..
Set your terminal program to ASCII capture..
Hit return to start the LIST command..
Once the list is complete stop the ASCII capture.
To load the program back there are two possible, similar, ways.
If your hardware supports hardware handshake properly just select the listing and use ASCII send to transfer it (You’ll need to edit the ‘Ready’ prompt from the end of the listing).
If your hardware doesn’t support hardware handshaking then you’ll need to paste a number of SPACE characters at the start of each line to give the interpreter enough time to tokenise the previous line. The number of spaces depends on two things, how fast your processor is and how fast the serial link is. The faster the processor the fewer spaces, the faster the serial link the more spaces. Otherwise just do as above.
(Alternately edit the NULL command to insert $20’s instead of $00’s into the start of each line and do ..
when you save the list)
If you want to save the program as binary you should save (Smeml) to (Svarl)-1.
If you want to save the program as ASCII you should redirect the character output vector to write to your filesystem and then call LIST. Doing this can also allow you to specify line numbers or ranges as with LIST. The output vector should be restored and the file closed when LIST returns or an error is encountered.
To load a binary program start loading it at (Smeml) and set (Svarl) to the last address + 1 then call LAB_1477 to clear the variables and reset the execution pointer. An easy way to do the first part is by copying (Smeml) to (Svarl) and using (Svarl) as a post incremented save pointer. If there is a chance that the program has been relocated it’s probably a good idea to rebuild the line pointer chain.
To load an ASCII program redirect the character input vector to read from your filesystem and return to the main interpreter loop. The input vector should be restored and the file closed when the file end is reached or an error is encountered.
I prefer ASCII format as it’s far more portable, easier to manipulate and can include direct commands and comment lines that aren’t saved to memory.
Is there an easy way to support a filename in the LOAD and save COMMANDs, and get access to that from my code? Right now I am prompting the user for it.
Call the evaluate following expression routine, LAB_EVEZ, and look for a string by testing if the data type flag, Dtypef, is negative. If it is the string descriptor is on the descriptor stack so don’t forget to pop it off there by calling LAB_22B6 once you’re done with it.
Daryl Rictor wrote a simple SAVE and LOAD program:
;******** LOAD & SAVE PATCH FOR ENHANCED BASIC ON 65C02 Simulator psave jsr pscan ldy #$00 lda itempl sta (itempl),y iny lda itemph sta (itempl),y ldx smeml lda smemh jsr print2byte jsr print_cr sec lda itempl sbc smeml tax lda itemph sbc smemh jsr print2byte jsr print_cr rts pload jsr pscan lda itempl sta svarl sta sarryl sta earryl lda itemph sta svarh sta sarryh sta earryh JMP LAB_1319 pscan lda smeml sta itempl lda smemh sta itemph pscan1 ldy #$00 lda (itempl),y bne pscan2 iny lda (itempl),y bne pscan2 clc lda #$02 adc itempl sta itempl lda #$00 adc itemph sta itemph rts pscan2 ldy #$00 lda (itempl),y tax iny lda (itempl),y sta itemph stx itempl bra pscan1
Another version of this:
;******** LOAD & SAVE PATCH FOR ENHANCED BASIC ON SBC-3 ; Daryl Rictor, Feb 2009 ; .include dos.lbl ; get DiskOS pointers ;input ; sbc scanned input ;output ; text output ;DiskOS ; diskos entry ;SaveF ; save program file from BASIC ;LoadF ; load program file from BASIC ;ibuffs+1 ($420) contains the name, start addr, end address psave ldx #$00 lda ibuffs+1 stz ibuffs+1 ; this fixes syntax error in ehbasic bne psave15 rts psave1 lda ibuffs+1,x stz ibuffs+1,x ; this fixes syntax error in ehbasic beq psave3 psave15 cmp #$b9 bne psave2 lda #"/" psave2 sta buffer+2,x inx cpx #$46 bne psave1 rts ; entry too long, abort psave3 lda #"," sta buffer+2,x inx phx jsr pscan ; Find end of program plx lda smemh jsr ToHex lda smeml jsr ToHex lda #"," sta buffer+2,x inx lda itemph jsr ToHex lda itempl jsr ToHex lda #$00 sta buffer+2,x jsr SaveF ; save file to IDE (in DiskOS) rts pload ldx #$00 lda ibuffs+1 stz ibuffs+1 ; this fixes syntax error in ehbasic bne pload15 rts pload1 lda ibuffs+1,x beq pload3 pload15 cmp #$b9 bne pload2 lda #"/" pload2 sta buffer+2,x inx cpx #$47 bne pload1 rts ; entry too long, abort pload3 lda #$00 sta buffer+2,x jsr Loadf ; load file from IDE (in DiskOS) jsr pscan lda itempl sta svarl sta sarryl sta earryl lda itemph sta svarh sta sarryh sta earryh JMP LAB_1319 pscan lda smeml sta itempl lda smemh sta itemph pscan1 ldy #$00 lda (itempl),y bne pscan2 iny lda (itempl),y bne pscan2 clc lda #$02 adc itempl sta itempl lda #$00 adc itemph sta itemph rts pscan2 ldy #$00 lda (itempl),y tax iny lda (itempl),y sta itemph stx itempl bra pscan1 SysJMP JSR Main_Loop ; in DiskOS rts ToHex PHA ; prints AA hex digits LSR ; MOVE UPPER NIBBLE TO LOWER LSR ; LSR ; LSR ; JSR SaveDig ; PLA ; SaveDig AND #$0F ; CMP #$0A ; BCC SaveDig1 ; ADC #$66 ; SaveDig1 EOR #$30 ; sta buffer+2,x ; inx rts
And another approach:
There seems to be quite a lot of mixed information about how to deal with string arguments in LOAD and SAVE. I’d like to present the way I came up with:
At the beginning of either LOAD and SAVE, i call a subroutine that gets the string argument using LAB_EVEX and opens the file:
openfile: jsr LAB_EVEX lda Dtypef bne @go ; not a string, trigger syntax error ldx #$02 jsr LAB_XERR @go: ldy #$00 @l: lda (ssptr_l),y beq @open cmp #'"' beq @term iny bne @l @term: lda #$00 sta (ssptr_l),y @open: lda ssptr_l ldx ssptr_h jsr krn_open bne io_error rts io_error: pha jsr krn_primm .asciiz "io error: " pla jmp krn_hexout
As it seems, after calling LAB_EVEX, ssptr points to the string given as parameter including the closing “, which I overwrite with $00 to be compatible with my open routine, which expects the address of a null terminated string.
In another thread, it was suggested to pop the string from the descriptor stack using LAB_22B6, which in my case resulted in ut1_ph/l not pointing to the string, but anywhere in the area of $exxx, where my os resides. So I went for the above approach. It works, but it feels rather dirty due to the overwriting of the closing “. At this point, I am open for suggestions.