An LSDJ-inspired music tracker for the Sega Master System and Game Gear, written in pure Z80 assembly. Make music on real hardware (via flashcart) or in an emulator, using just the D-pad and two buttons. Sound is the SN76489 PSG — three square channels and noise — plus 4-bit PCM samples and drawn wavetables via the volume-register DAC trick, a built-in tempo-synced echo, and Game Gear stereo. On a Master System with the FM Sound Unit you also get YM2413 FM: melodic voices (15 ROM patches + 8 ROM-baked custom presets, with tables and per-note commands) and a rhythm-mode drum kit, sounding alongside the PSG (SMS only, off by default).
📺 Video tutorials — a growing playlist walking through how to use SMSGGDJ.
One source tree builds two ROMs:
smsggdj.sms— Master System (full screen).smsggdj.gg— Game Gear / GGDJ (handheld screen, real stereo).
Prebuilt ROMs are on the Releases page — download the
version-stamped .sms (Master System) or .gg (Game Gear) ROM; flash to a cart
or open in an emulator, no toolchain needed.
Needs WLA-DX (wla-z80 + wlalink) and
Python 3. make run launches the bundled Emulicious (needs Java).
make # build both: build/smsggdj.sms and build/smsggdj.gg
make run # build both, launch the SMS ROM
make run-gg # build both, launch the Game Gear ROM
make cleanBoth ROMs boot to a blank song, ready to make music (the wavetables come preloaded with the stamp presets, so a fresh song makes sound right away).
Drop a ROM on a flashcart (Master Everdrive etc.) or open it in an emulator, and press play.
Emulator note: all manual emulator testing was done in SMS Plus (Bannister). Other emulators should work, but that's the one this project is exercised against.
- MANUAL.md — the user guide: controls, screens, writing a song, instruments, commands, live mode, saving, sync.
- tools/patcher.html — drop a built ROM + your own sounds in a browser, tune them (trim, gain, tanh, fades), audition the exact console sound, and download a ROM with your sample bank. No toolchain.
- tools/savetool.html — unpack songs from a
.sav, assemble a cart image (pick 8/16/32 KB), or click a slot to view a song's notes, commands and instruments — in the browser. - tools/migrate.html — carry an older (SMDJ3)
.savforward to the current compressed format: it RLE-packs every song into an SMDJ4 directory + heap image. Drop the old save, download the new one. - tools/palette.html — drop a built ROM and recolour its 8 UI palettes (0–7): pick a background + foreground for each (the pickers snap to the 64 hardware colours), then download the patched ROM. No toolchain.
- tools/fmpatch.html — drop a built
.smsROM and edit its 8 custom FM presets (the YM2413 user patches an FM instrument's PRST field selects): per-operator MUL/AR/DR/SL/RR/KSL/TL, feedback, waveforms and names, audition each through a JS port of the emu2413 YM2413 core, then download the patched ROM. No toolchain. - tools/als2smdj.html — drop an Ableton Live Set
(
.als) and get a.smdjsong: the first 3 MIDI tracks' Session clips become phrases/chains on a 16th-note grid (highest note wins, out-of-range folds in, note-offs ignored). Load the result withsavetool.html. No toolchain.
- CLAUDE.md — build system, architecture, and the hard invariants (IRQ shadow registers, VDP write spacing, per-region tables).
- DESIGN.md — the design contract: hardware constraints, the song data model, the sound engine, the command set, the sample pool, sync, and the GGDJ build (§15). Read the relevant section before changing behaviour.
- SAVEFORMAT.md — the SRAM /
.sav/.smdjsave format. - CHANGELOG.md — what changed, per version.
- HARDWARE.md — controller-port and Game Gear EXT pinouts, sync cabling, and the EXT paddle-PCB notes.
- smsvj — the VJ visual sibling: runs on a second SMS, projects its video as the visuals, and syncs to SMSGGDJ (or Ableton Link via the ESP32 bridge). Shares the clock vocabulary (tick / beat / bar), the SYNC contract on controller port 2, and the LIVE-mode launch-quantize input core. Run one SMS as the tracker and a second as the VJ.
- smsggdj-link-esp32 —
an ESP32 (Seeed XIAO ESP32-C3) Ableton Link bridge: joins a Link session
over WiFi and drives SMSGGDJ's
SYNC: INso the tracker follows Ableton Live's tempo and transport on real hardware. Wiring in HARDWARE.md. - ares-link-sync — a fork
of the ares emulator that joins an Ableton Link session and drives
SMSGGDJ's
SYNC: INfrom inside the emulator (frame-PLL'd timeline, bar-quantized launch, HUD). The software counterpart to the ESP32 bridge — Link-sync the tracker with no hardware.
src/ Z80 assembly (main, vdp, input, psg, engine, sample, editor)
tools/ Python build tools + the browser apps:
makefont / maketables / makelogo (build inputs)
smsggdj_sample.py WAV/pool -> sample bank
patcher.html browser sample patcher
savetool.html browser song/save manager
migrate.html SMDJ3 -> SMDJ4 save migrator
palette.html browser UI-palette recolourer
fmpatch.html browser FM custom-preset editor
samples/ sample sources: one subfolder per kit (up to 8 kits x 8 WAVs);
samples/pool.bin (if present) overrides as a pre-baked bank
art/ the logo art
The pool is built from kit folders under samples/ — up to 8 kits of 8
samples, taken in alphanumeric order (one subfolder per kit, WAVs inside). An
KIT instrument's KIT field picks the kit and the note maps chromatically to
the 8 slots, so one instrument is a whole drum kit. make trims each sample's
trailing silence and applies a gain (make SAMPLE_GAIN=N, default 10) for a
punchier 4-bit DAC. A committed samples/pool.bin (tuned in the patcher) still
overrides as a pre-baked bank if present. The pool is identical in both
flavours, so one bank serves .sms and .gg.
MIT — see LICENSE. Use it, fork it, learn from it.
The bundled Emulicious emulator (tools/emulicious/, not in this repo) has its
own license.
Made by little-scale.
