# Game Boy Astra WasmBoy RTC and MBC7 extensions

This is WasmBoy 0.7.1 core source by Aaron Turner and contributors, with the Game Boy Astra MBC3 clock and MBC7 sensor/EEPROM extensions. GPL-3.0-or-later; see LICENSE. Original source: https://github.com/torch2424/wasmboy (npm wasmboy@0.7.1). This archive contains no game ROMs.

## Rebuild

Node.js and npm required. Run `npm ci --ignore-scripts`, then `npm run build`. The pinned compiler is AssemblyScript 0.15.1. The output is `wasmboy-astra.wasm`. Build command: `asc core/index.ts -b wasmboy-astra.wasm -O3 --converge --memoryBase 0`.

## Runtime contract

Keep the unmodified 0.7.1 WasmBoy core for the existing illustrated adventure so its saves remain compatible. Use this separate core for cartridge mode, with a distinct save format/core identifier (`wasmboy-astra-rtc1`). Recommended generic config is `config(0,1,0,0,0,0,1,0,0,0)`. `useGbcWhenAvailable` is the second argument. Preserve options over reset and avoid forcing a Mario-specific manual palette on generic games.

Additional exports:

- `hasRtc()` returns 1 for timer-bearing cartridge types 0x0f/0x10, otherwise 0.
- `advanceRtc(seconds)` consumes a nonnegative finite count of whole wall-clock seconds. Fractional parts are discarded; the host should keep its fractional remainder. This core does not autonomously tick from CPU cycles.
- `getRtcRegister(index)` returns the live second/minute/hour/day-low/day-high registers for indices0 through4; invalid index returns-1.
- `setRtcRegister(index,value)` sets those live registers with hardware bit masks. These are for diagnostics or battery-file integration, not regular clock advancement.
- `astraReadBus(address)` / `astraWriteBus(address,value)` are debug bus accessors that respect banking and register traps.

The host should advance elapsed wall-clock seconds before frames, on pause/resume, before saving, and after restoring using a persisted timestamp. Update the host timestamp even when the hardware halt flag is set, because elapsed time while halted must be discarded. Do not add elapsed time twice. Saved quick states include the complete RTC live values, latched values, selected register, and last latch write in `WASMBOY_STATE` slot11. A save copied to a new core instance restores that state with `core.loadState()`.

RTC is initialized to zero, matching an unset battery clock. The game establishes its own time through registers; do not initialize Crystal registers to Unix time. The game tracks weekday offsets in its battery RAM.

## Changes

`core/memory/rtc.ts` implements selected register access, the0→1 snapshot latch, halt, 9-bit day wrap and sticky carry. `banking.ts`, `readTraps.ts`, `writeTraps.ts`, and `memory.ts` connect it to the cartridge bus and initialization. `core.ts` adds RTC save/load; `index.ts` exports host/diagnostic APIs. Non-enable MBC3 writes disable RAM/RTC access. RTC accesses never alias cartridge RAM.

Hardware reference: https://gbdev.io/pandocs/MBC3.html . This implements standard MBC3 as used by international Pokémon Crystal; it does not add Japanese MBC30 extended ROM/RAM banking, subsecond quartz timing quirks, or a cycle-level RTC oscillator.

## Validation

Run `node rtc-tests.cjs /absolute/path/to/app/dist/data` with the user-supplied ROMs placed at `roms/crystal.gbc`, `roms/ages.gbc`, `roms/seasons.gbc`, `roms/awakening.gb`, and `game.gb`. Tests include register access gating, latch semantics, halt/resume, day rollover/carry, long offline elapsed time, state roundtrip, independent RAM banks, invalid inputs, and ten-second nonblank boot checks for all five games. `rtc-test-report.json` records the run. These are targeted checks, not full gameplay or cycle-accuracy certification.

## MBC7 expansion (Astra core revision2)

The same core now supports MBC7 cartridge type0x22 for the supplied international Kirby Tilt 'n' Tumble. This adds7-bit ROM banking (including bank0), both register-access gates, sensor-register mirroring, required erase/sample latching, and93LC56 serial EEPROM. EEPROM commands implemented: READ, EWEN, EWDS, WRITE, ERASE, WRAL, ERAL. READ supports sequential words and address wrap; writes require EWEN. Interrupted serial commands, pin levels, write-enable, latched sensor values, and pending sample state are preserved in `WASMBOY_STATE` slot12. Slot11 is unchanged, and the test suite verifies restoring prior RTC-only states.

- `hasTilt()` returns1 for MBC7 cartridges, otherwise0.
- `setTilt(xDelta,yDelta)` accepts signed integer offsets from sensor neutral0x81D0. Approximately112 units equal1g. LowerX meansright, higherX meansleft; lowerY meansdown/bottom, higherY meansup/top. The core clamps resulting sensorregisters to0..65535.
- The host should call `setTilt` as control input changes, or eachframe. The game samples through its cartridge sensor-latch writes. Flat input is `(0,0)`.
- D-pad fallback uses±80 units. PreserveA as confirm so startup BALANCE calibration isn't biased. A six-frame (~100ms) positiveY320 pulse followed by neutral produces a jump in the supplied Kirby ROM; map this toB if a button fallback is desired.
- EEPROM occupies the first256 bytes of `CARTRIDGE_RAM`. Existing full-region save snapshots therefore persist it. A fresh cartridge starts with erased0xFF EEPROM. A battery-only importer/exporter for this cartridge should use these256bytes in little-endian word order.

MBC7 limitations: EEPROM programming finishes immediately after the final data bit, without analog write/erase settling delays. Accelerometer values are deterministic, without physical noise or cartridge-clock sampling delay. No physical rumble output is emulated. The test suite validates the supplied Kirby cartridge, not every possible MBC7 software program.

### Expanded validation

Run `node mbc7-tests.cjs /absolute/path/to/app/dist/data` with additional ROMs at `roms/kirby.gbc`, `roms/wario.gbc`, `roms/rampage.gbc`, `roms/pacman.gbc`. No ROMs are included in this source archive. Tests cover MBC7 enable gates, sensor polarity/latching/mirroring/clamping, ROM bank replacement, all EEPROM commands and protections, sequential reads, partial writes, fresh-core state restore, older RTC-state compatibility, all four additional cartridge boot checks, and real Kirby file creation, two-axis rolling and jump response after navigating BALANCE/title/file selection. The previously shipped RTC-only binary is retained solely as a compatibility fixture (`wasmboy-astra-rtc1.wasm`).

Sources consulted for hardware behavior: https://gbdev.io/pandocs/MBC7.html and upstream SameBoy `Core/memory.c` / `Core/mbc.c`. The MBC7 implementation is new AssemblyScript code based on documented register and serial protocols; it does not embed another emulator runtime.
