turbo tape can now adjust itself for tape motor speed
This commit is contained in:
1 parent
723a7772fa
commit
9061a8d0fc
18 files changed
+206
-62
No files matched your search
@@ -151,10 +151,16 @@ Needs about 700 bytes in KERNAL segment (if both normal and turbo are enabled, a
|
||||
|
||||
### `CONFIG_TAPE_TURBO`
|
||||
|
||||
Adds a minimal turbo tape support - just LOAD command (device 7, like on _Action Replay_ and _Final_ cartridges)
|
||||
Adds a minimal turbo tape support - just LOAD command (device 7, like on _Action Replay_ and _Final_ cartridges), up to 250 blocks
|
||||
|
||||
Needs about 650 bytes in KERNAL segment (if both normal and turbo are enabled, about 950 bytes are needed, as they share some code). If unsure - enable.
|
||||
|
||||
### `CONFIG_TAPE_TURBO_AUTOCALIBRATE`
|
||||
|
||||
Extends the tape turbo load functionality by ability to adjust to tape speed differences.
|
||||
|
||||
Needs about 100 bytes in KERNAL segment. If unsure - enable for Datasette or other tape recorder, disable for digital solutions like Tapuino.
|
||||
|
||||
### `CONFIG_TAPE_NO_KEY_SENSE`
|
||||
|
||||
Enable this option if you are using a tape interface adapter with some audio signal source connected. These adapters lack key sense functionality, so the computer is unable to tell whether Play got pressed or not - with this option ROM will assume Play got pressed after imppulses start arriving from the tape.
|
||||
|
||||
@@ -11,7 +11,7 @@ Here are the features of the Open ROMs not found in the original ROMs from the 8
|
||||
* JiffyDOS and DolphinDOS protocols support
|
||||
* DOS wedge (direct mode only) - `@<drive_number>`, `@<command>`, `@$`, `@$<params>`, `@`
|
||||
|
||||
* turbo tape load support (as device 7, or using `←L`), up to 250 blocks (can store bytes under I/O)
|
||||
* turbo tape load support (as device 7, or using `←L`), quite sophisticated: up to 250 blocks (can store bytes under I/O), can use sync signal for autocalibration (less load errors than simple turbos)
|
||||
* improved support for tape adapters (for using regular casette players and other audio devices instead of Datasette)
|
||||
|
||||
* extended `LOAD` command
|
||||
@@ -70,7 +70,7 @@ The following ROM features are currently missing:
|
||||
| Driver | Status | Remarks |
|
||||
| :----------------: | :------: | :------------------------------------------------: |
|
||||
| normal | PARTIAL | no tape speed calibratrion, no error correction |
|
||||
| turbo (250 blocks) | PARTIAL | no tape speed calibratrion |
|
||||
| turbo (250 blocks) | DONE | |
|
||||
|
||||
## IEC bus
|
||||
|
||||
|
||||
@@ -56,6 +56,7 @@
|
||||
|
||||
#define CONFIG_TAPE_NORMAL
|
||||
#define CONFIG_TAPE_TURBO
|
||||
#define CONFIG_TAPE_TURBO_AUTOCALIBRATE
|
||||
// #define CONFIG_TAPE_NO_KEY_SENSE
|
||||
// #define CONFIG_TAPE_NO_MOTOR_CONTROL
|
||||
|
||||
|
||||
@@ -50,6 +50,7 @@
|
||||
|
||||
#define CONFIG_TAPE_NORMAL
|
||||
#define CONFIG_TAPE_TURBO
|
||||
#define CONFIG_TAPE_TURBO_AUTOCALIBRATE
|
||||
// #define CONFIG_TAPE_NO_KEY_SENSE
|
||||
// #define CONFIG_TAPE_NO_MOTOR_CONTROL
|
||||
|
||||
|
||||
@@ -50,6 +50,7 @@
|
||||
|
||||
// #define CONFIG_TAPE_NORMAL
|
||||
// #define CONFIG_TAPE_TURBO
|
||||
// #define CONFIG_TAPE_TURBO_AUTOCALIBRATE
|
||||
// #define CONFIG_TAPE_NO_KEY_SENSE
|
||||
// #define CONFIG_TAPE_NO_MOTOR_CONTROL
|
||||
|
||||
|
||||
@@ -50,6 +50,7 @@
|
||||
|
||||
// #define CONFIG_TAPE_NORMAL
|
||||
#define CONFIG_TAPE_TURBO
|
||||
// #define CONFIG_TAPE_TURBO_AUTOCALIBRATE
|
||||
// #define CONFIG_TAPE_NO_KEY_SENSE
|
||||
// #define CONFIG_TAPE_NO_MOTOR_CONTROL
|
||||
|
||||
|
||||
@@ -50,6 +50,7 @@
|
||||
|
||||
#define CONFIG_TAPE_NORMAL
|
||||
#define CONFIG_TAPE_TURBO
|
||||
#define CONFIG_TAPE_TURBO_AUTOCALIBRATE
|
||||
// #define CONFIG_TAPE_NO_KEY_SENSE
|
||||
// #define CONFIG_TAPE_NO_MOTOR_CONTROL
|
||||
|
||||
|
||||
@@ -102,12 +102,12 @@
|
||||
|
||||
// Check that memory model and ROM layout configurations is correct
|
||||
{
|
||||
#if ROM_LAYOUT_M65 && !CONFIG_CPU_M65_45GS02
|
||||
.error "Mega65 ROM layout requires CONFIG_CPU_M65_45GS02"
|
||||
#endif
|
||||
#if ROM_LAYOUT_M65 && !CONFIG_MB_MEGA_65
|
||||
.error "Mega65 ROM layout requires CONFIG_MB_MEGA_65"
|
||||
#endif
|
||||
//#if ROM_LAYOUT_M65 && !CONFIG_CPU_M65_45GS02
|
||||
// .error "Mega65 ROM layout requires CONFIG_CPU_M65_45GS02"
|
||||
//#endif
|
||||
//#if ROM_LAYOUT_M65 && !CONFIG_MB_MEGA_65
|
||||
// .error "Mega65 ROM layout requires CONFIG_MB_MEGA_65"
|
||||
//#endif
|
||||
|
||||
.var selected = 0;
|
||||
|
||||
@@ -166,6 +166,15 @@
|
||||
|
||||
|
||||
|
||||
// Check that tape configuration is correct
|
||||
{
|
||||
#if !CONFIG_TAPE_TURBO && CONFIG_TAPE_TURBO_AUTOCALIBRATE
|
||||
.error "CONFIG_TAPE_TURBO_AUTOCALIBRATE requires CONFIG_TAPE_TURBO*"
|
||||
#endif
|
||||
}
|
||||
|
||||
|
||||
|
||||
// Check that RS-232 configuration is correct
|
||||
{
|
||||
#if CONFIG_RS232_UP9600 && (CONFIG_TAPE_NORMAL || CONFIG_TAPE_TURBO)
|
||||
|
||||
@@ -214,7 +214,7 @@
|
||||
.label RIDBS = $29C // -- WIP -- read pointer into RS-232 receive buffer
|
||||
.label RODBS = $29D // -- WIP -- read pointer into RS-232 send buffer
|
||||
.label RODBE = $29E // -- WIP -- write pointer into RS-232 send buffer
|
||||
.label IRQTMP = $29F // $29F-$2A0 -- NOT IMPLEMENTED --
|
||||
.label IRQTMP = $29F // $29F-$2A0 temporary IRQ vector storage [!] we use it for tape speed calibration instead
|
||||
.label ENABL = $2A1 // -- NOT IMPLEMENTED --
|
||||
.label TODSNS = $2A2 // -- NOT IMPLEMENTED --
|
||||
.label TRDTMP = $2A3 // -- NOT IMPLEMENTED --
|
||||
|
||||
@@ -67,7 +67,7 @@ chrout_done_unknown_device:
|
||||
chrout_done_success:
|
||||
|
||||
plp
|
||||
cli // XXX certainly needed for screen, what about other devices?
|
||||
cli // needed for screen (checked calling the routine on original ROMs), XXX what about other devices?
|
||||
|
||||
// Restore X and Y
|
||||
ply_trash_a
|
||||
|
||||
@@ -32,6 +32,7 @@
|
||||
|
||||
|
||||
// XXX use pilot to calibrate reading speed
|
||||
// XXX add error correction
|
||||
|
||||
|
||||
#if CONFIG_TAPE_NORMAL
|
||||
@@ -41,22 +42,6 @@ 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
|
||||
@@ -66,6 +51,7 @@ load_tape_normal:
|
||||
|
||||
// Start playing
|
||||
|
||||
jsr tape_common_prepare_cia
|
||||
jsr tape_ask_play
|
||||
|
||||
// FALLTROUGH
|
||||
|
||||
@@ -4,13 +4,9 @@
|
||||
// Tape (turbo) part of the LOAD routine
|
||||
//
|
||||
|
||||
// Based on routine by enthusi/Onslaught, found here:
|
||||
// Initially based on routine by enthusi/Onslaught, found here:
|
||||
// - https://codebase64.pokefinder.org/doku.php?id=base:turbotape_loader_source
|
||||
|
||||
|
||||
// XXX use calibration bits to improve reading
|
||||
// XXX find out how to use B0 tape timing
|
||||
// XXX put header type into (TAPE1)
|
||||
// but heavily reworked since then. Still, original authors deserve credits!
|
||||
|
||||
|
||||
#if CONFIG_TAPE_TURBO
|
||||
@@ -20,15 +16,11 @@ load_tape_turbo:
|
||||
|
||||
jsr tape_ditch_verify // only LOAD is supported, no VERIFY
|
||||
|
||||
lda #$00
|
||||
sta CIA2_TIMAHI // $DD05
|
||||
lda #$FE // timer threshold for TurboTape
|
||||
sta CIA2_TIMALO // $DD04
|
||||
|
||||
// Prepare for sound effects
|
||||
jsr tape_clean_sid
|
||||
|
||||
// Start playing
|
||||
jsr tape_common_prepare_cia
|
||||
jsr tape_ask_play
|
||||
|
||||
// FALLTROUGH
|
||||
@@ -76,7 +68,7 @@ load_tape_turbo_header_loop:
|
||||
// Handle the header
|
||||
|
||||
jsr tape_clean_sid
|
||||
jsr tape_handle_header // XXX handle non-relocatable programs - any non-0 even header type
|
||||
jsr tape_handle_header
|
||||
bcs load_tape_turbo_header // if name does not match, look for other header
|
||||
|
||||
// FALLTROUGH
|
||||
|
||||
@@ -0,0 +1,30 @@
|
||||
#if ROM_LAYOUT_STD || (ROM_LAYOUT_M65 && SEGMENT_KERNAL_0)
|
||||
|
||||
|
||||
#if CONFIG_TAPE_NORMAL || CONFIG_TAPE_TURBO
|
||||
|
||||
|
||||
tape_common_prepare_cia:
|
||||
|
||||
// Setup CIA #2 timers
|
||||
|
||||
ldx #$03 // set timer A to 4 ticks XXX consider setting to 8
|
||||
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
|
||||
|
||||
rts
|
||||
|
||||
#endif
|
||||
|
||||
|
||||
#endif // ROM layout
|
||||
@@ -18,7 +18,7 @@ tape_normal_get_pulse:
|
||||
// implementation is probably just shorter
|
||||
|
||||
lda #$10
|
||||
!:
|
||||
!:
|
||||
bit CIA1_ICR // $DC0D
|
||||
beq !- // busy loop to detect signal, restart timer afterwards
|
||||
lda CIA2_TIMBLO // $DD06
|
||||
|
||||
@@ -13,26 +13,34 @@
|
||||
|
||||
tape_turbo_get_bit:
|
||||
|
||||
lda #$10
|
||||
lda #$10
|
||||
!:
|
||||
bit CIA1_ICR // $DC0D
|
||||
beq !- // busy loop to detect signal
|
||||
lda CIA2_ICR // $DD0D
|
||||
pha
|
||||
lda #%00011001 // start timer, one-shot, force latch reload
|
||||
sta CIA2_CRA // $DD0E
|
||||
pla
|
||||
|
||||
pha // audio/video effects
|
||||
asl
|
||||
sta SID_SIGVOL
|
||||
beq !+
|
||||
lda #$06
|
||||
!:
|
||||
sta VIC_EXTCOL
|
||||
pla
|
||||
bit CIA1_ICR // $DC0D
|
||||
beq !- // busy loop to detect signal, restart timer afterwards
|
||||
lda CIA2_TIMBLO // $DD06
|
||||
ldx #%01010001 // start timer, force latch reload, count timer A underflows
|
||||
stx CIA2_CRB // $DD0F
|
||||
|
||||
lsr
|
||||
#if CONFIG_TAPE_TURBO_AUTOCALIBRATE
|
||||
tax
|
||||
cmp IRQTMP+0
|
||||
#else
|
||||
cmp #$BF // threshold calculated by autocalibration routines under VICE
|
||||
#endif
|
||||
|
||||
bcs !+
|
||||
|
||||
lda #$01
|
||||
sta SID_SIGVOL
|
||||
lda #$06
|
||||
sta VIC_EXTCOL
|
||||
sec
|
||||
rts
|
||||
!:
|
||||
lda #$00
|
||||
sta SID_SIGVOL
|
||||
sta VIC_EXTCOL
|
||||
clc
|
||||
rts
|
||||
|
||||
|
||||
|
||||
@@ -15,14 +15,16 @@
|
||||
|
||||
tape_turbo_get_byte:
|
||||
|
||||
phx_trash_a
|
||||
lda #$01
|
||||
sta INBIT // init the to-be-read byte with 1 (canary bit to mark loop end)
|
||||
!:
|
||||
jsr tape_turbo_get_bit
|
||||
rol INBIT
|
||||
bcc !- // is the initial 1 shifted into carry already?
|
||||
lda INBIT // much nicer than ldx #8: dex: loop
|
||||
|
||||
plx_trash_a
|
||||
lda INBIT
|
||||
|
||||
rts
|
||||
|
||||
|
||||
|
||||
@@ -22,18 +22,78 @@ tape_turbo_sync_common:
|
||||
|
||||
tape_turbo_sync_header:
|
||||
|
||||
ldx #$FF
|
||||
!:
|
||||
#if CONFIG_TAPE_TURBO_AUTOCALIBRATE
|
||||
|
||||
// Initial pulse threshold
|
||||
lda #$BF // auto-calibration under VICE often returns this value
|
||||
sta IRQTMP+0
|
||||
|
||||
// Zero temporary stack area
|
||||
lda #$00
|
||||
ldy #$03
|
||||
!:
|
||||
sta STACK, y
|
||||
dey
|
||||
bpl !-
|
||||
|
||||
#endif // CONFIG_TAPE_TURBO_AUTOCALIBRATE
|
||||
|
||||
// Perform synchronization
|
||||
ldx #$C0
|
||||
!:
|
||||
phx_trash_a
|
||||
ldy #$04
|
||||
!:
|
||||
jsr tape_turbo_sync_common
|
||||
dey
|
||||
bne !-
|
||||
plx_trash_a
|
||||
dex
|
||||
bne !--
|
||||
|
||||
// FALLTROUGH
|
||||
|
||||
#if CONFIG_TAPE_TURBO_AUTOCALIBRATE
|
||||
|
||||
tape_turbo_sync_calibrate:
|
||||
|
||||
ldy #$80
|
||||
|
||||
// FALLTROUGH
|
||||
|
||||
tape_turbo_sync_calibrate_loop:
|
||||
|
||||
// Skip 5 bits
|
||||
phy_trash_a
|
||||
ldy #$04
|
||||
!:
|
||||
jsr tape_turbo_get_bit
|
||||
bcs tape_turbo_sync_header
|
||||
dey
|
||||
bpl !-
|
||||
|
||||
jsr tape_turbo_sync_measure_0
|
||||
jsr tape_turbo_sync_measure_1
|
||||
jsr tape_turbo_sync_measure_0
|
||||
|
||||
ply_trash_a
|
||||
dey
|
||||
bne tape_turbo_sync_calibrate_loop
|
||||
|
||||
// Calculate new pulse threshold as arithmetic mean
|
||||
// We accumulated 256 zeros and 128 ones, so calculating average value is easy
|
||||
|
||||
lda STACK+0
|
||||
clc
|
||||
ror
|
||||
clc
|
||||
adc STACK+1
|
||||
sta IRQTMP+0
|
||||
|
||||
// FALLTROUGH
|
||||
|
||||
#endif // CONFIG_TAPE_TURBO_AUTOCALIBRATE
|
||||
|
||||
tape_turbo_sync_payload:
|
||||
|
||||
jsr tape_turbo_sync_common
|
||||
|
||||
@@ -0,0 +1,46 @@
|
||||
#if ROM_LAYOUT_STD || (ROM_LAYOUT_M65 && SEGMENT_KERNAL_0)
|
||||
|
||||
//
|
||||
// Tape (turbo) helper routine - measure bit length for calibration purposes
|
||||
//
|
||||
|
||||
#if CONFIG_TAPE_TURBO && CONFIG_TAPE_TURBO_AUTOCALIBRATE
|
||||
|
||||
|
||||
tape_turbo_sync_measure_0:
|
||||
|
||||
// Measure bit '0'
|
||||
jsr tape_turbo_get_bit
|
||||
bcs tape_turbo_sync_measure_fail
|
||||
txa
|
||||
adc STACK+2
|
||||
sta STACK+2
|
||||
bcc !+
|
||||
inc STACK+0
|
||||
!:
|
||||
rts
|
||||
|
||||
tape_turbo_sync_measure_1:
|
||||
|
||||
// Measure bit '1'
|
||||
jsr tape_turbo_get_bit
|
||||
bcc tape_turbo_sync_measure_fail
|
||||
txa
|
||||
adc STACK+3
|
||||
sta STACK+3
|
||||
bcc !+
|
||||
inc STACK+1
|
||||
!:
|
||||
rts
|
||||
|
||||
tape_turbo_sync_measure_fail:
|
||||
|
||||
pla
|
||||
pla
|
||||
jmp tape_turbo_sync_header
|
||||
|
||||
|
||||
#endif
|
||||
|
||||
|
||||
#endif // ROM layout
|
||||
Reference in new issue
Block a user