working first block

This commit is contained in:
Joppe Blondel
2026-10-04 17:10:21 +02:00
parent 5348660aa7
commit 79d427668a
3 changed files with 243 additions and 32 deletions
+8 -1
View File
@@ -20,6 +20,11 @@ class FSKWriter:
self.phase = 0.0
self.samples = bytearray()
self.samples.extend(b'\0'*int(1.0*self.sample_rate))
def finalize(self):
self.samples.extend(b'\0'*int(1.0*self.sample_rate))
def _tone(self, frequency: float, sample_count: int) -> None:
phase_step = 2.0 * math.pi * frequency / self.sample_rate
scale = int(32767 * self.amplitude)
@@ -41,7 +46,7 @@ class FSKWriter:
for _ in range(8):
self.bit(1)
self.bit(0)
self.byte(0x0f)
self.byte(0xf0)
def bit(self, value: int) -> None:
if value:
@@ -66,6 +71,7 @@ class FSKWriter:
self.byte(l&0xff)
self.bytes(data)
self.byte(self.chsum(data))
self.samples.extend(b'\0'*int(0.3*self.sample_rate))
def chsum(self, data: bytes) -> int:
cs = 0
@@ -93,6 +99,7 @@ def main() -> None:
tones.block(0, args.input.name.encode())
tones.finalize()
with wave.open(str(output_path), "wb") as wav:
wav.setnchannels(1)
wav.setsampwidth(2)
+234 -30
View File
@@ -4,6 +4,8 @@
.org TAPE_LOADER_ROM_ADDRESS
TAPE_PORT = 0x18
MAX_CYCLE_COUNT = 20
MAX_BLOCK_SIZE = 0x100
STACK_TOP = 0xBFFF
WORK_BASE = 0xB000
@@ -15,6 +17,10 @@ LONG_LEN = WORK_BASE + 0x04 ; byte
TRESHOLD = WORK_BASE + 0x05 ; byte
SHORT_COUNT = WORK_BASE + 0x06 ; byte
LONG_COUNT = WORK_BASE + 0x07 ; byte
BLOCK_LENGTH = WORK_BASE + 0x08 ; word
BLOCK_NUMBER = WORK_BASE + 0x0a ; byte
BLOCK_BUFFER = WORK_BASE + 0x100 ; MAX_BLOCK_SIZE
; #################################################3
; Entry
@@ -38,42 +44,23 @@ save_iff:
ld hl,#msg_start
call print_with_irqs
; Calibrate receiver
call calibrate
; Print parameters
; Read the first block
call read_block
jr z,1$
ld hl,#msg_error_checksum
ei
ld hl,#msg_short_len
call print_string
ld a,(SHORT_LEN)
call print_hex8
call print_crlf
ld hl,#msg_long_len
di
jp exit
1$:
; Filename stored in buffer
ei
ld hl,#msg_filename
call print_string
ld a,(LONG_LEN)
call print_hex8
call print_crlf
ld hl,#msg_treshold
ld hl,#BLOCK_BUFFER
call print_string
ld a,(TRESHOLD)
call print_hex8
call print_crlf
ld hl,#msg_short_count
call print_string
ld a,(SHORT_COUNT)
call print_hex8
call print_crlf
ld hl,#msg_long_count
call print_string
ld a,(LONG_COUNT)
call print_hex8
call print_crlf
call BIOS_FLUSH
di
; #################################################3
@@ -132,6 +119,19 @@ wait_cycle:
ld d,a
ret
; #################################################3
; Eat A cycles
; #################################################3
eat_cycles:
or a,a
ret z
ld c,a
1$:
call wait_cycle
dec c
jr nz,1$
ret
; #################################################3
; Average 16 cycle intervals
; Returns A = average loop count
@@ -157,6 +157,10 @@ average16:
ret
; #################################################3
; Calibrate
; Gets short and long pulse lenghts and bit pulse counts
; from training sequence
; carry = succeeded
; #################################################3
calibrate:
; establish comparator state
@@ -164,6 +168,9 @@ calibrate:
ld d,a
; Wait for the first edge
call wait_edge
; Wait for the next edge to be back in phase with the
; audio stream
call wait_edge
; Measure shoft pulses
call average16
@@ -210,6 +217,9 @@ calibrate:
cp a,c
jr nc,5$
inc e
ld a,#MAX_CYCLE_COUNT
cp a,e
jp c,error_cycle_count
jr 4$
5$:
ld a,e
@@ -223,13 +233,181 @@ calibrate:
cp a,c
jr c,7$
inc e
ld a,#MAX_CYCLE_COUNT
cp a,e
jp c,error_cycle_count
jr 6$
7$:
ld a,e
ld (LONG_COUNT),a
; First cycle of short was already consymed
ld a,(SHORT_COUNT)
dec a
call eat_cycles
; Consume rest of training bits
; 6 L/S pairs then last L
ld h,#6
8$:
ld a,(LONG_COUNT)
call eat_cycles
ld a,(SHORT_COUNT)
call eat_cycles
dec h
jr nz,8$
ld a,(LONG_COUNT)
call eat_cycles
; Test calibration with sync byte
call check_sync_byte
ret
error_cycle_count:
ei
ld hl,#msg_error_cycle_count
call print_string
call print_crlf
di
jp exit
; #################################################3
; Read one bit
; carry = value
; #################################################3
read_bit:
call wait_cycle
ld a,(TRESHOLD)
ld c,a
ld a,b
cp a,c
jr c,2$
; zero bit
1$:
ld a,(LONG_COUNT)
dec a
call eat_cycles
or a,a ; clear carry
ret
; one bit
2$:
ld a,(SHORT_COUNT)
dec a
call eat_cycles
scf ; set carry
ret
; #################################################3
; Read byte
; A = byte
; #################################################3
read_byte:
ld e,#0
ld h,#8
1$:
call read_bit
rl e
dec h
jr nz,1$
ld a,e
ret
; #################################################3
; Check sync byte
; carry = succeeded
; #################################################3
check_sync_byte:
call read_byte
ld e,a
ld a,#0xf0
cp a,e
jr z,1$
or a,a
ret
1$:
scf
ret
error_wrong_sync_byte:
ei
ld hl,#msg_error_sync_not_found
call print_string
call print_crlf
di
jp exit
; #################################################3
; Read a block
; checksum in a
; #################################################3
read_block:
call calibrate
jp nc,error_wrong_sync_byte
; Get block number
call read_byte
ld (BLOCK_NUMBER),a
; Get block length
call read_byte
ld b,a
push bc
call read_byte
pop bc
ld c,a
ld (BLOCK_LENGTH),bc
exx
ld bc,(BLOCK_LENGTH)
ld hl,#BLOCK_BUFFER
1$:
exx
call read_byte
exx
ld (hl),a
inc hl
dec bc
; Check for zero
ld a,b
or a,c
jr nz,1$
; Read checksum
exx
call read_byte
; Calculate checksum of block
ld hl,#BLOCK_BUFFER
ld bc,(BLOCK_LENGTH)
push af
xor a,a
ld e,a
2$:
ld a,e
add a,(hl)
ld e,a
inc hl
dec bc
; Check for zero
ld a,b
or a,c
jr nz,2$
pop af
; e is calculated checksum
; a is received checksum
ld h,a
ld l,e
cp a,e
ret
; #################################################3
; IO Helper functions
; #################################################3
@@ -254,6 +432,15 @@ print_crlf:
ld a,#10
jp BIOS_PUTC
print_hex16:
push hl
ld a,h
call print_hex8
pop hl
ld a,l
call print_hex8
ret
print_hex8:
push af
rrca
@@ -302,3 +489,20 @@ msg_short_count:
msg_long_count:
.ascii "Long count: "
.db 0
msg_error_cycle_count:
.ascii "Cycle count out of bounds"
.db 0
msg_error_sync_not_found:
.ascii "Sync not found"
.db 0
msg_error_checksum:
.ascii "Checksum error"
.db 0
msg_filename:
.ascii "Filename: "
.db 0
Binary file not shown.