Atari 5200
A browser emulator of the Atari 5200 SuperSystem, Atari's 1982 console. The 5200 is Atari 8-bit hardware in a console shell - a 6502 driving the ANTIC, GTIA and POKEY chips - so this build reuses the cycle-exact Sfotty Pie chips and adds a purpose-built 5200 memory map and analog controller. It runs entirely in the page and plugs into the shared in-browser 6502 debugger: live registers, side-effect-free memory, single-instruction step, breakpoints and write watchpoints.
It boots the open AltirraOS 5200 replacement BIOS and a bundled homebrew cartridge, with an on-screen controller (the analog stick as a d-pad, Fire, the 12-key keypad and Start/Pause/Reset) and physical-keyboard input.
Atari 5200 Online Emulator
Play Atari 5200 using JavaScript directly in your browser.
Controls
Configurations
| Configuration | Emulator | Machine | OS | Legal | |
|---|---|---|---|---|---|
| Atari 5200 — Hello demo | Atari 5200 | Atari 5200 | open | Open ⛶ | |
| Atari 5200 — Character set | Atari 5200 | Atari 5200 | open | Open ⛶ |
Machines emulated
Chips
Notes
Embedding
The 5200 is Atari 8-bit hardware (6502 + ANTIC/GTIA/POKEY) in a console shell, so this emulator is assembled from the Sfotty Pie chips — the cycle-exact @sfotty-pie/sfotty 6502 and the @sfotty-pie/a8 ANTIC/GTIA and POKEY — driven by a small 5200 machine written for this site. Only two things differ from an Atari 800: the memory map and the controllers. Both packages are TypeScript, so the boot entry is bundled with esbuild (--format=esm) into atari5200-boot.js, loaded as <script type="module">, and driven from a loop we control so it can be paused and single-stepped.
Boot. Construct an Atari5200 with the 2K BIOS, insert a cartridge, then run one machine cycle at a time and blit the frame through the Atari palette:
import { Atari5200 } from "./core/a8/machine5200.ts";
const machine = new Atari5200(bios, "ntsc");
machine.mmu.setCartridge(cart); // 4K/8K/16K/32K, mirrored to fill $4000-$BFFF
const palette = paletteFor("ntsc"); // 0xAABBGGRR — canvas-ready
(function frame(){
for (let c = 0; c < 29868; c++) machine.cycle(); // one NTSC frame of colour clocks
for (let i = 0; i < n; i++) img32[i] = palette[machine.frame[base + i]];
ctx.putImageData(img, 0, 0); requestAnimationFrame(frame);
})();
The machine is plain objects. Everything the debugger needs is a live property — no wasm heap to reach into:
| Member | Kind | What it does |
|---|---|---|
machine.cycle() | method | Run one whole machine cycle (ANTIC + POKEY + the CPU's bus access). |
machine.cpu | field | The Sfotty 6502: A X Y S PC and the flags are get/set properties, with getP()/setP() and state (=DECODE at an instruction boundary). |
machine.mmu.peek(a) | method | Read the 5200 bus with no side effects (never touches a chip register) — what the hex and disassembly views use; poke(a, v) writes memory live. |
machine.mmu.pots | field | The eight POKEY pot values (0..228) that are the four controllers' analog axes; setStick(n, x, y) drives them from a d-pad. |
machine.setTrigger(n, down) | method | The controller's fire button — the GTIA trigger line. |
machine.pressKey(code) | method | Press a keypad scan code into POKEY's key scanner (digits, *, #, Start, Pause, Reset). |
Because the CPU, bus and RAM are ordinary JavaScript, the debugger single-steps by cycling to the next DECODE, reads and writes registers straight off machine.cpu, and reads memory side-effect-free through mmu.peek — with no changes to the emulator core.
Debugger integration
Two pieces of custom work put the 5200 into the shared in-browser debugger, both without forking the reused chips.
1 · A purpose-built 5200 memory map. The 5200 relocates every chip and shrinks RAM, so it needs its own bus rather than the vendored Atari-800 Mmu. Mmu5200 implements the same Sfotty Memory interface (so the 6502 and ANTIC take it as their bus unchanged) and routes:
$0000-$3FFF 16K RAM
$4000-$BFFF cartridge ROM (smaller carts mirror up)
$C000-$CFFF GTIA // the AnticGtia object decodes any non-$D4 page as GTIA,
$D400-$D4FF ANTIC // so $C0xx lands on the GTIA registers with no remap
$E800-$EFFF POKEY // decoded on the low nibble
$F800-$FFFF 2K BIOS ROM
2 · The controllers. The 5200's analog stick is two POKEY pots. The vendored POKEY does not scan pots, so Mmu5200 answers POT0-7 reads from a synthesised stick value; a digital d-pad drives those pots to their extremes. Fire is a GTIA trigger line; the 12-key keypad and Start/Pause/Reset reach POKEY's real 15KHz key scanner through the shared key matrix, so KBCODE and the key senses follow from the scan exactly as on the console.
Techniques for deeper access — all through the reused chips, no fork:
- Side-effect-free reads.
mmu.peek(addr)serves RAM/cart/BIOS bytes and reports the chip-register windows as the undriven bus, so auto-polling the hex view can never trip a GTIA/POKEY read side effect. - Direct state. Registers are plain get/set properties on the
SfottyCPU (A X Y S PC, the flags,getP/setP), read and written live. - Instruction step. One
cycle()is a single colour clock; cycling untilcpu.state === DECODEadvances exactly one instruction. - Breakpoints. With any set, the loop steps instruction-by-instruction and halts when
cpu.state === DECODE && PC ∈ breakpoints. - Watchpoints. The write path checks each store against the watch set and trips the loop — usefully covering the chip registers a program pokes, not just RAM.
Everything the debugger shows — register read/write, memory hex/disassembly, follow-PC, single-step, breakpoints and watchpoints — is built from these.
Architecture
The Atari 5200 SuperSystem (Atari, 1982) is essentially an Atari 400 in a console shell: the same chip set, no keyboard, and a shrunk memory map with analog controllers. This emulator hangs the reused Sfotty Pie chips off a 5200 bus:
Sfotty(@sfotty-pie/sfotty) — an NMOS 6502 verified cycle-by-cycle against the SingleStepTests/65x02 suite; all documented and undocumented opcodes.AnticGtia— the combined ANTIC display-list processor and GTIA video chip, identical to the 800's, rendered into the framebuffer one colour clock at a time. On the 5200 GTIA answers at $C000 and ANTIC at $D400.Pokey— the POKEY audio, timers and 15KHz key scanner; on the 5200 it also carries the analog-stick pots and the controller keypad.Mmu5200— the 5200 memory map (16K RAM, the $4000-$BFFF cartridge window, the relocated chips, the 2K BIOS) plus the pot/trigger/keypad wiring. There is no PIA and no SIO — the console has neither.- ROM — Avery Lee's open AltirraOS 5200 replacement BIOS (2K), bundled; no original Atari firmware is used. It holds the 6502 vectors, the boot logo, and the character set the demos point
CHBASEat.
machine.cycle() steps ANTIC scheduling, POKEY and the bus phase (ANTIC DMA or the CPU) in lockstep, rendering as it goes; POKEY is the console's only /IRQ source. Because every component is an ordinary object, the whole machine state is inspectable — which is what the debugger reads each refresh.