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

141 lines
3.0 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
// 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