Bosconian
Bosconian (Namco, 1981) is a free-roaming multidirectional shooter: instead of a fixed screen, your fighter flies through open space, destroying enemy “I/O” bases and dodging asteroids, mines and a pursuing spy-ship formation, with a radar scanner showing the whole battlefield. This build runs the original arcade board in the browser — three Zilog Z80 CPUs and the Namco custom chips, re-implemented from scratch in JavaScript around the reused MIT Z80 core — and boots straight into the game’s attract mode. It is wired to the emulators.org in-frame debugger so you can single-step the main Z80, read and write its registers and the full 64K memory (video RAM sits at 0x8000), and set execution breakpoints and write watchpoints.
Runs on: Web browser
Bosconian Online Emulator
Play Bosconian using JavaScript directly in your browser.
Controls
Configurations
| Configuration | Emulator | Machine | OS | Legal | |
|---|---|---|---|---|---|
| Bosconian | Bosconian | Bosconian | grey | Open ⛶ |
Machine emulated
The Bosconian arcade board (Namco, 1981) - three Zilog Z80 CPUs at 3.072 MHz sharing one 64 KB address space, two Namco 06xx I/O buses driving the Namco 51xx / 50xx custom chips, the Namco 05xx hardware starfield, an 8×8 tile playfield with a radar strip, and up to six 16×16 sprites, scanned as a 288×224 horizontal raster. It is the free-roaming shooter that followed Galaxian and Galaga on Namco's custom-chip hardware.
Chips
Notes
Embedding
Bosconian is Namco's 1981 free-roaming arcade shooter. Its board is unusually rich for the era: three Zilog Z80 CPUs at 3.072 MHz that share one 64 KB address space (all RAM above 0x6800 is common to the three), plus a set of Namco custom chips reached through two Namco 06xx bus controllers. This build is a from-scratch JavaScript emulation whose board is a port of MAME's namco/galaga.cpp (the bosco driver), namco/bosco.cpp and starfield_05xx.cpp. All three Z80 cores are Molly Howell's MIT Z80.js (the same core reused across the site's Z80 machines). The whole board runs from a host-owned loop, so the debugger can pause and single-step it.
Boot. Constructing the machine fetches the ROMs, decodes the character / sprite / dot graphics and the colour PROMs, resets the main Z80 and starts the loop; the main CPU runs its power-on RAM check (the familiar Bosconian test pattern), releases the two sub-CPUs and comes up in attract mode:
var m = new Bosconian({ canvas, romBase, manifest });
m.boot(); // fetch ROMs, decode GFX + PROMs, reset the 3 Z80s, run
// each animation frame runs one 60Hz field of all three Z80s, then draws the screen
The machine object. Everything the host and debugger need is a field or method on the machine:
| Member | Kind | What it does |
|---|---|---|
m.cpu | field | The main Z80 core (the game, and the debugger target). Registers are read with getReg(name) / written with setReg(name,v) for A F B C D E H L, the AF/BC/DE/HL pairs, IX IY SP PC, and I R. |
m.sub / m.sub2 | field | The two sub-CPUs, held in reset by the main CPU until its self-test passes, then run in lockstep with it. |
m.dbgRead(a) / m.dbgWrite(a,v) | method | Side-effect-free read of the main 64K bus and the CPU write path -- what the debugger's memory views read and poke. |
m.setInput(id, down) | method | Drive a control (up, down, left, right, fire, coin, start1, start2, service) into the Namco 51xx input latch. |
EMU_BOOT.transport | field | The pause / resume / step / breakpoint / watchpoint surface the shared debugger drives. |
Video. The screen is drawn ROT0 (horizontal), 288×224: a 224-wide scrolling playfield on the left and a 64-wide radar strip on the right. Behind everything is the Namco 05xx hardware starfield (a 16-bit LFSR that emits pseudo-random coloured stars, scrolling in X and Y). On top sit a scrolling 32×32 playfield tilemap of 8×8 two-bit characters, up to six 16×16 sprites, an 8×32 radar tilemap repeated into the right strip, and the radar "bullet" dots. Colour is fixed in PROMs: a 32-entry palette PROM feeds a resistor-DAC, and a 256-entry lookup PROM maps each character / sprite pen into it.
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 of the main Z80. window.EMU_BOOT.transport maps the shared debugger onto it:
- pause / resume / isPaused -- stop or restart the
requestAnimationFrameloop. - stepInsn(n) -- run exactly n main-Z80 instructions through the core's
run_instruction()entry (honouring a pending 06xx NMI), then redraw. - step(n) -- advance n whole 60 Hz fields of all three Z80s, honouring the vblank IRQ and the periodic sub-CPU NMI. Because headless
requestAnimationFrameis throttled, driving fields withstep()is also how the machine is exercised under automation. - breakpoints -- a
Setof PC values checked before each main-Z80 instruction; a match pauses before the instruction runs. - watchpoints -- the shared memory-write path flags a hit when a watched address is written, and the loop pauses on it.
The stock Z80.js keeps its registers in a closure and only exposes a whole-core getState()/setState(). The vendored core is given two extra hooks -- get_pc() and set_pc() -- so the run loop can read PC before every instruction (for breakpoints) without allocating a state object, and the machine wraps getState/setState in focused getReg/setReg/getFlag/setFlag helpers that the plug-in binds to. Memory reads use the machine's side-effect-free dbgRead, which returns program ROM, the shared work RAM, the video RAM and the DIP switches but skips the 06xx custom-chip windows, so inspecting memory never nudges the Namco I/O chips. The Z80 disassembler is the shared decoder at /debugger/src/cpus/z80.js -- reused unchanged, since the Z80 is already a first-class debugger CPU.
Architecture
The Bosconian board (Namco, 1981) is the Galaga-family hardware, run on a horizontal (ROT0) monitor:
- Three Z80s -- a main CPU, a sub CPU and a sub-2 CPU, each a Zilog Z80 at 3.072 MHz (18.432 MHz / 6). Each has its own 16 KB program ROM at
0x0000–0x3fff; everything from0x6800up is shared -- the DIP switches, the Namco WSG sound registers, an ls259 latch at0x6820, the two 06xx custom-chip windows, the shared work RAM at0x7800, and the video RAM at0x8000. The main CPU is the debugger target. - Interrupts -- the main and sub CPUs take a vblank IRQ in interrupt mode 1 (RST 38h), each enabled by its own bit of the
0x6820latch; the sub-2 CPU takes a periodic NMI. Two more bits of the latch hold the sub CPUs in reset until the main CPU has finished its power-on self-test. - Namco 06xx ×2 -- bus controllers at
0x7000(driven by the main CPU) and0x9000(driven by the sub CPU). Each pulses an NMI at the CPU it serves to clock a byte in or out of the custom chip it has selected. - Namco 51xx / 50xx / 54xx / 52xx -- the custom I/O and sound chips. The 51xx is the input + coinage chip (emulated here at the same high level as MAME's original 51xx: it reads the joystick and buttons, counts coins into credits, remaps the 8-way stick, and enables the start buttons); the 50xx keeps the score; the 54xx (noise) and 52xx (speech) are sound chips, stubbed here.
- Video -- the Namco 05xx hardware starfield (a 16-bit LFSR clocked per pixel), a scrolling 32×32 playfield tilemap and an 8×32 radar tilemap of 8×8 two-bit characters, up to six multi-attribute 16×16 sprites, and the radar "bullet" dots. Colour comes from a 32-entry palette PROM through a resistor DAC, with a 256-entry lookup PROM mapping each layer's pen; the 05xx stars have their own 64-colour ramp.
Every animation frame the host loop runs one 60 Hz field of all three Z80s (interleaved in short quanta so they stay in step over shared RAM), services the vblank and NMI interrupts and the 06xx transfers, then composites the starfield, tilemaps, sprites and bullets into the 288×224 frame.
Sound
Pattern: chip synthesis. The from-scratch core emulates the whole board but originally stubbed its sound: writes to the Namco WSG registers at 0x6800–0x681f were discarded, so the machine ran silent. This integration wires those writes to the shared WSG chip (/debugger/src/chips/namco-wsg.js, the same chip Pac-Man and Dig Dug use) with the real 82s126 sound PROM, so any value the software writes to the WSG is synthesised and played. It is not the Galaga integration: that WebAssembly core hands finished audio back through its Run() callback, whereas this JavaScript core produces no audio buffer, so the chip is synthesised here.
The sound chip. Bosconian's melodic sound is the Namco 3-voice WSG (Waveform Sound Generator) — the same wavetable chip as Pac-Man and Galaga, mapped through MAME's namco_device::pacman_sound_w at 0x6800–0x681f (the galaga.cpp bosco driver). Three independent voices, each with a 20-bit phase accumulator, a 4-bit volume and a 3-bit selector into one of eight 32-step, 4-bit waveforms held in the board's 256-byte sound PROM. The emulation hooks the board's existing write decode: the line that used to drop the 0x6800–0x681f writes now calls wsg.write(addr - 0x6800, data).
Sample rate / pitch. The WSG's hardware update rate is 3.072 MHz / 32 = 96 kHz. Rather than run an internal 96 kHz loop and resample, each voice's accumulator is advanced directly at the host audio rate by freq × (96000 / EmuAudio.sampleRate) per output sample, so the pitch is exact and no resampling is needed. Every 60 Hz field the run loop renders exactly Math.round(EmuAudio.sampleRate / 60) mono samples, duplicates them to L+R, and pushes them to the shared sink as interleaved-stereo Int16 (EmuAudio.push).
Mute contract. window.EMU_BOOT.transport exposes isMuted()/setMute(m), delegated straight to EmuAudio. Audio starts muted (browsers block audio before a gesture); the shell's Sound button resumes the AudioContext and unmutes from a real click.
Silent by default. The bundled program, as run by this simplified from-scratch board, writes the WSG sound registers many thousands of times over a full attract loop and extended gameplay, but always with value 0. Its own sound-effect triggers are not fully reproduced in this core, so nothing drives the WSG and the machine stays silent. The WSG is fully wired, so the moment the software writes any non-zero value the chip sounds. The page starts muted; click the Sound button to enable audio.
Not emulated. The board's two discrete Namco custom sound chips, the 54xx explosion-noise generator and the 52xx speech chip (the "BLAST OFF" / "CONDITION RED" callouts), are separate MB88xx-microcontroller devices whose ROMs are not part of this romset, so they are silent. Making the game's own WSG music and effects sound needs deeper work on the sound-trigger path and is a known follow-up.