PlayStation Classic (Project Eris, Two DualSense Controllers)¶
A Sony PlayStation Classic (SCPH-1000R) modded with Project Eris so it runs a USB library of PS1 games plus RetroArch, with two wireless PS5 DualSense controllers through 8BitDo adapters. This page records the working setup, the install sequence, and the dead ends that took most of the time, so the next rebuild doesn't repeat them.
The Z2 Mini only appears here as a Linux toolbox (exFAT/NTFS formatting, ELF inspection). For server access see 01-connecting.md.
Why¶
The stock console has 20 built-in games and two wired controllers. The goal: add my own PS1 library and play two-player with DualSense controllers, wirelessly.
Two candidate mods were tried:
- AutoBleem v0.8.5. Runs entirely from a FAT32 stick in port 2, changes nothing on the console. Works with one 8BitDo adapter, but crashes the console when a second 8BitDo-connected controller connects (details under Troubleshooting). With the stick in port 2, two adapters also need a USB hub.
- Project Eris v1.0.0 (ModMyClassic). Installs a kernel and services on the console, boots Sony's own menu with USB games linked in, and enables booting the stick from the rear micro-USB port through an OTG cable, which frees both front ports for the adapters. This is what runs now.
Final setup¶
| Port | Device |
|---|---|
| Rear micro-USB | SanDisk Cruzer Blade 64 GB (USB 2.0) via a 2-in-1 OTG + power adapter |
| Front port 1 | 8BitDo USB Wireless Adapter 2 → DualSense #1 |
| Front port 2 | 8BitDo USB Wireless Adapter 2 → DualSense #2 |
| Item | Value |
|---|---|
| Mod | Project Eris v1.0.0 (Project_Eris-v1.0.0-fb9d576.zip, ModMyClassic) |
| Console kernel | Eris kernel v47 (Linux 4.4.22, built 2020-02-23), flashed by Eris |
| Stick | SanDisk Cruzer Blade 64 GB, USB 2.0, exFAT, MBR, label SONY |
| Adapter firmware | 8BitDo USB Adapter 2 v1.07 (both adapters) |
| Adapter mode | PSC mode (Create + D-pad Down) |
| Power | 5 V / 2 A USB brick (not a power-bar USB port) |
| Library | 15 PS1 games imported + the 20 built-in games; 5 GBA games (Pokémon Ruby, Sapphire, Emerald, FireRed, LeafGreen) |
| RetroArch cores | pcsx_rearmed (shipped), gambatte, gpsp, mgba (added) |
| Set up | 2026-09-30 → 2026-10-09 |
Controllers: 8BitDo USB Wireless Adapter 2¶
Firmware v1.07, not v1.10. On v1.10 (2025-07-11, the current release) a DualSense worked for about ten seconds on the PS Classic, then inputs stopped or a D-pad direction stuck (endless menu scroll). Rolling both adapters back to v1.07 (2024-10-25) fixed it. v1.07 is the newest version that predates all three 2025 releases and still carries the DualSense fixes from v1.05 and v1.06.
Flashing (macOS):
- Download the 8BitDo Firmware Updater for macOS from
support.8bitdo.com/firmware-updater.html(app v2.5.2, signed "Shenzhen 8BitDo Tech", notarized). - Plug one adapter into the Mac, no controller connected. The app shows
8BitDo USB Adapter 2 V1.xx Connected. - Firmware Update → select V1.07 → Update. The screen reads "Update from v1.10 to v1.07"; the app closes itself when the flash is done.
- Reopen the app to confirm
V1.07.
If the adapter enumerates as BOOT (USB 2dc8:3208) instead, the app shows a product picker: choose USB Adapter 2, not "USB Adapter for PS classic" (a different, older product).
Pairing and mode, on the console:
Pair: press the adapter's pair button (LED blinks fast), then hold Create + PS on the DualSense (3 s) → LED solid
PSC mode: hold Create + D-pad Down (3 s) → LED blinks twice
Clear: hold the adapter's pair button until the LED turns off (clears pairing and mode)
PSC mode makes the adapter enumerate as Sony's own PS Classic controller (USB 054c:0cda). Without it the adapter may come up as a Switch Pro Controller, which is what triggered AutoBleem's "new gamepad" mapping screen and the ghost presses on the second adapter. Rumble, touchpad, motion and adaptive triggers don't work through the adapter in this mode.
Install sequence (Project Eris)¶
Eris installs in two stages: the first boot must be from FAT32; every boot after that must be exFAT or NTFS (Eris refuses FAT32 with "Running on FAT32 is NOT supported! Backup USB to PC, reformat and copy back over to proceed!").
1. FAT32 install stick. Any stick works for this stage (it worked on a USB 3.0 Kingston).
diskutil info diskN | grep "Media Name" # confirm the target first
diskutil eraseDisk FAT32 SONY MBRFormat diskN
ditto -x -k Project_Eris-v1.0.0-fb9d576.zip /Volumes/SONY/
2. First boot (stick in front port 2). Eris backs up the console's boot/rootfs/userdata/recovery partitions and the original kernel to project_eris/backup/, installs its services, flashes kernel v47, shows "initial hack completed — restarting PSC" and powers off. Power it back on manually; it shows the FAT32 refusal. That's expected.
3. Save the console backup off the stick (see Backup), then copy the whole stick to the Mac:
rsync -a --exclude '._*' --exclude '.Spotlight-V100' --exclude '.fseventsd' /Volumes/SONY/ ~/eris_stick/
4. Reformat a USB 2.0 stick as exFAT and copy everything back.
diskutil info diskN | grep "Media Name" # must be the Cruzer
diskutil eraseDisk ExFAT SONY MBRFormat diskN
mdutil -i off /Volumes/SONY; touch /Volumes/SONY/.metadata_never_index
export COPYFILE_DISABLE=1
rsync -rt --exclude '._*' ~/eris_stick/ /Volumes/SONY/
find /Volumes/SONY -name '._*' -delete
rsync -rcn --exclude '._*' --out-format='%n' ~/eris_stick/ /Volumes/SONY/ # no output = verified
5. Boot from the rear port. Stick on the rear micro-USB through the OTG adapter, adapters in ports 1 and 2. The Eris Boot Menu appears: Project Eris (Sony UI with USB games), RetroArch, EmulationStation. △ toggles AutoBoot.
Adding games¶
Eris's importer (project_eris/opt/psc_transfer_tools/psc_game_add, run at every boot) only looks at files directly inside transfer/. A folder per game is silently ignored: logs/transfer.log says "No valid game files found in transfer folder."
transfer/
Crash Bandicoot - Warped (USA).bin
Crash Bandicoot - Warped (USA).cue
Legend of Dragoon, The (USA, Canada) (Disc 1).bin
Legend of Dragoon, The (USA, Canada) (Disc 1).cue
... (Disc 2–4)
export COPYFILE_DISABLE=1
for d in ~/games/*/; do rsync -rt --exclude '._*' "$d" /Volumes/SONY/transfer/; done
find /Volumes/SONY -name '._*' -delete
On the next boot the importer identifies each disc by serial, moves it to games/<n>/ with cover art, groups multi-disc games into one entry with a generated .m3u (Legend of Dragoon ×4, Syphon Filter 2 ×2), keeps multi-track .cue files intact (Doom, 8 audio tracks), and leaves the original .cue files in transfer/.Original Cue Files. Games are sorted alphabetically among the 20 built-ins (LINK_ALPHABETICALISE="1").
The import was rehearsed first on the Z2 Mini by running the ARM importer under qemu-arm in a throwaway Alpine container against a copy of the library. All 15 games imported cleanly there before anything was written to the stick.
RetroArch and extra cores¶
Eris ships only the PS1 core (pcsx_rearmed_libretro.so) and roms/<system>/ folders for about 40 systems. The console has no network, and Eris's built-in core updater points at classicmodscloud.com, which no longer responds. Cores were added by hand from libretro's ARM build server:
for c in gambatte gpsp mgba; do
curl -sfLO https://buildbot.libretro.com/nightly/linux/armhf/latest/${c}_libretro.so.zip
python3 -m zipfile -e ${c}_libretro.so.zip .
done
Compatibility was checked against the console's own libraries (from the rootfs backup) before copying:
| Core | Systems | Needs | Console has |
|---|---|---|---|
gambatte |
GB, GBC | GLIBC 2.15, GLIBCXX 3.4.21 | glibc 2.24, GLIBCXX 3.4.22 |
gpsp |
GBA (fast) | GLIBC 2.7 | ✓ |
mgba |
GBA | GLIBC 2.4 | ✓ |
All are ARMv7 hard-float (VFPv3-D16); the console's libc is ARMv7 / VFPv4.
readelf -V gambatte_libretro.so | grep -oE "GLIBC(XX)?_[0-9.]+" | sort -V -u | tail -3
readelf -A gambatte_libretro.so | grep -E "Tag_CPU_arch|Tag_FP_arch"
Cores go in project_eris/opt/retroarch/config/retroarch/cores/. EmulationStation's es_systems.cfg launches GB/GBC with gambatte_libretro.so and GBA with mgba_libretro.so. ROMs go in roms/gb, roms/gbc, roms/gba. The 39 roms/ subfolders are empty in the Eris zip and didn't survive the copy to the stick; they had to be recreated.
In RetroArch, Start + Select opens the menu (input_menu_toggle_gamepad_combo = "4").
GBA library¶
Five Pokémon cartridge images sit flat in roms/gba/, as-is (.gba, 16 MiB each, no zipping):
| File | Header |
|---|---|
Pokemon - Ruby Version (USA, Europe) (Rev 2).gba |
AXVE01 |
Pokemon - Sapphire Version (USA, Europe) (Rev 2).gba |
AXPE01 |
Pokemon - Emerald Version (USA, Europe).gba |
BPEE01 |
Pokemon - FireRed Version (USA, Europe) (Rev 1).gba |
BPRE01 |
Pokemon - LeafGreen Version (USA, Europe) (Rev 1).gba |
BPGE01 |
export COPYFILE_DISABLE=1
cp ~/Documents/"GBA Games"/*/*.gba /Volumes/SONY/roms/gba/
find /Volumes/SONY/roms -name '._*' -delete
They launch from Boot Menu → ES → Game Boy Advance with mgba_libretro.so. If one runs slowly, Start + Select → Core → gpsp is the faster fallback. mGBA emulates the cartridge real-time clock that Ruby, Sapphire and Emerald use for berries and tides.
Saves: autosave for a hand-off console¶
The console went to a young player, so in-game saves have to survive the power switch. Eris ships RetroArch with autosave_interval = "0": battery saves (.srm) are only written when the content is closed through the menu, so "save in Pokémon, then switch off" could lose the save. It was changed to 10 seconds in both config files on the stick (EmulationStation launches RetroArch with the main retroarch.cfg; retroarch_DEFAULT.cfg is what Eris regenerates it from):
project_eris/opt/retroarch/config/retroarch/retroarch.cfg autosave_interval = "10"
project_eris/opt/retroarch/config/retroarch/retroarch_DEFAULT.cfg autosave_interval = "10"
The originals are kept beside them as *.bak-before-autosave. config_save_on_exit = "true" writes the running config back on quit, so the value sticks. Saves land in project_eris/opt/retroarch/saves/<game>.srm.
The rule for the player: save in the Pokémon menu, wait a few seconds, then switch off. The boot menu's AutoBoot (highlight ES, press △) skips straight to the game list.
Verifying¶
- Boot shows the Eris Boot Menu, not the stock logo straight into Sony's menu.
logs/bootloader.logon the stick is rewritten every boot and ends withStarting Execute.logs/project_eris.logshowsEMMC Count 20 Media Count N, where N is the number of USB games.logs/transfer.loglistsAdding game … Found Serial: …for anything new intransfer/.- Both DualSenses work together in a stock two-player game.
macOS mounts the exFAT stick read/write, so all of the above can be checked from the Mac.
Backup¶
| What | Where | Notes |
|---|---|---|
Original console kernel + partition images (previous_raw_kernel.img.bak, LBOOT.EPB, LBOOT_KERNEL.EPB, LRECOVERY.EPB, ~113 MB) |
Z2 Mini: /data/files/Project Files/PS Classic/PS Classic console backup (Project Eris)/, with SHA256SUMS.txt |
Under /data/files, so covered by the nightly backup (05-backups.md). Copies also on the MacBook (~/Documents/PS Classic console backup (Project Eris)/) and on the stick (project_eris/backup/) |
| Stick contents after install (12,738 files) + added cores | Z2 Mini: ~/psc-eris/eris_stick/, ~/psc-eris/cores/ |
Rebuild source for a new stick. /home is outside the nightly backup scope; the stick itself is the other copy |
| Saves | Stick: games/<n>/.pcsx/ (Sony UI), project_eris/opt/retroarch/saves/ (RetroArch, incl. the Pokémon .srm files) |
Back up by copying the stick. RetroArch flushes .srm every 10 s (autosave_interval) |
The .EPB files are plain ZIPs (boot.img, rootfs.ext4, userdata.ext4, tz.img). They are what Eris's own restore and uninstall routines use; don't delete them.
Integrity check on the Z2 Mini:
cd "/data/files/Project Files/PS Classic/PS Classic console backup (Project Eris)/backup" && sha256sum -c ../SHA256SUMS.txt
Troubleshooting¶
Console boots straight to the stock menu and the stick's logs/bootloader.log doesn't change:
- The stick is a USB 3.0 drive. Both USB 3.0 Kingston DataTraveler 3.0 sticks were ignored after the install with every format tried: macOS exFAT (128 KB and 32 KB clusters), Linux exfatprogs exFAT, and Linux mkntfs NTFS. The same files on a USB 2.0 Cruzer Blade booted first time. Use a USB 2.0 stick; this matches the Eris guide's "USB 2.0 drive" requirement.
"Running on FAT32 is NOT supported": - Expected after the install. Reformat as exFAT or NTFS and copy back (step 4).
A game is missing from the carousel:
- It's in a subfolder of transfer/. Move the .cue/.bin up one level and reboot.
Syphon Filter 2 or 3 shows a black screen when launched from Sony's menu:
- Sony's built-in PCSX can't run them. Launch from Boot Menu → RetroArch → Playlists → "PlayStation Classic - External" (PCSX ReARMed). For SF2's disc change, use RetroArch's Disc Control menu (Start + Select). A per-game alternative exists (adding a .chd next to the .cue makes Eris's launcher send that game to RetroArch automatically) but wasn't used.
DualSense works for a few seconds, then a direction sticks or inputs stop: - Adapter firmware v1.10. Flash v1.07, then re-pair and redo PSC mode.
AutoBleem crashes (endless scroll, looping sound, power-off) as soon as a second 8BitDo controller connects: - With one adapter, connecting the controller makes AutoBleem's menu scroll endlessly until the first button press, apparently a phantom held D-pad input on connect. With two adapters the console crashes instead. It also happened in AutoBleem's "classic" (Sony UI) QuickBoot mode, and with the original wired pad as player 2 everything worked. The stock console with two adapters is fine. Not fixed in AutoBleem; Eris avoids it.
AutoBleem shows a "new gamepad" configuration screen:
- An adapter isn't in PSC mode and is presenting as a Switch Pro Controller. Don't map it; set PSC mode. A mapping saved this way lands in Autobleem/bin/autobleem/gpmapping/Nintendo Co., Ltd. Pro Controller.ini; delete it.
macOS won't eject the stick ("dissented by loginwindow"): - A Finder window is holding it. Eject from the Finder sidebar.
Hidden ._* files:
- macOS writes AppleDouble files to exFAT/FAT. Copy with COPYFILE_DISABLE=1 and delete ._* afterwards so the game scanners don't pick up stray ._*.cue files.
Decisions¶
| Decision | Reasoning |
|---|---|
| Project Eris over AutoBleem | AutoBleem crashes with two 8BitDo adapters; Eris doesn't, and Eris's rear-port OTG boot frees both front ports for the adapters with no hub |
| USB 2.0 Cruzer Blade | The deciding variable. USB 3.0 sticks were ignored post-install regardless of filesystem |
| exFAT, formatted on macOS | Simplest of the supported formats; macOS writes it natively. NTFS needs Linux or Windows tooling and was only tried on the USB 3.0 stick |
| 8BitDo firmware v1.07 | v1.10 drops DualSense input on the PS Classic; v1.07 is the newest release before the 2025 changes that still has the DualSense fixes |
Syphon Filter ⅔ via the RetroArch playlist, not .chd conversion |
No extra tooling or files; both games run in RetroArch as-is |
Cores from buildbot.libretro.com, checked with readelf |
ModMyClassic's core server is offline; the generic armhf builds link against glibc ≤ 2.15 and GLIBCXX ≤ 3.4.21, both older than the console's |
autosave_interval = "10" |
A child switches the console off instead of quitting through Start + Select; the Eris default of 0 only writes .srm saves on a clean quit |
| Z2 Mini as the Linux toolbox | exfatprogs, mkntfs, readelf, Docker + qemu-arm were already there; nothing installed on the host. Sticks were targeted only by /dev/disk/by-id/usb-…<serial>, never /dev/sdX, because sda is the backup drive |