turbo tape now adjusts it's reading speed dynamically

This commit is contained in:
FeralChild64 committed 2020-01-16 18:51:58 +01:00
1 parent f922f90653
commit 815dbe5f35
12 files changed
+75 -113

No files matched your search

-6
View File
@@ -155,12 +155,6 @@ Adds a minimal turbo tape support - just LOAD command (device 7, like on _Action
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.
+1 -1
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`), quite sophisticated: up to 250 blocks (can store bytes under I/O), can use sync signal for autocalibration (less load errors than simple turbos)
* turbo tape load support (as device 7, or using `←L`), quite sophisticated: up to 250 blocks (can store bytes under I/O), automatically adjusts for tape speed differences
* improved support for tape adapters (for using regular casette players and other audio devices instead of Datasette)
* extended `LOAD` command
-1
View File
@@ -56,7 +56,6 @@
#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,7 +50,6 @@
#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,7 +50,6 @@
// #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,7 +50,6 @@
// #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,7 +50,6 @@
#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 -1
View File
@@ -88,7 +88,7 @@
.label VERCKK = $93 // 0 = LOAD, 1 = VERIFY
.label C3PO = $94 // flag - is BSOUR content valid
.label BSOUR = $95 // serial bus buffered output byte
.label SYNO = $96 // -- NOT IMPLEMENTED --
.label SYNO = $96 // temporary tape routines storage, [!] our usage differs
.label XSAV = $97 // temporary register storage for ASCII/tape related routines [!] usage details might differ
.label LDTND = $98 // number of entries in LAT / FAT / SAT tables
.label DFLTN = $99 // default input device
+31
View File
@@ -2,6 +2,37 @@
// #LAYOUT# * KERNAL_0 #TAKE
// #LAYOUT# * * #IGNORE
//
// Prepare CIA timers for tape reading
//
//
// Checked under VICE, PAL, average of 256 pulses:
//
// normal - short - timer goes down to $C9
// normal - medium - timer goes down to $79
// normal - long - timer goes down to $52
//
// turbo - short - timer goes down to $B1
// turbo - long - timer goes down to $CD
//
//
// Measurement subroutine: .A should contain timer value, $C000-$C002 zeroed
//
// clc
// adc $C001
// sta $C001
// bcc !+
// inc $C000
// !:
// inc $C002
// beq !+
// rts
// !:
// lda $C000
// .break // .A contains our average
// rts
//
#if CONFIG_TAPE_NORMAL || CONFIG_TAPE_TURBO
+9 -8
View File
@@ -31,16 +31,13 @@ tape_turbo_get_bit:
#endif
#if CONFIG_TAPE_TURBO_AUTOCALIBRATE
tax
cmp IRQTMP+0
#else
cmp #$BF // threshold calculated by autocalibration routines under VICE
#endif
cmp SYNO // threshold
bcs !+
clc
ror
sta IRQTMP+0 // store half of the last measurement result for short pulse
lda #$01
sta SID_SIGVOL
lda #$06
@@ -48,6 +45,10 @@ tape_turbo_get_bit:
sec
rts
!:
clc
ror
sta IRQTMP+1 // store half of the last measurement result for long pulse
lda #$00
sta SID_SIGVOL
sta VIC_EXTCOL
+28 -1
View File
@@ -25,8 +25,35 @@ tape_turbo_get_byte:
rol INBIT
bcc !- // is the initial 1 shifted into carry already?
plx_trash_a
lda INBIT
// Compensate for tape speed variations
lda IRQTMP+0 // half of the last value for bit '0'
clc
adc IRQTMP+1 // half of the last value for bit '1'
sec
sbc SYNO // now we have a diff between current threshold and calculated one
beq tape_turbo_get_byte_done // branch if threshold correction not needed
bpl !+
lda SYNO
cmp #($BF - 10)
beq tape_turbo_get_byte_done // do not decrease threshold too far no matter what
dec SYNO
bne tape_turbo_get_byte_done // branch always
!:
lda SYNO
cmp #($BF + 10)
beq tape_turbo_get_byte_done // do not increase threshold too far no matter what
inc SYNO
tape_turbo_get_byte_done:
lda INBIT
rts
+5 -91
View File
@@ -15,8 +15,9 @@
tape_turbo_sync_header:
#if !CONFIG_TAPE_TURBO_AUTOCALIBRATE
// Initial pulse threshold
lda #$BF // measured 128 bits '0' and 128 bits '1' under VICE, calculated average
sta SYNO
// Synchronize with start of sync sequence
jsr tape_turbo_sync_first
@@ -24,106 +25,19 @@ tape_turbo_sync_header:
// Perform synchronization, double loop, total $C0 * $04 iterations
ldx #$C0
!:
phx_trash_a
ldy #$04
!:
stx XSAV
jsr tape_turbo_get_byte
cmp #$02
bne tape_turbo_sync_header // branch if failure
dey
bne !-
plx_trash_a
ldx XSAV
dex
bne !--
#else // 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 !-
// Synchronize with start of sync sequence
jsr tape_turbo_sync_first
// Perform synchronization, get measurements from 128 bytes
ldx #$10
// FALLTROUGH
tape_turbo_sync_outer_loop:
// Set .Y (inner loop counter) to $28-$38, average $30; $10 * $30 equals $C0 * $04
// We want a bit of irregularity with byte selection for calibration
txa
pha // store .X
clc
adc #$27
tay
// FALLTROUGH
tape_turbo_sync_inner_loop:
cpy #$09
bcc !+ // if inner couter is 8 or lower, get this byte for measurement
// Get byte without measurements
jsr tape_turbo_get_byte
cmp #$02
bne tape_turbo_sync_header // branch if failure
beq tape_turbo_sync_header_next_iter // branch always
!:
// Get byte and take measurements
phy_trash_a
// Skip 5 bits, they should be all 0
ldy #$04
!:
jsr tape_turbo_get_bit
bcs tape_turbo_sync_header
dey
bpl !-
// Get measurements from 3 bits
jsr tape_turbo_sync_measure_0
jsr tape_turbo_sync_measure_1
jsr tape_turbo_sync_measure_0
ply_trash_a
// FALLTROUGH
tape_turbo_sync_header_next_iter:
dey
bne tape_turbo_sync_inner_loop
plx_trash_a
dex
bne tape_turbo_sync_outer_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
#endif // CONFIG_TAPE_TURBO_AUTOCALIBRATE
// FALLTROUGH
tape_turbo_sync_payload: