phase 2: gap analysis — cat>> append + binary asset recovery
quality verification:
- confirmed all 8 unapplied edits in phase 1 also failed in their
original sessions (tool-result is_error=1, "String to replace
not found"). Our reconstruction is faithful to live execution.
gaps closed:
- include/modem.h: re-ran replay with cat>>heredoc handling in
chronological position. BATTLE TOADS dual-channel stereo UART
block (4495 bytes, 102 lines) now appended at correct point in
timeline. Two previously-failing edits now apply against the
post-append baseline. unapplied edits dropped 8 -> 6.
- web/fonts/: chunkfive-regular-webfont.{woff,woff2} restored
from live source /home/fox/git/www.unturf.com/css/chunkfive/.
HTML+CSS @font-face references now resolve.
remaining unapplied edits (6) confirmed legitimate live-session
failures, not reconstruction artifacts.
internal references audit:
- all #include directives resolve within recovered tree
- all font url() references resolve to recovered web/fonts/
- no other Bash file-creation ops target zebra-report
final tree: 22 files, ~160KB.
This commit is contained in:
parent
b77da42bbe
commit
4fadfca5b1
3 changed files with 102 additions and 0 deletions
102
include/modem.h
102
include/modem.h
|
|
@ -340,3 +340,105 @@ static inline int zebra_recv_ready(zebra_pulse_t *z, uint32_t sink,
|
|||
int timeout_ms) {
|
||||
return zebra_recv_hs_frame(z, sink, timeout_ms, ZEBRA_HS_TYPE_READY, NULL);
|
||||
}
|
||||
/* ------------------------------------------------------------------ *
|
||||
* BATTLE TOADS: dual-channel stereo UART *
|
||||
* *
|
||||
* One stereo tab → L and R modulated independently. *
|
||||
* Both channels use same UART framing and baud rate. *
|
||||
* TX sends byte_L and byte_R simultaneously each frame. *
|
||||
* RX decodes both channels from a single PA poll per half-symbol. *
|
||||
* Net throughput: 2x single-channel at same baud rate. *
|
||||
* ------------------------------------------------------------------ */
|
||||
|
||||
/* Send one dual-channel symbol: L=bit_l, R=bit_r */
|
||||
static inline void bt_send_symbol(zebra_pulse_t *z, uint32_t sink,
|
||||
int bit_l, int bit_r,
|
||||
struct timespec *next, long period_ns) {
|
||||
zebra_set_volume_lr_noack(z, sink,
|
||||
zebra_bit_to_vol(bit_l),
|
||||
zebra_bit_to_vol(bit_r));
|
||||
clock_nanosleep(CLOCK_MONOTONIC, TIMER_ABSTIME, next, NULL);
|
||||
ts_add_ns(next, period_ns);
|
||||
}
|
||||
|
||||
/* Send two bytes simultaneously: byte_l on L channel, byte_r on R channel.
|
||||
* Frame: start(0,0) + 8 paired data bits + stop(1,1) = 10 symbols. */
|
||||
static inline void bt_send_byte_lr(zebra_pulse_t *z, uint32_t sink,
|
||||
uint8_t byte_l, uint8_t byte_r,
|
||||
struct timespec *next, long period_ns) {
|
||||
bt_send_symbol(z, sink, 0, 0, next, period_ns); /* start */
|
||||
for (int i = 0; i < 8; i++)
|
||||
bt_send_symbol(z, sink,
|
||||
(byte_l >> i) & 1,
|
||||
(byte_r >> i) & 1,
|
||||
next, period_ns);
|
||||
bt_send_symbol(z, sink, 1, 1, next, period_ns); /* stop */
|
||||
}
|
||||
|
||||
/* Receive loop: decodes L and R channels from each PA poll.
|
||||
* Calls cb twice per frame — first with L byte, then R byte.
|
||||
* Output order: L0, R0, L1, R1, ... matching bt_send_byte_lr pairs. */
|
||||
static inline void bt_rx_run(zebra_pulse_t *z, uint32_t sink, int baud,
|
||||
zebra_byte_cb cb, void *userdata) {
|
||||
const int oversample = 4;
|
||||
long quarter_ns = 1000000000L / ((long)baud * oversample);
|
||||
long half_ns = 2 * quarter_ns;
|
||||
long full_ns = 4 * quarter_ns;
|
||||
|
||||
struct timespec ts;
|
||||
clock_gettime(CLOCK_MONOTONIC, &ts);
|
||||
int prev_l = 1, prev_r = 1; /* both idle at MARK */
|
||||
|
||||
for (;;) {
|
||||
ts_add_ns(&ts, quarter_ns);
|
||||
clock_nanosleep(CLOCK_MONOTONIC, TIMER_ABSTIME, &ts, NULL);
|
||||
|
||||
uint8_t vol_l, vol_r;
|
||||
if (zebra_get_volume_lr(z, sink, &vol_l, &vol_r) < 0) {
|
||||
struct timespec retry = {1, 0};
|
||||
nanosleep(&retry, NULL);
|
||||
prev_l = prev_r = 1;
|
||||
continue;
|
||||
}
|
||||
|
||||
int cur_l = zebra_vol_to_bit(vol_l);
|
||||
int cur_r = zebra_vol_to_bit(vol_r);
|
||||
|
||||
/* start bit: detect falling edge on L (TX sends both low together) */
|
||||
if (prev_l == 1 && cur_l == 0) {
|
||||
/* confirm start at center */
|
||||
ts_add_ns(&ts, half_ns);
|
||||
clock_nanosleep(CLOCK_MONOTONIC, TIMER_ABSTIME, &ts, NULL);
|
||||
if (zebra_get_volume_lr(z, sink, &vol_l, &vol_r) < 0)
|
||||
{ prev_l = prev_r = 1; continue; }
|
||||
if (zebra_vol_to_bit(vol_l) != 0)
|
||||
{ prev_l = prev_r = 1; continue; }
|
||||
|
||||
/* decode 8 paired data bits */
|
||||
uint8_t byte_l = 0, byte_r = 0;
|
||||
int ok = 1;
|
||||
for (int i = 0; i < 8; i++) {
|
||||
ts_add_ns(&ts, full_ns);
|
||||
clock_nanosleep(CLOCK_MONOTONIC, TIMER_ABSTIME, &ts, NULL);
|
||||
if (zebra_get_volume_lr(z, sink, &vol_l, &vol_r) < 0)
|
||||
{ ok = 0; break; }
|
||||
int bl = zebra_vol_to_bit(vol_l);
|
||||
int br = zebra_vol_to_bit(vol_r);
|
||||
if (bl < 0) bl = (vol_l >= ZEBRA_VOL_THRESHOLD) ? 1 : 0;
|
||||
if (br < 0) br = (vol_r >= ZEBRA_VOL_THRESHOLD) ? 1 : 0;
|
||||
byte_l |= (uint8_t)(bl << i);
|
||||
byte_r |= (uint8_t)(br << i);
|
||||
}
|
||||
if (ok) {
|
||||
cb(byte_l, userdata);
|
||||
cb(byte_r, userdata);
|
||||
}
|
||||
/* Resync sample clock after each frame — same fix as zebra_rx_run */
|
||||
clock_gettime(CLOCK_MONOTONIC, &ts);
|
||||
prev_l = prev_r = 1;
|
||||
} else {
|
||||
if (cur_l >= 0) prev_l = cur_l;
|
||||
if (cur_r >= 0) prev_r = cur_r;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
BIN
web/fonts/chunkfive-regular-webfont.woff
Normal file
BIN
web/fonts/chunkfive-regular-webfont.woff
Normal file
Binary file not shown.
BIN
web/fonts/chunkfive-regular-webfont.woff2
Normal file
BIN
web/fonts/chunkfive-regular-webfont.woff2
Normal file
Binary file not shown.
Loading…
Add table
Add a link
Reference in a new issue