SDL3 is built from source by default and optionally statically linked; both of these are controlled using Cargo features in the CLI and GUI packages AppImage builds need to statically link SDL3 when building SDL3 from source because otherwise the AppImage build process won't locate the SDL3 shared library file (possibly a way to fix this but I didn't see anything obvious) these changes required removing two config settings: * borderless vs. exclusive fullscreen, since changing this seems to be much more difficult in SDL3 * audio hardware/device queue size, which SDL3 no longer seems to expose directly
6.9 KiB
Architecture
Overview
The crates can be broken up roughly into 6 categories:
- Common libraries:
jgenesis-common,jgenesis-proc-macros,cdrom,dsp - CPU emulators:
z80-emu,m68000-emu,mos6502-emu,wdc65816-emu,spc700-emu,sh2-emu - Config libraries:
smsgg-config,genesis-config,nes-config,snes-config,gb-config - Emulation backend:
smsgg-core,genesis-core,segacd-core,s32x-core,nes-core,snes-core,snes-coprocessors,gb-core,ym-opll - Emulation frontend:
jgenesis-renderer,jgenesis-native-driver,jgenesis-native-config,jgenesis-cli,jgenesis-gui,jgenesis-web - CPU emulator test harnesses:
z80-test-runner,m68000-test-runner,mos6502-test-runner,wdc65816-test-runner,spc700-test-runner
Repo structure:
common/contains common library cratescpu/contains the CPU emulator and test harness cratesconfig/contains the config library cratesbackend/contains the emulation backend cratesfrontend/contains the emulation frontend crates
The CPU emulators are designed to be usable with any implementation of their respective bus traits. The test harnesses provide a bus implementation that maps every address to RAM (which is what the tests expect), while the various consoles provide implementations that emulate the console's memory map.
The "config" crates contain common structs and enums that are both used in the corresponding backend crate and serialized into the frontend's config file. These are in separate crates from the backend cores to improve incremental compilation times, specifically by only re-executing serde and clap derive macros when needed.
For the most part, the backends interact with the frontends through trait implementations. The backends implement traits that enable frontend features including save states and rewind. The frontends provide trait implementations to the backends that enable the backends to display video frames, output audio samples, and persist any save files (e.g. for a cartridge with battery-backed SRAM). The frontends are also responsible for passing current emulated controller state to the backends (i.e. which buttons are currently pressed).
Common Crates
jgenesis-common
Contains traits that define the interface between the emulation backends and the emulation frontends, as well as some dependency-light common code that is used across many of the other crates (e.g. helper extension traits).
jgenesis-proc-macros
Custom derive macros and other proc macros used across many of the other crates.
cdrom
Contains code for reading CD-ROM images in CUE/BIN or CHD format.
dsp
DSP (digital signal processing) code, used primarily for audio-related functionality (e.g. resampling).
CPU Crates
z80-emu
Instruction-based emulation core for the Zilog Z80 CPU, which is used in the Master System, the Game Gear, and the Genesis.
m68000-emu
Instruction-based emulation core for the Motorola 68000 CPU, which is used in the Genesis and the Sega CD.
mos6502-emu
Cycle-based emulation core for the MOS 6502 CPU. Supports both the stock 6502 and the NES 6502.
wdc65816-emu
Cycle-based emulation core for the WDC 65C816 CPU (aka 65816), which is used in the SNES.
spc700-emu
Cycle-based emulation core for the Sony SPC700 CPU, which is used in the SNES as a dedicated audio processor embedded inside the APU.
sh2-emu
Instruction-based emulation core for the Hitachi SH-2 CPU, used in the Sega 32X and the Sega Saturn. This implementation includes the SH7604 hardware features.
Config Crates
smsgg-config
Common structs and enums for the Sega Master System and Game Gear.
genesis-config
Common structs and enums for the Sega Genesis, including Sega CD and 32X.
nes-config
Common structs and enums for NES.
snes-config
Common structs and enums for SNES.
gb-config
Common structs and enums for Game Boy and Game Boy Color.
Backend Crates
ym-opll
Emulation core for the Yamaha OPLL sound chip, used in the Sega Master System FM sound unit expansion and the NES VRC7 mapper.
smsgg-core
Emulation core for the Sega Master System and Game Gear. The core is shared because there are very few hardware differences between the two.
genesis-core
Emulation core for the Sega Genesis / Mega Drive. Uses the PSG component from smsgg-core, since the Genesis reused the Master System PSG as a secondary sound chip.
segacd-core
Emulation core for the Sega CD / Mega CD. Uses many components from genesis-core, as the Genesis side of the system is virtually unchanged except for the parts of the memory map that the standalone Genesis maps to the cartridge.
s32x-core
Emulation core for the Sega 32X / Mega 32X. Also uses many components from genesis-core.
nes-core
Emulation core for the Nintendo Entertainment System (NES) / Famicom.
snes-core
Emulation core for the Super Nintendo Entertainment System (SNES) / Super Famicom. Depends on snes-coprocessors to emulate cartridges that contain coprocessors.
snes-coprocessors
Emulation for coprocessors used in SNES cartridges. Coprocessor cartridge implementations expose methods such as reading a memory address, writing a memory address, and ticking the internal processor (for cartridges that contain a CPU or DSP).
gb-core
Emulation core for the Game Boy and Game Boy Color.
Frontend Crates
jgenesis-renderer
GPU-based implementation of the Renderer trait in jgenesis-traits, built on top of wgpu. Can be used with any window that implements the raw-window-handle traits. Exists in its own crate so that it can be used in both the native and web frontends.
jgenesis-native-driver
Native emulation frontend that uses SDL3 for windowing, audio, and input.
jgenesis-native-config
Contains the code representation of the configuration file used by the CLI and GUI.
jgenesis-cli / jgenesis-gui
CLI and GUI that both invoke jgenesis-native-driver to run the emulator. jgenesis-gui is built using egui and eframe.
jgenesis-web
Web emulation frontend that compiles to WASM and runs in a web browser.
CPU Test Harness Crates
z80-test-runner
Test harness to test z80-emu against Z80 test suites that were assembled for old PCs, such as ZEXDOC and ZEXALL.
m68000-test-runner
Test harness to test m68000-emu against TomHarte's 68000 test suite.
mos6502-test-runner
Test harness to test mos6502-emu against TomHarte's NES 6502 test suite.
wdc65816-test-runner
Test harness to test wdc65816-emu against TomHarte's 65816 test suite.
spc700-test-runner
Test harness to test spc700-emu against JSON SPC700 test suites.