SearchA-ZZ › Zaxxon

Zaxxon

1982 Arcade Grey · Sega ROMs Online

Zaxxon (Sega, 1982) is the pioneering isometric-scrolling shooter and the first arcade game to show its action in a three-quarter axonometric view: you pilot a fighter over and through a fortress and into deep space, judging altitude against your shadow to skim walls, clear force fields and refuel. This build is a from-scratch emulation of the Sega arcade board in the browser: a single Zilog Z80 main CPU that runs the game, driving the huge isometric background pixmap, the 32×32 sprite hardware and a two-bit foreground character layer coloured through resistor-DAC PROMs. It boots straight into its self-test and attract mode, and is wired to the emulators.org in-frame debugger, so you can single-step the Z80, read and write its registers and the 64K memory, and set execution breakpoints and write watchpoints.

Board ported from MAME's sega/zaxxon.cpp ↗

Visit the official site ↗

Runs on: Web browser

Zaxxon Online Emulator

Play Zaxxon using JavaScript directly in your browser.

Configurations

ConfigurationEmulatorMachineOSLegal
ZaxxonZaxxonZaxxongreyOpen ⛶
Zaxxon (set 2)ZaxxonZaxxongreyOpen ⛶

Machine emulated

The Zaxxon arcade board (Sega, 1982) — a single Zilog Z80 at about 3.04 MHz driving Sega's isometric video hardware: a 256×4096-pixel scrolling background pixmap that gives the game its signature three-quarter view, up to 32 of the 32×32 three-bit sprites, an 8×8 two-bit foreground character layer for the score and text, and colour through resistor-DAC PROMs. The raster is scanned 256×224 and rotated 90° in the upright cabinet. Zaxxon was the first arcade game to advertise on television and a landmark of early pseudo-3D presentation.

Chips

Notes

Embedding

Zaxxon is Sega's 1982 arcade machine: a single Zilog Z80 main CPU at about 3.04 MHz that runs the game, plus a Sega sample/PSG sound board (not synthesised here). This build is a from-scratch JavaScript emulation whose video board is a port of MAME's sega/zaxxon.cpp and sega/zaxxon_v.cpp. The Z80 core is DrGoldfire's MIT Z80.js. The whole board runs from a host-owned requestAnimationFrame loop, so the debugger can pause and single-step it.

Boot. Constructing the machine decodes the character / background / sprite graphics once, builds the colour palette from the PROMs, resets the Z80 and starts the loop; the board comes up in its RAM self-test and then attract mode:

var m = new ZaxxonMachine({ maincpu, colorcodes });  // decode GFX, build palette, reset Z80
function frame(){                                // one 60 Hz field
  for (var c = 0; c < CYCLES; ) c += m.cpu.run_instruction();
  m.vblank();                                 // raise the Z80 IRQ if interrupts are enabled
  m.renderTo(buf32);                           // draw the 224x256 rotated frame
}

The machine object. Everything the host and debugger need is a field or method on the machine:

MemberKindWhat it does
m.cpufieldThe Z80 core (DrGoldfire Z80.js). Its state is read and written as one object through getState() / setState(), and it steps one instruction with run_instruction().
m.read(a) / m.write(a,v)methodThe Z80 memory bus. read is side-effect-free (it never disturbs the input latches), so the debugger's memory views use it directly.
m.renderTo(buf32)methodRender one whole frame — background pixmap, sprites, foreground characters — into a 224×256 Uint32Array, already rotated 90° for the upright cabinet.
m.setInput(port, mask, down) / m.insertCoin(slot)methodDrive the joystick / fire / start bits into the IN0/IN2 latches and pulse a coin.
m.watchSet / m.watchHitfieldA Set of watched write addresses and the flag m.write raises when one is hit — the host loop's watchpoint hook.
EMU_BOOT.transportfieldThe pause / resume / step / breakpoint / watchpoint surface the shared debugger drives.

