// // Tape (normal) part of the LOAD routine // // We have the following possible CPU frequencies: // - C64    PAL:  CPU frequency 0.985248 MHz // - C64    NTSC: CPU frequency 1.022727 MHz // 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)    tap value $30 (PAL: 352 us) // - M (medium)   tap value $42 (PAL: 512 us) // - L (long)     tap value $56 (PAL: 672 us) // // 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: // // (S,M) = 0 bit // (M,S) = 1 bit // (L,M) = new-data marker // (L,S) = end-of-data marker // XXX use pilot to calibrate reading speed #if CONFIG_TAPE_NORMAL load_tape_normal: jsr tape_ditch_verify // only LOAD is supported, no VERIFY // Setup CIA #2 timers ldx #$03 // set timer A to 4 ticks stx CIA2_TIMALO // $DD04 ldx #$00 stx CIA2_TIMAHI // $DD05 stx CIA2_TIMBHI // $DD07 dex // puts $FF - for running timer B as long as possible stx CIA2_TIMBLO // $DD06 // Let timer A run continuously ldx #%00010001 // start timer, force latch reload stx CIA2_CRA // $DD0E // Start playing jsr tape_ask_play // FALLTROUGH load_tape_normal_header: // Read pilot and sync of the first header jsr tape_normal_pilot ldy #$89 jsr tape_normal_sync bcs load_tape_normal_header ldy #$00 // FALLTROUGH load_tape_normal_header_loop: // Read the header jsr tape_normal_get_marker // XXX handle result jsr tape_normal_get_byte // XXX handle errors sta (TAPE1), y iny cpy #$15 bne load_tape_normal_header_loop // Read pilot and sync of the second header jsr tape_normal_pilot ldy #$09 jsr tape_normal_sync bcs load_tape_normal_header // XXX do not skip second header, use it to correct data ldy #$15 !: jsr tape_normal_get_marker jsr tape_normal_get_byte dey bne !- // For now only one type of header is supported ldy #$00 lda (TAPE1),y cmp #$01 bne load_tape_normal_header // XXX also handle other header types, see Mapping the C64 page 77 // Handle the header jsr tape_handle_header bcs load_tape_normal_header // if name does not match, look for other header // FALLTROUGH load_tape_normal_payload: // Retrieve block jsr tape_normal_get_block // XXX handle errors // Advance MEMUSS (see Mapping the C64, page 36), check if end tya clc adc MEMUSS+0 sta MEMUSS+0 bcc !+ inc MEMUSS+1 !: jsr lvs_check_EAL bne load_tape_normal_payload jmp tape_load_success #endif