refactored LOAD routine so that it's parts are reuseable

This commit is contained in:
FeralChild64 committed 2019-07-19 17:23:11 +02:00
1 parent 66047996bb
commit da4cc3a89b
12 files changed
+269 -231

No files matched your search

+82 -23
View File
@@ -1,33 +1,92 @@
;;
;; Names of ZP and low memory locations (only the implemented ones)
;; Names of ZP and low memory locations
;; (https://www.c64-wiki.com/wiki/Zeropage)
;;
;; $000-$001 - 6502 CPU registers
;; $00-$01 - 6502 CPU registers are here
;;
;; Page 0 - BASIC area ($02-$8F)
;;
.alias TXTTAB $2B
;;
;; Page 0 - Kernal area ($90-$FF)
;;
.alias IOSTATUS $90
.alias STKEY $91 ; Keys down clears bits. STOP - bit 7, C= - bit 6, SPACE - bit 4, CTRL - bit 2
.alias VERCK $93 ; 0 = LOAD, 1 = VERIVY
.alias C3PO $94 ; flag - is BSOUR content valid
.alias BSOUR $95 ; serial bus buffered output byte
.alias LDTND $98 ; number of entries in LAT / FAT / SAT tables
.alias DFLTN $99
.alias DFLTO $9A
.alias MSGFLG $9D ; bit 6 = error messages, bit 7 = control message
.alias TIME $A0 ; $A0-$A2, jiffy clock
;; 2-byte location below seems to be a good place for temporary storage,
;; it seems used for timing during tape reads only - see:
;; - 'C64 Programmer's Reference Guide', page 314
;; - 'Compute's Mapping the Commodore 64', page 32
.alias CMP0 $B0 ; $B0-$B1
.alias FNLEN $B7 ; current file name length
.alias STAL $C1 ; $C1-$C2 LOAD/SAVE start address
;;
;; Other low memory addresses
;;
;; Kernal tables for opened files, 10 entries each
.alias LAT $259 ; logical file numbers
.alias FAT $263 ; device numbers
.alias SAT $26D ; secondary addresses
.alias MEMSTR $281
.alias MEMSIZ $283 ; NOTE: Mapping the 64 erroniously has the hex as $282, while the DEC is correct
.alias HIBASE $288 ; high byte of start of screen
.alias RSSTAT $297 ; RS-232 status
.alias PALNTSC $2A6 ; 0 = NTSC, 1 = PAL
;; Registers for SYS call
.alias sys_reg_a $30c
.alias sys_reg_x $30d
.alias sys_reg_y $30e
.alias sys_reg_p $30f
.alias sys_jmp $310
.alias SAREG $30C
.alias SXREG $30D
.alias SYREG $30E
.alias SPREG $30F
.alias USRPOK $310 ; JMP instruction
.alias USRADD $311 ; $311 - $312
;; Kernal vectors - interrupts
.alias CINV $0314
.alias CBINV $0316
.alias NMINV $0318
.alias CINV $314
.alias CBINV $316
.alias NMINV $318
;; Kernal vectors - routines
.alias IOPEN $031A
.alias ICLOSE $031C
.alias ICHKIN $031E
.alias ICKOUT $0320
.alias ICLRCH $0322
.alias IBASIN $0324
.alias IBASOUT $0326
.alias ISTOP $0328
.alias IGETIN $032A
.alias ICLALL $032C
.alias USRCMD $032E
.alias ILOAD $0330
.alias ISAVE $0331
.alias IOPEN $31A
.alias ICLOSE $31C
.alias ICHKIN $31E
.alias ICKOUT $320
.alias ICLRCH $322
.alias IBASIN $324
.alias IBASOUT $326
.alias ISTOP $328
.alias IGETIN $32A
.alias ICLALL $32C
.alias USRCMD $32E
.alias ILOAD $330
.alias ISAVE $331
.alias TBUFFR $33C ; $33C-$3FB, tape buffer
+1 -31
View File
@@ -52,33 +52,13 @@
.alias memmove_dst $6b
.alias memmove_size $6d
.alias TXTTAB $2B
.alias IOSTATUS $90
; Keys down clears bits. STOP=bit 7, C= bit 6, SPACE bit 4, CTRL bit 2
.alias BUCKYSTATUS $91
.alias load_or_verify_flag $93
.alias C3PO $94 ; flag - is BSOUR content valid
.alias BSOUR $95 ; serial bus buffered output byte
.alias current_file_num $98
.alias LDTND $98 ; number of entries in LAT / FAT / SAT tables
.alias DFLTN $99
.alias input_device_number DFLTN
.alias MSGFLG $9D ; bit 6 = error messages, bit 7 = control message
.alias jiffy_clock_24bits $a0
.alias cassette_buffer_bytes_used $A6
.alias load_or_scroll_temp_pointer $AC
;; We also use the following for temp colour pointer when scrolling
.alias load_save_verify_end_address $AE
;; 2-byte location below seems to be a good place for temporary storage,
;; it seems used for timing during tape reads only - see:
;; - 'C64 Programmer's Reference Guide', page 314
;; - 'Compute's Mapping the Commodore 64', page 32
.alias CMP0 $B0 ;; $B0-$B1
.alias cassette_buffer_ptr $B2
.alias current_filename_length $B7
.alias current_logical_filenum $B8
.alias current_secondary_address $B9
.alias current_device_number $BA
@@ -112,19 +92,11 @@
.alias rs232_tx_buffer_ptr $F9
.alias basic_input_buffer $0200
;; Kernal tables for opened files, 10 entries each
.alias LAT $0259 ; logical file numbers
.alias FAT $0263 ; device numbers
.alias SAT $026D ; secondary addresses
; "Compute's Mapping the 64" book
.alias keyboard_buffer $0277
.alias MEMSTR $0281
.alias MEMSIZ $0283 ; NOTE: Mapping the 64 erroniously has the hex as $282, while the DEC is correct
.alias text_colour $0286 ; p55
.alias colour_under_cursor $0287 ; p56
.alias HIBASE $0288 ; p56 (high byte of start of screen)
.alias key_buffer_size $0289 ; p57
;; 0 = cursor keys, insert, delete and space repeat, but nothing else
@@ -140,8 +112,6 @@
.alias keyboard_decoding_ptr $028F
.alias enable_case_switch $0291
.alias screen_scroll_disable $0292
.alias RSSTAT $0297 ; RS-232 status
.alias pal_or_ntsc $02A6
;; BASIC uses some extra bytes for memory access under ROMs located at $2A7 onwards
;; IRQs are disabled when doing such accesses, and a default NMI handler only increments
+1 -1
View File
@@ -29,7 +29,7 @@ no_space_to_skip:
basic_execute_statement:
;; Check for RUN/STOP
lda BUCKYSTATUS
lda STKEY
bpl basic_do_break
;; Skip over any white space and :
+1 -1
View File
@@ -22,7 +22,7 @@ list_loop:
jmp basic_main_loop
list_more_lines:
lda BUCKYSTATUS
lda STKEY
bmi +
jmp basic_do_break
*
+2 -2
View File
@@ -26,7 +26,7 @@ cmd_load:
;; Set filename and length
lda #$00
sta current_filename_length
sta FNLEN
;; Without tape support, LOAD must have a filename
;; (This also skips any leading spaces)
@@ -57,7 +57,7 @@ getting_filename:
jmp got_filename
*
inc current_filename_length
inc FNLEN
jmp getting_filename
got_filename:
+9 -9
View File
@@ -10,22 +10,22 @@ cmd_sys:
jsr basic_parse_line_number
;; setup call
lda #$4c ;JMP
sta sys_jmp
lda #$4C ;JMP
sta USRPOK
lda basic_line_number+0
sta sys_jmp+1
sta USRADD+0
lda basic_line_number+1
sta sys_jmp+2
sta USRADD+1
;; Setup the register values
lda sys_reg_p
lda SPREG
pha
ldy sys_reg_y
ldx sys_reg_x
lda sys_reg_a
ldy SYREG
ldx SXREG
lda SAREG
plp
;; Call the routine.
jsr sys_jmp
jsr USRPOK
jmp basic_execute_statement
-28
View File
@@ -3,30 +3,18 @@
; (And only those for now that we feel the need to implement initially)
; (https://www.c64-wiki.com/wiki/Zeropage)
.alias TXTTAB $2B
.alias IOSTATUS $90
; Keys down clears bits. STOP=bit 7, C= bit 6, SPACE bit 4, CTRL bit 2
.alias BUCKYSTATUS $91
.alias kernal_load_or_verify_flag $93
.alias C3PO $94 ; flag - is BSOUR content valid
.alias BSOUR $95 ; serial bus buffered output byte
.alias current_file_num $98
.alias LDTND $98 ; number of entries in LAT / FAT / SAT tables
.alias DFLTN $99
.alias input_device_number DFLTN
.alias MSGFLG $9D ; bit 6 = error messages, bit 7 = control message
.alias jiffy_clock_24bits $a0
.alias cassette_buffer_bytes_used $A6
.alias load_or_scroll_temp_pointer $AC
;; We also use the following for temp colour pointer when scrolling
.alias load_save_verify_end_address $AE
.alias cassette_buffer_ptr $B2
.alias current_filename_length $B7
.alias current_logical_filenum $B8
.alias current_secondary_address $B9
.alias current_device_number $BA
.alias current_filename_ptr $BB
.alias load_save_start_ptr $C1
.alias load_save_end_ptr $C3
.alias last_key_matrix_position $C5
.alias keys_in_key_buffer $C6
@@ -53,25 +41,11 @@
.alias keyboard_decoding_table_ptr $F5
.alias rs232_rx_buffer_ptr $F7
.alias rs232_tx_buffer_ptr $F9
;; 2-byte location below seems to be a good place for temporary storage,
;; it seems used for timing during tape reads only - see:
;; - 'C64 Programmer's Reference Guide', page 314
;; - 'Compute's Mapping the Commodore 64', page 32
.alias CMP0 $B0 ;; $B0-$B1
;; Kernal tables for opened files, 10 entries each
.alias LAT $0259 ; logical file numbers
.alias FAT $0263 ; device numbers
.alias SAT $026D ; secondary addresses
; "Compute's Mapping the 64" book
.alias keyboard_buffer $0277
.alias MEMSTR $0281
.alias MEMSIZ $0283 ; NOTE: Mapping the 64 erroniously has the hex as $282, while the DEC is correct
.alias text_colour $0286 ; p55
.alias colour_under_cursor $0287 ; p56
.alias HIBASE $0288 ; p56 (high byte of start of screen)
.alias key_buffer_size $0289 ; p57
;; 0 = cursor keys, insert, delete and space repeat, but nothing else
@@ -87,8 +61,6 @@
.alias keyboard_decoding_ptr $028F
.alias enable_case_switch $0291
.alias screen_scroll_disable $0292
.alias RSSTAT $0297 ; RS-232 status
.alias pal_or_ntsc $02A6
;; Under-ROM routines
;; (BASIC also includes them. XXX - We should de-duplicate them in a safe manner)
+39 -130
View File
@@ -19,7 +19,7 @@
;; Searching through Compute's Mapping the 64, we find the following
;; things are used:
;; $93 = kernal_load_or_verify_flag
;; $93 = VERCK
;; $AC = current pointer for loading/verifying
;; $C1 = similar to the above.
@@ -30,11 +30,11 @@
load:
;; Are we loading or verifying?
sta kernal_load_or_verify_flag
sta VERCK
;; Store start address of LOAD
stx load_save_start_ptr+0
sty load_save_start_ptr+1
stx STAL+0
sty STAL+1
;; Reset status
jsr kernalstatus_reset
@@ -43,21 +43,8 @@ load:
jsr install_ram_routines
;; Display SEARCHING FOR + filename
lda MSGFLG
bpl +
jsr printf
.byte $0D,"SEARCHING FOR ",0
ldy #$00
print_filename_loop:
jsr lvs_display_searching_for
cpy current_filename_length
beq +
ldx #<current_filename_ptr
jsr peek_under_roms
jsr JCHROUT
iny
jmp print_filename_loop
*
;; http://www.zimmers.net/anonftp/pub/cbm/programming/serial-bus.pdf
;; p13, 16; also p16 tells us this routine doesn't mess with the file table
;; in the C64, only in the drive.
@@ -65,21 +52,21 @@ print_filename_loop:
;; Call device to LISTEN (p16)
lda current_device_number
jsr listen
bcs load_device_not_found_error
bcs lvs_device_not_found_error
;; Open channel #0 (p16)
lda #$00
jsr tksa
bcs load_error
bcs lvs_load_verify_error
;; Send filename (p16)
ldy #0
send_filename:
load_send_filename:
cpy FNLEN
beq load_filename_sent
cpy current_filename_length
beq sent_filename
ldx #<current_filename_ptr
jsr peek_under_roms
iny
@@ -90,7 +77,7 @@ send_filename:
pha
;; Set Carry flag on the last file name character, to mark EOI
cmp current_filename_length
cmp FNLEN
clc
bne +
sec
@@ -100,108 +87,66 @@ send_filename:
pla
tay
jmp send_filename
jmp load_send_filename
sent_filename:
load_filename_sent:
;; Command device to unlisten to indicate end of file name. (p16)
jsr unlsn
bcs load_error
bcs lvs_load_verify_error
jsr iec_set_idle ;; XXX is it needed?
;; Now command device to talk (p16)
lda current_device_number
jsr talk
bcs load_error
bcs lvs_load_verify_error
lda #$60 ; open channel / data (p3) , required according to p13
jsr iec_tx_command
bcs load_error
bcs lvs_load_verify_error
;; We are currently talker, so do the IEC turn around so that we
;; are the listener (p16)
jsr iec_turnaround_to_listen
bcs load_error
bcs lvs_load_verify_error
;; Get load address and store it if secondary address is zero
jsr iec_rx_byte
bcs load_file_not_found_error
bcs lvs_file_not_found_error
ldx current_secondary_address
beq +
sta load_save_start_ptr+0
sta STAL+0
*
jsr iec_rx_byte
bcs load_file_not_found_error
bcs lvs_file_not_found_error
ldx current_secondary_address
beq +
sta load_save_start_ptr+1
sta STAL+1
*
;; Display LOADING / VERIFYING and start address
lda MSGFLG
bpl load_loop
lda kernal_load_or_verify_flag
beq +
jsr printf
.byte $0D, "VERIFYING", 0
jmp load_print_start_addr
*
jsr printf
.byte $0D, "LOADING", 0
load_print_start_addr:
jsr printf
.byte " FROM $",0
lda load_save_start_ptr+1
jsr printf_printhexbyte
lda load_save_start_ptr+0
jsr printf_printhexbyte
;; Display start address
jsr lvs_display_loading_verifying
load_loop:
;; We are now ready to receive bytes
jsr iec_rx_byte
bcs load_error
bcs lvs_load_verify_error
;; Save it and advance pointer.
;; As with our BASIC, we want to enable LOADing
;; anywhere in memory, including over the IO space.
;; Thus we have to use a helper routine in low memory
;; to do the memory access
;; Handle the byte (store in memory / verify)
jsr lvs_handle_byte_load_verify
bcs lvs_load_verify_error
;; Advance pointer to data
jsr lvs_advance_pointer
bcs lvs_wrap_around_error
;; Save byte under ROMs and IO if required
php
sei
ldx #$33
stx $01
ldy #0
sta (load_save_start_ptr),y
ldx #$37
stx $01
plp
;; Advance pointer
inc load_save_start_ptr
bne +
inc load_save_start_ptr+1
;; If we wrap around to $0000, then this is bad.
beq load_wrap_around_error
*
;; Check for EOI - if so, this was the last byte
lda IOSTATUS
and #K_STS_EOI
beq load_loop
load_done:
;; Display end address
lda MSGFLG
bpl +
jsr printf
.byte " TO $",0
lda load_save_start_ptr+1
jsr printf_printhexbyte
lda load_save_start_ptr+0
jsr printf_printhexbyte
lda #$0D
jsr JCHROUT
*
jsr lvs_display_done
;; Close file on drive
;; Command drive to stop talking and to close the file
@@ -214,7 +159,7 @@ load_done:
lda current_device_number
jsr listen
lda #$e0
lda #$E0
jsr iec_tx_command
;; Tell drive to unlisten
@@ -223,41 +168,5 @@ load_done:
;; Set IEC status back to idle
jsr iec_set_idle
;; Return last address - Compute's Mapping the 64 says without the '+1',
;; checked (short test program) on original ROMs that this is really the case
ldx load_save_start_ptr+0
ldy load_save_start_ptr+1
clc
rts
load_wrap_around_error:
;; This error is probably not even detected by C64 Kernal;
;; report BASIC error code that looks the most sane
lda #B_ERR_OVERFLOW
sec
rts
load_device_not_found_error:
jsr kernalstatus_DEVICE_NOT_FOUND
jmp kernalerror_DEVICE_NOT_FOUND
load_file_not_found_error:
jmp kernalerror_FILE_NOT_FOUND
load_error:
;; XXX should we really return BASIC error code here?
lda kernal_load_or_verify_flag
beq load_verify_error
lda #B_ERR_LOAD
bne +
load_verify_error:
lda #B_ERR_VERIFY
*
sec
rts
;; Return last address
jmp lvs_return_last_address
+128
View File
@@ -0,0 +1,128 @@
;;
;; Helper functions for various LOAD/VERIVY/SAVE routine variants (IEC / U64 / etc.)
;;
lvs_handle_byte_load_verify:
;; Save it and advance pointer.
;; As with our BASIC, we want to enable LOADing
;; anywhere in memory, including over the IO space.
;; Thus we have to use a helper routine in low memory
;; to do the memory access
;; Save byte under ROMs and IO if required
php
sei
;; XXX behavior should depend on address
ldx #$33
stx $01
ldy #0
sta (STAL),y
ldx #$37
stx $01
plp
rts
lvs_advance_pointer:
;; Advance pointer
inc STAL
bne lvs_success_end
inc STAL+1
;; If we wrap around to $0000, then this is bad.
beq lvs_error_end
*
clc
rts
lvs_display_searching_for:
lda MSGFLG
bpl lvs_display_end
jsr printf
.byte $0D,"SEARCHING FOR ",0
ldy #$00
*
cpy FNLEN
beq lvs_display_end
ldx #<current_filename_ptr
jsr peek_under_roms
jsr JCHROUT
iny
jmp -
lvs_display_end:
rts
lvs_display_loading_verifying:
;; Display LOADING / VERIFYING and start address
lda MSGFLG
bpl lvs_display_end
lda VERCK
beq +
jsr printf
.byte $0D,"VERIFYING",0
jmp lvs_display_start_addr
*
jsr printf
.byte $0D,"LOADING",0
;; FALLTHROUGH
lvs_display_start_addr:
jsr printf
.byte " FROM $",0
lda STAL+1
jsr printf_printhexbyte
lda STAL+0
jmp printf_printhexbyte
lvs_display_done:
;; Display end address
lda MSGFLG
bpl lvs_display_end
jsr printf
.byte " TO $",0
lda STAL+1
jsr printf_printhexbyte
lda STAL+0
jsr printf_printhexbyte
lda #$0D
jmp JCHROUT
lvs_wrap_around_error:
;; This error is probably not even detected by C64 Kernal;
;; report BASIC error code that looks the most sane
lda #B_ERR_OVERFLOW
lvs_error_end:
sec
rts
lvs_return_last_address:
;; Return last address - Compute's Mapping the 64 says without the '+1',
;; checked (short test program) on original ROMs that this is really the case
ldx STAL+0
ldy STAL+1
;; FALLTHROUGH
lvs_success_end:
clc
rts
lvs_device_not_found_error:
jsr kernalstatus_DEVICE_NOT_FOUND
jmp kernalerror_DEVICE_NOT_FOUND
.alias lvs_file_not_found_error kernalerror_FILE_NOT_FOUND
lvs_load_verify_error:
;; XXX should we really return BASIC error code here?
lda VERCK
beq lvs_verify_error
lda #B_ERR_LOAD
bne lvs_error_end
;; FALLTHROUGH
lvs_verify_error:
lda #B_ERR_VERIFY
sec
rts
+1 -1
View File
@@ -334,7 +334,7 @@ next_row:
;; so that RUN/STOP etc can be checked easily
;; (Compute's Mapping the 64, p27)
lda ScanResult+0
sta BUCKYSTATUS
sta STKEY
;; Store de-bounce data for bucky keys
;; (Compute's Mapping the 64, p58-59)
+3 -3
View File
@@ -13,8 +13,8 @@ setnam:
;; There are 6 sane ways to implement this routine,
;; I hope this one won't cause similarity to CBM code
sta current_filename_length
sty current_filename_ptr + 1
stx current_filename_ptr + 0
sta FNLEN
sty STAL + 1
stx STAL + 0
rts
+2 -2
View File
@@ -9,11 +9,11 @@
;;
stop:
;; Bit 7 of BUCKYSTATUS contains the state of the STOP key
;; Bit 7 of STKEY contains the state of the STOP key
;; (Compute's Mapping the 64, p27)
;; BASIC checks carry flag to indicate STOP or not
lda BUCKYSTATUS
lda STKEY
and #$80
beq stop_pressed