Search › A-Z › W › Williams Arcade
Williams Arcade
Williams Arcade is Williams Electronics' second-generation arcade board (1980–82): a Motorola 6809 driving a bitmap display, a hardware blitter and 6821 PIAs. This build runs the board in the browser, a pure-JavaScript machine model plus an MIT 6809 core, and boots Robotron: 2084 (Vid Kidz / Williams, 1982) straight into attract mode, with Joust as a sibling on the same hardware. It is wired to the emulators.org in-frame debugger so you can single-step the 6809, read and write the registers and the full 64K memory, set execution breakpoints and write watchpoints, and use the on-screen twin-stick pad.
Runs on: Web browser
Williams Arcade Online Emulator
Play Williams Arcade using JavaScript directly in your browser.
Controls
Configurations
| Configuration | Emulator | Machine | OS | Legal | |
|---|---|---|---|---|---|
| Robotron: 2084 | Williams Arcade | Williams | grey | Open ⛶ | |
| Joust | Williams Arcade | Williams | grey | Open ⛶ |
Machine emulated
The Williams arcade board (1980–82) - a Motorola 6809 at ~1 MHz with 48 KB of RAM, up to 48 KB of bank-switched ROM and 1 KB of battery-backed CMOS. Its 304×256, 16-colour bitmap lives directly in RAM, drawn by a custom hardware blitter, and the monitor is turned 90° in the cabinet. It ran Defender, Stargate, Robotron: 2084, Joust, Bubbles and Sinistar.
Chips
Notes
Embedding
The Williams "6809" board (Defender, Stargate, Robotron, Joust, Bubbles, Sinistar) is a single Motorola 6809 at ~1 MHz driving a 304×256, 16-colour bitmap held directly in main RAM, with a hardware blitter for fast sprite copies and a pair of 6821 PIAs for the controls. This build vendors the pure-JavaScript machine model from 8bitworkshop (GPL-3.0) together with Martin Maly's MIT CPU6809 core, and drives them from a loop the host owns so the debugger can control the machine.
Boot. The 0xC000-byte program image is loaded (Robotron by default), the CPU is pointed at the memory bus and reset through the $FFFE vector, and it runs its self-test straight into attract mode:
var m = new WilliamsMachine({ isDefender: false });
m.loadROM(WILLIAMS_ROMS['robotron']); // 12 x 4K program ROMs, concatenated
m.cpu.init(write, m.membus.read, 0); // bind bus + reset (reads $FFFE)
m.banksel = 1; // ROM banked in at $0000-$8FFF
(function loop(){ m.advanceFrame(); requestAnimationFrame(loop); })();
The machine is plain objects. Everything the debugger needs is a method or field on the machine or its CPU:
| Member | Kind | What it does |
|---|---|---|
m.advanceFrame(trap) | method | Run one 304-line video field, firing the quarter-screen IRQs the game times on. trap() is polled before every instruction so the host can stop on a breakpoint or watchpoint. |
m.cpu.advanceInsn() | method | Execute exactly one 6809 instruction and return its cycle count, the single-step primitive. |
m.cpu.saveState() / m.cpu.set(reg,v) | method | Read the whole register file (PC A B X Y U SP DP CC) and write any register back, how the debugger shows and edits registers. |
m.read(a) / m.write(a,v) / m.readConst(a) | method | Live bus access and a side-effect-free read (the $C000-$CBFF I/O window is skipped) for the memory views. |
m.ram / m.rom / m.nvram / m.palette | field | The 48K work+video RAM, the 48K program ROM, the 1K CMOS and the 16-entry palette, as plain arrays. |
m.pia6821 / m.setSwitch(i,mask,down) | field | The eight input latches and a helper to set/clear a control bit, how coins, start and the twin sticks reach the game. |
Video. Writes to $0000-$97FF land two 4-bit pixels each into a 256×304 buffer; the display is the Williams monitor rotated 90°, so the host un-rotates the buffer onto the canvas each field. Palette writes to $C000-$C00F repaint live.
Debugger integration
The debugger drives a host-owned run loop: because the 6809 interpreter runs one instruction at a time in JavaScript, the loop can pause, single-step and check breakpoints between any two instructions; no changes to the CPU core are needed beyond one added register setter.
window.EMU_BOOT.transport exposes the controls the shared debugger calls:
- pause / resume / isPaused - stop or restart the
requestAnimationFrameloop. - stepInsn(n) - call
cpu.advanceInsn()exactly n times and redraw, so a single step advances the PC by one instruction. - step(n) - advance n whole 60 Hz video fields (with their four quarter-screen IRQs).
- breakpoints - a
Setof PC values. When non-empty the frame loop runs instruction-by-instruction and pauses before executing an address in the set; when empty it runs a full field at speed, so an idle debugger costs nothing. - watchpoints - the CPU's memory-write path is wrapped (the core is re-
init'd with a write shim), so a store to a watched address pauses the loop. This is the one place the core is extended.
The plug-in (williams-debug.js) reads these hooks and calls EmuKit.defineMachine with the full 6809 register set (read from saveState(), written through cpu.set(), with the E F H I N Z V C flags decoded from CC), memory chips for the 64K CPU bus / RAM / ROM / CMOS using the shared m6809 disassembler, and a custom twin-stick control view. Memory reads for the views use readConst, which skips the I/O window so auto-polling never ticks the video counter or a PIA.
Architecture
Williams' second-generation arcade board is one Motorola 6809 with 48 KB of RAM, up to 48 KB of ROM (bank-switched over the low RAM), 1 KB of battery-backed CMOS and two signature custom parts, all modelled here as plain JavaScript on WilliamsMachine:
- CPU - the 6809, with the whole 64 KB memory map built from range decoders.
$0000-$8FFFis RAM or banked ROM (a write to$9000flips the bank);$9800-$BFFFis work RAM;$C000-$CFFFis the I/O page;$D000-$FFFFis fixed ROM. - Blitter - the "special chip" DMA copier: eight registers at
$CA00describe a source, destination, width, height and a flags byte (transparency, solid fill, shifted pixels, X/Y mirroring); one write to$CA00runs the copy that draws every sprite. - Video - no framebuffer chip: the CRT simply scans
$0000-$97FF, one byte per two horizontal-nibble pixels, through a 16-entryRRRGGGBBpalette at$C000. A quarter-screen interrupt fires four times a field for split-screen timing. - I/O - two 6821 PIAs carry the coin door, start buttons and the joysticks; on the real board a second 6808 + DAC plays sound (dropped in this silent build).
- CMOS - 1 KB of non-volatile RAM at
$CC00holds bookkeeping and high scores; a watchdog resets the board if the game stops kicking it.
Robotron: 2084 (Vid Kidz / Williams, 1982) uses this board with two 8-way joysticks - one to run, one to fire - and it is the default boot here; Joust (1982) is the same hardware and ships as a sibling config.