turbo tape now adjusts it's reading speed dynamically
This commit is contained in:
1 parent
f922f90653
commit
815dbe5f35
12 files changed
+75
-113
No files matched your search
@@ -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.
|
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`
|
### `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.
|
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
|
* JiffyDOS and DolphinDOS protocols support
|
||||||
* DOS wedge (direct mode only) - `@<drive_number>`, `@<command>`, `@$`, `@$<params>`, `@`
|
* 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)
|
* improved support for tape adapters (for using regular casette players and other audio devices instead of Datasette)
|
||||||
|
|
||||||
* extended `LOAD` command
|
* extended `LOAD` command
|
||||||
|
|||||||
@@ -56,7 +56,6 @@
|
|||||||
|
|
||||||
#define CONFIG_TAPE_NORMAL
|
#define CONFIG_TAPE_NORMAL
|
||||||
#define CONFIG_TAPE_TURBO
|
#define CONFIG_TAPE_TURBO
|
||||||
#define CONFIG_TAPE_TURBO_AUTOCALIBRATE
|
|
||||||
// #define CONFIG_TAPE_NO_KEY_SENSE
|
// #define CONFIG_TAPE_NO_KEY_SENSE
|
||||||
// #define CONFIG_TAPE_NO_MOTOR_CONTROL
|
// #define CONFIG_TAPE_NO_MOTOR_CONTROL
|
||||||
|
|
||||||
|
|||||||
@@ -50,7 +50,6 @@
|
|||||||
|
|
||||||
#define CONFIG_TAPE_NORMAL
|
#define CONFIG_TAPE_NORMAL
|
||||||
#define CONFIG_TAPE_TURBO
|
#define CONFIG_TAPE_TURBO
|
||||||
#define CONFIG_TAPE_TURBO_AUTOCALIBRATE
|
|
||||||
// #define CONFIG_TAPE_NO_KEY_SENSE
|
// #define CONFIG_TAPE_NO_KEY_SENSE
|
||||||
// #define CONFIG_TAPE_NO_MOTOR_CONTROL
|
// #define CONFIG_TAPE_NO_MOTOR_CONTROL
|
||||||
|
|
||||||
|
|||||||
@@ -50,7 +50,6 @@
|
|||||||
|
|
||||||
// #define CONFIG_TAPE_NORMAL
|
// #define CONFIG_TAPE_NORMAL
|
||||||
// #define CONFIG_TAPE_TURBO
|
// #define CONFIG_TAPE_TURBO
|
||||||
// #define CONFIG_TAPE_TURBO_AUTOCALIBRATE
|
|
||||||
// #define CONFIG_TAPE_NO_KEY_SENSE
|
// #define CONFIG_TAPE_NO_KEY_SENSE
|
||||||
// #define CONFIG_TAPE_NO_MOTOR_CONTROL
|
// #define CONFIG_TAPE_NO_MOTOR_CONTROL
|
||||||
|
|
||||||
|
|||||||
@@ -50,7 +50,6 @@
|
|||||||
|
|
||||||
// #define CONFIG_TAPE_NORMAL
|
// #define CONFIG_TAPE_NORMAL
|
||||||
#define CONFIG_TAPE_TURBO
|
#define CONFIG_TAPE_TURBO
|
||||||
// #define CONFIG_TAPE_TURBO_AUTOCALIBRATE
|
|
||||||
// #define CONFIG_TAPE_NO_KEY_SENSE
|
// #define CONFIG_TAPE_NO_KEY_SENSE
|
||||||
// #define CONFIG_TAPE_NO_MOTOR_CONTROL
|
// #define CONFIG_TAPE_NO_MOTOR_CONTROL
|
||||||
|
|
||||||
|
|||||||
@@ -50,7 +50,6 @@
|
|||||||
|
|
||||||
#define CONFIG_TAPE_NORMAL
|
#define CONFIG_TAPE_NORMAL
|
||||||
#define CONFIG_TAPE_TURBO
|
#define CONFIG_TAPE_TURBO
|
||||||
#define CONFIG_TAPE_TURBO_AUTOCALIBRATE
|
|
||||||
// #define CONFIG_TAPE_NO_KEY_SENSE
|
// #define CONFIG_TAPE_NO_KEY_SENSE
|
||||||
// #define CONFIG_TAPE_NO_MOTOR_CONTROL
|
// #define CONFIG_TAPE_NO_MOTOR_CONTROL
|
||||||
|
|
||||||
|
|||||||
@@ -88,7 +88,7 @@
|
|||||||
.label VERCKK = $93 // 0 = LOAD, 1 = VERIFY
|
.label VERCKK = $93 // 0 = LOAD, 1 = VERIFY
|
||||||
.label C3PO = $94 // flag - is BSOUR content valid
|
.label C3PO = $94 // flag - is BSOUR content valid
|
||||||
.label BSOUR = $95 // serial bus buffered output byte
|
.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 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 LDTND = $98 // number of entries in LAT / FAT / SAT tables
|
||||||
.label DFLTN = $99 // default input device
|
.label DFLTN = $99 // default input device
|
||||||
|
|||||||
@@ -2,6 +2,37 @@
|
|||||||
// #LAYOUT# * KERNAL_0 #TAKE
|
// #LAYOUT# * KERNAL_0 #TAKE
|
||||||
// #LAYOUT# * * #IGNORE
|
// #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
|
#if CONFIG_TAPE_NORMAL || CONFIG_TAPE_TURBO
|
||||||
|
|
||||||
|
|||||||
@@ -31,16 +31,13 @@ tape_turbo_get_bit:
|
|||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
cmp SYNO // threshold
|
||||||
#if CONFIG_TAPE_TURBO_AUTOCALIBRATE
|
|
||||||
tax
|
|
||||||
cmp IRQTMP+0
|
|
||||||
#else
|
|
||||||
cmp #$BF // threshold calculated by autocalibration routines under VICE
|
|
||||||
#endif
|
|
||||||
|
|
||||||
bcs !+
|
bcs !+
|
||||||
|
|
||||||
|
clc
|
||||||
|
ror
|
||||||
|
sta IRQTMP+0 // store half of the last measurement result for short pulse
|
||||||
|
|
||||||
lda #$01
|
lda #$01
|
||||||
sta SID_SIGVOL
|
sta SID_SIGVOL
|
||||||
lda #$06
|
lda #$06
|
||||||
@@ -48,6 +45,10 @@ tape_turbo_get_bit:
|
|||||||
sec
|
sec
|
||||||
rts
|
rts
|
||||||
!:
|
!:
|
||||||
|
clc
|
||||||
|
ror
|
||||||
|
sta IRQTMP+1 // store half of the last measurement result for long pulse
|
||||||
|
|
||||||
lda #$00
|
lda #$00
|
||||||
sta SID_SIGVOL
|
sta SID_SIGVOL
|
||||||
sta VIC_EXTCOL
|
sta VIC_EXTCOL
|
||||||
|
|||||||
@@ -25,8 +25,35 @@ tape_turbo_get_byte:
|
|||||||
rol INBIT
|
rol INBIT
|
||||||
bcc !- // is the initial 1 shifted into carry already?
|
bcc !- // is the initial 1 shifted into carry already?
|
||||||
plx_trash_a
|
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
|
rts
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@@ -15,8 +15,9 @@
|
|||||||
|
|
||||||
tape_turbo_sync_header:
|
tape_turbo_sync_header:
|
||||||
|
|
||||||
|
// Initial pulse threshold
|
||||||
#if !CONFIG_TAPE_TURBO_AUTOCALIBRATE
|
lda #$BF // measured 128 bits '0' and 128 bits '1' under VICE, calculated average
|
||||||
|
sta SYNO
|
||||||
|
|
||||||
// Synchronize with start of sync sequence
|
// Synchronize with start of sync sequence
|
||||||
jsr tape_turbo_sync_first
|
jsr tape_turbo_sync_first
|
||||||
@@ -24,106 +25,19 @@ tape_turbo_sync_header:
|
|||||||
// Perform synchronization, double loop, total $C0 * $04 iterations
|
// Perform synchronization, double loop, total $C0 * $04 iterations
|
||||||
ldx #$C0
|
ldx #$C0
|
||||||
!:
|
!:
|
||||||
phx_trash_a
|
|
||||||
ldy #$04
|
ldy #$04
|
||||||
!:
|
!:
|
||||||
|
stx XSAV
|
||||||
jsr tape_turbo_get_byte
|
jsr tape_turbo_get_byte
|
||||||
cmp #$02
|
cmp #$02
|
||||||
bne tape_turbo_sync_header // branch if failure
|
bne tape_turbo_sync_header // branch if failure
|
||||||
|
|
||||||
dey
|
dey
|
||||||
bne !-
|
bne !-
|
||||||
plx_trash_a
|
ldx XSAV
|
||||||
dex
|
dex
|
||||||
bne !--
|
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
|
// FALLTROUGH
|
||||||
|
|
||||||
tape_turbo_sync_payload:
|
tape_turbo_sync_payload:
|
||||||
|
|||||||
Reference in new issue
Block a user