Search › A-Z › M › Missile Command
Missile Command
Missile Command (Atari, 1980), designed by Dave Theurer, is the trackball defence classic in which you fire from three missile bases to protect six cities from an accelerating rain of ballistic missiles, smart bombs and bombers. This build runs the original Atari board in the browser: a MOS 6502 driving a bitmapped raster display, with the original ROMs. It boots straight into attract mode, the demo defending its cities under the falling missiles, and is wired to the emulators.org in-frame debugger so you can single-step the 6502, read and write the registers and the whole memory map, watch the bitmap frame buffer, and set execution breakpoints and write watchpoints.
Runs on: Web browser
Missile Command Online Emulator
Play Missile Command using JavaScript directly in your browser.
Controls
Configurations
| Configuration | Emulator | Machine | OS | Legal | |
|---|---|---|---|---|---|
| Missile Command | Missile Command | Missile Command | grey | Open ⛶ |
Machine emulated
The Missile Command arcade board (Atari, 1980) is a single MOS 6502 at 1.25 MHz driving a bitmapped raster display: a 256×231 frame buffer held directly in the RAM the CPU shares with the video hardware, three colour bits per pixel from an eight-entry palette. Designed by Dave Theurer, it became one of Atari's biggest hits, its trackball crosshair and three-base defence a defining Cold-War arcade experience. The unusual "MADSEL" hardware lets the 6502 plot individual pixels through (zero-page,X) instructions whose pointer is a pixel address.
Chips
Notes
Embedding
Missile Command is a single MOS 6502 at 1.25 MHz (10 MHz / 8) driving a bitmapped raster display: 256×231 visible pixels, three colours per pixel from an eight-entry palette. This build vendors a self-hosted machine (no CDN): a JavaScript port of Mike Chambers' public-domain Fake6502 core, our model of the Atari bus / bitmap video / palette hardware, and the original Atari program ROMs, driven from a host-owned loop so the debugger can control it.
Boot. The 12 KB of program ROM loads at $5000–$7FFF. The board only decodes 15 address bits (global mask $7FFF), so the 6502's reset vector at $FFFC folds down to $7FFC; the CPU starts at $7B4B and drops straight into attract mode:
var m = new MissileMachine(); // loads ROM, builds 6502 + bitmap video
m.reset(); // pulls the reset vector at $FFFC (-> $7FFC -> $7B4B)
// one frame: 4 IRQ slices (~240 Hz), clocked off 32V, then render the bitmap
for (var s = 0; s < 4; s++) { m.tickTrackball(); m.cpu.irq(); runCycles(4800); }
m.renderTo(ctx, W, H);
The machine is plain objects. Everything the host and debugger need is a field or method on the machine or its CPU:
| Member | Kind | What it does |
|---|---|---|
m.cpu.step() | method | Fetch, decode and run one 6502 instruction; returns its cycle count. The single-step primitive. |
m.cpu.irq() | method | Request the maskable interrupt -- the ~240 Hz tick (32V, four assertions per 60 Hz frame) that drives the game. |
m.renderTo(ctx,w,h) | method | Draw the current frame: walk the 256×231 bitmap out of RAM, resolve each 3-bit pixel through the palette, and blit it to the canvas. |
m.dbgRead(a) / m.memWrite(a,v) | method | Side-effect-free read and the CPU write path -- what the debugger's memory views read and poke. |
m.setInput(id,down) | method | Drive a control (trackball up/down/left/right, the three base fires, coin, start) into the input latches. |
m.cpu.a/x/y/sp/pc/flags | field | The live 6502 registers, read and written directly. |
Video. RAM $0000–$3FFF is the frame buffer: 256 lines of 64 bytes, 4 pixels per byte. The bottom 32 lines carry a scattered 3rd colour bit. Each frame the loop runs one display's worth of 6502 (four IRQ slices), then renders the bitmap straight from that RAM; the zero page and stack live in the top, undisplayed, lines exactly as on the real board.
Debugger integration
The debugger drives a host-owned run loop: because the 6502 interpreter runs one instruction at a time, the loop can pause, single-step and check breakpoints between any two instructions. window.EMU_BOOT.transport exposes the controls the shared debugger calls:
- pause / resume / isPaused -- stop or restart the
requestAnimationFrameloop. - stepInsn(n) -- call
cpu.step()exactly n times and redraw, so a single step advances the PC by one instruction. - step(n) -- advance n whole frames (each with its four IRQ slices).
- breakpoints -- a
Setof PC values. When non-empty the loop runs instruction-by-instruction and pauses before executing a watched address; when empty it runs a frame at speed, so an idle debugger costs nothing. - watchpoints -- every framebuffer / RAM write funnels through one
poke(); it flags a hit when a watched address is written and the loop pauses on it. Registers are ordinary JavaScript and the RAM map is exposed side-effect-free (the POKEY RNG and the VBLANK bit are computed only on the live read path, never ondbgRead).
Extending the core for MADSEL. Missile Command's video is the interesting bit: the game plots pixels with LDA/STA (zero-page,X), and the hardware's "MADSEL" logic reinterprets that operand access as a pixel address into video RAM (a read-modify-write that changes just the addressed pixel). We reproduce it with a one-flag extension to Fake6502: indx() raises cpu.madsel after computing the 16-bit pointer, and the machine's read/write callback consumes it on the single operand access that follows, routing it through vramMadRead/vramMadWrite (2 colour bits at addr>>2, plus the scattered 3rd bit for the bottom of the screen). A neat trick for this hardware: put a write watchpoint on a frame-buffer byte and single-step -- you catch the exact instruction that lights a pixel, whether it arrived by a direct RAM store or a MADSEL plot.
The plug-in (missilecmd-debug.js) reads these hooks and calls EmuKit.defineMachine with the 6502 register set bound to the shared mos6502 disassembler, three memory chips (the CPU bus, the program ROM and the bitmap frame buffer), and an on-screen gamepad (trackball D-pad + three base fires + coin/start).
Architecture
Missile Command (Atari, 1980) is a raster board unlike its tilemap siblings: a single MOS 6502 at 1.25 MHz painting a full bitmap. Modelled here as plain JavaScript objects:
- CPU -- a port of Fake6502 (NMOS 6502 with BCD, which the score uses), reaching memory only through the machine's
memRead/memWrite, so the bus and I/O live in one place. Partial address decode is modelled by masking every normal access to 15 bits, which folds the CPU vectors into ROM. - Video -- a 256×231 bitmap held in RAM
$0000–$3FFF(64 bytes per line, 4 pixels per byte, 2 colour bits packed as bit p and bit p+4). The bottom 32 lines gain a 3rd colour bit stored in a scattered low-RAM region. Colour is an eight-entry write-only palette RAM (1 bit each of R, G, B). - MADSEL -- the pixel plotter:
(zp,X)operand accesses are re-routed to a pixel-addressed video path (vramaddr = pixaddr >> 2) with per-pixel read-modify-write masks, exactly as the board's write-mask PROM dictates (computed analytically here and verified against the dumped PROM). - Bus / I/O -- the frame-buffer RAM, two 8-way DIP banks (game options via the POKEY pot pins, pricing at
$4A00), the trackball counter port and its direction lines, the three fire buttons, coin/start latches, the CTRLD / flip-screen output latch, and the POKEY (random-number register modelled; sound stubbed). - ROMs -- 12 KB of 6502 program (six 2 KB mask ROMs) plus a 32-byte write-mask PROM (reproduced analytically).
The one piece of timing the game truly needs is its IRQ, clocked off 32V about four times per 60 Hz frame; the host loop reproduces exactly that -- four IRQ slices per frame -- and renders the bitmap at the end of each frame.