Video. Zaxxon's isometric background is a huge 256×4096-pixel pixmap assembled once from the tilemap ROM; each field the renderer scrolls a 256×224 window through it, then draws the 32×32 three-bit sprites and the 8×8 two-bit foreground characters on top. The native 256×224 index buffer is rotated 90° (ROT90, with a cocktail flip bit) into the 224×256 canvas, colouring every pixel through the resistor-DAC palette built from the colour PROMs.

Debugger integration

Because the whole board is ordinary JavaScript and the host owns the run loop, the debugger's controls need no changes to the CPU core: the loop can pause, single-step and check breakpoints between any two instructions. window.EMU_BOOT.transport maps the shared debugger onto the Z80:

  • pause / resume / isPaused — stop or restart the requestAnimationFrame loop.
  • stepInsn(n) — run exactly n instructions through the core's run_instruction() entry; single-step always makes progress, even sitting on a breakpoint.
  • step(n) — advance n whole 60 Hz fields (each a full timeslice of Z80 instructions followed by the vblank IRQ), then redraw.
  • breakpoints — a Set of PC values. When it is non-empty the loop drops into an instruction-at-a-time timeslice and compares getState().pc before each instruction, pausing before the matched instruction runs.
  • watchpoints — the machine's single memory-write path (m.write) tests each address against m.watchSet and raises m.watchHit; the loop notices the flag and pauses on the write.

The registers window reads the Z80 core's state live and writes each field straight back: A and F, the B C D E H L bytes and their BC/DE/HL/AF pairs, the IX/IY index registers, SP, PC, the interrupt vector I and refresh R, and the S Z H P/V N C flags (each toggled independently). Register writes go through getState()/setState() so a single edit never clobbers the rest of the machine state. Memory views read through m.read, which returns program ROM, work RAM, video RAM, sprite RAM and the input ports without side effects, so inspecting memory never latches a phantom coin. The disassembler is the shared z80 decoder at /debugger/src/cpus/z80.js — reused unchanged, since the Z80 is already a first-class debugger CPU. The four memory chips exposed are the 64K CPU bus, the 24K program ROM, the 1K video RAM and the 256-byte sprite RAM.

Architecture

Zaxxon (Sega, 1982) is one of the first arcade games with an isometric (axonometric) three-quarter view, giving the illusion of flying over a 3-D fortress. The board is built around a single 8-bit CPU and Sega's tile/sprite video hardware:

  • Main CPU — Zilog Z80 at roughly 3.04 MHz. Program ROM at 0x0000–0x5fff, 4 KB work RAM at 0x6000, 1 KB foreground video RAM at 0x8000, 256 bytes of sprite RAM at 0xa000, the input ports and dip switches in the 0xc000 page, and the coin latch (U55) and video control latch (U56) in the 0xc000/0xe000 pages. A vblank IRQ each field drives the game. This is the CPU the debugger targets.
  • Sound — a Sega discrete/sample sound board triggered through an 8255 PPI; it is not synthesised in this build (the game plays silently), but the CPU-side latches are accepted so the game logic runs unchanged.
  • Background — the signature isometric scroll: a 256×4096-pixel pixmap of 8×8 three-bit tiles, assembled once from a 32 KB tilemap ROM, scrolled diagonally by the video control latch's 11-bit position register. A BEN bit enables it and a CREF bit selects its colour bank.
  • Sprites — up to 32 sprites, each a 32×32 three-bit object with independent X/Y flip, drawn from the 256-byte sprite RAM.
  • Foreground — an 8×8 two-bit character tilemap (score and text) over the whole screen, transparent on pen 0, its per-column colour taken from a colour-code PROM.
  • Palette — a 256-entry colour PROM turned into RGB by a resistor DAC (three bits each for red and green over 1000/470/220 Ω, two bits for blue over 470/220 Ω); a second colour-code PROM selects the foreground colours.

A 74LS259 addressed latch (U56) holds the interrupt-enable, background-enable, the two colour-reference bits and the background scroll position; a second latch (U55) holds the coin counters and the cocktail flip bit. The graphics ROMs are decoded to one-byte-per-pixel tiles and sprites once at boot.