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

296 lines
4.0 KiB
ArmAsm

//
// Common routines for tape support
//
#if CONFIG_TAPE_NORMAL || CONFIG_TAPE_TURBO
//
// Check if VERIFY asked - if yes, terminate loading
//
tape_ditch_verify:
lda VERCKK
bne !+
rts
!:
pla
pla
jmp lvs_device_not_found_error
//
// Loading terminated by user
//
tape_break_error:
pla
pla
cli
jmp kernalerror_ROUTINE_TERMINATED
//
// Handle tape deck motor
//
tape_motor_off:
lda CPU_R6510
ora #$20
bne !+ // branch always
tape_motor_on:
lda CPU_R6510
and #($FF - $20)
!:
sta CPU_R6510
rts
//
// Handle screen (visible/blanked) + tape deck motor (on/off),
// store/restore screen color
//
tape_screen_show_motor_off:
jsr tape_motor_off
lda COLSTORE
sta VIC_EXTCOL
jmp screen_show
tape_screen_hide_motor_on:
lda VIC_EXTCOL
sta COLSTORE
jsr screen_blank
jmp tape_motor_on
//
// Ask user to press PLAY on tape deck,
// Unless user cancelled loading, blank screen and start motor
//
tape_ask_play:
sei // timing is critical for tape loading
jsr tape_motor_off
ldx #__MSG_KERNAL_PRESS_PLAY
jsr print_kernal_message
// Clean the SID registers, we need it for sound effects
lda #$00
ldy #$1C
!:
sta __SID_BASE, y
dey
bpl !-
// FALLTROUGH
tape_wait_play_loop:
jsr udtim_keyboard
jsr STOP
bcs tape_break_error
!:
lda CPU_R6510
and #$10 // check for pressed button
bne tape_wait_play_loop
jmp tape_screen_hide_motor_on
//
// Handle file header - display it, decide whether load the file or not, etc.
//
tape_handle_header:
jsr tape_screen_show_motor_off
// Header structure described here:
// - https://www.luigidifraia.com/c64/docs/tapeloaders.html#turbotape64
//
// 1 byte (skipped) - file type (0 = data, odd value = relocatable, even value = non-relocatable)
// 2 bytes - start address
// 2 bytes - end address + 1
// 1 byte - if $0B (tape timing) contained at the time of saving
// 16 bytes - filename, padded with 0x20
// Print FOUND + file name
ldx #__MSG_KERNAL_FOUND
jsr print_kernal_message
ldy #$05
!:
lda (TAPE1), y
jsr JCHROUT
iny
cpy #$15
bne !-
jsr print_return
// Header, wait for user decision
jsr tape_header_get_decision
bcs tape_break_error
// Check if file name matches
/* XXX does not work yet
jsr tape_match_filename
bcs tape_handle_header_skip
*/
// Setup STAL and EAL
ldy #$00
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
// Print LOADING
jsr lvs_display_loading_verifying
// Load the file
jsr tape_screen_hide_motor_on
// FALLTROUGH
tape_return_ok:
clc
rts
tape_handle_header_skip:
// Skip this file
jsr tape_screen_hide_motor_on
// FALLTROUGH
tape_return_not_ok:
sec
rts
//
// Check whether file name matches the pattern
//
/* XXX does not work yet
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
beq !+ // end of pattern
lda (FNADDR), y // byte from pattern
!:
.break
cmp #KEY_ASTERISK
beq tape_return_ok
cmp (TAPE1 + 5),y
bne tape_return_not_ok
iny
cpy #$10
bne tape_match_loop
clc
rts
*/
//
// Get user decision whether to load the file or not
//
tape_header_get_decision:
ldy #$00
!:
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 !-
// 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_show_motor_off
jsr lvs_display_done
jsr print_return
cli
jmp lvs_success_end
tape_load_error:
jsr tape_screen_show_motor_off
cli
jmp lvs_load_verify_error
#endif