245 lines
24 KiB
Markdown
245 lines
24 KiB
Markdown
# Project status
|
||
|
||
What the emulator does today, what it deliberately leaves out, and what comes next.
|
||
Update this file when a feature lands or a limit is removed.
|
||
|
||
## Current behavior
|
||
|
||
- Native desktop window, with animation and keyboard controls for display testing.
|
||
- Platform-independent 240×160 framebuffer and GBA RGB555 color conversion.
|
||
- Optional row capture at HBlank, double-buffered frame publication at VBlank, and retained mid-frame changes.
|
||
- CPU-configured HBlank DMA raster demo with per-row palette changes.
|
||
- Mode 0 tile backgrounds: 4-bit/8-bit pixels, palettes, flips, scrolling, map sizes, transparency, and priorities.
|
||
- Mode 3 video RAM snapshots, BG2 enable, palette backdrop, forced blank, and green swap.
|
||
- Mode 1 mixed text/affine backgrounds and Mode 2 affine backgrounds, with signed transforms and map wrapping/clipping.
|
||
- Mode 3/4/5 bitmap transforms through BG2 affine registers, with Mode 4/5 page selection.
|
||
- Mode 4 indexed colors and transparent index zero; Mode 5 opaque 160×128 RGB555 pixels.
|
||
- Regular and affine sprites in Modes 0–5: palettes, rotation, scaling, flips, clipping, and priority selection.
|
||
- One-line-ahead sprite row preparation, with buffered palette indices and metadata.
|
||
- Background and sprite mosaic, with independent 1–16 pixel dimensions and per-layer enable flags.
|
||
- Separate live vertical mosaic counters for backgrounds and sprites, with phase-preserving size writes.
|
||
- WIN0/WIN1 rectangles and OBJ window masks, with per-region layer and color-effect controls.
|
||
- Vertical WIN0/WIN1 edge tracking across visible rows, VBlank, and frame boundaries.
|
||
- Horizontal WIN0/WIN1 comparator history, including mid-line writes and offscreen edges.
|
||
- Alpha blending, brightness increase/decrease, and semi-transparent sprites using five-bit color arithmetic.
|
||
- 96 KiB video RAM, 1 KiB palette RAM, and 1 KiB object attribute memory, with mirrors and byte-write behavior.
|
||
- Active-low `KEYINPUT` for all ten GBA buttons, independent of the window library.
|
||
- `KEYCNT` selection and OR/AND matching, keypad IRQ latching, and HALT wake-up through IE bit 12.
|
||
- Original ARM graphics demo that uses DMA, BIOS VBlank waiting, and a ROM-side IRQ callback.
|
||
- Sixteen active 32-bit CPU registers, with ARM7 mode-specific register banks.
|
||
- Persistent ARM/Thumb instruction buffering, sequential fetch retention, branch/vector target pairs, and deferred fetch diagnostics.
|
||
- Shared mapped fetch samples for instruction retention, supported open-bus values, BIOS snapshots, and IWRAM refill history.
|
||
- User, System, Supervisor, IRQ, FIQ, Abort, and Undefined modes.
|
||
- Current and saved program status registers (`CPSR`/`SPSR`), with `MRS`/`MSR` transfers.
|
||
- ARM/Thumb software interrupts (`SWI`), exception vectors, and status-restoring returns.
|
||
- CPU interrupt entry, interrupt masks, and FIQ priority.
|
||
- GBA interrupt enable (`IE`), request flags (`IF`), and master enable (`IME`) registers.
|
||
- Four 16-bit timers, with reloads, prescalers, count-up cascading, and timer-generated IRQs.
|
||
- A shared free-running timer divider survives enable and clock-source changes; HALT advances it and STOP freezes it.
|
||
- A 228-line display clock, VCOUNT/DISPSTAT, and VBlank/HBlank/VCount-match interrupts.
|
||
- Four direct memory access (DMA) channels, with immediate, VBlank, and visible-line HBlank triggers.
|
||
- Halfword/word DMA, address controls, repeat, channel priority, CPU pausing, and completion IRQs.
|
||
- Separate retained DMA channel data, with known-value reuse for blocked sources below work RAM.
|
||
- One-shot non-sequential nominal CPU code timing after successful DMA, including RAM-only transfers.
|
||
- HALT with enabled-request wake-up, continued device clocks, and bounded idle steps.
|
||
- BIOS-only CPU writes to POSTFLG/HALTCNT, with HALT and keypad-wake STOP.
|
||
- STOP freezes CPU/DMA/GBA-device clocks, retains device phases, and reports a stopped frame runner without spinning.
|
||
- Machine execution to the next VBlank event, with a configurable step limit.
|
||
- CPU/device stepping with nominal ARM7 instruction costs and memory wait states.
|
||
- Ordered CPU timing transactions record source, data, internal, and refill costs, with whole-step diagnostic rollback.
|
||
- Code costs use actual ARM PC+8/Thumb PC+4 source fetches and branch/exception target pairs, including region and ROM boundaries.
|
||
- IRQ entry samples its discarded incoming-state fetch before the ARM vector pair, with local IWRAM history updates.
|
||
- Persistent fetch access kinds follow CPU data/internal work, compose with DMA resume, and reset after target refills.
|
||
- Game Pak wait-state control (`WAITCNT`) for all three ROM windows and supported save-byte accesses.
|
||
- Bit 14 enables a nominal eight-halfword opcode prefetch queue, with partial fetches, cancellation, and DMA/idle integration.
|
||
- Staged timer/audio/serial clocks follow CPU and DMA bus-completion phases, including timer/serial IF reads, acknowledgements, and failed-step rollback.
|
||
- The unchanged original ARM cancellation probe matches both published read interval totals and its unadjusted timer samples.
|
||
- Sequential/non-sequential data accesses, branch refill costs, and variable multiply timing.
|
||
- Optional caller-supplied 16 KiB BIOS mapping, with CPU read protection based on retained ARM PC+8 or aligned Thumb PC+4 words.
|
||
- CPU/DMA writes to the mapped BIOS complete without changing its image; host writes retain read-only diagnostics.
|
||
- Optional original BIOS replacement: minimal boot, SoftReset, selective RegisterRamReset, IRQ dispatch, interrupt waits, memory copy/fill, integer/fixed-point arithmetic, affine matrices, bit unpacking, LZ77/run-length/Huffman decompression, and differential filters.
|
||
- All 16 ARM data-processing operations, with immediate and shifted-register operands.
|
||
- Logical operations: `AND`, `EOR`, `TST`, `TEQ`, `ORR`, `MOV`, `BIC`, and `MVN`.
|
||
- Arithmetic operations: `SUB`, `RSB`, `ADD`, `ADC`, `SBC`, `RSC`, `CMP`, and `CMN`.
|
||
- Logical and arithmetic shifts, rotate-right, and rotate-right through carry (`RRX`).
|
||
- Immediate and register-specified shift amounts, including zero and amounts of 32 or more.
|
||
- `MUL`, `MLA`, `UMULL`, `UMLAL`, `SMULL`, and `SMLAL`.
|
||
- Negative (N), zero (Z), carry (C), and signed overflow (V) flags.
|
||
- All 15 defined ARM condition codes, including always (`AL`).
|
||
- `B` and `BL` with signed relative displacement and conditional execution.
|
||
- `BX` switches between ARM and Thumb using target bit zero.
|
||
- `LDR`, `STR`, `LDRB`, `STRB`, `LDRH`, `STRH`, `LDRSB`, and `LDRSH`.
|
||
- Single-load base/destination aliases retain the loaded value over writeback for r0–r14, across word, byte, halfword, and signed loads.
|
||
- Pre/post-indexed addressing, positive/negative offsets, and base-register writeback.
|
||
- `LDM`/`STM` in increment-after, increment-before, decrement-after, and decrement-before modes.
|
||
- Stack save/restore, PC loads, empty register lists, and ARM7 base-register overlap rules.
|
||
- `SWP`/`SWPB`, including unaligned word rotation and register aliases.
|
||
- 256 KiB external work RAM and 32 KiB internal work RAM, including mirrors.
|
||
- Read-only cartridge bytes in the three GBA cartridge windows.
|
||
- Explicit cartridge RTC selection with first-window GPIO read enable, direction/latch behavior, and serial calendar/control transactions.
|
||
- Validated RTC date/time, BCD transfers, read snapshots, complete writes/reset, and caller-supplied battery-clock advancement.
|
||
- Desktop `--rtc` seeds UTC once and supplies host elapsed seconds independently of CPU cycles and STOP.
|
||
- Cartridge GPIO and Flash controller changes participate in CPU/DMA rollback and block-store preflight without modifying ROM bytes.
|
||
- Explicit Macronix Flash64/Flash128 identification, read-only arrays, and 128 KiB bank selection.
|
||
- Exact-size core save-image initialization and inspection; desktop save selection starts erased and performs no save-file access.
|
||
- Raw ROM-file loading with original BIOS boot, terminal diagnostics, and final CPU/step reports.
|
||
- Firmware boot initializes BG2/BG3 identity scales for bitmap and affine programs that do not program their own matrices.
|
||
- RegisterRamReset supports disabled sound and disconnected serial initialization, including the common `r0=0xff` request.
|
||
- Disconnected Joybus selection, local data/status registers, and transmit-pending state without invented remote events or IRQs.
|
||
- Direct Sound A/B support timer-driven FIFO playback, stereo digital levels, and DMA1/A or DMA2/B refill blocks.
|
||
- PSG pulse channels 1 and 2 support independent nominal frequency/duty playback, length, envelope, status, and stereo mixing. Channel 1 also supports sweep.
|
||
- Noise channel 4 supports nominal 7/15-bit generation, divider clocks, shared length/envelope behavior, status, and stereo mixing.
|
||
- Wave channel 3 supports single-bank nibble playback, rotating RAM, volume/force-volume, length, activity status, and digital mixing.
|
||
- Two-bank wave playback, active bank changes, and unsupported serial operations remain diagnostic with whole-access and block-store rollback.
|
||
- ROM windows with scanline capture, keyboard input, focus-loss release, bounded execution slices, and interactive keypad wake from STOP.
|
||
- Optional ROM-window frame limits and an original input-test ROM generator.
|
||
- Headless JSON ROM suites with PC or VBlank completion, register/CPSR/memory/pixel assertions, scheduled buttons, bounded budgets, and structured failure reports.
|
||
- Hash-pinned preparation of public `jsmolka/gba-tests` ARM, Thumb, memory, and BIOS ROMs, with verified result-register checkpoints.
|
||
- These pinned ROMs pass their checkpoints on Darwin arm64 in debug and release builds; coverage limits remain documented.
|
||
- A [pinned MIT Pong homebrew](public-pong.md) passes captured-pixel menu, ball-motion, and paddle press/release checks in both profiles.
|
||
A bounded native-window run also completes; scoring, full playthrough, audio, and saves are not validated by this ROM.
|
||
- The original BIOS exposes documented boot, SoftReset, SWI, and IRQ protected-read words through its actual exit layout.
|
||
- ARM test/compare Rd=15 status restoration, without a PC result write or nominal refill.
|
||
- ARM unused-memory data reads return a PC+8 word snapshot, with normal byte lanes and load rotation.
|
||
- Thumb unused-memory reads follow the actual PC+4 fetch region, including mapped boundaries, ROM windows, and IWRAM lane history.
|
||
- Persistent IWRAM lanes track ARM/Thumb fetches, CPU data accesses, and successful DMA, with known-bit tracking and diagnostic rollback.
|
||
- Cold fills, ARM/Thumb target pairs, and discarded IRQ source fetches update addressed IWRAM lanes; state changes do not erase them.
|
||
- Little-endian byte, halfword, and word reads/writes.
|
||
- ARM7TDMI word-load rotation, aligned stores, and odd-address halfword-load behavior.
|
||
- Explicit errors for unsupported instructions when their condition passes, and for unsupported memory accesses.
|
||
|
||
Thumb execution includes:
|
||
|
||
- Immediate and register arithmetic, shifts, comparisons, logical operations, and multiply.
|
||
- High-register operations and `BX`.
|
||
- Word, byte, halfword, and signed loads/stores with register or immediate offsets.
|
||
- PC-relative literal loads, PC/SP-relative address calculation, and stack-pointer adjustment.
|
||
- `PUSH`/`POP` and multiple-register loads/stores, including PC+6 stores for empty register lists.
|
||
- All 14 conditional branches, unconditional branches, and both halves of `BL`.
|
||
|
||
## Deliberate limits
|
||
|
||
This is an interpreter scaffold, not an accurate GBA implementation.
|
||
It models CPU reset state and an optional minimal firmware subset, not the complete GBA boot sequence or BIOS service set.
|
||
Status handling covers ARM7 flags, modes, interrupt masks, and instruction state; reserved bits read as zero.
|
||
The reserved ARM condition code `0xF` and Thumb condition code `0xE` return errors.
|
||
ARMv5+ extensions such as `BLX`, `BKPT`, and Thumb-2 instructions are not supported.
|
||
The ARMv4T high-register format requires at least one high register; low-to-low forms in that format return errors.
|
||
`LDRT`/`STRT` single-transfer variants and invalid register combinations return errors.
|
||
CPU BIOS reads are protected by the executing address using bounded ARM and Thumb prefetch snapshots.
|
||
Thumb BIOS execution retains the full word at `(PC+4) & ~3`, not a repeated halfword.
|
||
Missing lookahead invalidates that history; protected reads with unknown history remain diagnostics.
|
||
Exact refill and BIOS data-access ordering remain unmodeled. The Thumb rule has source-based, not physical-hardware validation.
|
||
This is not a full fetch pipeline. The original BIOS reproduces documented boundary readback words, not all firmware side effects.
|
||
Multiply flags N/Z are implemented. Unspecified multiply C/V outputs are preserved deterministically, not hardware-verified.
|
||
Instruction and memory errors are development diagnostics, not emulated CPU exceptions.
|
||
Block transfers validate all accesses before committing register, RAM, or I/O changes.
|
||
This diagnostic policy does not reproduce partial transfers during hardware data aborts.
|
||
CPU instructions, including swaps, finish before a newly requested DMA unit runs. Sub-instruction bus arbitration is not modeled.
|
||
CPU/bus costs are nominal estimates, not a cycle-accurate implementation.
|
||
The instruction buffer retains the next fetch kind; cold startup costs and per-access device scheduling remain unmodeled.
|
||
Game Pak prefetch uses source-backed queue rules, not hardware-verified timing.
|
||
Live WAITCNT transitions, page-boundary behavior, and exact DMA/idle ordering still need independent timing validation.
|
||
Timer data accesses follow ordered nominal bus phases. Other devices remain instruction-batched; exact timer startup and IRQ delays remain unverified.
|
||
Graphics support includes Mode 0–5 debug snapshots and HBlank row capture with sprites, mosaic, windows, and color effects.
|
||
Internal affine origins, vertical window flags, and vertical mosaic counters track line boundaries.
|
||
Horizontal window comparators retain four-cycle event history.
|
||
Sprite rows prepare one line ahead with a whole-row cycle40 sample and nominal per-row work limits.
|
||
Individual fetch timing, hardware-accurate work cutoffs, video-bus contention, and per-pixel color composition remain unimplemented.
|
||
There is no host audio output or save writing/persistence.
|
||
The [Flash subset](hardware/saves.md) supports explicit device selection, identification, array reads, and banking.
|
||
Flash programming, erase, busy polling, wider accesses, unverified aliases, and other save-device protocols remain diagnostic or unimplemented.
|
||
The optional [cartridge GPIO/RTC subset](hardware/cartridge-gpio.md) supports calendar/control transfers and explicit clock updates, selected with `--rtc` in ROM modes.
|
||
RTC persistence, interrupts, invalid-date correction, physical subsecond timing, GPIO aliases, and byte writes remain unsupported or unverified.
|
||
The core uses deterministic caller time. Desktop RTC runs use host UTC/elapsed time and are not fully deterministic.
|
||
The [audio subset](hardware/audio.md) supports Direct Sound, both PSG pulse channels, single-bank wave channel 3, noise channel 4, and instantaneous digital mixing.
|
||
Optional 32,768 Hz digital capture provides bounded, transactional stereo samples with explicit drop counts.
|
||
Two-bank wave playback, active wave-bank changes, and unverified sound-DMA pairings remain diagnostic.
|
||
PSG timing and signed mixing are nominal; hardware startup edges and analog behavior remain unverified.
|
||
The [serial subset](hardware/serial.md) supports disconnected normal 8/32-bit transfers, external-clock waiting, idle multiplayer configuration, and general-purpose pins.
|
||
Internal clocks shift high input at nominal rates, clear busy, and request completion IRQs. External requests retain busy without clock edges.
|
||
Disconnected multiplayer exposes child/ready status and 16-bit send/receive registers without inventing transfers or completion IRQs.
|
||
Pre-transfer ID is a zero placeholder; receive-write behavior and reset/alias details lack physical-hardware validation.
|
||
Joybus supports local configuration, data latches, and transmit-pending status, without an external master or completion IRQs.
|
||
Connected links, multiplayer transfers, UART, Joybus commands, GPIO interrupts, and unverified mid-transfer reconfiguration remain unsupported.
|
||
RCNT retains inactive bits 8/14 in normal mode and bit 8 in Joybus. Effective GPIO interrupt enable remains diagnostic.
|
||
Mapped I/O covers DMA, timers, interrupts, WAITCNT, display control/status, background control/scroll/affine registers, window/effect registers, KEYINPUT/KEYCNT, POSTFLG, and HALTCNT.
|
||
Keypad IRQs use a documented polling model; hardware retrigger edges and asynchronous input timing remain unverified.
|
||
STOP implements keypad wake only. Serial/Game Pak wake sources, oscillator restart delays, and exact wake timing remain unimplemented or unverified.
|
||
The presentation framebuffer is separate from emulated video RAM.
|
||
All named graphics demos connect desktop input and rendering to the emulated CPU. The default display test remains host-generated.
|
||
ROM files can run in bounded terminal mode or a window with the original BIOS replacement.
|
||
ROM windows have no demo-specific startup checks. Input is sampled between bounded execution slices.
|
||
Audio, saves, and external BIOS loading remain unavailable. ROM loading does not establish commercial-game compatibility.
|
||
A local Emerald run now completes its all-device reset and master sound enable.
|
||
It also passes the pulse/noise triggers and normal-mode RCNT configuration.
|
||
It also completes a CpuSet call to address zero through the corrected ignored BIOS-write behavior.
|
||
It also accepts an external-clock serial request without inventing clock edges or completion.
|
||
It now also completes internally clocked normal transfers and selects idle multiplayer mode.
|
||
With explicit `--rtc` selection, it also passes Game Pak GPIO configuration and RTC calendar reads.
|
||
With `--save-type flash128`, it also passes Flash identification and reaches a later startup check.
|
||
It now passes disconnected Joybus setup and completes a bounded 600-frame native run without a diagnostic error.
|
||
That run used no scripted input or pixel assertions.
|
||
A later [fixed-time input probe](research/emerald-wave.md) found a wave trigger with its gate disabled.
|
||
Wave support now passes that point and reaches 1,320 frames with scheduled Start/A presses and releases.
|
||
Output differs from a no-input control, but readable menus and gameplay remain unverified.
|
||
Flash writing and persistence remain unimplemented.
|
||
Without `--rtc`, cartridge GPIO writes still return read-only diagnostics.
|
||
No title-screen, gameplay, or audible-game compatibility is established.
|
||
See [the startup result](research/emerald-reset.md) for the bounded run and next investigation.
|
||
See [cartridge loading](hardware/cartridge.md) for file limits, step budgets, and exit status.
|
||
The [ROM suite runner](rom-tests.md) has original regressions and a [pinned public ARM baseline](public-arm-tests.md).
|
||
The pinned public ARM ROM passes its result checkpoint in debug and release builds.
|
||
The [pinned public Thumb ROM](public-thumb-tests.md) also passes after correcting its empty-list store PC value.
|
||
The [pinned public memory ROM](public-memory-tests.md) passes without a core change; its video-byte assertions have documented limits.
|
||
The [pinned BIOS read-protection ROM](public-bios-tests.md) passes after correcting the replacement firmware's exit layout.
|
||
The bus still derives retained words from the actual image; no test-specific override or ROM patch is used.
|
||
Other public suites remain unverified. These results do not establish full CPU or memory compatibility.
|
||
The runner supports PC checkpoints or bounded VBlank completion, scripted button snapshots, and captured-pixel assertions.
|
||
Debug-port logging, audio assertions, and whole-image comparisons remain unsupported.
|
||
|
||
ARM data reads from unused address ranges use a bounded [PC+8 open-bus snapshot](hardware/cpu.md#arm-unused-memory-data-reads).
|
||
Thumb reads use [region-dependent snapshots](hardware/cpu.md#thumb-unused-memory-data-reads) and persistent local IWRAM lanes.
|
||
Only actual IWRAM fetches and data accesses drive those lanes, independently of CPU state and executing region.
|
||
Cold fills and target pairs establish both lanes when all required samples are mapped.
|
||
State changes and other-region accesses preserve local history; an IRQ source fetch updates lanes when it addresses IWRAM.
|
||
Failed instructions discard staged updates.
|
||
Successful DMA can establish lanes before CPU startup. Resumed fetches then update their addressed lanes.
|
||
ARM/Thumb instruction buffering retains sequential instructions and refill target pairs.
|
||
Instruction buffering and supported bus history now consume the same mapped fetch samples, without sharing retained storage.
|
||
Mapped boundary snapshots follow the actual fetched bus; unknown IWRAM lanes, missing bytes, and I/O fetch values remain diagnostic.
|
||
Complete general-bus history, exact boundary timing, general DMA handoff, and unused/write-only I/O open bus remain incomplete.
|
||
[DMA channel data latches](hardware/dma.md#retained-channel-data) support blocked-source reuse, but never replace CPU bus history.
|
||
BIOS protection uses separate retained BIOS fetch snapshots as described in [BIOS behavior](hardware/bios.md#cpu-bios-read-protection).
|
||
Host inspection and instruction fetches remain strict. Other unmapped reads return errors.
|
||
Reads beyond the supplied cartridge bytes also return errors.
|
||
Direct memory-bus halfword and word accesses require alignment.
|
||
CPU load/store instructions apply ARM7TDMI alignment and rotation rules before accessing the bus.
|
||
Ordinary ROM writes remain read-only. Explicitly selected cartridge GPIO and supported Flash command writes are separate from ROM storage.
|
||
|
||
## Next steps
|
||
|
||
Follow the [general GBA usability roadmap](usability-roadmap.md).
|
||
Prioritize repeatable homebrew gameplay, demonstrated compatibility failures, cartridge saves, and audio.
|
||
The goal is usable emulation across games, not an Emerald-specific implementation.
|
||
|
||
The remaining hardware-validation backlog includes:
|
||
|
||
1. Extend shared fetch samples to verified general-bus data-access history and unsupported fetch regions.
|
||
General DMA open-bus reads and sub-instruction arbitration remain separate from retained channel data and local IWRAM lanes.
|
||
Keep unknown history diagnostic until fetch ordering and latch ownership have independent coverage.
|
||
Validate BIOS snapshots with independent hardware tests before claiming exact refill or data-access history.
|
||
The desktop runner still uses only the original BIOS. Keep protected reads image-derived for all supplied images.
|
||
2. Validate the active nominal Game Pak prefetch queue against independent timing tests.
|
||
The [cancellation probe](research/prefetch-cancellation.md) now matches after [ordered timer accesses](research/ordered-timer-access.md).
|
||
The [shared timer prescaler](research/timer-prescaler.md) now retains a common clock origin across enable and clock-source changes.
|
||
Validate delayed timer startup/control edges and extend ordered observations to other devices without duplicate clocks or lost rollback.
|
||
Validate full-buffer restart, page boundaries, live WAITCNT transitions, and cold-start costs.
|
||
See [prefetch behavior and evidence](research/gamepak-prefetch.md); exact bus arbitration and timer/IRQ delays remain separate work.
|
||
3. Validate keypad retrigger behavior with hardware tests and add remaining device registers; extend BIOS reset coverage as sound/serial support becomes available.
|
||
Validate STOP entry/wake edges and add external wake sources and remaining DMA device modes.
|
||
4. Replace nominal sprite work limits with verified individual fetch timing; add background fetch timing and per-pixel composition.
|
||
5. Validate more original/public test ROMs through the window. Expand compatibility evidence across independent programs.
|
||
|
||
Keep the emulator core independent of window and audio libraries.
|
||
Treat Nintendo DS support as a separate project phase.
|