various LOAD improvements
This commit is contained in:
1 parent
e145bb6c86
commit
982b287e92
8 files changed
+232
-64
No files matched your search
@@ -32,6 +32,7 @@ The following ROM features are currently missing:
|
||||
* BASIC expression parsing
|
||||
* floating point routines
|
||||
* tape (normal mode) support
|
||||
* tape loading ignores secondary address
|
||||
* IEC support for SAVE
|
||||
* RS-232 support
|
||||
* NMI handling is incomplete
|
||||
|
||||
@@ -94,7 +94,11 @@
|
||||
.label DFLTN = $99 // default input device
|
||||
.label DFLTO = $9A // default output device
|
||||
.label PRTY = $9B // tape storage for parity/checksum
|
||||
#if !CONFIG_TAPE_NORMAL && !CONFIG_TAPE_TURBO
|
||||
.label DPSW = $9C // -- NOT IMPLEMENTED --
|
||||
#else
|
||||
.label COLSTORE = $9C // [!] screen border storage for tape routines
|
||||
#endif
|
||||
.label MSGFLG = $9D // bit 6 = error messages, bit 7 = control message
|
||||
.label PTR1 = $9E // -- NOT IMPLEMENTED --
|
||||
.label PTR2 = $9F // -- NOT IMPLEMENTED --
|
||||
@@ -277,6 +281,6 @@
|
||||
|
||||
// $314 $334-$33B -- UNUSED -- free for user software
|
||||
|
||||
.label TBUFFR = $33C // $33C-$3FB, -- NOT IMPLEMENTED --, tape buffer
|
||||
.label TBUFFR = $33C // $33C-$3FB [!] tape buffer, our usage details differ
|
||||
|
||||
// $3FC $3FC-$3FF -- UNUSED -- free for user software
|
||||
@@ -17,6 +17,7 @@
|
||||
|
||||
#if CONFIG_TAPE_NORMAL || CONFIG_TAPE_TURBO
|
||||
.label __MSG_KERNAL_PRESS_PLAY = __msg_kernalplay - __msg_kernal_first
|
||||
.label __MSG_KERNAL_FOUND = __msg_kernalfound - __msg_kernal_first
|
||||
#endif
|
||||
|
||||
#if CONFIG_SHOW_PAL_NTSC
|
||||
@@ -70,6 +71,11 @@ __msg_kernalplay:
|
||||
.text "PRESS PLAY ON TAPE"
|
||||
.byte $80 + $0D // end of string mark + return
|
||||
|
||||
__msg_kernalfound:
|
||||
.byte $0D
|
||||
.text "FOUND"
|
||||
.byte $80 + $20 // end of string mark + space
|
||||
|
||||
#endif
|
||||
|
||||
#if CONFIG_SHOW_PAL_NTSC
|
||||
|
||||
@@ -4,7 +4,7 @@
|
||||
//
|
||||
// On NTSC this means 1023 cycles (slightly less on PAL, but we have to be sure).
|
||||
// We can't count on badlines, as the screen might be disabled.
|
||||
// Delay here is implemeented using VIC-II raster register. Since one raster is
|
||||
// Delay here is implemented using VIC-II raster register. Since one raster is
|
||||
// 63 cycles, we need at least 17 full rasters to be 100% sure we wait enough
|
||||
|
||||
|
||||
@@ -12,7 +12,15 @@
|
||||
|
||||
|
||||
iec_wait1ms:
|
||||
|
||||
ldx #18 // we probably won't start with the beginning of raster
|
||||
|
||||
#endif // CONFIG_IEC
|
||||
#if CONFIG_IEC || CONFIG_TAPE_TURBO || CONFIG_TAPE_NORMAL
|
||||
|
||||
wait_x_bars: // additional entry point for tape support
|
||||
// has to preserve .Y and put .X to 0
|
||||
|
||||
lda VIC_RASTER
|
||||
!:
|
||||
cmp VIC_RASTER
|
||||
@@ -24,4 +32,4 @@ iec_wait1ms:
|
||||
rts
|
||||
|
||||
|
||||
#endif // CONFIG_IEC
|
||||
#endif // CONFIG_IEC || CONFIG_TAPE_TURBO || CONFIG_TAPE_NORMAL
|
||||
@@ -90,9 +90,9 @@ iec_load_loop:
|
||||
jsr lvs_handle_byte_load_verify
|
||||
bcs load_iec_error
|
||||
|
||||
// Advance pointer to data
|
||||
// Advance pointer to data; it is OK if it advances past $FFFF,
|
||||
// one autostart technique does exactly this
|
||||
jsr lvs_advance_pointer
|
||||
bcs_far lvs_wrap_around_error
|
||||
|
||||
// Handle STOP key; it is probably an overkill to do it
|
||||
// with every byte, once per 32 bytes should be enough
|
||||
|
||||
@@ -79,16 +79,10 @@ lvs_handle_byte_verify:
|
||||
lvs_advance_pointer:
|
||||
|
||||
// Advance pointer
|
||||
inc STAL
|
||||
beq !+
|
||||
jmp lvs_success_end
|
||||
!:
|
||||
inc STAL+1
|
||||
// If we wrap around to $0000, then this is bad.
|
||||
inc STAL+0
|
||||
bne !+
|
||||
jmp lvs_error_end
|
||||
inc STAL+1
|
||||
!:
|
||||
clc
|
||||
rts
|
||||
|
||||
|
||||
@@ -155,12 +149,6 @@ lvs_display_done:
|
||||
ldx #__MSG_KERNAL_TO_HEX
|
||||
jmp !-
|
||||
|
||||
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
|
||||
|
||||
@@ -7,66 +7,75 @@
|
||||
// - https://codebase64.pokefinder.org/doku.php?id=base:turbotape_loader_source
|
||||
|
||||
|
||||
// XXX use calibration bits to improve reading
|
||||
// XXX handle load address from Kernal API
|
||||
// XXX add name matching
|
||||
|
||||
|
||||
#if CONFIG_TAPE_TURBO
|
||||
|
||||
|
||||
load_tape_turbo:
|
||||
|
||||
// XXX prepare SID, store screen color somewhere, read header
|
||||
|
||||
jsr tape_ditch_verify // only LOAD is supported, no VERIFY
|
||||
|
||||
ldy #$00
|
||||
sty PRTY // initial checksum value
|
||||
|
||||
sty CIA2_TIMAHI
|
||||
lda #$00
|
||||
sta CIA2_TIMAHI
|
||||
lda #$FE // timer threshold for TurboTape
|
||||
sta CIA2_TIMALO
|
||||
|
||||
jsr tape_ask_play
|
||||
|
||||
// FALLTROUGH
|
||||
|
||||
load_tape_turbo_header:
|
||||
|
||||
// Read file header
|
||||
|
||||
ldy #$00
|
||||
jsr tape_turbo_sync
|
||||
|
||||
jsr tape_turbo_sync // .X gets set to 0
|
||||
|
||||
stx STAL+0 // instead of a later lda, sta
|
||||
jsr tape_turbo_get_byte // important trick - save time/bytes by using y-indexing
|
||||
tay
|
||||
ldy #$15
|
||||
!:
|
||||
jsr tape_turbo_get_byte
|
||||
sta STAL+1,x // .X still 0
|
||||
inx
|
||||
cpx #$03
|
||||
bne !-
|
||||
jsr tape_turbo_get_byte
|
||||
sta (TAPE1), y
|
||||
dey
|
||||
bpl !-
|
||||
|
||||
jsr tape_handle_header
|
||||
bcs load_tape_turbo_header // if name does not match, look for other header
|
||||
|
||||
// FALLTROUGH
|
||||
|
||||
load_tape_turbo_payload:
|
||||
|
||||
// Read file payload
|
||||
|
||||
jsr tape_turbo_sync // .X gets set to 0
|
||||
|
||||
ldy #$00
|
||||
sty PRTY // initial checksum value
|
||||
|
||||
// FALLTROUGH
|
||||
|
||||
load_tape_turbo_loop:
|
||||
|
||||
jsr tape_turbo_get_byte
|
||||
|
||||
dec CPU_R6510 // to load below i/o area!
|
||||
|
||||
sta (STAL),y
|
||||
eor PRTY
|
||||
sta PRTY
|
||||
|
||||
dec CPU_R6510 // to load below I/O area
|
||||
sta (STAL),y
|
||||
inc CPU_R6510
|
||||
|
||||
iny
|
||||
bne !+
|
||||
inc STAL+1
|
||||
!:
|
||||
cpy MEMUSS+0
|
||||
eor PRTY // handle checksum
|
||||
sta PRTY
|
||||
|
||||
jsr lvs_advance_pointer
|
||||
|
||||
lda STAL+1
|
||||
sbc MEMUSS+1
|
||||
bcc load_tape_turbo_loop
|
||||
cmp EAL+1
|
||||
bne load_tape_turbo_loop
|
||||
lda STAL+0
|
||||
cmp EAL+0
|
||||
bne load_tape_turbo_loop
|
||||
|
||||
// Verify the checksum
|
||||
|
||||
@@ -75,7 +84,6 @@ load_tape_turbo_loop:
|
||||
beq_far tape_load_success
|
||||
jmp tape_load_error
|
||||
|
||||
|
||||
tape_turbo_get_byte:
|
||||
|
||||
lda #$01
|
||||
|
||||
+167
-14
@@ -7,6 +7,10 @@
|
||||
#if CONFIG_TAPE_NORMAL || CONFIG_TAPE_TURBO
|
||||
|
||||
|
||||
//
|
||||
// Check if VERIFY asked - if yes, terminate loading
|
||||
//
|
||||
|
||||
tape_ditch_verify:
|
||||
|
||||
lda VERCKK
|
||||
@@ -18,24 +22,52 @@ tape_ditch_verify:
|
||||
jmp lvs_device_not_found_error
|
||||
|
||||
|
||||
//
|
||||
// Handle tape deck motor
|
||||
//
|
||||
|
||||
tape_motor_off:
|
||||
|
||||
lda CPU_R6510
|
||||
ora #$20
|
||||
sta CPU_R6510
|
||||
|
||||
rts
|
||||
|
||||
bne !+ // branch always
|
||||
|
||||
tape_motor_on:
|
||||
|
||||
lda CPU_R6510
|
||||
and #($FF - $20)
|
||||
!:
|
||||
sta CPU_R6510
|
||||
|
||||
rts
|
||||
|
||||
|
||||
//
|
||||
// Handle screen (visible/blanked) + tape deck motor (on/off),
|
||||
// store/restore screen color
|
||||
//
|
||||
|
||||
tape_screen_show_motor_off:
|
||||
|
||||
jsr tape_motor_off
|
||||
|
||||
lda COLSTORE
|
||||
sta VIC_EXTCOL
|
||||
|
||||
jmp screen_show
|
||||
|
||||
tape_screen_hide_motor_on:
|
||||
lda VIC_EXTCOL
|
||||
sta COLSTORE
|
||||
|
||||
jsr screen_blank
|
||||
jmp tape_motor_on
|
||||
|
||||
|
||||
//
|
||||
// Ask user to press PLAY on tape deck,
|
||||
// Unless user cancelled loading, blank screen and start motor
|
||||
//
|
||||
|
||||
tape_ask_play:
|
||||
|
||||
sei // timing is critical for tape loading
|
||||
@@ -45,9 +77,18 @@ tape_ask_play:
|
||||
ldx #__MSG_KERNAL_PRESS_PLAY
|
||||
jsr print_kernal_message
|
||||
|
||||
// Clean the SID registers, we need it for sound effects
|
||||
|
||||
lda #$00
|
||||
ldy #$1C
|
||||
!:
|
||||
sta __SID_BASE, y
|
||||
dey
|
||||
bpl !-
|
||||
|
||||
// FALLTROUGH
|
||||
|
||||
tape_wait_button_loop:
|
||||
tape_wait_play_loop:
|
||||
|
||||
jsr udtim_keyboard
|
||||
jsr STOP
|
||||
@@ -61,27 +102,139 @@ tape_wait_button_loop:
|
||||
!:
|
||||
lda CPU_R6510
|
||||
and #$10 // check for pressed button
|
||||
bne tape_wait_button_loop
|
||||
bne tape_wait_play_loop
|
||||
|
||||
jsr screen_blank
|
||||
jsr tape_motor_on
|
||||
jmp tape_screen_hide_motor_on
|
||||
|
||||
|
||||
//
|
||||
// Handle file header - display it, decide whether load the file or not, etc.
|
||||
//
|
||||
|
||||
tape_handle_header:
|
||||
|
||||
jsr tape_screen_show_motor_off
|
||||
|
||||
// Header structure described here:
|
||||
// - https://www.luigidifraia.com/c64/docs/tapeloaders.html#turbotape64
|
||||
//
|
||||
// 1 byte - file type (0 = data, odd value = relocatable, even value = non-relocatable)
|
||||
// 2 bytes - start address
|
||||
// 2 bytes - end address + 1
|
||||
// 1 byte - if $0B (tape timing) contained at the time of saving XXX handle this
|
||||
// 16 bytes - filename, padded with 0x20
|
||||
//
|
||||
// Out tape buffer contains header in reversed order
|
||||
|
||||
// Print FOUND + file name
|
||||
|
||||
ldx #__MSG_KERNAL_FOUND
|
||||
jsr print_kernal_message
|
||||
|
||||
ldy #$10
|
||||
!:
|
||||
lda (TAPE1), y
|
||||
jsr JCHROUT
|
||||
dey
|
||||
bpl !-
|
||||
jsr print_return
|
||||
|
||||
// Header, wait for user decision
|
||||
|
||||
jsr tape_header_get_decision
|
||||
bcs tape_handle_header_skip
|
||||
|
||||
// XXX Perform filename matching
|
||||
|
||||
// Setup STAL and EAL
|
||||
|
||||
ldy #$15
|
||||
lda (TAPE1), y
|
||||
sta STAL+0
|
||||
|
||||
dey
|
||||
lda (TAPE1), y
|
||||
sta STAL+1
|
||||
|
||||
dey
|
||||
lda (TAPE1), y
|
||||
sta EAL+0
|
||||
|
||||
dey
|
||||
lda (TAPE1), y
|
||||
sta EAL+1
|
||||
|
||||
// Print LOADING
|
||||
|
||||
jsr lvs_display_loading_verifying
|
||||
|
||||
// Load the file
|
||||
|
||||
jsr tape_screen_hide_motor_on
|
||||
|
||||
clc
|
||||
rts
|
||||
|
||||
tape_handle_header_skip:
|
||||
|
||||
// Skip this file
|
||||
|
||||
jsr tape_screen_hide_motor_on
|
||||
|
||||
sec
|
||||
rts
|
||||
|
||||
|
||||
//
|
||||
// Get user decision whether to load the file or not
|
||||
//
|
||||
|
||||
tape_header_get_decision:
|
||||
|
||||
ldy #$00
|
||||
!:
|
||||
jsr udtim_keyboard
|
||||
lda STKEY
|
||||
bpl tape_header_wait_stop // STOP pressed
|
||||
and #$10
|
||||
beq tape_header_wait_space // space pressed
|
||||
|
||||
ldx #$80
|
||||
jsr wait_x_bars // sets .X to 0
|
||||
dex
|
||||
jsr wait_x_bars
|
||||
|
||||
dey
|
||||
bne !-
|
||||
|
||||
// FALLTROUGH - timeout
|
||||
|
||||
tape_header_wait_space:
|
||||
|
||||
clc
|
||||
rts
|
||||
|
||||
tape_header_wait_stop:
|
||||
|
||||
sec
|
||||
rts
|
||||
|
||||
|
||||
//
|
||||
// Report that file loading succeeded (or not)
|
||||
//
|
||||
|
||||
tape_load_success:
|
||||
|
||||
jsr screen_show
|
||||
jsr tape_motor_off
|
||||
jsr tape_screen_show_motor_off
|
||||
jsr lvs_display_done
|
||||
|
||||
cli
|
||||
jmp lvs_success_end
|
||||
|
||||
|
||||
tape_load_error:
|
||||
|
||||
jsr screen_show
|
||||
jsr tape_motor_off
|
||||
jsr tape_screen_show_motor_off
|
||||
|
||||
cli
|
||||
jmp lvs_load_verify_error
|
||||
|
||||
Reference in new issue
Block a user