turbo tape can now adjust itself for tape motor speed

This commit is contained in:
FeralChild64 committed 2020-01-14 16:22:30 +01:00
1 parent 723a7772fa
commit 9061a8d0fc
18 files changed
+206 -62

No files matched your search

+7 -1
View File
@@ -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.
+2 -2
View File
@@ -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
+1
View File
@@ -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
+1
View File
@@ -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
+1
View File
@@ -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
+1
View File
@@ -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
+1
View File
@@ -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
+15 -6
View File
@@ -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)
+1 -1
View File
@@ -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 --
+1 -1
View File
@@ -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
+2 -16
View File
@@ -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 -12
View File
@@ -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
+30
View File
@@ -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
+1 -1
View File
@@ -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
+26 -18
View File
@@ -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
+4 -2
View File
@@ -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
+62 -2
View File
@@ -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
+46
View File
@@ -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