Files
open-roms/c64/kernal/tape/load_tape_normal.s
T

136 lines
3.1 KiB
ArmAsm
Raw Blame History

This file contains invisible Unicode characters
This file contains invisible Unicode characters that are indistinguishable to humans but may be processed differently by a computer. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
//
// 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
// Temporarily store MEMUSS in EAL
lda MEMUSS+1
sta EAL+1
lda MEMUSS+0
sta EAL+0
// Start playing
jsr tape_ask_play
// FALLTROUGH
load_tape_normal_header:
// Try to load header into tape buffer
lda TAPE1+1
sta MEMUSS+1
lda TAPE1+0
sta MEMUSS+0
// Retrieve the header
jsr tape_normal_pilot_header
ldy #$C1 // size limit (including checksum)
jsr tape_normal_get_data
bcs load_tape_normal_header // unable to read block, try again
// Check header type
ldy #$00 // XXX probably can be optimized for 65C02
lda (TAPE1),y
cmp #$05
beq_far tape_load_error // end of tape mark, nothing to load
cmp #$01
beq !+
cmp #$03
bne load_tape_normal_header // header types 1 and 3 are loadable, see Mapping the C64, page 77
lda #$01
sta SA // this file is non-relocatable; override secondary address with 1
!:
// Handle the header
// Restore MEMUSS
lda EAL+1
sta MEMUSS+1
lda EAL+0
sta MEMUSS+0
// 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 data
jsr tape_normal_pilot_data
ldy #$00 // no data size limit
jsr tape_normal_get_data
bcs_far tape_load_error
jsr lvs_check_EAL
bne_far tape_load_error // amount of data read does not match header info
jmp tape_load_success
#endif