Commit Graph

10 Commits

Author SHA1 Message Date
David Montero Crespo a3562ba93f fix(chipbus): Galaksija display renders legible text (ASCII font8x8)
Galaksija stores ASCII codes in its 0x2800 video RAM (verified by snooping
the boot: it writes "@'READY" + ">_" prompt). The original CHRGEN ROM uses
a hardware-specific addressing that does not map char-code*8 to a glyph, so
rendering through it produced garbled output. Render the ASCII codes with
the public-domain IBM/VGA 8x8 font (font8x8 by Daniel Hepper / Marcel
Sondaar) instead -- legible green-on-black phosphor text. The boot screen
now reads "@'READY" with the ">_" input prompt, exactly like a real
Galaksija. Tests updated to check the bright-green channel.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-06-05 12:21:17 -03:00
David Montero Crespo e3d21cd6fc feat(chipbus): Galaksija video display chip - full computer renders READY
galaksija-display.c: a 32x16 text video chip that renders the Galaksija
video RAM. It is a passive bus snoop -- watches WR + address + data, and on
a write into the 0x2800 video region stores the character and renders that
cell into a 256x128 framebuffer using the public-domain CHRGEN font (code*8,
bit 0 = lit). It never drives the bus. The host blits the framebuffer to the
chip canvas (vx_framebuffer_init / vx_buffer_write).

Two tests:
- chipbus-galaksija-display: snoop+render smoke test (a write of 'R' to
  0x2802 lights its cell; unwritten cells stay blank).
- chipbus-galaksija-computer: the COMPLETE machine over the chip-to-chip bus
  (Z80 + galaksija-rom + ram-64k + inverter decode + galaksija-display) boots
  the public-domain ROM and renders the monitor's "READY" prompt on screen.

40 chipbus tests across 10 files pass.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-06-05 12:14:40 -03:00
David Montero Crespo 8441d370d3 test(chipbus): a real Galaksija (1983 Z80 home computer) boots over the bus
The public-domain Galaksija ROM (Voja Antonic; ROM A monitor + integer
BASIC, ROM B float BASIC, 8 KB) runs on a standalone Z80 + external ROM +
RAM + an inverter for address decode, all chip-to-chip over the shared bus,
no board:

  ROM 0x0000-0x1FFF   rom.CE = A13
  RAM 0x2000-0x3FFF   ram.CE = NOT A13   (the inverter chip)
  RD -> both OE ; WR -> RAM WE

Pin-level boot proof (mirrors test_intel/test_z80/galaksija.test.js): watch
M1, read the address bus on each opcode fetch, and confirm the Z80 leaves
the reset vector (DI; SUB A; JP 0x03DA), reaches the init routine at 0x03DA,
and runs 1000+ fetches across 50+ distinct ROM addresses -- the real
firmware executing end-to-end through the settle-kernel bus. The on-screen
"READY" prompt is the next milestone (needs the video display chip
rendering the 0x2800 video RAM).

galaksija-rom.c embeds the public-domain ROM A+B image. 38 chipbus tests
across 8 files pass.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-06-05 11:55:28 -03:00
David Montero Crespo 0cd2dc2062 test(chipbus): Phase 3 core - Z80 + ROM + RAM + address decode over the bus
The architectural heart of the retro computer, proven on real chips. A Z80,
a 32K ROM, a 64K RAM and an inverter (address-decode glue) are wired
chip-to-chip over a shared address + data bus, no board:

  ROM at 0x0000-0x7FFF   rom.CE = A15
  RAM at 0x8000-0xFFFF   ram.CE = NOT A15  (the inverter chip)
  RD -> both OE ; WR -> RAM WE

