SearchA-ZB › Bally Astrocade

Bally Astrocade

2026 Z80 core · MIT Grey BIOS Online

The Bally Astrocade (1978, also sold as the Bally Professional Arcade and Bally Home Library Computer) is a Zilog Z80 driving a pair of Bally custom LSI chips: the "address" (data) chip that generates a 160×102 bitmap from 4 KB of screen RAM and provides the "magic" function-generator writes, and the I/O chip for sound and the controllers.

This is a purpose-built pure-JavaScript machine: the MIT-licensed DrGoldfire Z80 interpreter plus an original implementation of the Bally data chip written for emulators.org, so the whole Z80 is single-steppable in the shared in-page debugger. It self-hosts the real 8 KB on-board BIOS (a Bally system ROM, marked grey) and boots to the Astrocade's built-in menu.

Visit the project ↗

Visit the official site ↗

Runs on: Web browser

Bally Astrocade Online Emulator

Play Bally Astrocade using JavaScript directly in your browser.

Configurations

ConfigurationEmulatorMachineOSLegal
Astrocade built-in menuBally AstrocadeAstrocadegreyOpen ⛶
280 ZZZAPBally AstrocadeAstrocadegreyOpen ⛶
GalaxianBally AstrocadeAstrocadegreyOpen ⛶
Astro BattleBally AstrocadeAstrocadegreyOpen ⛶
Cosmic RaidersBally AstrocadeAstrocadegreyOpen ⛶

Chips

Notes

Embedding

The Bally Astrocade (1978, also sold as the Bally Professional Arcade and Bally Home Library Computer) is a Zilog Z80 driving a pair of Bally custom chips — the "address" (video/data) chip and the I/O chip. This build is a small, purpose-built machine assembled from self-hosted parts, so the whole Z80 is inspectable by the shared debugger:

  • Z80.js — Molly Howell's MIT-licensed Z80 interpreter (getState/setState/run_instruction/interrupt).
  • astrocade.js — an original implementation of the Bally data chip written for emulators.org: the 160×102 bitmap in 4 KB of screen RAM, the eight colour registers with the horizontal colour split, the "magic" function generator (shift / rotate / expand / flop / OR / XOR write modes), the 512-entry palette and the once-per-frame screen interrupt. Register semantics follow MAME's astrocde_v.cpp and the consumer memory/I-O map in astrohome.cpp.
var machine = new AstrocadeMachine({ bios: biosBytes, cart: cartBytes });
(function loop(){
  machine.runFrameFast();          // one frame of Z80 + data chip + screen INT
  machine.render(img.data); ctx.putImageData(img, 0, 0);
  requestAnimationFrame(loop);
})();

The magic register. The Astrocade has no framebuffer poke path in the usual sense: the CPU writes to the mirror region 0x0000-0x0FFF and the data chip transforms each byte (shift, rotate, 1→2 bit expand, mirror, OR/XOR) before storing it into screen RAM at 0x4000+offset. All of the BIOS menu and every game draw through it, so funcgenWrite() reproduces that pipeline exactly. Direct writes to 0x4000-0x4FFF bypass it.

The machine is plain objectsmachine.cpu.getState() / setState() expose the whole Z80; machine.readMem/writeMem the 64 KB bus; machine.screen the 4 KB bitmap; machine.colors the palette registers; machine.handle/keypad/knob the controller latches. Everything the debugger needs is reachable without touching the core.

Debugger integration

The debugger plug-in (astrocade-debug.js) reads the live machine from window.EMU_BOOT and calls EmuKit.defineMachine. The Z80 is disassembled by the shared z80 decoder (/debugger/src/cpus/z80.js) — no new decoder was needed.

Owning the loop. The boot shim owns the frame loop, so pause, resume and frame-step are ours. With no breakpoints set we run machine.runFrameFast(); with any set we run machine.runFrameStep(bps), checking the program counter before every instruction. Single-step calls cpu.run_instruction(). Write watchpoints wrap machine.writeMem and pause the loop when the CPU writes a watched bus address.

Registers. The Z80 state comes from cpu.getState(); the plug-in presents AF BC DE HL IX IY SP PC I R and the individual, writable flag chips, writing back through setState(). Memory is exposed side-effect-free: the 64 KB Z80 bus (hex + Z80 disassembly) and the 4 KB screen RAM (peekScreen, which never disturbs the data chip).

Input. The on-screen controller mirrors the real console: an eight-way joystick + trigger (hand-controller latch, ports 0x10-0x13), the knob nudge, and the numeric keypad (the 4×6 matrix read at ports 0x14-0x17) the boot menu is navigated with. Presses drive machine.press/release, which set the exact matrix bits.

Architecture

The Astrocade packed surprisingly capable graphics into a 1978 console by pairing a Z80 with two Bally custom LSI chips:

  • Z80 — the CPU at 1.789 MHz (the 14.318 MHz master clock divided by 8). On-board ROM 0x0000-0x1FFF, cartridge 0x2000-0x3FFF, screen RAM 0x4000-0x4FFF.
  • The address (data) chip — generates the 160×102 display from screen RAM, holds the eight colour registers (four either side of a programmable horizontal colour split, each choosing from 256 colours), and provides the "magic" function generator that transforms CPU writes on the way into video memory. It also raises the programmable screen interrupt.
  • The I/O chip — three tone channels, a noise/vibrato generator and the controller/keypad/knob inputs. Sound is silent here for headless use.
  • Controllers — four hand controllers, each an eight-way joystick that is also a 256-position knob (paddle) with a trigger, plus a 24-key console keypad.

The 8 KB on-board ROM contains a menu plus built-in programs (a calculator, a doodle/scribbling program and games), which is what this default configuration boots to. Because the whole machine is ordinary JavaScript and the CPU is a straight interpreter, the entire state is inspectable and pokeable at runtime.