Retain independent known data across DMA blocks. Duplicate mapped halfword sources and select the destination lane for blocked sources below work RAM. Keep cold history diagnostic, commit only successful units, and preserve separate CPU/BIOS history rules. Add 13 original regressions and pinned source research. CPU resume ownership, general DMA open bus, and IWRAM DMA lane effects remain explicit limits. Validated on Darwin arm64: 930 workspace and 861 core/demo tests in debug and release, 39 Python tests, native ROM windows, ten window smoke modes, fmt, clippy, and rustdoc. Public ARM/Thumb/memory/BIOS reports match the previous results exactly.
14 KiB
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
KEYINPUTfor all ten GBA buttons, independent of the window library. KEYCNTselection 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.
- User, System, Supervisor, IRQ, FIQ, Abort, and Undefined modes.
- Current and saved program status registers (
CPSR/SPSR), withMRS/MSRtransfers. - 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.
- 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.
- 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, andMVN. - Arithmetic operations:
SUB,RSB,ADD,ADC,SBC,RSC,CMP, andCMN. - 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, andSMLAL.- Negative (N), zero (Z), carry (C), and signed overflow (V) flags.
- All 15 defined ARM condition codes, including always (
AL). BandBLwith signed relative displacement and conditional execution.BXswitches between ARM and Thumb using target bit zero.LDR,STR,LDRB,STRB,LDRH,STRH,LDRSB, andLDRSH.- 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/STMin 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-testsARM, 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 use repeated PC+4 halfwords in 16-bit code regions and aligned PC+4 words in BIOS/OAM.
- Sequential Thumb IWRAM history retains fetched and data-access lanes, with known-bit tracking and diagnostic rollback.
- Successful refills into Thumb IWRAM establish bus history from the target and target+2 halfwords, including exception returns.
- 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/POPand 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.
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 for file limits, step budgets, and exit status.
The ROM suite runner has original regressions and a pinned public ARM baseline.
The pinned public ARM ROM passes its result checkpoint in debug and release builds.
The pinned public Thumb ROM also passes after correcting its empty-list store PC value.
The pinned public memory ROM passes without a core change; its video-byte assertions have documented limits.
The pinned BIOS read-protection ROM 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. Thumb reads use region-dependent snapshots and bounded sequential IWRAM lane history. Cold or invalidated IWRAM history remains diagnostic until all lanes are known. Refills into Thumb IWRAM establish new target-pair history after the instruction succeeds. Accepted machine IRQs, successful DMA, unsupported refills, and other execution states/regions invalidate continuation history. This is not a fetch pipeline. ARM-target refill history, region-crossing fetches, DMA-to-CPU handoff, and unused/write-only I/O open bus remain unsupported. DMA channel data latches support blocked-source reuse, but never replace CPU bus history. BIOS protection uses separate retained BIOS fetch snapshots as described in BIOS behavior. 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
- Extend the DMA channel-latch foundation with validated DMA-to-CPU bus ownership and IWRAM effects. General DMA open-bus reads need separate evidence; blocked-source reuse does not establish their values. 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.
- Refine nominal timing with a fetch pipeline, Game Pak prefetch, per-access device updates, and verified timer/IRQ delays.
- 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.
- Replace nominal sprite work limits with verified individual fetch timing; add background fetch timing and per-pixel composition.
- 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.