The ROM program writes 0x5A to RAM at 0x8000, clears A, reads it back, and
HALTs only if the byte survived. HALT going low proves the full core works:
the Z80 runs from ROM, the inverter decodes A15 to select RAM (the settle
kernel drives the combinational glue across hops), and the RAM latches a
write and returns it on a read over the shared tri-state bus, all within
synchronous bus cycles. Adds z80-ram-rom.c (boot image) + ram-64k/inverter
fixtures. 37 chipbus tests across 7 files pass.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-06-05 10:23:57 -03:00
David Montero Crespo 89a5298f47 test(chipbus): live proof - a real Z80 boots from a ROM over the bus
End-to-end validation of Phases 0-2 on an actual CPU. The real Z80
(examples/intel/z80.c) and a 32K EPROM (z80-boot-rom.c, a rom-32k variant
holding JP 0x0006 / HALT) are wired chip-to-chip over a shared address +
data bus with no board. RD drives the ROM's OE; CE is left enabled.

Booting exercises all three phases at once: the Z80 drives the address ->
the ROM reacts on the shared net key (Phase 0); asserts RD -> the ROM
tri-state-drives the data bus while the Z80 released it (Phase 1); and reads
the data bus in the SAME tickTimers step, getting the settled byte
(Phase 2 settle-before-read). The Z80 fetches C3,06,00, jumps to 0x0006,
fetches 76, and HALTs -> drives HALT low, which the test observes.

z80.wasm is compiled from the committed examples/intel/z80.c; the boot ROM
source + chip.json live in test_custom_chips/sdk/examples. All 36 chipbus
tests pass.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-06-05 10:07:26 -03:00
David Montero Crespo 474d132368 test(chipbus): Phase 0 live proof - two real WASM chips exchange a byte
End-to-end proof of the chip-to-chip net-key fix through the real
ChipRuntime + PinManager (not a unit stub). Two chips compiled from C
with wasi-sdk:
- bus-driver.c: drives 0xA5 onto D0..D7 at setup.
- bus-reader.c: polls D0..D7 on a 1ms timer, mirrors onto OUT0..OUT7.
Wired chip-to-chip with no board; with the chipbus flag both chips' Dn
pins resolve to one shared net key, so the reader reproduces 0xA5.

