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

357 lines
4.6 KiB
ArmAsm

;; #LAYOUT# STD * #TAKE
;; #LAYOUT# CRT KERNAL_0 #TAKE
;; #LAYOUT# M65 KERNAL_1 #TAKE
;; #LAYOUT# * * #IGNORE
;
; Common routines for tape support
;
!ifdef HAS_TAPE {
;
; Loading terminated by user
;
tape_break_error:
pla
pla
cli
jmp kernalerror_ROUTINE_TERMINATED
;
; Ask user to press PLAY on tape deck,
; Unless user cancelled loading, blank screen and start motor
;
tape_ask_play:
!ifndef CONFIG_TAPE_NO_KEY_SENSE {
; First check whether the button is already pressed
lda CPU_R6510
and #$10
beq tape_wait_play_done
}
; Display message
ldx #__MSG_KERNAL_PRESS_PLAY
jsr print_kernal_message
; FALLTROUGH
!ifndef CONFIG_TAPE_NO_KEY_SENSE {
tape_wait_play_loop:
jsr STOP
bcs tape_break_error
lda CPU_R6510
and #$10 ; check for pressed button
bne tape_wait_play_loop
; FALLTROUGH
} else {
; The ROM is configured for tape adapter without the key sense - but it is still
; possible, that regular Datasette or Tapuino is connected
lda CPU_R6510
and #$10
beq tape_wait_first_pulse ; branch if button reported pressed, most likely really no key sense
; We have key sense - perform regular waiting
@1:
jsr STOP
bcs tape_break_error
lda CPU_R6510
and #$10
beq @1
tape_wait_first_pulse:
; We have no key sense - so just turn the motor on and wait for the first pulse
jsr tape_motor_on
@2:
jsr STOP
bcs tape_break_error
lda #$10
bit CIA1_ICR ; $DC0D
bne @2
@3:
jsr STOP
bcs tape_break_error
lda #$10
bit CIA1_ICR ; $DC0D
beq @3
}
; FALLTROUGH
tape_wait_play_done:
lda #$01
sta CAS1 ; set the interlock
!ifdef CONFIG_TAPE_HEAD_ALIGN {
rts
tape_prepare_reading:
} ; CONFIG_TAPE_HEAD_ALIGN
; Display confirmation
ldx #__MSG_KERNAL_OK
jsr print_kernal_message
; Prepare for reading
jsr print_return
jmp tape_screen_off_motor_on
;
; Handle file header - display it, decide whether load the file or not, etc.
;
tape_handle_header:
!ifndef CONFIG_TAPE_NO_MOTOR_CONTROL {
jsr tape_screen_on_motor_off
}
; Print FOUND + file name
ldx #__MSG_KERNAL_FOUND
jsr print_kernal_message
ldy #$05
@4:
lda (TAPE1), y
jsr JCHROUT
iny
cpy #$15
bne @4
!ifndef CONFIG_TAPE_NO_MOTOR_CONTROL {
; Header, wait for user decision
jsr tape_header_get_decision
bcs tape_break_error
}
; Check if file name matches
jsr tape_match_filename
bcs tape_handle_header_skip
; Setup STAL and EAL
ldy #$01
lda (TAPE1), y
sta STAL+0
iny
lda (TAPE1), y
sta STAL+1
iny
lda (TAPE1), y
sta EAL+0
iny
lda (TAPE1), y
sta EAL+1
; Handle the secondary address, 0 means loading to location from MEMUSS
lda SA
bne @5
; EAL = EAL - STAL
sec
lda EAL+0
sbc STAL+0
sta EAL+0
lda EAL+1
sbc STAL+1
sta EAL+1
; STAL = MEMUSS
lda MEMUSS+0
sta STAL+0
lda MEMUSS+1
sta STAL+1
; EAL = EAL + STAL
clc
lda EAL+0
adc STAL+0
sta EAL+0
lda EAL+1
adc STAL+1
sta EAL+1
@5:
; Setup MEMUSS (see Mapping the C64, page 36)
jsr lvs_STAL_to_MEMUSS
!ifdef CONFIG_MB_M65 {
; Switch to legacy mode if needed
jsr m65_load_autoswitch_tape
}
; Print LOADING and start address
jsr lvs_display_loading_verifying
; FALLTROUGH
!ifndef CONFIG_TAPE_NO_MOTOR_CONTROL {
tape_handle_header_displayed:
; Load the file
jsr tape_screen_off_motor_on
; FALLTROUGH
}
tape_return_ok:
clc
rts
tape_handle_header_skip:
; Skip this file
jsr print_return
jsr tape_screen_off_motor_on
; FALLTROUGH
tape_return_not_ok:
sec
rts
;
; Check whether file name matches the pattern
;
tape_match_filename:
lda FNLEN
beq tape_return_ok ; no pattern to match
ldy #$00
tape_match_loop:
lda #$20 ; default byte, for padding
cpy FNLEN
bcs @6 ; end of pattern
lda (FNADDR), y ; byte from pattern
@6:
cmp #KEY_ASTERISK
beq tape_return_ok
iny
iny
iny
iny
iny
cmp (TAPE1), y
bne tape_return_not_ok
dey
dey
dey
dey
cpy #$10
bne tape_match_loop
clc
rts
!ifndef CONFIG_TAPE_NO_MOTOR_CONTROL {
;
; Get user decision whether to load the file or not
;
tape_header_get_decision:
ldy #$00
@7:
jsr udtim_keyboard
lda STKEY
bpl tape_header_wait_stop ; STOP pressed
and #$10
beq tape_header_wait_space ; SPACE pressed
ldx #$80
jsr wait_x_bars ; sets .X to 0
dex
jsr wait_x_bars
dey
bne @7
; FALLTROUGH - timeout
tape_header_wait_space:
clc
rts
tape_header_wait_stop:
sec
rts
}
;
; Report that file loading succeeded (or not)
;
tape_load_success:
jsr tape_screen_on_motor_off
jsr lvs_display_done
jmp lvs_return_last_address
tape_load_error:
jsr tape_screen_on_motor_off
jmp lvs_load_verify_error
}