Repository navigation
Share the Genesis and PICO-8 cores with esp-box-emu; add PICO-8 - #17
Conversation
The Genesis core and glue are now the esp-cpp/gwenesis submodule (branch esp32), shared with esp-box-emu. The P4's all-PSRAM placement is the GENESIS_HOT_IN_PSRAM gate, so the Tab5 also gets box-emu's newer glue: - skip rendering frames the display cannot take, and (bounded) while behind - Sonic 3's Z80 V-int handling - two line-interrupt fixes (Sonic 2 Chemical Plant drawn all underwater; Sonic 3 water only on every other frame) That needs three small Tab5Emu additions the glue uses: frame_slot_free() and frames_dropped()/frames_blitted()/blit_cycles() for the skip rule and perf line, and gamepad_state_latched() so a tap shorter than a skipped frame is not lost. PICO-8 is new: the esp-cpp/femto8 submodule (branch esp32) as the pico8 component, a Pico8Cart, and .p8 / .p8.png in rom_info. Audio goes through Tab5Emu::play_audio (PICO8_AUDIO_VIA_EMU) so the 44.1 kHz output is resampled to the 48 kHz DAC. Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01SFCMzomCZ5wRHJN4sxwkvY
There was a problem hiding this comment.
🟡 Changes recommended
The input latch is not drained before the PICO-8 cart task starts, so its first poll can replay already-released touch or gamepad presses from the launcher or previous cores.
1 open issue
What changed in this PR
This PR shares the Genesis and PICO-8 cores with esp-box-emu and integrates PICO-8 into Tab5Emu’s cartridge system.
Changes:
- Replace vendored Genesis sources and local glue with the shared gwenesis submodule.
- Add PICO-8 cartridge lifecycle support, ROM detection, and build/linker configuration.
- Extend Tab5Emu with latched input and video queue statistics, and update CI submodule checkout.
| File | Description |
|---|---|
main/pico8_cart.hpp |
Add PICO-8 lifecycle, menu, save, and video integration. |
main/carts.hpp |
Register PICO-8 cartridge creation. |
components/tab5-emu/src/tab5-emu.cpp |
Implement input latching, frame availability, and video counters. |
components/tab5-emu/include/tab5-emu.hpp |
Expose the new input and video APIs. |
components/rom_info/src/rom_info.cpp |
Recognize .p8 and .p8.png carts. |
components/rom_info/include/rom_info.hpp |
Add the PICO-8 platform identifier and documentation. |
components/pico8/linker.lf |
Define static placement and reset boundaries. |
components/pico8/CMakeLists.txt |
Build femto8 and its shared platform glue. |
components/genesis/src/z80_shared_memory.cpp |
Remove local Z80 allocation code in favor of shared glue. |
components/genesis/src/genesis_shared_memory.cpp |
Remove local Genesis allocation code in favor of shared glue. |
components/genesis/include/z80_shared_memory.hpp |
Remove the local Z80 memory interface. |
components/genesis/include/genesis.hpp |
Replace the local core interface with the submodule’s version. |
components/genesis/include/genesis_shared_memory.hpp |
Remove the local Genesis memory interface. |
components/genesis/include/genesis_dualcore.h |
Replace local dual-core declarations with the shared version. |
components/genesis/gwenesis/src/vdp/gwenesis_vdp.h |
Remove vendored VDP declarations for the submodule migration. |
components/genesis/gwenesis/src/sound/z80inst.h |
Remove vendored Z80 sound interface declarations. |
components/genesis/gwenesis/src/sound/z80inst.c |
Remove vendored Z80 sound integration. |
components/genesis/gwenesis/src/sound/ym2612.h |
Remove vendored FM sound declarations. |
components/genesis/gwenesis/src/sound/gwenesis_sn76489.h |
Remove vendored PSG declarations. |
components/genesis/gwenesis/src/sound/gwenesis_sn76489.c |
Remove vendored PSG implementation. |
components/genesis/gwenesis/src/savestate/gwenesis_savestate.h |
Remove vendored save-state declarations. |
components/genesis/gwenesis/src/savestate/gwenesis_savestate.c |
Remove vendored save-state coordination. |
components/genesis/gwenesis/src/io/gwenesis_io.h |
Remove vendored controller I/O declarations. |
components/genesis/gwenesis/src/io/gwenesis_io.c |
Remove vendored controller I/O implementation. |
components/genesis/gwenesis/src/cpus/Z80/Z80.h |
Remove vendored Z80 CPU declarations. |
components/genesis/gwenesis/src/cpus/Z80/ConDebug.c |
Remove the vendored Z80 console debugger. |
components/genesis/gwenesis/src/cpus/Z80/CodesXX.h |
Remove vendored Z80 indexed instructions. |
components/genesis/gwenesis/src/cpus/Z80/CodesXCB.h |
Remove vendored Z80 indexed bit instructions. |
components/genesis/gwenesis/src/cpus/Z80/CodesED.h |
Remove vendored Z80 extended instructions. |
components/genesis/gwenesis/src/cpus/Z80/CodesCB.h |
Remove vendored Z80 bit instructions. |
components/genesis/gwenesis/src/cpus/Z80/Codes.h |
Remove vendored Z80 base instructions. |
components/genesis/gwenesis/src/cpus/M68K/readme.txt |
Remove vendored Musashi documentation. |
components/genesis/gwenesis/src/cpus/M68K/macros.h |
Remove vendored M68K utility macros. |
components/genesis/gwenesis/src/cpus/M68K/m68kcpu.c |
Remove the vendored M68K CPU implementation. |
components/genesis/gwenesis/src/cpus/M68K/m68kconf.h |
Remove vendored M68K configuration. |
components/genesis/gwenesis/src/cpus/M68K/m68k.h |
Remove vendored M68K declarations. |
components/genesis/gwenesis/src/bus/gwenesis_bus.h |
Remove vendored Genesis bus declarations. |
components/genesis/gwenesis/src/bus/gwenesis_bus.c |
Remove vendored Genesis memory-bus implementation. |
components/genesis/gwenesis/README.md |
Remove the old vendored-snapshot README. |
components/genesis/gwenesis/CMakeLists.txt |
Remove the vendored core’s build configuration. |
components/genesis/CMakeLists.txt |
Use the submodule’s port sources and headers. |
CMakeLists.txt |
Enable and include the PICO-8 component. |
.gitmodules |
Register the gwenesis and femto8 submodules. |
.github/workflows/build.yml |
Initialize both new submodules before CI builds. |
Review effort: Balanced
|
|
||
| void init() { | ||
| #if defined(ENABLE_PICO8) | ||
| init_pico8(get_rom_filename(), romdata_, rom_size_bytes_); |
There was a problem hiding this comment.
Fixed in esp-cpp/femto8@3c5fc45 (pinned by 3c8ac29). The fix went into the shared init_pico8() rather than Pico8Cart, so esp-box-emu gets it too. It now drains gamepad_state_latched() and sets the input gate before starting the cart task, the same way resume already did.
ESP-IDF Size Report for 'Tab5 Emu'
FLASH uses app .bin size or json2 flash sum. RAM sums DRAM+IRAM via idf_size. Percentages shown when totals are available. |
Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01SFCMzomCZ5wRHJN4sxwkvY

Summary
esp32), shared with esp-box-emu. The P4's all-PSRAM buffer placement is theGENESIS_HOT_IN_PSRAMgate, so the Tab5 now picks up box-emu's newer glue:frame_slot_free(), plus theframes_dropped()/frames_blitted()/blit_cycles()counters, for the Genesis skip rule and its perf line;gamepad_state_latched()for PICO-8, so a press shorter than a frame isn't lost.esp32) as thepico8component;Pico8Cart, and.p8/.p8.pngdetection inrom_info;Tab5Emu::play_audio(PICO8_AUDIO_VIA_EMU), so femto8's 44.1 kHz output is resampled to the 48 kHz DAC;-msmall-data-limit=0, so the statics that the linker.lf reset covers stay in .bss/.data.Test plan
/sdcard/pico8/and ametadata.csvline; not tried yet.🤖 Generated with Claude Code
https://claude.ai/code/session_01SFCMzomCZ5wRHJN4sxwkvY