Files
open-roms/c64/basic/cmd_load.s
T
2019-06-24 19:06:23 +02:00

159 lines
3.4 KiB
ArmAsm

cmd_load:
;; Parse filename
;; (we can tell the KERNAL where it is in memory directly, since the
;; KERNAL will be able to peek under ROMs to read it, since it will have
;; to be able to peek under the ROMs for SAVE and VERIFY).
;; Parse optional device #
;; Parse optional secondary address
;; XXX - C64 BASIC apparently doesn't clear variables after a LOAD in the
;; middle of a program. For safety, we do.
jsr basic_do_clr
;; XXX temporary, to set valid device number
lda #$08
sta current_device_number
;; Set filename and length
lda #$00
sta current_filename_length
;; Without tape support, LOAD must have a filename
;; (This also skips any leading spaces)
jsr basic_end_of_statement_check
bcc +
jmp do_MISSING_FILENAME_error
*
jsr basic_fetch_and_consume_character
cmp #$22
beq +
jmp do_SYNTAX_ERROR
*
;; Filename starts here so set pointer
lda basic_current_statement_ptr+0
sta current_filename_ptr+0
lda basic_current_statement_ptr+1
sta current_filename_ptr+1
;; Now search for end of line or closing quote
;; so that we know the length of the filename
getting_filename:
jsr basic_fetch_and_consume_character
cmp #$22
beq got_filename
cmp #$00
bne +
jsr basic_unconsume_character
jmp got_filename
*
inc current_filename_length
jmp getting_filename
got_filename:
;; Try to load an IEC file
lda #0 ; use supplied load address, not the one from the file
sta current_secondary_address
lda #$00 ; LOAD not verify
ldx #<$0801 ; LOAD address = $0801
ldy #>$0801
jsr $ffd5
bcc +
;; A = KERNAL error code, which also almost match
;; basic ERROR codes, so we can just copy the
;; error code to X, decrement, and handle normally
tax
dex
jmp do_basic_error
*
;; $YYXX is the last loaded address, so store it
stx basic_end_of_text_ptr+0
sty basic_end_of_text_ptr+1
;; Now relink the loaded program, as we cannot trust the line
;; links supplied. For example, the VICE virtual drive emulation
;; always supplies $0101 as the address of the next line.
jsr basic_relink_program
;; After LOADing, we either start the program from the beginning,
;; or go back to the READY prompt if LOAD was called from direct mode.
;; Reset to start of program
lda basic_start_of_text_ptr+0
sta basic_current_line_ptr+0
lda basic_start_of_text_ptr+1
sta basic_current_line_ptr+1
;; XXX - should run program if LOAD was used in program mode
jmp basic_main_loop
basic_relink_program:
;; Start by getting pointer to the first line
lda basic_start_of_text_ptr+0
sta basic_current_line_ptr+0
lda basic_start_of_text_ptr+1
sta basic_current_line_ptr+1
basic_relink_loop:
;; Is the pointer to the end of the program
ldy #1
ldx #<basic_current_line_ptr+0
jsr peek_under_roms
cmp #$00
bne +
;; End of program
rts
*
;; Now search forward to find the end of the line
;; Skip forward pointer and line number
ldy #4
end_of_line_search:
ldx #<basic_current_line_ptr+0
jsr peek_under_roms
cmp #$00
beq +
;; Not yet end of line
iny
bne end_of_line_search
;; line too long
jmp do_STRING_TOO_LONG_error
*
;; Found end of line, so update pointer
;; First, skip over the $00 char
iny
;; Now overwrite the pointer (carefully)
;;
tya
clc
adc basic_current_line_ptr+0
pha
php
ldy #0
ldx #<basic_current_line_ptr+0
jsr poke_under_roms
plp
lda basic_current_line_ptr+1
adc #0
ldy #1
jsr poke_under_roms
sta basic_current_line_ptr+1
pla
sta basic_current_line_ptr+0
jmp basic_relink_loop