?yieldtrace shows the crash occurs with zero compiled-TB DONE_FLAG resume
re-entries, so it is not the store block-replay path. Combined with
nondeterminism and identity-independence, the corruption is a guest-RAM data
race with concurrent device/timer callbacks. Blanket store-TCI stays default.
E15/E16: runtime store-gating bisection plus repeated-run testing show the
0x4201e210 reader-open corruption is a race (identity-independent, config
alternates crash/pass), not a miscompiled TB. Blanket store-TCI suppresses it
in practice. Wire ?sthash and ?stcw/stcmask/stcval opt-in debug controls.
Benchmark showed the narrowed 32-bit-only fallback is slightly faster when it
works but failed once with an app-init watchdog. Restore blanket store-TCI as
the default and document the narrowed result as diagnostic only.
Default browser path now keeps only 32-bit qemu store TBs on TCI. Normal raw-SD
reader-open passes, while ?nostoretci still reproduces the original
0x4201e210 load fault as a negative control.
Add ?nostoretci and ?tcgdiff2=open browser-test plumbing. ?nostoretci confirms
the original compiled-store corruption still reproduces at normal speed; the
file-open-armed E11 run catches stale register state before the known
0x4201e210 load fault. Production path remains store-TCI and browser raw-SD
stays green.
E11 proved inline compiled stores are correct under live cross-TB accumulation
(153k comparisons, zero divergence) but is too slow to reach the reader
corruption in-browser (guest watchdog fires first). Suspects narrowed to the
store slow-path and store-width interaction; next instrument is a deterministic
slow-path store unit test. Option A (deterministic two-pass) retained as future.
E10 per-TB compiled-vs-TCI differential compared 160k+ store TBs during a
full reader-open with zero divergence, exonerating single-TB store codegen
and confirming the inflate corruption is emergent across TBs. Harness is
opt-in via ?tcgdiff (wasm_diff_enable from app.js preRun); production
store-TCI path is unchanged.
icount throttled TCG and starved the guest watchdog. Measured book open dropped from 146s to 31s. Off by default; ?icount restores it, ?noicount removed in favor of the new default. Harness now reports open-file timing.
The file browser no longer auto-seeds, so the headless test seeds Test/example.txt into OPFS before autoboot. Docs corrected: store-containing-TB TCI is upstream qemu-wasm design (compiled store path is not rewind-safe), not a port bug.
Add directory navigation, folder creation, inline deletion, clear controls, and a focused editor view. Include the opt-in FAT16 vvfat experiment and fail-fast browser diagnostics; raw FAT32 remains the default.
Bumps third_party/qemu to the X3 grayscale persistence render. The
in-browser reader now shows crisp black text on white (no inversion, no
muddle). Marks the grayscale defect resolved in ISSUES.
Bumps third_party/qemu to the wasm32 store-TB TCI workaround so the
browser reader no longer panics in uzlib font decompression. Adds
docs/wasm-inflate-panic.md with the full investigation (native control,
non-deterministic reject, JIT promotion) and next steps. Updates ISSUES:
the panic is worked around; the reader now inverts into muddled
grayscale after the initial BW page (new top reader defect). tests
navigate the 4th Open press into the reader.
Native and wasm now share one source tree, so the xteink machine and SD
fixes never diverge. scripts/build-qemu.sh configures a dedicated
build-native/ dir (ucontext coroutine backend; the fork defaults to the
wasm fiber backend) that never clobbers the Emscripten build/ config.
Retires the separate _scratch/qemu-src patch-based native build.
Browser SD files are persisted in OPFS (web/sdstore.js) and edited in the
Files tab. At boot the browser builds a deterministic 64 MiB FAT32 image
(web/fat32.js) with nested directories and VFAT long names, then mounts
it as a raw block device, bypassing QEMU's broken populated-vvfat WASM
coroutine path. Guest writes mutate only the ephemeral image.
Exposes a hidden #frame-generation indicator that increments on every
e-ink flush, so automation can wait on real display updates instead of
fixed sleeps. Adds tests/ with a Makefile runner: 'make test' for JS +
FAT32/mtools checks, 'make browser-test' for a headless-Firefox boot of
the official CrossPoint 1.4.1 firmware that navigates to
Test/example.txt. Bumps third_party/qemu to the SPI-SD/CMD13 fixes and
updates README/ROADMAP/ISSUES for the new architecture.
The 7.7k-line qemu-wasm patch was really a fork, so vendor it as a submodule
(pinned at the xteink QEMU fork) and build it directly. Removes the
clone/commit-check/patch/reset machinery, the redundant web-dev/patch targets,
and 0002-qemu-wasm.patch. Editing third_party/qemu now recompiles incrementally
via plain `make web`. Native build keeps 0001-xteink-machine.patch.
CrossPoint flash detection sends Read-ID (0x90/0xAB); the model only handled it
for SST chips, so the is25lp128 returned nothing and detection fell into an
SFDP/garbage path that crashed QEMU. Return manufacturer + device id for any
chip, as real hardware does.
Add a log panel that captures QEMU stdout/stderr, route serial to stdio, and
pass -d guest_errors,unimp so device warnings (e.g. the m25p80 Read-ID gap that
stalls CrossPoint boot) are visible in the browser. Read the framebuffer via
HEAPU8 to match the validated node path.
--tls generates a self-signed cert (SANs: localhost, 127.0.0.1, LAN IP) so a
headless box is reachable directly over HTTPS, which browsers treat as a secure
context (required for cross-origin isolation). make web now defaults to TLS.
Accept the ~5 MB release firmware.bin directly: place it at 0x10000 in a
0xFF-erased 16 MB image alongside the bundled ESP32-C3 bootloader (0x0) and
CrossPoint partition table (0x8000). m25p80 requires a full chip-size backing,
so the 16 MB image is still built, but the user no longer pre-merges. Full
16 MB images are still accepted as-is.
Drop EMULATE_FUNCTION_POINTER_CASTS (it broke the wasm32 TCG ffi_call_js
path with BigInt errors) and fix the underlying function-pointer signature
mismatches instead: object_class_cmp GCompareFunc, esp_sha hash-callback
wrappers, and an xts_aes NULL guard in the ESP32-C3 cache. Backport the
upstream Emscripten anonymous-RAM allocator fix. Firmware now boots and
initializes the X3 panel; a post-init boot stall remains.