SearchA-ZG › Galaga

Galaga

1981 Arcade Source available Online

Galaga (Namco, 1981) is the sequel to Galaxian and one of the most celebrated fixed shooters of the golden age of arcade games: your fighter holds the bottom of the screen while formations of alien insects sweep in, and a captured fighter can be recovered to fly as a dual ship. This build runs the original arcade board in the browser, three Zilog Z80 CPUs and the Namco custom chips, compiled from C++ to WebAssembly, and boots straight into the game’s attract mode. It is wired to the emulators.org in-frame debugger so you can single-step the main Z80, read and write its registers and the full 64K memory (video RAM sits at 0x8000), and set execution breakpoints and write watchpoints.

Visit the source repository ↗

Visit the official site ↗

Runs on: Web browser

Galaga Online Emulator

Play Galaga using JavaScript directly in your browser.

Configurations

ConfigurationEmulatorMachineOSLegal
GalagaGalagaGalagagreyOpen ⛶

Machine emulated

The Galaga arcade board (Namco, 1981) - three Zilog Z80 CPUs at 3.072 MHz sharing one 64 KB address space, the Namco 05xx/06xx I/O bus and the Namco 51xx / 54xx custom chips (emulated as real MB88xx microcontrollers), a hardware starfield, an 8×8 tile background and up to 64 sprites, scanned as a 224×288 raster rotated 90° in the upright cabinet. It is the sequel to Galaxian and a landmark of the golden age of arcade video games.

Chips

Notes

Embedding

Galaga is the 1981 Namco arcade machine: three Zilog Z80 CPUs at 3.072 MHz sharing one 64 KB address space, driving a 224×288 raster rotated 90° in the upright cabinet. This build compiles the C++ emulation core from paolosev/galaga to a self-contained WebAssembly module with Emscripten and drives it from a host-owned loop.

Boot. The core is exposed to JavaScript through Emscripten embind. Creating the machine loads the program ROMs, resets all three CPUs and the custom chips, and the board comes up in attract mode:

var galaga = new Module.GalagaMachine();   // loads ROMs, resets 3 Z80s + customs
galaga.Run(16, function(video, audio){    // advance ~one 60Hz field
  image.data.set(video);                  // 224x288 RGBA, already rotated
  ctx.putImageData(image, 0, 0);
});

The machine object. GalagaMachine presents the whole cabinet as a handful of methods:

MemberKindWhat it does
Run(ms, cb)methodRun every device forward by ms of emulated time, then hand back the rotated 224×288 RGBA frame and the audio samples through cb.
set_MoveLeft/Right(b), set_Button1(b)methodDrive player-one joystick and fire into the Namco 51xx input latch.
set_InsertCoin(b), set_Start1Player/Start2Player(b)methodThe coin slot and the 1P/2P start buttons.
DbgStepInsn(), DbgPeek(a) / DbgPoke(a,v), DbgGetReg/SetRegmethodThe debugger surface added for emulators.org, one main-CPU instruction, side-effect-free memory, and the main Z80's registers (see the Debugger note).

Video. Each animation frame the loop calls Run with the elapsed wall-clock time (capped at 67 ms). The core renders the starfield, the tile background and the sprites into an off-screen buffer, rotates it to the cabinet's portrait orientation and returns it as a Uint8Array that aliases directly into the WebAssembly heap.

Debugger integration

The Galaga core runs frame-at-a-time inside WebAssembly, so the debugger's single-step, breakpoints and watchpoints are not reachable from the original code. Following the runbook's guidance, the core was extended: a small set of Dbg… methods was added to the C++ and exported through embind, all operating on the main Z80 (the CPU that runs the game).

window.EMU_BOOT.transport maps the shared debugger's controls onto those methods:

  • pause / resume / isPaused - stop or restart the requestAnimationFrame loop that calls Run.
  • stepInsn(n) - DbgStepInsn() runs exactly one instruction of the main Z80 (mirroring the core's own fetch/execute, honouring a pending IRQ/NMI) and returns the new PC. Single-step always makes progress, even off a breakpoint.
  • step(n) - advance n whole 60 Hz fields.
  • breakpoints - a std::set of PC values checked at the top of the main Z80's execute loop; a match aborts the timeslice and pauses before the instruction runs.
  • watchpoints - the main CPU's memory-write path (MainCpu::WriteMemory) is instrumented so a write to a watched address pauses the loop.

Registers are read and written live through DbgGetReg/DbgSetReg (A F B C D E H L, IX IY SP PC I R, plus the S Z H P/V N C flags derived from F). Memory views read through DbgPeek, which returns program ROM below 0x4000 and RAM/video-RAM above it without touching the I/O ports, so inspecting memory never disturbs the machine. A per-frame DbgConsumePause() tells the host loop whether a breakpoint or watchpoint fired. The plug-in (galaga-debug.js) feeds all of this to EmuKit.defineMachine and reuses the shared z80 disassembler at /debugger/src/cpus/z80.js.

Architecture

The Galaga board (Namco, 1981) is unusually rich for its era - three Z80s and a set of Namco custom chips, all modelled by the core:

  • Main CPU - Z80 running the game; 16 KB of program ROM at 0x0000, shared work and video RAM from 0x8000. This is the CPU the debugger targets.
  • Sub CPU - a second Z80 for game logic and object handling, sharing the same RAM.
  • Sound CPU - a third Z80 driving the Namco 3-channel wavetable sound generator.
  • Namco 51xx / 54xx - input/coinage and noise custom chips, emulated here as real MB88xx 4-bit microcontrollers, which is why the machine passes its power-on self-test and reaches attract mode.
  • Namco 05xx / 06xx - the I/O bus controller that ties the customs to the main CPU at 0x7000.
  • Video - a hardware starfield, a 8×8 tile background and up to 64 sprites, coloured through PROM look-up tables and scanned as a 224×288 portrait raster.

A latch at 0x6820 enables each CPU's interrupt and holds the sub/sound CPUs in reset until the main CPU has finished its self-test, the sequence the host loop reproduces every field.