SG-1000
The Sega SG-1000 (1983) was Sega's first cartridge console: a Zilog Z80, a Texas Instruments TMS9918A video chip and an SN76489 sound chip, with the cartridge mapped straight in from address 0.
This is a purpose-built pure-JavaScript machine - the MIT-licensed DrGoldfire Z80 interpreter paired with a TMS9918A VDP and machine glue written for emulators.org - so the whole Z80 is single-steppable, register-editable and breakpointable in the shared in-page debugger. It boots directly from the cartridge; the SG-1000 needs no BIOS.
Runs on: Web browser
SG-1000 Online Emulator
Play SG-1000 using JavaScript directly in your browser.
Controls
Configurations
| Configuration | Emulator | Machine | OS | Legal | |
|---|---|---|---|---|---|
| Colour Block demo | SG-1000 | sg-1000 | open | Open ⛶ |
Chips
Notes
Embedding
The SG-1000 is one of the simplest cartridge consoles: a Zilog Z80 CPU, a Texas Instruments TMS9918A video chip and an SN76489 sound chip, with 1–8 KB of work RAM and the cartridge mapped straight in from address 0. There was no established pure-JavaScript SG-1000 core with an inspectable CPU, so we built one from three small, self-hosted parts:
Z80.js- Molly Howell's MIT-licensed Z80 interpreter. Constructed with a core object of four callbacks (mem_read,mem_write,io_read,io_write); it exposesgetState(),setState(),reset(),run_instruction()andinterrupt().tms9918.js- a TMS9918A VDP we wrote: 16 KB VRAM, the eight write-only registers and the read status register, the two-byte control-port protocol, all four background modes (Graphics I, Graphics II, Multicolor, Text) and the sprite engine. It renders a whole 256×192 frame into an RGBA buffer.sega8.js- the machine: the SG-1000 memory map (cartridge at 0x0000, RAM at 0xC000), the I/O ports (VDP at 0xBE/0xBF, controller at 0xDC), the SN76489 (silent here) and a frame loop that raises the VDP vertical-blank interrupt.
var machine = new Sega8Machine({ kind: 'sg1000', rom: cartBytes });
(function loop(){
machine.runFrameFast(); // one frame of Z80 + VDP + interrupt
machine.render(img.data); ctx.putImageData(img, 0, 0);
requestAnimationFrame(loop);
})();
The machine is plain objects. Everything the debugger needs is reachable:
| Member | Kind | What it does |
|---|---|---|
machine.cpu.run_instruction() | method | Fetch and execute exactly one Z80 instruction; returns the T-cycle count. The single-step primitive. |
machine.cpu.getState() / setState() | method | Read / write the entire Z80 state as a plain object (pc, sp, a, b, c, d, e, h, l, ix, iy, i, r, flags{…}, plus the shadow set). How the debugger reads and pokes registers. |
machine.runFrameFast() / runFrameStep(bps) | method | Run a whole frame at speed, or step it instruction-by-instruction halting on an execution-breakpoint Set. |
machine.readMem(a) / writeMem(a,v) | method | Read/write the 64K Z80 address space. I/O is port-mapped, so a memory read is side-effect-free, safe for the auto-polling hex view. |
machine.vdp.vram / .reg / .status | field | The TMS9918A's 16 KB VRAM, eight registers and status flags. |
machine.press(id) / release(id) | method | Drive the joystick latch (active-low) that the game reads at port 0xDC. |
Debugger integration
The debugger plug-in (sg1000-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).
Owning the loop. The boot shim owns the frame loop, so pause, resume and frame-step are ours directly. With no breakpoints set we run machine.runFrameFast(); with any set we run machine.runFrameStep(bps), which checks the program counter before every instruction and halts the moment it hits a breakpoint. Single-step calls cpu.run_instruction() once. Write watchpoints wrap machine.writeMem and pause when a watched address is written.
Registers. The Z80 state comes straight from cpu.getState(); the plug-in presents the 16-bit pairs AF BC DE HL IX IY SP PC and decodes the flag byte (S Z H P/V N C) into individual, writable flag chips, writing back through setState().
Architecture
The SG-1000 (1983) was Sega's first cartridge console and the direct ancestor of the Master System. The machine is small:
Z80- the CPU, clocked at 3.58 MHz. The cartridge is mapped from address 0; work RAM sits at 0xC000.TMS9918A- the video chip: 256×192, 16 fixed colours, a 32-entry sprite table, and the Graphics I / Graphics II / Multicolor / Text modes. Its vertical-blank drives the Z80's maskable interrupt.SN76489- the PSG (three squares + noise); silent here for headless use.- Controllers are read as an active-low byte at port 0xDC (bit 0 up, 1 down, 2 left, 3 right, 4/5 the two buttons).
Because the whole machine is ordinary JavaScript objects and the CPU is a straight interpreter, the entire state is inspectable and pokeable at runtime, an ideal debugging target.