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

163 lines
3.7 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.
;; #LAYOUT# STD * #TAKE
;; #LAYOUT# CRT KERNAL_0 #TAKE
;; #LAYOUT# M65 KERNAL_1 #TAKE
;; #LAYOUT# * * #IGNORE
;
; 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
!ifdef CONFIG_TAPE_NORMAL {
!ifndef CONFIG_TAPE_AUTODETECT {
load_tape_normal:
jsr tape_ditch_verify ; only LOAD is supported, no VERIFY
; Start playing
jsr tape_common_prepare_cia
jsr tape_ask_play
!ifdef CONFIG_TAPE_HEAD_ALIGN {
jsr tape_prepare_reading
}
; FALLTROUGH
load_tape_normal_header:
} else {
load_tape_normal_takeover: ; entry point for turbo->normal takeover
}
jsr load_MEMUSS_to_STAL
; Try to load header into tape buffer (we will restore MEMUSS later)
jsr tape_normal_get_pilot_header
!ifdef CONFIG_TAPE_AUTODETECT {
bcs load_tape_normal_switch_turbo ; failed, try turbo
}
jsr load_TAPE1_to_MEMUSS
jsr tape_normal_get_data_1
!ifndef CONFIG_TAPE_AUTODETECT {
bcs load_tape_normal_header ; unable to read block, try again
} else {
bcc load_tape_normal_switch_turbo_skip
load_tape_normal_switch_turbo:
jsr lvs_STAL_to_MEMUSS
jmp load_tape_turbo_takeover ; unable to read block, try turbo instead
load_tape_normal_switch_turbo_skip:
}
jsr load_TAPE1_to_MEMUSS
jsr tape_normal_get_data_2
!ifndef CONFIG_TAPE_AUTODETECT {
bcs load_tape_normal_header ; block load error, try again
} else {
bcs load_tape_normal_switch_turbo ; block load error, try turbo instead
}
; Check header type
ldy #$00
lda (TAPE1),y
cmp #$05
+beq tape_load_error ; end of tape mark, nothing to load
cmp #$01
beq @1
cmp #$03
!ifndef CONFIG_TAPE_AUTODETECT {
bne load_tape_normal_header ; header types 1 and 3 are loadable, see Mapping the C64, page 77
} else {
bne load_tape_normal_takeover
}
lda #$01
sta SA ; this file is non-relocatable; override secondary address with 1
@1:
; Restore MEMUSS, handle header
jsr lvs_STAL_to_MEMUSS
jsr tape_handle_header
!ifndef CONFIG_TAPE_AUTODETECT {
bcs load_tape_normal_header ; if name does not match, look for other header
} else {
bcs load_tape_normal_takeover
}
; FALLTROUGH
load_tape_normal_payload:
; Retrieve data
jsr tape_normal_get_pilot_data
ldy #$00 ; no data size limit
jsr tape_normal_get_data_1
+bcs tape_load_error
jsr lvs_check_EAL
+bne tape_load_error ; amount of data read does not match header info
jsr lvs_STAL_to_MEMUSS
jsr tape_normal_get_data_2
+bcs tape_load_error
jmp tape_load_success
load_TAPE1_to_MEMUSS: ; set MEMUSS (start address) as tape buffer
lda TAPE1+1
sta MEMUSS+1
lda TAPE1+0
sta MEMUSS+0
rts
load_MEMUSS_to_STAL: ; preserve MEMUSS
lda MEMUSS+1
sta STAL+1
lda MEMUSS+0
sta STAL+0
rts
}