From 35d360c24b765143b1caceb576e698109dbb046c Mon Sep 17 00:00:00 2001 From: FeralChild64 Date: Thu, 16 Jan 2020 21:09:22 +0100 Subject: [PATCH] started work on tape format autodetection --- c64/,,config_custom.s | 1 + c64/kernal/tape/load_tape_normal.s | 27 ++++-- c64/kernal/tape/load_tape_turbo.s | 11 +++ c64/kernal/tape/tape_common_autodetect.s | 101 ++++++++++++++++++++++ c64/kernal/tape/tape_common_prepare_cia.s | 26 ++++-- c64/kernal/tape/tape_turbo_sync_measure.s | 45 ---------- 6 files changed, 156 insertions(+), 55 deletions(-) create mode 100644 c64/kernal/tape/tape_common_autodetect.s delete mode 100644 c64/kernal/tape/tape_turbo_sync_measure.s diff --git a/c64/,,config_custom.s b/c64/,,config_custom.s index 95bfda75..fe27fb2b 100644 --- a/c64/,,config_custom.s +++ b/c64/,,config_custom.s @@ -56,6 +56,7 @@ #define CONFIG_TAPE_NORMAL #define CONFIG_TAPE_TURBO +#define CONFIG_TAPE_AUTODETECT // not fully done yet! // #define CONFIG_TAPE_NO_KEY_SENSE // #define CONFIG_TAPE_NO_MOTOR_CONTROL diff --git a/c64/kernal/tape/load_tape_normal.s b/c64/kernal/tape/load_tape_normal.s index 37b815a7..2a24826c 100644 --- a/c64/kernal/tape/load_tape_normal.s +++ b/c64/kernal/tape/load_tape_normal.s @@ -44,6 +44,28 @@ load_tape_normal: jsr tape_ditch_verify // only LOAD is supported, no VERIFY +#if CONFIG_TAPE_TURBO && CONFIG_TAPE_AUTODETECT + + // Prepare for sound effects in case of turbo takeover + jsr tape_clean_sid + +#endif + + // Start playing + jsr tape_common_prepare_cia + jsr tape_ask_play + +#if CONFIG_TAPE_TURBO && CONFIG_TAPE_AUTODETECT + + // FALLTROUGH + +load_tape_normal_takeover: // entry point for turbo->normal takeover + + jsr tape_common_autodetect + bcs_16 load_tape_turbo_takeover + +#endif + // Temporarily store MEMUSS in EAL lda MEMUSS+1 @@ -51,11 +73,6 @@ load_tape_normal: lda MEMUSS+0 sta EAL+0 - // Start playing - - jsr tape_common_prepare_cia - jsr tape_ask_play - // FALLTROUGH load_tape_normal_header: diff --git a/c64/kernal/tape/load_tape_turbo.s b/c64/kernal/tape/load_tape_turbo.s index d5b43db1..c09d6bc9 100644 --- a/c64/kernal/tape/load_tape_turbo.s +++ b/c64/kernal/tape/load_tape_turbo.s @@ -27,6 +27,17 @@ load_tape_turbo: // FALLTROUGH +#if CONFIG_TAPE_NORMAL && CONFIG_TAPE_AUTODETECT + +load_tape_turbo_takeover: // entry point for turbo->normal takeover + + jsr tape_common_autodetect + bcc_16 load_tape_normal_takeover + +#endif + + // FALLTROUGH + load_tape_turbo_header: // Read file header; structure described here: diff --git a/c64/kernal/tape/tape_common_autodetect.s b/c64/kernal/tape/tape_common_autodetect.s new file mode 100644 index 00000000..85a08757 --- /dev/null +++ b/c64/kernal/tape/tape_common_autodetect.s @@ -0,0 +1,101 @@ +// #LAYOUT# STD * #TAKE +// #LAYOUT# * KERNAL_0 #TAKE +// #LAYOUT# * * #IGNORE + +// +// Tries to detect +// +// Carry clear - NORMAL, Carry set - TURBO +// + +// XXX implement fallback to autodetection, correct screen color for NORMAL + + +#if CONFIG_TAPE_NORMAL && CONFIG_TAPE_TURBO && CONFIG_TAPE_AUTODETECT + + +tape_common_autodetect: + + // Set screen color to something neutral, silence the audio + + lda #$0C + sta VIC_EXTCOL + lda #$00 + sta SID_SIGVOL + + // FALLTROUGH + +tape_common_autodetect_retry: + + // It is not trivial to distinguish between NORMAL and TURBO, + // as short pulses of NORMAL (and sync uses only shorts) + // have similar lengths as long pulses of TURBO + + // Thus, the routine here reads certain amount of pulses + // looking for evidence for either NORMAL or TURBO system; + // in case of no evidence found, assume NORMAL + + lda #$00 // plus = probably NORMAL, minus = TURBO + sta XSAV + + ldy #$60 // $60 pulses cover 12 bytes of TURBO recording + jsr tape_normal_get_pulse // first pulse might be a garbage, ignore it + + // FALLTROUGH + +tape_common_autodetect_loop: + + jsr tape_normal_get_pulse // read pulse for detection attempt + + // If garbage found, retry detection + cmp #$28 + bcc tape_common_autodetect_retry // this is a VERY long pulse + cmp #$E8 + bcs tape_common_autodetect_retry // this is a VERY short pulse + + // First try to distinguish TURBO short signal (reference: $CD) + // from NORMAL signals (reference: $A5 or lower), these values + // give us threshold of ($CD + $A5) / 2 = $B9 + + cmp #$B9 + bcc !+ + dec XSAV // above $B9 (so signal is shorter), looks like TURBO +!: + // Now try to distinguish TURBO signals (reference: $B1 or higher) + // from NORMAL medium/long signals (reference: $7D or below), these values + // give us threshold of ($B1 + $7D) / 2 = $97 + + cmp #$97 + bcs !+ + inc XSAV +!: + // The sync for TURBO is not too long - if we have enough evidence, + // assume TURBO recording already + + lda XSAV + cmp #$FD + beq tape_common_autodetect_turbo + + // Next iteration + dey + bpl tape_common_autodetect_loop + + // Last chance for TURBO + + lda XSAV + bmi tape_common_autodetect_turbo + + // FALLTROUGH + +tape_common_autodetect_normal: + + clc + rts + +tape_common_autodetect_turbo: + + sec + rts + + +#endif diff --git a/c64/kernal/tape/tape_common_prepare_cia.s b/c64/kernal/tape/tape_common_prepare_cia.s index 8650e3e1..fefffbba 100644 --- a/c64/kernal/tape/tape_common_prepare_cia.s +++ b/c64/kernal/tape/tape_common_prepare_cia.s @@ -7,14 +7,14 @@ // // -// Checked under VICE, PAL, average of 256 pulses: +// Checked under VICE, PAL, average of 256 pulses: XXX retry measurements for NORMAL, something is probably wrong // -// normal - short - timer goes down to $C9 -// normal - medium - timer goes down to $79 +// normal - short - timer goes down to $A5 +// normal - medium - timer goes down to $7D // normal - long - timer goes down to $52 // -// turbo - short - timer goes down to $B1 -// turbo - long - timer goes down to $CD +// turbo - short - timer goes down to $CD +// turbo - long - timer goes down to $B1 // // // Measurement subroutine: .A should contain timer value, $C000-$C002 zeroed @@ -58,3 +58,19 @@ tape_common_prepare_cia: rts #endif + + +xxx_measure: + clc + adc $C001 + sta $C001 + bcc !+ + inc $C000 + !: + inc $C002 + beq !+ + rts + !: + lda $C000 + .break // .A contains our average + rts diff --git a/c64/kernal/tape/tape_turbo_sync_measure.s b/c64/kernal/tape/tape_turbo_sync_measure.s deleted file mode 100644 index 6257ec6f..00000000 --- a/c64/kernal/tape/tape_turbo_sync_measure.s +++ /dev/null @@ -1,45 +0,0 @@ -// #LAYOUT# STD * #TAKE -// #LAYOUT# * KERNAL_0 #TAKE -// #LAYOUT# * * #IGNORE - -// -// Tape (turbo) helper routine - measure bit length for calibration purposes -// - -#if CONFIG_TAPE_TURBO && CONFIG_TAPE_TURBO_AUTOCALIBRATE - - -tape_turbo_sync_measure_0: - - // Measure bit '0' - jsr tape_turbo_get_bit - bcs tape_turbo_sync_measure_fail - txa - adc STACK+2 - sta STACK+2 - bcc !+ - inc STACK+0 -!: - rts - -tape_turbo_sync_measure_1: - - // Measure bit '1' - jsr tape_turbo_get_bit - bcc tape_turbo_sync_measure_fail - txa - adc STACK+3 - sta STACK+3 - bcc !+ - inc STACK+1 -!: - rts - -tape_turbo_sync_measure_fail: - - pla - pla - jmp tape_turbo_sync_header - - -#endif