Releases: soniciso1/LuaMD
Release list
LuaMD v1.0
Mega Drive / Genesis emulator running as native x86_64 shellcode on PS5,
delivered through Luac0re. No kernel
exploit — everything runs in userland inside the ps2emu sandbox of
Star Wars Racer Revenge.
Sibling to LuaGB, whose PS5 runtime
this reuses.
Credits
- Clownacy — clownmdemu,
the emulation core, plus theclown68000andclownz80interpreters (AGPLv3). - Gezine — Luac0re, the JIT exploit
and Lua delivery framework this runs on. No Luac0re, no project. - egycnq — the savedata write method, which
is what makes cartridge saves persist, and EmuC0re,
whose PS5 runtime structure this follows.
Install
Download md.lua below. You need Luac0re already working, with its loader
listening on port 9026.
1. Put your ROMs in the savedata
ROMs are read from a roms/ folder inside the game's savedata container —
the same container Luac0re lives in — and nowhere else.
/savedata0/
lua/ <- Luac0re (already there, leave it alone)
roms/ <- CREATE THIS. your .bin / .md / .gen / .smd files
saves/ <- CREATE THIS, empty. cartridge SRAM lands here
VMC0.card <- leave alone
VMC1.card <- leave alone
sce_sys/ <- leave alone
Use any PS5 save manager that can mount and write a savedata image: mount the
save, create roms/ and saves/, copy your ROMs in, then unmount to commit.
Do this with the game closed. Mounting the savedata image while the game is
running desynchronises the game's own mount — directories read back empty and
writes fail.
Alternatively the payload serves FTP on port 1337 while it waits on the ROM
screen and writes straight into the container, so after the initial Luac0re
setup no save manager is needed. With roms/ empty it waits indefinitely; with
ROMs already there it waits a few seconds and moves on.
Watch the space. The container is around 42 MB and the two PS2 virtual
memory cards take 16.5 MB before you start, leaving roughly 24 MB. A Mega Drive
cartridge is 512 KB to 4 MB.
2. Launch the game
Start Star Wars Racer Revenge, then OPTIONS → HALL OF FAME to arm the
Luac0re loader.
3. Send the payload
python md_launcher.py <PS5_IP>
Or send md.lua to port 9026 by any means you already use.
Controls
| DualSense | Mega Drive |
|---|---|
| Square | A |
| Cross | B |
| Circle | C |
| Triangle | X |
| L2 / R2 | Y / Z |
| Options | Start |
| L3 | Mode |
| D-Pad | D-Pad |
| L1 | back to the ROM picker (saves first) |
| R1 (hold 1 second) | quit |
Six-button support is free — games that only understand three never poll for
the rest. R1 requires a deliberate full second held: quitting ends the Luac0re
session and means relaunching the game.
A web controller is also served at http://<PS5_IP>:9030 — touch, keyboard and
Gamepad API. The input source locks to whichever device you press first.
Saving
Cartridge SRAM is written into saves/<rom>.srm inside the savedata container,
so a backup of the save captures your games too. Press L1 to return to the
picker — that commits it. Yanking power will not.
Most cartridges have no battery at all; the load line says which.
Supported
.bin, .md, .gen raw dumps, and .smd (Super Magic Drive), which is
deinterleaved on load.
Not supported: Mega CD, 32X, Sega Pico, save states.
Known limits
- One payload send per Luac0re session. The emulator takes over the display and
stops ps2emu's graphics thread, so after it exits the loader cannot serve
another payload — relaunch the game to send again. - Tested against NTSC cartridges. PAL region detection is implemented but has
not been exercised on hardware.
Licence
AGPLv3, because clownmdemu is. Full source is in the repository, including
the one documented change to upstream (md/source/mega-cd-boot-rom.c — the
Mega CD BIOS array, 135 KB of the core's 190 KB, removed because a
cartridge-only build never maps those addresses and the payload has a hard
256 KB ceiling).