- sdk/examples/bus-{driver,reader}.{c,chip.json}: the proof chips.
- __tests__/fixtures/chipbus/*.wasm: committed fixtures (regenerate with
  the test_intel/scripts/compile-chip.sh flags).
- __tests__/chipbus-twochip-integration.test.ts: loads the fixtures via a
  relative path; skipIf they are absent.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-06-05 02:10:08 -03:00
David Montero Crespo 36ad2bef3f feat(i2c): cross-board bridging across all velxio boards (AVR/RP2040/ESP32 xtensa+riscv)
Closes the remaining gaps in cross-board I2C so any topology of
supported boards (Uno↔ESP32, two ESP32s, Uno↔Uno↔Uno, ESP32-C3
connected to anything, etc.) works end-to-end with all I2C
components including write-only sinks (SSD1306, PCF8574, LCD-I2C).

Implementation (6 phases):

1. **BFS routing in I2CBusManager**: connectToSlave + handleExternalConnect
   walk the bridge graph with a visited Set so multi-hop chains
   (A↔B↔C with the device on C) resolve transparently.  A new
   forwarder-device shim is installed at intermediate hops so the
   existing handleExternalWrite/Read/Stop machinery routes
   through without per-method visited tracking.

2. **Per-peer proxy ownership in Esp32BridgeShim**: replaces the
   global _proxiedAddrs Set with _proxiedByPeer Map so concurrent
   bridges to the same ESP32 (e.g. wired to both Uno and Pico)
   don't wipe each other's proxies on teardown.  Interconnect's
   per-wire teardown calls clearProxiesForPeer(peerBus) instead of
   clearAllProxies.

3. **BFS-aware proxy sync**: syncProxyFromPeer now walks the peer
   bus + its transitive bridges, so an ESP32 sees devices on
   boards two or more hops away.  _peerDeviceLookup keeps a flat
   addr → device map for write-forwarding and resync.

4. **Periodic resync (250 ms)**: Esp32BridgeShim runs a setInterval
   while any proxy is live, re-dumping each device with
   dumpRegisters() and pushing updateProxyI2c only when an XOR-
   stride hash changes.  This keeps RTC time advancing visible to
   ESP32 firmware without flooding the WS pipe with static
   calibration dumps.  Hash is primed during initial sync so the
   first tick doesn't push a redundant identical buffer.

5. **Write-forwarding ProxySlave → peer**: backend ProxySlave
   buffers write bytes during the transaction and emits a
   `proxy_i2c_complete` event on STOP / repeated-START.  Frontend
   Esp32Bridge dispatches the event to a new onProxyI2cComplete
   callback; the shim replays the byte sequence on the actual
   peer I2CDevice via writeByte() + stop().  Makes ESP32 firmware
   writes to peer SSD1306 actually repaint the OLED, peer PCF8574
   latch updates, peer I2CMemoryDevice register mutations propagate.

6. **ESP32-C3 routed as bridge**: Interconnect.isBrowserSim no
   longer claims c3/xiao-c3/c3-supermini — they were already
   going through Esp32Bridge per the store's ESP32_RISCV_KINDS
   routing, but Interconnect was treating them as browser sims
   which broke proxy install.  isEsp32Bridge now correctly
   includes c3 family + ESP32-S3 + Arduino Nano ESP32.

Defensive: addBoard now disposes any existing shim's proxies
before overwriting simulatorMap entry so test reruns don't leak
timers.

Tests:
- 4 BFS multi-hop tests (i2c-multi-board-slave-gap.test.ts)
- 11 cross-board scenarios + per-peer + write-forward + resync
  (i2c-esp32-multiboard-bridge.test.ts)
- 1 real-firmware E2E for write-forward via QEMU (compile +
  load + observe proxy_i2c_complete arriving with the byte)
- New sketch fixture: esp32_i2c_write_to_peer.ino

Result: 90 test files / 1295 tests pass / 0 fail.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-12 17:51:39 -03:00
David Montero Crespo 71616e580d Add end-to-end tests for ESP32 I2C functionality and circuit verification
- Implemented `i2c-esp32-real-firmware.test.ts` to test ESP32 I2C communication via backend and WebSocket.
- Created `load-example-transitions.test.ts` to ensure proper loading of examples between board-less and board-based contexts.
- Added `CircuitVerificationModal.tsx` to display circuit verification results before running simulations.
- Developed `circuitVerifier.ts` to perform pre-flight checks for circuit safety, identifying potential issues like short circuits and component overloads.
- Introduced minimal ESP32 I2C master sketch `esp32_i2c_writer.ino` for testing I2C transactions.
2026-05-12 16:55:15 -03:00
David Montero Crespo a097601a73 Add HD44780Decoder and various I2C sketches
- Implement HD44780Decoder for decoding I2C commands to HD44780-compatible LCDs.
- Add bmp280_bridge_reader.ino to read BMP280 chip_id and status registers via I2C.
- Create i2c_scanner_multi.ino to scan I2C addresses and report responding devices.
- Introduce lcd_i2c_hello.ino to demonstrate basic LCD functionality with I2C.
- Implement pcf8574_bidirectional.ino to test bidirectional communication with PCF8574.
- Add pico_i2c_master_reader.ino for reading BMP280 from a Raspberry Pi Pico.
- Create rtc_lcd_clock.ino to display time from a DS1307 RTC on an I2C LCD.
2026-05-12 14:26:33 -03:00
David Montero Crespo 7f2014bef7 Add ESP32 chip demos and comprehensive tests for I2C, SPI, and UART interactions
- Implemented `esp32_spi_chip_demo.ino` to demonstrate SPI communication with a 74HC595 shift register.
- Created `esp32_uart_chip_demo.ino` for UART loopback testing with ROT13 transformation.
- Added Python tests for compiling chips and sketches, ensuring valid WASM output and successful compilation for various board families.
- Developed end-to-end tests for ESP32 with custom chips using I2C and SPI, validating synchronous communication through the backend.
- Introduced GPIO bridge tests to verify serial communication and GPIO state changes.
- Ensured all tests validate the expected behavior of the custom chips and their interaction with the ESP32 firmware.
2026-04-28 19:24:39 -03:00