180 lines
16 KiB
Markdown
180 lines
16 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 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/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.
|
||
- 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.
|
||
- 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.
|
||
- Raw ROM-file loading with original BIOS boot, terminal diagnostics, and final CPU/step reports.
|
||
- 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 per-case checkpoints, register/CPSR/memory assertions, 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.
|
||
- 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.
|
||
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 sound or cartridge save support.
|
||
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.
|
||
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 requires known completion addresses and has no debug-port protocol, scripted input, or rendered-image assertions.
|
||
|
||
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.
|
||
Writes to cartridge addresses return errors instead of modeling cartridge hardware.
|
||
|
||
## Next steps
|
||
|
||
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. Add Game Pak prefetch using the ordered CPU timing path; bit 14 still does not accelerate execution.
|
||
Verify queue startup, full-buffer restart, page boundaries, partial ARM fetches, and invalidation before enabling it.
|
||
See [prefetch research and prerequisites](research/gamepak-prefetch.md).
|
||
Validate cold-start costs, then extend per-access device updates, bus arbitration, and timer/IRQ delays.
|
||
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; add audio, cartridge hardware, and saves before testing Emerald compatibility.
|
||
|
||
Keep the emulator core independent of window and audio libraries.
|
||
Treat Nintendo DS support as a separate project phase.
|