Release date: September 2026
Previous release: 1.9 (September 2026)
Version 1.9.1 is the maintenance release that finishes what 1.9 started. The integrated Game Boy
Advance and Game Boy now sound and time the way the hardware does: the Game Boy's LCD runs
on its own 4.194304 MHz clock, the Game Boy APU was rewritten against the manuals and has tests for
the first time, the GBA's sound controller and its host-side BIOS sound driver match the official
IPL, and the aging cartridge's timing checks pass. On the GameCube side the release is about the
interface and the build: the legacy debug console and the Win32 front end are gone in favour of the
single SDL2 one, the SDL port gains the settings and memory-card dialogs it was missing, the TEV
gets its swap tables, and the recompilers run on 32-bit hosts and Windows 7. The portable suite
closes at 362 of 362 tests.
Highlights
- The portable machines sound right. The Game Boy's APU was wrong in almost every clock it has
— the frame sequencer ran sixteen times too fast, the length counters counted backwards, the pulse
and wave dividers were half their rate (every note an octave high), the duty phases were wrong and
NR51 was swapped, which mirrored the whole stereo image. The suite that now pins it down
(GbApu, fifteen tests) is new; the module had no tests at all. On the GBA, channel 3 was clocked
by a timer, the mixer's levels were half of what the hardware gives the direct-sound FIFOs, the
waveform RAM lost its second bank, and a decreasing sweep that underflowed stopped the channel. - The portable machines time right. The Game Boy's LCD advanced one dot per four clocks — a
GBA rule — so a frame was 280896 clocks instead of 70224 and every device that counts clocks got
four times its rate per frame of picture. The dot clock is now the machine's own 4.194304 MHz
clock, one clock per dot. The GBA's memory model caught up with GBATEK: the internal memories
charge their documented access cycles (including the undocumented4000800hwaitstate register),
the Game Pak uses the first/second access times ofWAITCNTwith the 128 KByte non-sequential
rule, a DMA transfer spends its cycles while it runs, and a transfer no longer rewrites the
SAD/DADregisters. - The HLE BIOS is the official BIOS. The host-side BIOS calls have the official SWI numbers now
(the sound driver is1Ah..1Fh/28h/29h, not28h..2Fh), the four decompressors were read out
of the official image and fixed (HuffUnComp's bitstream starts at
source + 4 + (treeSize + 1) * 2and is read as a rotated word;RL's flag byte is one token,
not eight), the sound driver mixes its twelve virtual channels, and the IRQ contract is the
hardware's: acknowledgingIFis the handler's job. Metroid Fusion on the high-level BIOS now
draws the same frames as on the real image. - Nintendo's own aging cartridge runs. The AGB aging cartridge (
AGB_CHECKER_TCHK10) is the
release's oracle, exactly as the real BIOS image is for the HLE. Eleven of its checks were
answered by the timing work — five MEMORY sub-tests, the H-Blank status and interrupt flags, the
video capture window,KEY INTR, the DMA priority preemption and the address-control registers. - One front end and one debugger. The Win32 front end (
ui.cpp, 4940 lines, with its
DirectSound, GDI andGetAsyncKeyStateback ends) and the legacy debug console are gone; the SDL2
front end is the only build, and the Debug menu has one item that opens the new debugger. The SDL
port gains the two dialogs it was missing — Options → Settings… and Options → Memcards. - 32-bit and Windows 7. The recompilers exist as x86 modules next to the x86-64 ones: the
32-bit host no longer falls back to the interpreter, and the same sources build a 32-bit emulator.
The Windows projects target Windows 7 (_WIN32_WINNT=0x0601), the oldest Windows SDL2 2.28 and
the emulator run on. - The Flipper's TEV gets its swap tables. The two 2-bit fields of
TEV_ALPHA_ENVare the raster
and texel swap-table selects, not a mode and a fixed component pick; the four tables are the low
four bits ofTEV_KSEL_2k. The CP's BP write mask (0xFE) limits the very next register write,
which is what keeps the library's shared payloads from clobbering each other. The demo
tev-swap's doughnuts come out grey (0.0% saturated pixels, was 69%).
Added
The Game Boy side of the portable core
- A
GbApusuite (fifteen tests) and aGbPpusuite for the Game Boy machine, which had none: the
divider rates of the four channels against the manuals' frequency formulas, the duty waveform
phases, the length timer, the 512 Hz frame sequencer with the envelope at 64 Hz and the sweep at
128 Hz, the wave RAM access order and volume shifts, the noise LFSR sequence, NR50/NR51 mixing,
the exact sample clock, PCM12/PCM34 (the CGB's view of the four generation circuits), the CGB's
own high pass filter and the setting that turns it off. On the LCD side: the mode timings in the
machine's own clocks (one clock to a dot, 456 to a line), the STAT/LYC interrupts, the CGB
attribute map, the DMG compatibility rules and OPRI, the HDMA destination bank, and the LCD-off
blank. - The two Acid2 pictures are pixel for pixel identical to Matt Currie's reference images —
dmg-acid2on the DMG,dmg-acid2on a CGB in DMG mode (shade for shade through the emulator's
own grey ramp) andcgb-acid2on the CGB. They are what found the lost line-start STAT
interrupts, and they are the end-to-end check of the one-line-at-a-time renderer. - A way to listen and to compare:
--wav <file>records the mix in both harnesses,--rate N
changes the sample rate and--no-hpfturns the DMG/CGB high pass filter off
(audio.highPassFilter), which is what a recording that will be filtered later wants. The GBA
harness also got--log(the core's own warnings, e.g. an unimplemented SWI, used to be thrown
away) and--bios. - The Game Boy frontend blends each shown frame with the one before it — dmgemu's
lcd_effect, the
trail an LCD leaves while the picture moves. It lives inHost::Present, so a.gbaand a
.gb/.gbcrun get it from the same code, andvideo.lcdEffectturns it off (on by default).
The cores are not touched: the frame the screenshots and the debug interface read stays clean. --keysis pushed through to the Game Boy machine, which is how the Metroid II run below was
checked.
Build and tooling
- The recompilers on 32-bit hosts (issue #417).
gekkojit_x64.cpp,gekkojit_ps_x64.cpp,
dspjit_x64.cppandgekkojit_layout_x64.hare marked x86-64-only and each got a 32-bit sibling
(jit_x86.h,gekkojit_layout_x86.h,gekkojit_x86.cpp,gekkojit_ps_x86.cpp,
dspjit_x86.cpp). The translator is the x86-64 one adapted to eight general purpose registers,
four of them callee-saved, with the layout written down ingekkojit_layout_x86.h, and the state
hash of a workload is identical on all four JIT builds — MSVC and GCC, x86-64 and i386. - Windows 7. The Visual Studio projects and
CMakeLists.txtcarry both module sets and let the
preprocessor pick; the emulator projects define_WIN32_WINNT=0x0601andWINVER=0x0601, and no
emulator source calls an API newer than that, so the Windows 7 target of SDL2 2.28 is the oldest
the emulator runs on. - SDL2 is linked as a static library from the bundled tree.
testing/gba_benchgrew theBus,HleBios,GbBus,GbApu,GbPpu,AudioandSettings
suites; the Visual Studio project and the Readme follow, so the Windows build of the harness
compiles the tests that compare the host BIOS with the official image.
Changed
The SDL front end is the only one (issues #421, #422, #420)
- The Win32 front end and its back ends are deleted:
ui.cpp(the main window, the menu, the game
selector, the settings property sheet, the controller and memory-card dialogs),
audio.cpp/audio.h(DirectSound),video.cpp(GDI) andpad.cpp(GetAsyncKeyState),
together with the dialog, menu, accelerator and bitmap templates only they used. The interfaces
the rest of the emulator speaks stay where they were; the application icon stays in the resource
script. - The settings of the two ports are one pair of files again (
Data/DefaultSettings.jsonand
Data/Settings.json); the Windows/SDL split is gone, and theDOLDEBUGkey, unread since the
debug console was removed, is gone with it. - The legacy debug console is gone (
cui.*,cuinull.cpp,cuisdl.cpp,debugui.*). The Debug
menu of both ports carries a single item, Open Debugger…, which opens or closes a DebugUI2
session; the crash report reaches the front end with the sameUIReportcommand it used when no
console was open. - The SDL port can mount a DolphinSDK folder again — File → Mount DolphinSDK as DVD… was a stub
there and now opens the directory browser and callsDvdMountSDK. - The settings dialog and the memory cards (issue #420). Options → Settings… is one window
with a tab per Win32 property-sheet page: the directories the selector scans and the file filter
(GUI/Selector), and the emulated console version plus the three firmware images (GCN
Hardware). The version combo carries a "User defined" entry so a hand-edited configuration is
shown as it is; Apply writes the configuration the waySaveSettingsdoes, with the paths going
back throughAddSelectorPath, and Cancel drops the copy. Options → Memcards is a window per
slot: the connection flag, the save policy (SyncSave) and the card file, with Create New…
asking for one of the six sizes the hardware has. Unlike the Win32 dialog, which left the running
card alone until the next boot, OK re-points (flushing the card it replaces) or connects a card
that is already open.
The GBA/Game Boy core
- The sound controller against GBATEK and the AGB manual. Channel 3 is clocked by
NR33and
not by a timer —SOUND3CNT_Xbit 14 is the length flag and nothing else, and only the two
direct-sound FIFOs are timer driven; the waveform RAM is two banks of 16 bytes with the CPU
reaching the one that is not playing; the mixer follows GBATEK's "Max Output Levels" (a PSG
channel spans a quarter of the output range, a FIFO the whole of it, andSOUNDCNT_L's level has
"no effect on direct sound"); a decreasing sweep that would underflow keeps the frequency instead
of stopping the channel; and the sum is clipped by the 10-bit output stage as the hardware clips
it. - The device is the clock of the machine. The machine pushes every sample it mixes into the
mixer buffer and the device plays it from its own audio callback. The buffer keeps a cushion of
three video frames, throws away what does not fit, fills a period it cannot fill with silence
instead of stale samples, and reports its delay, gaps and drops in the window title. The frame
loop holds the machine back only when the buffer is genuinely ahead, and fast forward throws its
sound away. The rate correction is a slow PI controller on a filtered level, gains worked out
from the loop: the old one-liner answered a sawtooth with an undamped integrator whose period
worked out at half a frame, which swung the full ±1% between neighbouring frames and threw away
9450 frames a minute. - A repeating DMA streams its source. GBATEK reloads
CNT_Land optionallyDADon a repeat —
notSAD, so the source pointer carries on. A sound DMA is always repeating (the FIFO asks for 16
bytes at a time), so the old code restarted the stream at the same address on every refill and the
FIFO played one 16-byte block over and over — a high buzzy squeak that vaguely followed the tune.
A transfer also does not change theSAD/DADregisters, which hold the values the CPU wrote;
the running pointers live in the engine. - The video capture runs on the lines GBATEK gives it — started at
VCOUNT=2, repeated each
scanline, stopped atVCOUNT=162with the channel's enable bit self-cleared — and a
higher-priority DMA request that arrives while a transfer is running is serviced at the next unit
boundary instead of being lost until the channel's next trigger. - The EEPROM answers only in its own window. GBATEK puts the chip at
D000000h-DFFFFFFhon a
cartridge of 16 MByte or less (or in the last 256 bytes of a full 32 MByte image); everywhere else
the ROM still drives the bus. That is what lets a game run its own EEPROM routine from the
cartridge — Minish Cap fetches instructions between the read request and the data transfer. The
chip's idle read also drives bit 0, the ready line the games poll after a write, instead of
returning the mirrored ROM. - The host-side sound driver's channel array is twelve entries of 40h bytes at
50h + n * 40h(GBATEK: 1-12 channels), not sixteen of 30h; a DMA's unit size followsCNT_H
bit 10 on every channel, not just DMA3; the DMA's per-unit cost follows the bus width of the
source and destination; and the internal memories charge their documented cycles, with the
on-board 256K WRAM's waitstates taken from the undocumented4000800h. - An idle
WAITCNTbit 15 (the read-only Game Pak Type Flag) can no longer be set by a write, and
DISPCNTbit 5 — the "H-Blank Interval Free" flag — no longer silently means something else to
the renderer.
The GBA HLE BIOS
- The SWI numbers are the official ones: the sound driver at
1Ah..1Fh, with
VSyncOff/VSyncOnat28h/29h. Before, the whole block was at28h..2Fhand1Ahwas
calledDivArm2, so a game'sSoundDriverInitwas answered with a division and its music never
started. HuffUnComp,BitUnPack,LZ77(both write variants),RLand the two delta filters were
re-read out of the official image's own code and are now covered by a differential test that
encodes random data into valid streams and compares the bytes both implementations wrote.
MidiKey2Frequses the BIOS's own fixed point — a 16.16 semitone table, the octave as a shift,
the product truncated, the fine value as a slope — instead of a double-precision guess.- The sound driver's entry points are implemented from what a probe can measure out of the real
BIOS: the work area's identifier68736D53hand its0FB0hsize, thepcmbuflayout (two
0630hbyte halves at+0350hand+0980h), the two FIFO DMAs (B600h: repeating, 32-bit, with
an incrementing source),SOUNDCNT_H210Eh, the timer 0 reload for every playback frequency
index, andSoundDriverMain, which mixes the twelve virtual channels with the driver's own
envelope state machine and fixed-point levels. The reverb is not modelled, and the sample stepping
is a 16.16 accumulator rather than the driver's exact arithmetic. - The IRQ contract is the hardware's: the custom boot ROM no longer acknowledges
IFbefore
dispatching, because the official BIOS does not either. Metroid Fusion's handler readsIFto see
what happened, so a pre-acknowledged IF left it doing nothing every frame and the game froze on
its title screen. The SIO link driver now installs its own acknowledge-and-return handler, which
is what a program enabling that interrupt has to do.
Gekko, the TEV and the build
- TEV swap tables and the compare operation. The two 2-bit fields of
TEV_ALPHA_ENVare the
swap-table selects (GXSetTevSwapMode's raster and texel selects) and the four tables are the low
four bits ofTEV_KSEL_2k/2k+1;TEV_KSELresets to the tables GX initialisation programs
(RGBA/RRRA/GGGA/BBBA). The compare operation shares the same bits, so it is decoded the way the
driver encodes it — the bias field's fourth value marks it, the sub bit picks the comparison — and
the mask tests the pre-shift stage value. - The CP's BP write mask (0xFE). A write to it limits which bits of the very next BP register
write are updated and then clears itself. The library uses it for the registers whose payload two
features share — the K constant selects and the swap tables ofTEV_KSEL, the cull mode of
GEN_MODE, the blend mode ofPE_CMODE1— so without it the swap tables would be clobbered by
the firstGXSetTevKColorSel. The mask travels down the CP chain with the write and each block
merges it into its own register value. - Two TEV arithmetic details. The interpolated blend factor is a u0.8 fraction normalised over
256, so 255 is exactly 1.0 and 128 is 129/256 (all three copies of the model divided by 255, half
an LSB away), andDIVIDE_2truncates without rounding. A bit-exact model of the design's stage
then matches the demo on all 64 argument-sweep states, all 24 arithmetic states and the 11 states
that used to separate the two models. - The disassembler. The halfword transfer's bit 22 selects the offset form and was inverted, so
every immediate offset printed as a register and every register offset as an immediate — the
official BIOS's own decompressors were unreadable. A register offset's shift is printed now, and a
pre-indexed writeback is outside the bracket ([r1, #4]!, not[r1, #4!]). Both are what made
the HLE BIOS work above possible. - The GBA module uses the stdint types (issue #419) instead of the project's
u8/s8aliases;
json.cppis self-contained (the standard library,verify.hand its own UTF-8 codec), so the
portable core compiles it next to its own sources without SDL, OpenGL or ImGui, and the GBA
settings reader uses the shared Json engine (issue #423) instead of its hand-written parser. - The debugger window is opt-in in
--gba/--gb:emulation.debugger(false by default)
decides whether it opens with the machine; the JDI node and the MCP transport come up either way,
andF2opens and closes the window as before.
Fixed
The portable machines
- The Game Boy's clock (found by capturing
zelda.gband comparing it with another emulator).
The LCD advanced one dot per four clocks, so a frame was 280896 clocks instead of 70224: the APU
mixed 2940 samples a frame where the device plays 738.35, so three quarters of the music was
thrown away in bursts (the rattle that would not go away no matter how the buffer was steered);
DIV ran at 64 kHz instead of 16384 Hz and the serial port at four times its baud rate; and the CPU
had four frames of work to get through in one. The emitter now runs on one clock per dot. - The Game Boy APU's every rate. The frame sequencer stepped every 512 system clocks instead of
8192, so the length, the envelope and the sweep all ran sixteen times too fast, and it clocked the
length on step 7 as well (320 Hz with jitter instead of 256). The length counters loaded
64 - NRx1and counted up to 64 — backwards. The pulse and wave dividers ran at
(2048 - x) * 2and(2048 - x)instead of* 4and* 2. The four duty waveforms had the
right ratios but the wrong phases. NR50's master volume was never applied to the mix, and NR51's
halves
were swapped, which mirrored the whole stereo image. The sample clock now keeps the fraction of a
clock it used to round away. - The line-start STAT interrupts.
BeginVisibleLinecalledEnterMode(2)and threw its return
value away, so the STAT request a line start produces — the mode 2 source turning on, and an LYC
that matches the newLY— never reachedIF. Every visible line's mode 2 and LYC interrupt was
lost (the ones inside VBlank still worked, which is why it hid), and the raster effects driven by
LY=LYCthat draw the Acid2 hair, eye, mouth and footer never ran. A register write can raise the
STAT line now (enabling a source whose condition is already true, or aLYCwrite that makes it
match "constantly"), and STAT bit 2 stays live while the LCD is off. - A CGB running a monochrome cartridge (the frontend's default for a DMG game) ignored the
DMG's own display rules:LCDCbit 0 was the CGB's master priority instead of blanking the
background and the window, the window bit was not overridden by it, objects were prioritised by
OAM position instead of X (OPRIwas stored but never reached the PPU), the bank 1 attribute map
was read although the manual says that bank "is not present in this mode", and
BGP/OBP0/OBP1were ignored instead of indexing the CGB palettes. - The CGB's VRAM DMA always wrote bank 0, while the manual is explicit that the destination is
VBK, and readingHDMA5during an active HBlank transfer returned bit 7 set, which Pan Docs
defines as "Not Active". The mode 3 OBJ penalty11 - (X mod 8)dropped to 4 or 5 on the last two
columns of a tile where Pan Docs floors it at 6. Turning the LCD off left the last picture in the
frame buffer instead of the blank white of the disabled screen. - The GBA LCD audited against the manuals. BG2 is affine in mode 1 (Final Fantasy V Advance's
"SQUARE ENIX PRESENTS" screen was a field of noise); the bitmap modes sample through the BG2
matrix (the boot ROM and the no-BIOS start leave the identity matrix, as the real BIOS programs
it); mode 5's bitmap line is 320 bytes and not mode 3's 480; a window's garbage dimensions reach
the screen edge; the OBJ window needsDISPCNTbits 12 and 15; the Green Swap exchanges the
green of each pair of dots instead of byte-swapping every pixel; a semi-transparent OBJ needs a
2nd target selected inBLDCNTand the window's effect bit gates the alpha blend as well as the
brightness; an OBJ whose 8-bit Y range runs past line 255 wraps to the top; and the 28-bit affine
reference point is kept sign-extended. - The text layers' scroll offsets.
BGxHOFS/BGxVOFShold a nine-bit offset (0-511) but were
sampled through the register's readable form, which the PPU trimmed to eight bits. Castlevania:
Circle of the Moon's attract demo scrolled a room to dot 296, the renderer used 40, and the top of
the screen showed whatever the map's other half happens to hold — a band of green "corrupt
background" — while the camera appeared frozen relative to the player. - A double-sized affine OBJ is anchored in the middle of its doubled area. The X/Y attributes
are the upper-left corner of the display area and the rotation/scaling centre is the middle of
that area — half a base size right and below the reference point normally, a whole one when the
double-size flag is set. Every doubled OBJ sat half a base size too high and too far left; the
real BIOS's boot animation is what pinned it (the 64x64 letters snapped down by 32 pixels on their
landing frame). Final Fantasy V Advance's letterbox also pins the OBJ Y wrap: its rows of 16x16
OBJs atY=240..243fill the gaps the wrapped lines leave. - The V-Counter match interrupt is an edge, not a level.
UpdateVCountMatchrequested it
whenever the match condition was true on an evaluation, and aDISPSTATwrite evaluates it too,
so a program that wrote the register back whileVCOUNTstill equalled its setting took two match
interrupts for one line. Minish Cap writesDISPSTATat line 80 of every frame — in the handler
of the match it has just taken — and its own copy of the BIOS sound driver advances its sequencer
once per match, so the intro music ticked twice per frame: the notes came twice as fast and the
track ran out of sequence at 11 s. It is now the edge of the gated (match AND enable) condition,
which is what GBATEK's "requested when the flag becomes set" means; a program that enables the
interrupt while the counter already matches still gets it. - The Save file of a fresh Minish Cap cartridge came up corrupted. The EEPROM's ready line
(bit 0 of the ROM bus in the chip's window) was never driven, so the save library's poll after a
write always saw a busy chip, every write timed out, and after three attempts the library stamped
itsDAMEDAMEfailure marker over the block it was writing — file headers included. With the
ready line on the bus every write is verified on the first attempt. - The HLE sound driver's channel array was misaligned. Sixteen entries of 30h bytes spans the
same 300h bytes as the real twelve of 40h, which hid the mistake: only channel 0 landed where the
official driver looks, so channels 1..11 were mixed from the next channel's envelope and volume
bytes — heard as wrong notes, crackle and an apparent speed change. - The halfword transfer offset form in the disassembler (see Changed), which is what made the
decompressors readable.
The core, the harness and the shell
- Thumb
LDMIA/STMIAskipped an instruction.ThumbMultipleTransfertreated bit 7 of the
register list as "r15 in the list", but a Thumb register list is eight bits wide (r0-r7) and can
never name r15. The BIOS loads itsBitUnPackparameter block withLDMIA r1!,{r5,r7}, so the
instruction that followed was skipped, the block stayed zero,BitUnPackread a zero item count
and bailed out: the seven letter sprites had no glyph data and the boot animation was invisible.
This is why the emulator's own boot ROM did not draw. SVBKmaps a written 0 to WRAM bank 1. A DMG-only cartridge runs on the emulated CGB in
compatibility mode, and the register mapped a written 0 to bank 0. With the power-up value0xF8
that aliased0xC000-0xCFFFand0xD000-0xDFFFonto one 4 KByte page, so a game whose variables
or stack live in the upper bank had its own low-RAM scratch overwrite them: Metroid II kept a
return address at0xDFFB, read back0x0000and restarted from the reset vector for ever.- Json's one-byte UTF-8 sequences. The local decoder's shortest-form table had entries for two,
three and four bytes only, so every ASCII character came out as U+FFFD. SinceAddUtf8Stringis
how the whole debug interface builds its Json, the regression corrupted every answer made that way
— the Markdown panels of the debugger, the disassembly and the symbol names, the reports, the MCP
tool answers and the OS time of the status bar (which showed a row of question marks). Of the 16
unit-test failures at the parent commit, 15 were this. - The
Apu::ReadSamplescall site in the tests handed amaxFramescount to an
int16_t buffer[128]while the call writes two samples per frame: the 256-byte stack buffer was
overflowed and the run died later, in the middle of another suite. Found with AddressSanitizer;
the buffers are sized for stereo frames now. - The DMA transfer's unit size follows
CNT_Hbit 10 on every channel (see Changed), which is
why the Minish Cap engine's per-frame 32-bitDMA0block was half copied before.
Known issues
- The official GBA BIOS runs its boot and its animation is now drawn: the mode 2 BG3 that is
only visible inside the OBJ window, with the nine 32x64/64x64 window sprites,WINOUT = 0x3F27
and alpha blending around it. Both the emulator's own boot ROM and the real image hand over to a
cartridge. What is left to model on the cartridge side is the EEPROM window of a full 32 MByte
image (the last 256 bytes); the harness exercises the 16 MByte layout, where the chip answers
anywhere atD000000h-DFFFFFFh. - A real Game Boy Color cartridge's picture is still work in progress: the machine boots, runs
its own boot ROM and passes its tests, but at some moments its frame does not match VRAM. The
remaining difference is read as the mode 3 line length (a line is composed at once rather than dot
by dot), the HBlank/HDMA timing and the PPU-internal VRAM read-block windows. DMG and CGB in DMG
mode are exact against the Acid2 references. - The GBA's per-line OBJ cycle budget and
DISPCNTbit 5 are not modelled, and the
VRAM/OAM/Palette contention cycle ("+1 cycle if the GBA accesses video memory at the same time")
is not: the accesses take their documented 1/1/2 cycles but never the extra one. The cartridge
prefetch buffer is modelled as a waitstate rule rather than as a real 8-halfword buffer. - A preempted DMA transfer runs to its end before the preempted one resumes instead of the two
interleaving a unit at a time. Nintendo's aging cartridge's remaining failures (the
waitstate/prefetch checks,KEY INPUT SIMPLE) are in this area, and are recorded in
testing/gba_bench/Readme.mdwith the addresses of its test table. - The GBA's sound output stage is not modelled:
SOUNDBIASis stored and read back, but neither its
bias level nor the PWM amplitude resolution changes the mix, which is produced as clean 16-bit
samples. The wave RAM is plain memory rather than the hardware's shift register. - The sound driver's reverb is not modelled on the HLE path (the mode's reverb bits are stored, the
driver's delay line is not), and the pitch stepping is a 16.16 accumulator rather than the
driver's exact fixed point. - Save states, rewind, the EEPROM's "last byte is the AND of the old and new value" quirk and the
RTC's per-minute interrupt register are not implemented on the portable machines. - The serial port's JOY bus mode (
RCNTbit 15, a GameCube controller on the link port) is decoded
but not driven; UART mode works register-wise but has no peer. The emulator-to-emulator cable
(normal and multiplayer) is implemented and tested. - The Linux build still has no sound and no input for the GameCube side, and the Linux headless
target has no OpenGL offscreen backend (the Visual Studio one does). The twoSettingstests that
comparebuild/Data/GBASettings.jsonwith the defaults byte for byte need that file to have LF
endings; a Windows checkout withcore.autocrlfreports the\rs as a difference. - Nintendo's aging cartridge is not fully green: ten checks still fail, all of them in the
waitstate/prefetch area above. The GBA'sPputestRegisterReadBackand thememorytest ROM
pin the data rules where the timing is approximated.
Up next
The portable core is the work of the next release as well: the Game Boy Color picture, the remaining
aging-cartridge checks (the waitstate model and the real prefetch buffer), and the GBA Link and
Game Boy Player jobs the integrated machine exists for — a GameCube title with a GBA in its link
port is the test that proves them.
1.9.1 is a maintenance release inside the 1.9 line. Release 2.0 remains the next major version,
the peripheral release: the EXI bus and the devices on it (memory cards, the Broadband Adapter,
the RTC), the serial interface and the pads, the disk interface and the drive, and the link port the
GBA side already has. After that the project moves into its steady state of planned, methodical
improvement.
Building
Windows. Open scripts/VS2026/pureikyubu.sln in Visual Studio 2026 and build. The emulator is
the SDL2 front end in every configuration — there is no second port any more — and the solution
holds the same four projects: pureikyubu, SDL2 (a static library), GBA and gba_bench. Both
x64 and x86 (Win32) build, the recompilers follow the host, and the projects target Windows 7. The
pureikyubu_headless target is part of the solution but is not built by "Build Solution".
Linux.
sudo apt install libglew-dev libsdl2-dev
git clone https://github.com/emu-russia/pureikyubu.git
cd pureikyubu
git submodule update --init
cd build && cmake .. && make
./pureikyubu pong.dol
cmake -DHEADLESS=ON .. && make # the windowless targetTests.
MSBuild scripts/VS2026/pureikyubu_test.slnx -p:Configuration=Release -p:Platform=x64
vstest.console.exe scripts/VS2026/x64/Release/pureikyubu_test.dll /Platform:x64
The portable machines have their own harness — 362 of 362 tests pass:
testing/gba_bench/check.sh
testing/gba_bench/get_test_roms.sh # the public test ROMs and the two Acid2 pictures
The previous releases are still available: Release Notes 1.9 ·
Заметки о релизе 1.9 · Release Notes 1.8 ·
Release Notes 1.7. The long story of the work after release 1.6 is in the
digest.
Nintendo GameCube, Game Boy, Game Boy Color and Game Boy Advance are trademarks of Nintendo. This
emulator is not affiliated with Nintendo. No BIOS image and no game is distributed with it.