LOAD/SAVE of BASIC files
This commit is contained in:
1 parent
e6a2af6f8a
commit
33faa4fac2
9 files changed
+353
-2887
No files matched your search
+318
-1
@@ -1,3 +1,320 @@
|
||||
.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
|
||||
Reference in new issue
Block a user