working first block
This commit is contained in:
@@ -20,6 +20,11 @@ class FSKWriter:
|
|||||||
self.phase = 0.0
|
self.phase = 0.0
|
||||||
self.samples = bytearray()
|
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:
|
def _tone(self, frequency: float, sample_count: int) -> None:
|
||||||
phase_step = 2.0 * math.pi * frequency / self.sample_rate
|
phase_step = 2.0 * math.pi * frequency / self.sample_rate
|
||||||
scale = int(32767 * self.amplitude)
|
scale = int(32767 * self.amplitude)
|
||||||
@@ -41,7 +46,7 @@ class FSKWriter:
|
|||||||
for _ in range(8):
|
for _ in range(8):
|
||||||
self.bit(1)
|
self.bit(1)
|
||||||
self.bit(0)
|
self.bit(0)
|
||||||
self.byte(0x0f)
|
self.byte(0xf0)
|
||||||
|
|
||||||
def bit(self, value: int) -> None:
|
def bit(self, value: int) -> None:
|
||||||
if value:
|
if value:
|
||||||
@@ -66,6 +71,7 @@ class FSKWriter:
|
|||||||
self.byte(l&0xff)
|
self.byte(l&0xff)
|
||||||
self.bytes(data)
|
self.bytes(data)
|
||||||
self.byte(self.chsum(data))
|
self.byte(self.chsum(data))
|
||||||
|
self.samples.extend(b'\0'*int(0.3*self.sample_rate))
|
||||||
|
|
||||||
def chsum(self, data: bytes) -> int:
|
def chsum(self, data: bytes) -> int:
|
||||||
cs = 0
|
cs = 0
|
||||||
@@ -93,6 +99,7 @@ def main() -> None:
|
|||||||
tones.block(0, args.input.name.encode())
|
tones.block(0, args.input.name.encode())
|
||||||
|
|
||||||
|
|
||||||
|
tones.finalize()
|
||||||
with wave.open(str(output_path), "wb") as wav:
|
with wave.open(str(output_path), "wb") as wav:
|
||||||
wav.setnchannels(1)
|
wav.setnchannels(1)
|
||||||
wav.setsampwidth(2)
|
wav.setsampwidth(2)
|
||||||
|
|||||||
+234
-30
@@ -4,6 +4,8 @@
|
|||||||
.org TAPE_LOADER_ROM_ADDRESS
|
.org TAPE_LOADER_ROM_ADDRESS
|
||||||
|
|
||||||
TAPE_PORT = 0x18
|
TAPE_PORT = 0x18
|
||||||
|
MAX_CYCLE_COUNT = 20
|
||||||
|
MAX_BLOCK_SIZE = 0x100
|
||||||
|
|
||||||
STACK_TOP = 0xBFFF
|
STACK_TOP = 0xBFFF
|
||||||
WORK_BASE = 0xB000
|
WORK_BASE = 0xB000
|
||||||
@@ -15,6 +17,10 @@ LONG_LEN = WORK_BASE + 0x04 ; byte
|
|||||||
TRESHOLD = WORK_BASE + 0x05 ; byte
|
TRESHOLD = WORK_BASE + 0x05 ; byte
|
||||||
SHORT_COUNT = WORK_BASE + 0x06 ; byte
|
SHORT_COUNT = WORK_BASE + 0x06 ; byte
|
||||||
LONG_COUNT = WORK_BASE + 0x07 ; 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
|
; #################################################3
|
||||||
; Entry
|
; Entry
|
||||||
@@ -38,42 +44,23 @@ save_iff:
|
|||||||
ld hl,#msg_start
|
ld hl,#msg_start
|
||||||
call print_with_irqs
|
call print_with_irqs
|
||||||
|
|
||||||
; Calibrate receiver
|
; Read the first block
|
||||||
call calibrate
|
call read_block
|
||||||
|
jr z,1$
|
||||||
; Print parameters
|
ld hl,#msg_error_checksum
|
||||||
ei
|
ei
|
||||||
ld hl,#msg_short_len
|
|
||||||
call print_string
|
call print_string
|
||||||
ld a,(SHORT_LEN)
|
|
||||||
call print_hex8
|
|
||||||
call print_crlf
|
call print_crlf
|
||||||
|
di
|
||||||
ld hl,#msg_long_len
|
jp exit
|
||||||
|
1$:
|
||||||
|
; Filename stored in buffer
|
||||||
|
ei
|
||||||
|
ld hl,#msg_filename
|
||||||
call print_string
|
call print_string
|
||||||
ld a,(LONG_LEN)
|
ld hl,#BLOCK_BUFFER
|
||||||
call print_hex8
|
|
||||||
call print_crlf
|
|
||||||
|
|
||||||
ld hl,#msg_treshold
|
|
||||||
call print_string
|
call print_string
|
||||||
ld a,(TRESHOLD)
|
|
||||||
call print_hex8
|
|
||||||
call print_crlf
|
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
|
di
|
||||||
|
|
||||||
; #################################################3
|
; #################################################3
|
||||||
@@ -132,6 +119,19 @@ wait_cycle:
|
|||||||
ld d,a
|
ld d,a
|
||||||
ret
|
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
|
; #################################################3
|
||||||
; Average 16 cycle intervals
|
; Average 16 cycle intervals
|
||||||
; Returns A = average loop count
|
; Returns A = average loop count
|
||||||
@@ -157,6 +157,10 @@ average16:
|
|||||||
ret
|
ret
|
||||||
|
|
||||||
; #################################################3
|
; #################################################3
|
||||||
|
; Calibrate
|
||||||
|
; Gets short and long pulse lenghts and bit pulse counts
|
||||||
|
; from training sequence
|
||||||
|
; carry = succeeded
|
||||||
; #################################################3
|
; #################################################3
|
||||||
calibrate:
|
calibrate:
|
||||||
; establish comparator state
|
; establish comparator state
|
||||||
@@ -164,6 +168,9 @@ calibrate:
|
|||||||
ld d,a
|
ld d,a
|
||||||
; Wait for the first edge
|
; Wait for the first edge
|
||||||
call wait_edge
|
call wait_edge
|
||||||
|
; Wait for the next edge to be back in phase with the
|
||||||
|
; audio stream
|
||||||
|
call wait_edge
|
||||||
|
|
||||||
; Measure shoft pulses
|
; Measure shoft pulses
|
||||||
call average16
|
call average16
|
||||||
@@ -210,6 +217,9 @@ calibrate:
|
|||||||
cp a,c
|
cp a,c
|
||||||
jr nc,5$
|
jr nc,5$
|
||||||
inc e
|
inc e
|
||||||
|
ld a,#MAX_CYCLE_COUNT
|
||||||
|
cp a,e
|
||||||
|
jp c,error_cycle_count
|
||||||
jr 4$
|
jr 4$
|
||||||
5$:
|
5$:
|
||||||
ld a,e
|
ld a,e
|
||||||
@@ -223,13 +233,181 @@ calibrate:
|
|||||||
cp a,c
|
cp a,c
|
||||||
jr c,7$
|
jr c,7$
|
||||||
inc e
|
inc e
|
||||||
|
ld a,#MAX_CYCLE_COUNT
|
||||||
|
cp a,e
|
||||||
|
jp c,error_cycle_count
|
||||||
jr 6$
|
jr 6$
|
||||||
7$:
|
7$:
|
||||||
ld a,e
|
ld a,e
|
||||||
ld (LONG_COUNT),a
|
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
|
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
|
; #################################################3
|
||||||
; IO Helper functions
|
; IO Helper functions
|
||||||
; #################################################3
|
; #################################################3
|
||||||
@@ -254,6 +432,15 @@ print_crlf:
|
|||||||
ld a,#10
|
ld a,#10
|
||||||
jp BIOS_PUTC
|
jp BIOS_PUTC
|
||||||
|
|
||||||
|
print_hex16:
|
||||||
|
push hl
|
||||||
|
ld a,h
|
||||||
|
call print_hex8
|
||||||
|
pop hl
|
||||||
|
ld a,l
|
||||||
|
call print_hex8
|
||||||
|
ret
|
||||||
|
|
||||||
print_hex8:
|
print_hex8:
|
||||||
push af
|
push af
|
||||||
rrca
|
rrca
|
||||||
@@ -302,3 +489,20 @@ msg_short_count:
|
|||||||
msg_long_count:
|
msg_long_count:
|
||||||
.ascii "Long count: "
|
.ascii "Long count: "
|
||||||
.db 0
|
.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.
Reference in New Issue
Block a user