diff --git a/c64/kernal/tape/load_tape_normal.s b/c64/kernal/tape/load_tape_normal.s index ddb6ec94..05b905b4 100644 --- a/c64/kernal/tape/load_tape_normal.s +++ b/c64/kernal/tape/load_tape_normal.s @@ -7,21 +7,23 @@ // We have the following possible CPU frequencies: // - C64    PAL:  CPU frequency 0.985248 MHz // - C64    NTSC: CPU frequency 1.022727 MHz -// Average is 1.0039875 MHz and we will take this value for calculation (but it really does not change much). +// The clock difference is about 4% - it is unlikely to cause problems. // // We have to distinguish the following pulse lengths (http://sidpreservation.6581.org/tape-format/): -// - S (short)    352 us -// - M (medium)   512 us -// - L (long)     672 us +// - S (short)    tap value $30 (PAL: 352 us) +// - M (medium)   tap value $42 (PAL: 512 us) +// - L (long)     tap value $56 (PAL: 672 us) // -// This gives us the following thresholds -// - S vs M       432 us (108 or $6C 4-tick periods) -// - M vs L       592 us (149 or $95 4-tick periods) +// The TAP format (http://unusedino.de/ec64/technical/formats/tap.html) uses a resolution of 8 PAL ticks; +// this implementation sets the timer for twice the precision (timer B is triggered every 4 CPU cycles), +// probably an overkill, but in realityy it does not cost us anything. +// +// So -= we have the following thresholds: +// - S vs M       $72 (in our units of 4 ticks) +// - M vs L       $98 (in our units of 4 ticks) +// +// We need to recognize the following pulse sequences: // -// 4-tick periods should be enough - TAP file format description (http://unusedino.de/ec64/technical/formats/tap.html) -// tells it uses exactly 8 PAL ticks as a resolution - -// The following encoding is used: // (S,M) = 0 bit // (M,S) = 1 bit // (L,M) = new-data marker diff --git a/c64/kernal/tape/tape_normal_get_byte.s b/c64/kernal/tape/tape_normal_get_byte.s index 3eb3de09..c0b8e79a 100644 --- a/c64/kernal/tape/tape_normal_get_byte.s +++ b/c64/kernal/tape/tape_normal_get_byte.s @@ -1,6 +1,6 @@ // -// Tape (turbo) helper routine - byte reading +// Tape (normal) helper routine - byte reading // // Returns byte in .A, Carry flag set = error // @@ -11,19 +11,13 @@ tape_normal_get_byte: - // Init byte checksum and canary bit + // Init parity bit and canary bit lda #$01 sta PRTY lda #%01111111 // canary bit is 0 sta INBIT - // First we need a byte marker - (L,M) -!: - jsr tape_normal_get_pulse - cmp #($FF - $95 - $04) - bcs !- // too short for a long pulse - jsr tape_normal_get_pulse - bcs !- // too short for a medium pulse + jsr tape_normal_get_marker // XXX this is probablyy not the proper place // Now fetch individual bits @@ -44,7 +38,7 @@ tape_normal_get_byte_loop: ror INBIT // put the bit in bcs tape_normal_get_byte_loop // loop if no canary bit reached - // Byte retrieved (on stack), now we need to validate the checksum + // Byte retrieved (on stack), now we need to validate the parity jsr tape_normal_get_bit bcs tape_normal_get_byte_error diff --git a/c64/kernal/tape/tape_normal_get_marker.s b/c64/kernal/tape/tape_normal_get_marker.s new file mode 100644 index 00000000..59f73d8e --- /dev/null +++ b/c64/kernal/tape/tape_normal_get_marker.s @@ -0,0 +1,16 @@ + +// +// Tape (normal) helper routine - marker reading +// +// Reeturns marker type in Carry flag, set = end of data +// + +tape_normal_get_marker: + + // (L,M) - end of byte, (L,S) - end of data + + jsr tape_normal_get_pulse + cmp #($FF - $98 - $04) + bcs tape_normal_get_marker // too short for a long pulse + + jmp tape_normal_get_pulse diff --git a/c64/kernal/tape/tape_normal_get_pulse.s b/c64/kernal/tape/tape_normal_get_pulse.s index ae525d0f..cbddc175 100644 --- a/c64/kernal/tape/tape_normal_get_pulse.s +++ b/c64/kernal/tape/tape_normal_get_pulse.s @@ -1,6 +1,6 @@ // -// Tape (turbo) helper routine - pulse reading +// Tape (normal) helper routine - pulse reading // // Returns pulse length (with a bias, see comments) in .A // @@ -34,7 +34,7 @@ tape_normal_get_pulse: // this is total 17 cycles, or $4 periods of 4 ticks (timer A) each - we need to take it into account // every time we check the pulse length - cmp #($FF - $6C - $04) // short vs medium is the default check + cmp #($FF - $72 - $04) // short vs medium is the default check rts