Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
8.8 KiB
Setting up MSXgl on macOS
MSXgl ships its build toolchain as Windows and Linux x86 binaries only. On a Mac (Apple Silicon or Intel) those bundled binaries cannot run, which is why a fresh checkout fails to build out of the box. This guide explains the one-time setup that makes it work, and documents exactly which samples build and which don't.
Tested on: macOS (Apple Silicon, arm64), Node v24, SDCC 4.6, openMSX 21.
1. Install the prerequisites (Homebrew)
brew install sdcc openmsx node
- sdcc — the Z80 C compiler / assembler / linker (
sdcc,sdasz80,sdar). MSXgl was written against SDCC 4.2; Homebrew currently ships 4.6. Almost everything compiles, but a couple of samples don't (see Known issues below). - openmsx — the emulator used to run the built programs.
- node — the build system is a set of Node.js scripts. (A system Node works fine;
the
nodebinary bundled intools/build/Node/is Windows/Linux only.)
Verify:
sdcc -v # should print 4.x
openmsx -v
node -v
2. How the project was adapted for macOS
These changes are already applied in this checkout. They make the build prefer the system (Homebrew) toolchain on macOS/Linux while leaving Windows behavior unchanged. If you ever start from a clean MSXgl download, you'll need to redo them.
| File | Change |
|---|---|
engine/script/js/setup_global.js |
On non-Windows, use sdcc/sdasz80/sdar from PATH and derive the SDCC lib path from where sdcc is installed. |
engine/script/js/default_config.js |
The hardcoded SDCC tool paths are guarded with if (process.platform === "win32") so they no longer override the system toolchain. Emulator auto-detects openmsx from PATH. |
projects/default_config.js |
Same two changes. This file is an auto-generated copy of the engine template and loads after it — if you delete it, it regenerates from the (now-fixed) template. |
tools/build/msxtar/msxtar |
Rebuilt as a native macOS binary from tools/build/msxtar/src/main.cc (the bundled one is Linux-only). Needed for all disk/tape image generation. The Linux original is kept as msxtar.linux.bak. |
engine/src/vdp.h |
The struct-based VDP_SetSpriteData inline is now restricted to MSX1 (#if (MSX_VERSION < MSX_2)), removing a name clash with the MSX2 const u8* version that newer SDCC rejects. |
engine/src/rom_mapper.h |
The TARGET_DOS2_MAPPER branch now #includes dos_mapper.h, so DOSMapper_SetPage/GetPage are declared (they were implicitly declared before, which newer SDCC rejects). |
engine/script/js/setup_emulator.js + both default_config.js |
Added an EmulMachineName config option: when set, the openMSX runner uses that machine (e.g. a real MSX with a Disk BIOS) instead of C-BIOS. Needed to run disk/DOS targets — see section 4. |
The MSX toolkit helpers in tools/MSXtk/bin/ (MSXhex, MSXbin, MSXmath,
MSXzip) were also rebuilt as native macOS arm64 binaries. The Windows .exe
versions sit alongside them and are ignored on macOS.
To rebuild msxtar yourself: cd tools/build/msxtar/src && g++ main.cc -w -o ../msxtar
(harmless deprecation warnings; -w silences them).
Note: this directory is not a git repository, so the edits above are not tracked. Keep a backup if you plan to update MSXgl from upstream.
3. Build and run a sample
cd projects/samples
./build.sh s_bios # compile + link + package -> out/s_bios.rom
./build.sh s_bios run # same, then launch it in openMSX
- Built ROMs land in
projects/samples/out/and are copied toprojects/samples/emul/rom/. - Swap
s_biosfor any other sample name (the part before.c/.js), e.g.s_print,s_psg,s_game,s_scroll,s_math. - Common extra flags:
run(launch emulator),clean(remove intermediates). Targets/machine are set per sample in itss_*.jsand inproject_config.js.
To build your own project, copy projects/template/ and use its build.sh the same way.
4. Running disk / DOS programs (extra setup)
ROM and tape targets run on C-BIOS, the free BIOS openMSX bundles — no extra
setup. But C-BIOS cannot boot a disk: it only autostarts cartridge ROMs (its boot
screen literally says "This version of C-BIOS can only start cartridges"). So disk and
MSX-DOS targets (DOS0/1/2, BIN_DISK, _MAPPER-to-disk, etc.) need a real MSX
machine config, which requires that machine's system ROMs (copyrighted — supply
them from a machine you own).
Setup:
- Put the system ROMs where openMSX looks for them — either
~/.openMSX/share/systemroms/or~/.openMSX/share/machines/(both are searched recursively). openMSX matches ROMs by SHA-1, so filenames don't matter, but the dumps must be exact (an unextracted.zipor a bad dump is silently ignored). - Confirm a disk-capable machine resolves, e.g.:
Good disk-equipped machines:
openmsx -machine Philips_NMS_8250 -diska projects/samples/emul/dsk/DOS1_s_dos.dskPhilips_NMS_8250,Sony_HB-F1XD,Panasonic_FS-A1ST(turboR),National_FS-4500. - Tell MSXgl's runner to use that machine by setting
EmulMachineNameinprojects/default_config.js(already wired up and set toPhilips_NMS_8250in this checkout):It applies only to disk/DOS/tape targets (the ones C-BIOS can't boot). Plain cartridge ROM targets ignore it and keep using the version-correct C-BIOS machine — so an MSX2+ ROM still runs onEmulMachineName = "Philips_NMS_8250";C-BIOS_MSX2+, not on the (MSX2) machine set here. Leave it""to use C-BIOS for everything.
Verified:
./build.sh s_dos run→ boots MSX-DOS onPhilips_NMS_8250and runss_dosfrom the generated.dsk.projects/mazegame(MSX2+ Konami-SCC ROM) →./build.sh runlaunches onC-BIOS_MSX2+_EUautomatically.
What works ✅
All 55 samples build cleanly (verified: 55 pass, 0 fail), across every output
format — plain/mapped ROM, BASIC binary, tape, and MSX-DOS 0/1/2 disk images. This
includes graphics/VDP, input, every audio replayer, the MegaROM mappers, and the
disk/tape samples. Running any of them in openMSX (./build.sh <name> run) works.
This required the native msxtar and the two small source fixes listed in section 2.
Without those, 8 samples fail — see below for what they were, in case you start from a
clean MSXgl checkout and hit them again.
Previously-failing samples (now fixed) ⚠️
On a clean MSXgl download these 8 fail. They are fixed in this checkout; the notes below say how, so you can reapply after an upstream update.
A. Disk / tape formats — bundled msxtar is Linux-only (6 samples)
s_dos, s_dos0, s_dos2, s_lvgm, s_usr, s_zip
They compile and link fine but fail at the final disk-image (.dsk) step with
/bin/sh: ./msxtar: cannot execute binary file, because the shipped
tools/build/msxtar/msxtar is a Linux x86-64 ELF binary. The same blocks any
BIN_DISK, BIN_TAPE, DOS0/1/2, or _MAPPER-to-disk target you configure yourself.
Fix (applied): rebuilt msxtar natively from its bundled source —
cd tools/build/msxtar/src && g++ main.cc -w -o ../msxtar.
B. SDCC 4.6 source incompatibilities (2 samples)
The code was written for SDCC 4.2; SDCC 4.6 has a stricter front-end. These would fail the same way on Linux/Windows with SDCC 4.6 — they are not macOS-specific.
| Sample | Original error | Fix (applied) |
|---|---|---|
s_sprite |
vdp.h:1217: error 20: Undefined identifier 'data'/'index' — name clash: on MSX2 VDP_SetSpriteData was declared both as a struct-based inline and as the real const u8* function. |
Restricted the struct-based inline to MSX1 with #if (MSX_VERSION < MSX_2). |
s_dosmap |
rom_mapper.h:275/282: error 101: too many parameters — DOSMapper_SetPage/GetPage were implicitly declared. |
Added #include "dos_mapper.h" to the TARGET_DOS2_MAPPER branch. |
(Alternative to the source fixes: install SDCC 4.2 and point the build at it via
Compiler/Assembler/Linker/SDCCPath in projects/default_config.js.)
Quick reference
# one-time
brew install sdcc openmsx node
# build a ROM and run it
cd projects/samples
./build.sh s_bios run
# rebuild everything to see current pass/fail
for p in $(ls s_*.js | sed 's/\.js$//'); do ./build.sh "$p" >/dev/null 2>&1 \
&& echo "PASS $p" || echo "FAIL $p"; done
Bottom line: with SDCC and openMSX installed and the fixes in this checkout, MSXgl
development works fully on macOS — all 55 samples build across every output format
(ROM, BASIC binary, tape, and MSX-DOS disk). ROM/tape samples run on free C-BIOS out of
the box; disk/DOS samples run too, but require real MSX system ROMs and an
EmulMachineName (see section 4).