LOAD/SAVE of BASIC files
This commit is contained in:
1 parent
e6a2af6f8a
commit
33faa4fac2
9 files changed
+352
-2886
No files matched your search
File diff suppressed because it is too large.
Load diff
@@ -0,0 +1,24 @@
|
|||||||
|
10 REM ENDLESS RULE 30
|
||||||
|
20 W=78
|
||||||
|
30 DIM A(79),B(79)
|
||||||
|
40 FOR I=1 TO W
|
||||||
|
50 A(I)=INT(RND(1)*2)
|
||||||
|
60 NEXT I
|
||||||
|
70 E$=CHR$(27)
|
||||||
|
80 PRINT E$;"[2J";E$;"[H";
|
||||||
|
|
||||||
|
90 A(0)=A(W)
|
||||||
|
100 A(W+1)=A(1)
|
||||||
|
|
||||||
|
110 FOR I=1 TO W
|
||||||
|
120 POKE 48128,32+10*A(I)
|
||||||
|
130 B(I)=ABS(A(I-1)-(A(I) OR A(I+1)))
|
||||||
|
140 NEXT I
|
||||||
|
|
||||||
|
150 POKE 48128,10
|
||||||
|
|
||||||
|
160 FOR I=1 TO W
|
||||||
|
170 A(I)=B(I)
|
||||||
|
180 NEXT I
|
||||||
|
|
||||||
|
190 GOTO 90
|
||||||
@@ -1 +0,0 @@
|
|||||||
tmp/
|
|
||||||
@@ -9,6 +9,7 @@ PR_WRITTEN_BY:
|
|||||||
COLD_START:
|
COLD_START:
|
||||||
lda #$00
|
lda #$00
|
||||||
sta CURDVC
|
sta CURDVC
|
||||||
|
sta LOAD_ACTIVE
|
||||||
ldx #$FF
|
ldx #$FF
|
||||||
stx CURLIN+1
|
stx CURLIN+1
|
||||||
ldx #$FB
|
ldx #$FB
|
||||||
|
|||||||
+318
-1
@@ -1,3 +1,320 @@
|
|||||||
.segment "CODE"
|
.segment "CODE"
|
||||||
|
|
||||||
; None yet
|
LOADSAVE_LFN = $FF
|
||||||
|
|
||||||
|
; ============================================================================
|
||||||
|
; COPY STRING EXPRESSION TO FILE_NAME_BUFFER
|
||||||
|
;
|
||||||
|
; Entry:
|
||||||
|
; TXTPTR points at string expression
|
||||||
|
;
|
||||||
|
; Exit:
|
||||||
|
; FILE_NAME_BUFFER contains NUL-terminated filename
|
||||||
|
;
|
||||||
|
; Clobbers:
|
||||||
|
; A,X,Y,INDEX,STRNG2
|
||||||
|
; ============================================================================
|
||||||
|
PARSE_LOADSAVE_FILENAME:
|
||||||
|
jsr FRMEVL
|
||||||
|
jsr CHKSTR
|
||||||
|
jsr FREFAC
|
||||||
|
; FREFAC:
|
||||||
|
; A = length
|
||||||
|
; INDEX = string address
|
||||||
|
sta STRNG2
|
||||||
|
ldy #$00
|
||||||
|
@copy:
|
||||||
|
cpy STRNG2
|
||||||
|
beq @done
|
||||||
|
lda (INDEX),y
|
||||||
|
sta FILE_NAME_BUFFER,y
|
||||||
|
iny
|
||||||
|
bne @copy
|
||||||
|
@done:
|
||||||
|
lda #$00
|
||||||
|
sta FILE_NAME_BUFFER,y
|
||||||
|
rts
|
||||||
|
|
||||||
|
; ============================================================================
|
||||||
|
; SET UP THE COMMON FILE ARGUMENTS
|
||||||
|
; ============================================================================
|
||||||
|
LOADSAVE_SET_FILE:
|
||||||
|
lda #LOADSAVE_LFN
|
||||||
|
sta IO_FILE_DESCRIPTOR
|
||||||
|
lda #<FILE_NAME_BUFFER
|
||||||
|
sta IO_FILE_DATA
|
||||||
|
lda #>FILE_NAME_BUFFER
|
||||||
|
sta IO_FILE_DATA+1
|
||||||
|
rts
|
||||||
|
|
||||||
|
; ============================================================================
|
||||||
|
; WAIT FOR FILE COMMAND COMPLETION
|
||||||
|
;
|
||||||
|
; Jumps to IQERR on host-side failure.
|
||||||
|
; ============================================================================
|
||||||
|
LOADSAVE_WAIT:
|
||||||
|
lda IO_FILE_STATUS
|
||||||
|
and #FILE_STATUS_READY
|
||||||
|
beq LOADSAVE_WAIT
|
||||||
|
lda IO_FILE_STATUS
|
||||||
|
and #FILE_STATUS_ERROR
|
||||||
|
beq @ok
|
||||||
|
jmp IQERR
|
||||||
|
@ok:
|
||||||
|
rts
|
||||||
|
|
||||||
|
|
||||||
|
; ============================================================================
|
||||||
|
; OPEN FOR READING
|
||||||
|
; ============================================================================
|
||||||
|
LOADSAVE_OPEN_R:
|
||||||
|
jsr LOADSAVE_SET_FILE
|
||||||
|
lda #IO_COMMAND_OPEN_R
|
||||||
|
sta IO_FILE_COMMAND
|
||||||
|
jmp LOADSAVE_WAIT
|
||||||
|
|
||||||
|
; ============================================================================
|
||||||
|
; OPEN FOR WRITING / TRUNCATE
|
||||||
|
; ============================================================================
|
||||||
|
LOADSAVE_OPEN_W:
|
||||||
|
jsr LOADSAVE_SET_FILE
|
||||||
|
lda #IO_COMMAND_OPEN_W
|
||||||
|
sta IO_FILE_COMMAND
|
||||||
|
jmp LOADSAVE_WAIT
|
||||||
|
|
||||||
|
; ============================================================================
|
||||||
|
; CLOSE INTERNAL LOAD/SAVE FILE
|
||||||
|
; ============================================================================
|
||||||
|
LOADSAVE_CLOSE:
|
||||||
|
lda #LOADSAVE_LFN
|
||||||
|
sta IO_FILE_DESCRIPTOR
|
||||||
|
lda #IO_COMMAND_CLOSE
|
||||||
|
sta IO_FILE_COMMAND
|
||||||
|
jsr LOADSAVE_WAIT
|
||||||
|
jsr CLRCH
|
||||||
|
rts
|
||||||
|
|
||||||
|
; ============================================================================
|
||||||
|
; SAVE "filename"
|
||||||
|
;
|
||||||
|
; Saves plain ASCII BASIC source, equivalent to LIST output.
|
||||||
|
; ============================================================================
|
||||||
|
SAVE:
|
||||||
|
jsr PARSE_LOADSAVE_FILENAME
|
||||||
|
jsr LOADSAVE_OPEN_W
|
||||||
|
; Route OUTDO/CHROUT to our internal file.
|
||||||
|
ldx #LOADSAVE_LFN
|
||||||
|
jsr CHKOUT
|
||||||
|
stx CURDVC
|
||||||
|
; Start with first BASIC line.
|
||||||
|
lda TXTTAB
|
||||||
|
sta LOWTRX
|
||||||
|
lda TXTTAB+1
|
||||||
|
sta LOWTRX+1
|
||||||
|
SAVE_NEXT_LINE:
|
||||||
|
; The high byte of the forward link is zero at end of program.
|
||||||
|
ldy #$01
|
||||||
|
lda (LOWTRX),y
|
||||||
|
beq SAVE_DONE
|
||||||
|
; ------------------------------------------------------------
|
||||||
|
; Print line number.
|
||||||
|
;
|
||||||
|
; record:
|
||||||
|
; +0/+1 = next line
|
||||||
|
; +2/+3 = line number
|
||||||
|
; +4... = tokenized body
|
||||||
|
; ------------------------------------------------------------
|
||||||
|
iny ; Y=2
|
||||||
|
lda (LOWTRX),y
|
||||||
|
tax
|
||||||
|
iny ; Y=3
|
||||||
|
lda (LOWTRX),y
|
||||||
|
jsr LINPRT
|
||||||
|
lda #' '
|
||||||
|
jsr OUTDO
|
||||||
|
; DATAFLG follows LIST's quoting/token rules.
|
||||||
|
lda #$01
|
||||||
|
sta DATAFLG
|
||||||
|
ldy #$04
|
||||||
|
SAVE_LINE_CHAR:
|
||||||
|
lda (LOWTRX),y
|
||||||
|
beq SAVE_LINE_DONE
|
||||||
|
; Test whether it's plain ASCII/token BEFORE doing CMPs
|
||||||
|
bpl SAVE_PLAIN_CHAR
|
||||||
|
cmp #$FF
|
||||||
|
beq SAVE_PLAIN_CHAR
|
||||||
|
bit DATAFLG
|
||||||
|
bmi SAVE_PLAIN_CHAR
|
||||||
|
; Token
|
||||||
|
sec
|
||||||
|
sbc #$7F
|
||||||
|
tax
|
||||||
|
sty FORPNT
|
||||||
|
ldy #$FF
|
||||||
|
SAVE_FIND_TOKEN:
|
||||||
|
dex
|
||||||
|
beq SAVE_TOKEN_FOUND
|
||||||
|
SAVE_SKIP_TOKEN:
|
||||||
|
iny
|
||||||
|
lda TOKEN_NAME_TABLE,y
|
||||||
|
bpl SAVE_SKIP_TOKEN
|
||||||
|
bmi SAVE_FIND_TOKEN
|
||||||
|
SAVE_TOKEN_FOUND:
|
||||||
|
iny
|
||||||
|
lda TOKEN_NAME_TABLE,y
|
||||||
|
bmi SAVE_TOKEN_LAST
|
||||||
|
jsr OUTDO
|
||||||
|
bne SAVE_TOKEN_FOUND
|
||||||
|
SAVE_TOKEN_LAST:
|
||||||
|
and #$7F
|
||||||
|
jsr OUTDO
|
||||||
|
ldy FORPNT
|
||||||
|
iny
|
||||||
|
jmp SAVE_LINE_CHAR
|
||||||
|
SAVE_PLAIN_CHAR:
|
||||||
|
and #$7F
|
||||||
|
jsr OUTDO
|
||||||
|
; Quote state must be updated AFTER output/test.
|
||||||
|
cmp #$22
|
||||||
|
bne SAVE_PLAIN_DONE
|
||||||
|
lda DATAFLG
|
||||||
|
eor #$FF
|
||||||
|
sta DATAFLG
|
||||||
|
SAVE_PLAIN_DONE:
|
||||||
|
iny
|
||||||
|
jmp SAVE_LINE_CHAR
|
||||||
|
SAVE_LINE_DONE:
|
||||||
|
; Every saved source line ends in LF.
|
||||||
|
jsr LFDO
|
||||||
|
; Follow next-line pointer.
|
||||||
|
ldy #$00
|
||||||
|
lda (LOWTRX),y
|
||||||
|
tax
|
||||||
|
iny
|
||||||
|
lda (LOWTRX),y
|
||||||
|
stx LOWTRX
|
||||||
|
sta LOWTRX+1
|
||||||
|
jmp SAVE_NEXT_LINE
|
||||||
|
SAVE_DONE:
|
||||||
|
jsr LOADSAVE_CLOSE
|
||||||
|
rts
|
||||||
|
|
||||||
|
; ============================================================================
|
||||||
|
; LOAD "filename"
|
||||||
|
;
|
||||||
|
; Replaces current program.
|
||||||
|
; Reads ASCII source one line at a time, tokenizes through the normal
|
||||||
|
; BASIC parser, and inserts using NUMBERED_LINE.
|
||||||
|
;
|
||||||
|
; IMPORTANT:
|
||||||
|
; NUMBERED_LINE eventually reaches FIX_LINKS -> SETPTRS -> STKINI, which
|
||||||
|
; resets the hardware stack. Therefore LOAD cannot expect NUMBERED_LINE to
|
||||||
|
; return with RTS. FIX_LINKS jumps back to LOAD_NEXT_LINE while LOAD_ACTIVE
|
||||||
|
; is set.
|
||||||
|
; ============================================================================
|
||||||
|
|
||||||
|
LOAD:
|
||||||
|
; Copy the filename before SCRTCH destroys temporary strings.
|
||||||
|
jsr PARSE_LOADSAVE_FILENAME
|
||||||
|
jsr LOADSAVE_OPEN_R
|
||||||
|
; Delete current program.
|
||||||
|
jsr SCRTCH
|
||||||
|
; Route CHRIN to the file.
|
||||||
|
ldx #LOADSAVE_LFN
|
||||||
|
jsr CHKIN
|
||||||
|
stx CURDVC
|
||||||
|
; Tell FIX_LINKS that program insertion belongs to LOAD.
|
||||||
|
lda #$01
|
||||||
|
sta LOAD_ACTIVE
|
||||||
|
; ----------------------------------------------------------------------------
|
||||||
|
; Entry point used both initially and by FIX_LINKS after inserting each line.
|
||||||
|
; Must be a globally visible label if FIX_LINKS lives in another source file.
|
||||||
|
; ----------------------------------------------------------------------------
|
||||||
|
LOAD_NEXT_LINE:
|
||||||
|
ldx #$00
|
||||||
|
; ----------------------------------------------------------------------------
|
||||||
|
; Read one physical source line into INPUTBUFFER.
|
||||||
|
;
|
||||||
|
; "10 PRINT 1\n" -> normal line
|
||||||
|
; "10 PRINT 1"<EOF> -> final line still accepted
|
||||||
|
; EOF with X=0 -> done loading
|
||||||
|
; ----------------------------------------------------------------------------
|
||||||
|
@read_char:
|
||||||
|
jsr CHRIN
|
||||||
|
; If host says EOF, A is not considered valid data.
|
||||||
|
pha
|
||||||
|
lda IO_FILE_STATUS
|
||||||
|
and #FILE_STATUS_EOF
|
||||||
|
bne @eof
|
||||||
|
pla
|
||||||
|
; LF terminates a source line.
|
||||||
|
cmp #LF
|
||||||
|
beq @line_complete
|
||||||
|
; Accept CRLF files too.
|
||||||
|
cmp #$0D
|
||||||
|
beq @read_char
|
||||||
|
; Same practical line limit as interactive INLIN.
|
||||||
|
cpx #$47
|
||||||
|
bcs @line_too_long
|
||||||
|
sta INPUTBUFFER,x
|
||||||
|
inx
|
||||||
|
jmp @read_char
|
||||||
|
@eof:
|
||||||
|
pla
|
||||||
|
; EOF with no accumulated characters means real end of file.
|
||||||
|
cpx #$00
|
||||||
|
beq @load_done
|
||||||
|
; Otherwise process the unterminated final line.
|
||||||
|
@line_complete:
|
||||||
|
lda #$00
|
||||||
|
sta INPUTBUFFER,x
|
||||||
|
; Point CHRGET at INPUTBUFFER-1, exactly like INLIN returns.
|
||||||
|
lda #<(INPUTBUFFER-1)
|
||||||
|
sta TXTPTR
|
||||||
|
lda #>(INPUTBUFFER-1)
|
||||||
|
sta TXTPTR+1
|
||||||
|
jsr CHRGET
|
||||||
|
; Ignore empty physical lines.
|
||||||
|
beq LOAD_NEXT_LINE
|
||||||
|
; A source file must consist of numbered program lines.
|
||||||
|
;
|
||||||
|
; CHRGET leaves carry clear for a leading decimal digit,
|
||||||
|
; exactly like the normal RESTART path.
|
||||||
|
bcc @numbered
|
||||||
|
jmp @syntax_error
|
||||||
|
@numbered:
|
||||||
|
; NUMBERED_LINE performs:
|
||||||
|
;
|
||||||
|
; LINGET
|
||||||
|
; PARSE_INPUT_LINE
|
||||||
|
; FNDLIN
|
||||||
|
; PUT_NEW_LINE
|
||||||
|
; FIX_LINKS
|
||||||
|
;
|
||||||
|
; DO NOT JSR here.
|
||||||
|
;
|
||||||
|
; FIX_LINKS eventually calls SETPTRS/STKINI, which resets the
|
||||||
|
; hardware stack. FIX_LINKS will detect LOAD_ACTIVE and jump back
|
||||||
|
; to LOAD_NEXT_LINE.
|
||||||
|
jmp NUMBERED_LINE
|
||||||
|
@line_too_long:
|
||||||
|
@syntax_error:
|
||||||
|
lda #$00
|
||||||
|
sta LOAD_ACTIVE
|
||||||
|
|
||||||
|
jsr CLRCH
|
||||||
|
jsr LOADSAVE_CLOSE
|
||||||
|
jmp SYNERR
|
||||||
|
@load_done:
|
||||||
|
lda #$00
|
||||||
|
sta LOAD_ACTIVE
|
||||||
|
jsr CLRCH
|
||||||
|
jsr LOADSAVE_CLOSE
|
||||||
|
; Do NOT JSR SETPTRS here.
|
||||||
|
;
|
||||||
|
; Every successfully inserted line already passed through
|
||||||
|
; FIX_LINKS -> SETPTRS -> LE33D.
|
||||||
|
;
|
||||||
|
; Also do not RTS: SETPTRS/STKINI during loading may have destroyed
|
||||||
|
; the original LOAD command's return frame.
|
||||||
|
jmp RESTART
|
||||||
@@ -6,7 +6,6 @@
|
|||||||
.include "defines.s"
|
.include "defines.s"
|
||||||
.include "macros.s"
|
.include "macros.s"
|
||||||
.include "zeropage.s"
|
.include "zeropage.s"
|
||||||
|
|
||||||
.include "header.s"
|
.include "header.s"
|
||||||
.include "token.s"
|
.include "token.s"
|
||||||
.include "error.s"
|
.include "error.s"
|
||||||
|
|||||||
@@ -168,6 +168,10 @@ L23E6:
|
|||||||
FIX_LINKS:
|
FIX_LINKS:
|
||||||
jsr SETPTRS
|
jsr SETPTRS
|
||||||
jsr LE33D
|
jsr LE33D
|
||||||
|
lda LOAD_ACTIVE
|
||||||
|
beq :+
|
||||||
|
jmp LOAD_NEXT_LINE
|
||||||
|
:
|
||||||
jmp L2351
|
jmp L2351
|
||||||
LE33D:
|
LE33D:
|
||||||
lda TXTTAB
|
lda TXTTAB
|
||||||
|
|||||||
+3
-1
@@ -1,6 +1,6 @@
|
|||||||
init_token_tables
|
init_token_tables
|
||||||
|
|
||||||
keyword_rts "WOZMON", RESET
|
keyword_rts "WOZ", RESET
|
||||||
|
|
||||||
keyword_rts "END", END
|
keyword_rts "END", END
|
||||||
keyword_rts "FOR", FOR
|
keyword_rts "FOR", FOR
|
||||||
@@ -21,6 +21,8 @@
|
|||||||
keyword_rts "STOP", STOP
|
keyword_rts "STOP", STOP
|
||||||
keyword_rts "ON", ON
|
keyword_rts "ON", ON
|
||||||
keyword_rts "WAIT", WAIT
|
keyword_rts "WAIT", WAIT
|
||||||
|
keyword_rts "LOAD", LOAD
|
||||||
|
keyword_rts "SAVE", SAVE
|
||||||
keyword_rts "DEF", DEF
|
keyword_rts "DEF", DEF
|
||||||
keyword_rts "POKE", POKE
|
keyword_rts "POKE", POKE
|
||||||
keyword_rts "PRINT#", PRINTH
|
keyword_rts "PRINT#", PRINTH
|
||||||
|
|||||||
@@ -151,6 +151,8 @@ STRNG2:
|
|||||||
.res 2
|
.res 2
|
||||||
CURDVC:
|
CURDVC:
|
||||||
.res 1
|
.res 1
|
||||||
|
LOAD_ACTIVE:
|
||||||
|
.res 1
|
||||||
FILE_NAME_BUFFER = $0300
|
FILE_NAME_BUFFER = $0300
|
||||||
CHRGET:
|
CHRGET:
|
||||||
TXTPTR = <(GENERIC_TXTPTR-GENERIC_CHRGET + CHRGET)
|
TXTPTR = <(GENERIC_TXTPTR-GENERIC_CHRGET + CHRGET)
|
||||||
|
|||||||
Reference in new issue
Block a user