working irl decoding

This commit is contained in:
Joppe Blondel
2026-10-09 14:51:56 +02:00
parent b8c6eaf4c9
commit c84b3fdc97
7 changed files with 352 additions and 70 deletions
+65 -52
View File
@@ -95,6 +95,11 @@ sample_pulse:
; returns a (average)
; cary is timeout
; uses b,e,h
; NOTE: USES 8 BIT COUNTER
; @1MHZ t_long<1.14ms
; @2MHZ t_long<571us
; @4MHZ t_long<285us
; TODO: Check feasibility of using 16bit accumulator
; -------------------------------------------------------
average8:
ld e,0
@@ -118,27 +123,33 @@ average8:
ret
; -------------------------------------------------------
; Make a +/-25% window around a
; needs a
; returns b (minimum) c (maximum)
; uses e,h
; NOTE: USES 8 BIT COUNTER
; @1MHZ t_long<1.14ms
; @2MHZ t_long<571us
; @4MHZ t_long<285us
; TODO: Check feasibility of using 16bit accumulator
; Make non-overlapping short and long pulse windows
; Boundary is the midpoint between both averages
; Short minimum and long maximum allow a 50% margin
; needs SHORT_AVG and LONG_AVG
; uses a,c
; -------------------------------------------------------
make_window:
ld e,a
make_windows:
ld a,(SHORT_AVG)
srl a
srl a
ld h,a ; h = a/4
ld a,e
sub h
ld b,a ; b = a-25%
ld a,e
add h
ld c,a ; c = a+25%
ld (SHORT_MIN),a ; short minimum = 50% of short
ld a,(LONG_AVG)
ld c,a
inc a
srl a ; ceil(long/2)
add c
ld (LONG_MAX),a ; long maximum = 150% of long
ld a,(SHORT_AVG)
ld c,a
ld a,(LONG_AVG)
add c
inc a
srl a ; ceil((short+long)/2)
ld (LONG_MIN),a ; midpoint belongs to long
dec a
ld (SHORT_MAX),a ; short ends below midpoint
ret
; -------------------------------------------------------
@@ -148,7 +159,7 @@ make_window:
; carry is error, a contains error code
; -------------------------------------------------------
calibrate:
ld a,(TAPE_PORT) ; get current state
in a,(TAPE_PORT) ; get current state
ld d,a
call sample_pulse ; make sure we start in silence
jp nc,cal_err ; should timeout
@@ -169,11 +180,6 @@ calibrate:
call average8
jr c,cal_err_short_leader_average
ld (SHORT_AVG),a
call make_window
ld a,b
ld (SHORT_MIN),a
ld a,c
ld (SHORT_MAX),a
; find the long leader
; need 8 consecutive pulses > short*1.5
ld a,(SHORT_AVG)
@@ -201,11 +207,6 @@ calibrate:
call average8
jr c,cal_err_long_leader_average
ld (LONG_AVG),a
call make_window
ld a,b
ld (LONG_MIN),a
ld a,c
ld (LONG_MAX),a
; A quick sanity check: long>1.5*short
ld a,(SHORT_AVG)
ld c,a
@@ -215,29 +216,31 @@ calibrate:
ld a,(LONG_AVG)
cp c
jr c,cal_err_sanity_check
; Find the marker. marker is 2*long
; threshold is 1.5*long
ld a,(LONG_AVG)
call make_windows
; Find the marker: 8 consecutive short intervals
; Classify them using short*1.5
ld a,(SHORT_AVG)
ld c,a
srl a
add c
ld c,a ; c = 1.5*long
; Find two consecutive marker-width intervals
ld c,a ; c = 1.5*short
ld e,0 ; consecutive short counter
5$:
ld e,0
6$:
call measure_pulse
jr c,cal_err_marker_measure
ld a,b
cp c
jr c,5$ ; not a marker
inc e ; marker interval found
jr c,6$ ; short interval found
ld e,0 ; long interval, restart marker
jr 5$
6$:
inc e
ld a,e
cp 2 ; we need two of them
jr c,6$ ; not 2 yet, measure next
; both marker halves found
cp 8
jr c,5$
; marker found
; we are at the beginning of the first data pulse
; next 8 bytes is the training byte 0x55
; next byte is the training byte 0x55
call read_byte
jr c,cal_err_training_read
cp a,055h
@@ -348,22 +351,23 @@ read_byte:
; -------------------------------------------------------
; Read and check sync bytes
; carry is error
; carry is error, error value in a
; -------------------------------------------------------
read_sync:
call read_byte
ret c
jr c,sync_err_read_1
cp 05ah
jr nz,9$
jr nz,sync_err_value_1
call read_byte
ret c
jr c,sync_err_read_2
cp 0c3h
jr nz,9$
jr nz,sync_err_value_2
or a
ret
9$:
scf
ret
create_error_return sync_err_read_1, 001h
create_error_return sync_err_read_2, 002h
create_error_return sync_err_value_1, 003h
create_error_return sync_err_value_2, 004h
; -------------------------------------------------------
; Read a block into BLOCK_BUFFER
@@ -379,6 +383,8 @@ read_block:
push de
push hl
exx
call BIOS_FLUSH
di
; calibrate reader
call calibrate
jr nc,1$ ; if no error jump
@@ -390,6 +396,7 @@ read_block:
; calibrated, read sync bytes
call read_sync
jr nc,2$ ; if no error jump
ld b,a
ld a,BLOCK_ERROR_SYNC
scf
jr 101$
@@ -400,10 +407,13 @@ read_block:
ld hl,BLOCK_BUFFER
exx
4$:
call read_byte
call read_byte ; byte in a
jr nc,5$
; read error
exx
ld a,e
exx
ld b,a ; store count in block in specific error
ld a,BLOCK_ERROR_READ
scf
jr 101$
@@ -440,6 +450,7 @@ read_block:
pop hl
pop de
exx
ei
ret
; -------------------------------------------------------
@@ -455,6 +466,7 @@ read_block_dry:
push de
push hl
exx
di
; calibrate reader
call calibrate
jr nc,1$ ; if no error jump
@@ -496,6 +508,7 @@ read_block_dry:
pop hl
pop de
exx
ei
ret
; -------------------------------------------------------
; CRC16