69 Commits

Author SHA1 Message Date
Abdessamad Derraz
cbb86c7746 docs: add missing CLI flags to wiki tools page 2026-04-01 18:51:44 +02:00
Abdessamad Derraz
9bbd39369d fix: alias-only files missing from full packs
find_undeclared_files was enriching declared_names with DB aliases,
filtering core extras that were never packed by Phase 1 under that
name. Pass strict YAML names to _collect_emulator_extras so alias-
only files (dc_bios.bin, amiga-os-310-a1200.rom, scph102.bin, etc.)
get packed at the emulator's expected path. Also fix truth mode
output message and --all-variants --verify-packs quick-exit bypass.
2026-04-01 18:39:36 +02:00
Abdessamad Derraz
a1333137a0 fix: truth mode skipping phases 2-3 due to indent 2026-04-01 15:12:45 +02:00
Abdessamad Derraz
1efe95228f feat: propagate source flags to pipeline 2026-04-01 14:52:39 +02:00
Abdessamad Derraz
074e3371f2 feat: source mode text in pack readme 2026-04-01 14:52:25 +02:00
Abdessamad Derraz
85cc23398a feat: source-aware pack verification 2026-04-01 14:52:02 +02:00
Abdessamad Derraz
47a68c1a11 feat: add --source and --all-variants flags 2026-04-01 14:50:33 +02:00
Abdessamad Derraz
5f579d1851 feat: add source param to manifest and split packs 2026-04-01 14:44:39 +02:00
Abdessamad Derraz
2c1c2a7bfe feat: add combined source+required variant tests 2026-04-01 14:42:52 +02:00
Abdessamad Derraz
423a1b201e feat: add source param to generate_pack 2026-04-01 14:39:04 +02:00
Abdessamad Derraz
9c6b3dfe96 feat: add include_all to _collect_emulator_extras 2026-04-01 14:33:54 +02:00
Abdessamad Derraz
b070fa41de feat: add include_all param to find_undeclared_files 2026-04-01 14:29:31 +02:00
Abdessamad Derraz
0a272dc4e9 chore: lint and format entire codebase
Run ruff check --fix: remove unused imports (F401), fix f-strings
without placeholders (F541), remove unused variables (F841), fix
duplicate dict key (F601).

Run isort --profile black: normalize import ordering across all files.

Run ruff format: apply consistent formatting (black-compatible) to
all 58 Python files.

3 intentional E402 remain (imports after require_yaml() must execute
after yaml is available).
2026-04-01 13:17:55 +02:00
Abdessamad Derraz
a2d30557e4 chore: remove unused imports from generate_site.py 2026-04-01 13:13:06 +02:00
Abdessamad Derraz
0e6db8abdf docs: sync wiki sources with pipeline changes
Update wiki source files (the single source of truth for the site):
- tools.md: renumber pipeline steps 1-8, add step 6 (pack integrity),
  add missing CLI flags for cross_reference.py and refresh_data_dirs.py
- architecture.md: update mermaid diagram with pack integrity step,
  fix test file count (5 files, 249 tests)
- testing-guide.md: add test_pack_integrity section, add step 5 to
  verification discipline checklist
2026-04-01 13:08:19 +02:00
Abdessamad Derraz
6eca4c416a chore: remove dead wiki generator functions, update docs
Remove 4 unused functions from generate_site.py (generate_wiki_index,
generate_wiki_architecture, generate_wiki_tools, generate_wiki_profiling)
that contained stale data. Wiki pages are sourced from wiki/ directory.

Update generate_site.py contributing section with correct test counts
(249 total, 186 E2E, 8 pack integrity) and pack integrity documentation.
2026-04-01 13:05:34 +02:00
Abdessamad Derraz
e5859eb761 refactor: dry pack integrity into cli and update docs
Move verification logic to generate_pack.py --verify-packs (single
source of truth). test_pack_integrity.py is now a thin wrapper that
calls the CLI. Pipeline step 6/8 uses the same CLI entry point.

Renumber all pipeline steps 1-8 (was skipping from 5 to 8/9).

Update generate_site.py with pack integrity test documentation.
2026-04-01 12:31:10 +02:00
Abdessamad Derraz
754e829b35 feat: add pack integrity test and integrate into pipeline
Extract each platform ZIP to tmp/ (real filesystem, not /tmp tmpfs)
and verify every declared file exists at the correct path with the
correct hash per the platform's native verification mode.

Handles ZIP inner content verification (checkInsideZip, md5_composite,
inner ROM MD5) and path collision deduplication.

Integrated as pipeline step 6/8. Renumber all pipeline steps to be
sequential (was skipping from 5 to 8).
2026-04-01 12:22:50 +02:00
Abdessamad Derraz
7beb651049 fix: correct core extras placement for retrodeck and romm packs
RetroDECK: core extras with subdirectory paths (e.g. vice/C64/,
fbneo/, dc/) were placed outside bios/ because the prefix was only
inferred for bare filenames. Add _detect_extras_prefix() to infer
the dominant BIOS prefix from YAML destinations.

RomM: core extras landed flat at bios/{file} instead of the required
bios/{platform_slug}/{file}. Add _detect_slug_structure() to detect
per-system slug layouts and _map_emulator_to_slug() to route each
extra to the correct slug subfolder.

Also skip manifest writes when only the generated timestamp changed,
preventing unnecessary diffs in install/*.json.
2026-04-01 11:08:01 +02:00
Abdessamad Derraz
5eeaf87a3a fix: resolve all untested and missing bios across platforms
Batocera: fix sc3000.rom md5 (no dump matches upstream hash),
remove erroneous bk0010.zip mame entries (upstream confirmed
mame needs no bios for bk), add PSP2UPDAT.PUP correct version.
Recalbox: add MSX2R2.ROM from blueMSX v2.82.
RetroDECK: fix stale peribox_ev/gen.zip md5 hashes.

Regenerate database, manifests, readme.
2026-04-01 01:42:39 +02:00
Abdessamad Derraz
ab3255b0c7 chore: regenerate readme, manifests after md5 resolution fix 2026-03-31 14:37:52 +02:00
Abdessamad Derraz
2d17e0e9d9 fix: trust full MD5 for cross-name variant resolution 2026-03-31 14:17:24 +02:00
Abdessamad Derraz
03002515fe fix: readme and site coverage use data_dir and supplemental indexes 2026-03-31 13:58:52 +02:00
Abdessamad Derraz
eb354128e2 fix: consistency check allows pack to resolve more than verify 2026-03-31 13:46:12 +02:00
Abdessamad Derraz
6b5c3d8bf2 fix: pack conformance matches builder logic for perfect stats 2026-03-31 12:25:07 +02:00
Abdessamad Derraz
d685ad111d feat: add 63 missing BIOS files from multiple sources
MAME/MESS ROM sets (23 ZIPs from archive.org MESS 0.151 + MAME 0.285 split),
Dolphin BT firmware (15 files from linux-firmware), Commodore VIC-20/Plus4
regional ROMs (8 from zimmers.net), IBM AT 5170 BIOS + BASIC (3 from
minuszerodegrees.net + PCem), Apple DiskII boot/state-machine ROMs (4 from
Asimov mirror), Commodore 1540/1541 drive ROMs (2 reconstructed from MAME
chips), Oric Microdisc ROM, SMS Japanese BIOS, Videoton TVC64 + BK-0010
enriched ZIPs. All platforms at 0 required missing except Batocera bk0010.zip
(2/11 ROM chips unavailable).
2026-03-31 11:00:31 +02:00
Abdessamad Derraz
b56f8dd05f feat: add archive_prefix for core-specific BIOS subdirectories
Closes #43

FBNeo and Kronos expect BIOS archives in core-specific subdirectories
(system/fbneo/, system/kronos/). RetroArch firmware check uses .info
paths which include these prefixes, so files at root show as Missing.

Add archive_prefix field to emulator profiles. The pack code now places
archive copies in the prefixed subdirectory while keeping root copies
for cores that expect them there (e.g. Geolith for neogeo.zip).
2026-03-31 09:17:54 +02:00
Abdessamad Derraz
40ff2b5307 Merge branch 'main' of https://github.com/Abdess/retrobios 2026-03-30 23:58:20 +02:00
Abdessamad Derraz
d0dd05ddf6 docs: add wiki pages for all audiences, fix .old.yml leak
9 new wiki pages: getting-started, faq, troubleshooting,
advanced-usage, verification-modes, adding-a-platform,
adding-a-scraper, testing-guide, release-process.

Updated architecture.md with mermaid diagrams, tools.md with
full pipeline and target/exporter sections, profiling.md with
missing fields, index.md with glossary and nav links.

Expanded CONTRIBUTING.md from stub to full contributor guide.

Filter .old.yml from load_emulator_profiles, generate_db alias
collection, and generate_readme counts. Fix BizHawk sha1 mode
in tools.md, fix RetroPie path, fix export_truth.py typos.
2026-03-30 23:58:12 +02:00
Abdessamad Derraz
d4b0af0a38 docs: add wiki pages for all audiences, fix .old.yml leak
9 new wiki pages: getting-started, faq, troubleshooting,
advanced-usage, verification-modes, adding-a-platform,
adding-a-scraper, testing-guide, release-process.

Updated architecture.md with mermaid diagrams, tools.md with
full pipeline and target/exporter sections, profiling.md with
missing fields, index.md with glossary and nav links.

Expanded CONTRIBUTING.md from stub to full contributor guide.

Filter .old.yml from load_emulator_profiles, generate_db alias
collection, and generate_readme counts. Fix BizHawk sha1 mode
in tools.md, fix RetroPie path, fix export_truth.py typos.
2026-03-30 23:42:00 +02:00
Abdessamad Derraz
038c3d3b40 feat: enrich MAME/FBNeo profiles with upstream BIOS contents
auto-fetched from mamedev/mame 0.287 and finalburnneo/FBNeo v1.0.0.2.
mame: +20 new BIOS root sets, 96 entries enriched with contents.
mamearcade: 47 entries enriched with contents.
mamemess: 20 entries enriched with contents.
fbneo: +13 new ROM entries from upstream BIOS sets.
2026-03-30 21:39:02 +02:00
Abdessamad Derraz
427fef5669 fix: text-based YAML patching preserves formatting
replace yaml.dump with surgical text edits for contents/source_ref.
preserves comments, block scalars, quoting, indentation.
fix FBNeo new entry detection using parsed keys instead of text search.
2026-03-30 21:35:41 +02:00
Abdessamad Derraz
75e34898ee feat: add MAME/FBNeo hash auto-fetch scrapers
sparse clone upstream repos, parse BIOS root sets from C source,
cache as JSON, merge into emulator profiles with backup.
covers macro expansion, version detection, subset profile protection.
2026-03-30 19:11:26 +02:00
Abdessamad Derraz
94c3ac9834 feat: add hash merge for MAME and FBNeo profiles 2026-03-30 18:33:09 +02:00
Abdessamad Derraz
319a1d2041 feat: add MAME source code parser for BIOS root sets 2026-03-30 18:29:31 +02:00
Abdessamad Derraz
00d7b57884 feat: add FBNeo source parser for BIOS sets 2026-03-30 18:29:06 +02:00
Abdessamad Derraz
caf6285a04 fix: skip entries without md5 in batocera and retrobat exports 2026-03-30 17:46:48 +02:00
Abdessamad Derraz
529cb8a915 fix: recalbox paths from scrape, batocera md5 fallback from scrape 2026-03-30 17:35:39 +02:00
Abdessamad Derraz
1146fdf177 fix: rewrite emudeck exporter to match exact checkBIOS.sh format 2026-03-30 17:21:56 +02:00
Abdessamad Derraz
4fbb3571f8 fix: exporters use _dest fallback, merge colliding systems, per-platform subdirs 2026-03-30 17:15:44 +02:00
Abdessamad Derraz
0be68edad0 feat: add exporters for lakka, retropie, emudeck, retrodeck, romm 2026-03-30 17:07:08 +02:00
Abdessamad Derraz
1ffc4f89ca refactor: registry merge is fully flexible, no hardcoded lists 2026-03-30 16:38:13 +02:00
Abdessamad Derraz
f1ebfff5bd refactor: registry merge uses exclusion list instead of hardcoded fields 2026-03-30 16:36:40 +02:00
Abdessamad Derraz
425ea064ae fix: scrapers merge into existing YAML instead of overwriting 2026-03-30 16:31:40 +02:00
Abdessamad Derraz
6818a18a42 feat: load_platform_config merges all metadata from registry 2026-03-30 16:24:40 +02:00
Abdessamad Derraz
c11de6dba6 fix: restore retroarch.yml fields lost by scraper regeneration 2026-03-30 16:22:16 +02:00
Abdessamad Derraz
c4f3192020 fix: system.dat rom quoting, native_ids, acronym display names 2026-03-30 16:17:50 +02:00
Abdessamad Derraz
e2d0510f4e fix: exporters match exact native formats with display names 2026-03-30 16:09:02 +02:00
Abdessamad Derraz
74269bab84 fix: rewrite exporters to match exact native formats 2026-03-30 15:49:33 +02:00
Abdessamad Derraz
1e6b499602 feat: add batocera, recalbox, retrobat native exporters 2026-03-30 15:31:44 +02:00
Abdessamad Derraz
9b785ec785 feat: add missing laseractive sega pac bios files
v1.05 japan and v1.01 japan from archive.org.
v1.04 us variant alias for pioneer-named file.
resolves retrobat laseractive missing files.
2026-03-30 15:16:23 +02:00
Abdessamad Derraz
d415777f2c feat: add PS3UPDAT.PUP to rpcs3 profile
storage: large_file, validated via SCEUF magic + HMAC-SHA1
per entry (PUP.cpp:23-77). also adds missing standard fields
(cores, core_classification, upstream), removes non-standard
firmware_file/validation/firmware_version fields.
2026-03-30 15:06:51 +02:00
Abdessamad Derraz
eafabd20f3 refactor: skip writing generated files when content unchanged
write_if_changed in common.py compares content after stripping
timestamps (generated_at, Auto-generated on, Generated on).
applied to generate_db, generate_readme, generate_site.
eliminates timestamp-only diffs in database.json, README.md,
mkdocs.yml, and 423 docs pages.
2026-03-30 14:33:44 +02:00
Abdessamad Derraz
2aca4927c0 chore: regenerate database, readme, manifests, site 2026-03-30 14:19:00 +02:00
Abdessamad Derraz
17777f315b feat: agnostic bios mode for filename-agnostic emulators
bios_mode: agnostic (profile) and agnostic: true (file) for
emulators that accept any valid BIOS without specific filename.
find_undeclared_files skips agnostic entries, pack extras scan
includes all matching DB files by path prefix + size criteria,
resolve_local_file has agnostic fallback with rename README.
applied to pcsx2, lrps2 (bios_mode), melonds dsi_nand (file).
2026-03-30 14:18:54 +02:00
Abdessamad Derraz
692484d32d refactor: remove false aliases from pcsx2 and melonds profiles
aliases must be same-SHA1 alternative names, not distinct files.
pcsx2: 164 different BIOS dumps are separate DB entries, not aliases.
melonds: 6 regional NAND dumps are separate DB entries, not aliases.
also cleans pcsx2 non-standard fields, fixes display_name.
2026-03-30 12:37:32 +02:00
Abdessamad Derraz
a8430940f9 feat: add regional nand aliases to melonds profile
dsi_nand.bin aliases: DSi_Nand_USA/EUR/JPN/AUS/CHN/KOR.bin
for repo resolution. Code loads a single configurable path
(libretro.cpp:836, EmuInstance.cpp:1036-1050), validates
nocash footer (DSi_NAND.cpp:42-111). size + storage added.
2026-03-30 12:20:26 +02:00
Abdessamad Derraz
1f073f521d fix: preserve batocera version when github fetch fails 2026-03-30 11:55:57 +02:00
Abdessamad Derraz
903c49edcf feat: add tests for registry merge, all_libretro expansion, hash fallback, system normalization 2026-03-30 11:33:59 +02:00
Abdessamad Derraz
d3a2224dd2 chore: regenerate database, readme, manifests, site 2026-03-30 09:42:39 +02:00
Abdessamad Derraz
f898f26847 chore: regenerate retrobat.yml with corrected system slugs 2026-03-30 09:11:00 +02:00
Abdessamad Derraz
2712307420 feat: add tandy vis bios root set to mame profiles
vis.zip (p513bk0b.bin + p513bk1b.bin) from src/mame/trs/vis.cpp.
Driver added in MAME 0.180, not present in older cores.
2026-03-30 09:09:58 +02:00
Abdessamad Derraz
54022e9db1 feat: hash-based matching for cross-reference
expand_platform_declared_names resolves platform file MD5s
through the database to recover canonical names and aliases,
eliminating false positive undeclared files when a platform
renames a file (e.g. Batocera ROM1 vs gsplus ROM).
2026-03-30 08:25:54 +02:00
Abdessamad Derraz
4db9e4350c fix: add missing system slugs to batocera and retrobat scrapers 2026-03-30 07:58:46 +02:00
Abdessamad Derraz
6864ce6584 feat: diff hash fallback detects platform renames 2026-03-30 07:53:59 +02:00
Abdessamad Derraz
12196b6445 feat: add 55 missing cores across 6 platform registries 2026-03-30 07:17:57 +02:00
Abdessamad Derraz
7551e41a7b feat: load_platform_config merges cores from registry 2026-03-30 07:13:15 +02:00
Abdessamad Derraz
7b484605d4 feat: add 47 missing cores to batocera platform config 2026-03-30 07:09:52 +02:00
Abdessamad Derraz
b587381f05 feat: resolve_platform_cores expands all_libretro in list 2026-03-30 07:06:32 +02:00
167 changed files with 56770 additions and 6557 deletions

3
.gitignore vendored
View File

@@ -29,13 +29,14 @@ data/
# Large files stored as GitHub Release assets (additional)
bios/Arcade/MAME/artwork/snspell.zip
bios/Arcade/MAME/MAME 0.174 Arcade XML.dat
bios/Sony/PlayStation Vita/.variants/PSP2UPDAT.PUP
bios/Sony/PlayStation Vita/.variants/PSP2UPDAT.PUP.3ae832c9
bios/Nintendo/DS/DSi_Nand_JPN.bin
bios/Nintendo/DS/DSi_Nand_EUR.bin
bios/Nintendo/DS/DSi_Nand_USA.bin
bios/Nintendo/DS/DSi_Nand_AUS.bin
bios/Nintendo/DS/DSi_Nand_CHN.bin
bios/Nintendo/DS/DSi_Nand_KOR.bin
bios/Nintendo/DS/dsi_nand.bin
# QEMU EDK2 firmware (64MB each)
bios/QEMU/edk2-aarch64-code.fd

View File

@@ -2,7 +2,7 @@
Complete BIOS and firmware packs for Batocera, BizHawk, EmuDeck, Lakka, Recalbox, RetroArch, RetroBat, RetroDECK, RetroPie, and RomM.
**7,244** verified files across **387** systems, ready to extract into your emulator's BIOS directory.
**7,295** verified files across **396** systems, ready to extract into your emulator's BIOS directory.
## Quick Install
@@ -27,14 +27,14 @@ Pick your platform, download the ZIP, extract to the BIOS path.
| Platform | BIOS files | Extract to | Download |
|----------|-----------|-----------|----------|
| Batocera | 359 | `/userdata/bios/` | [Download](../../releases/latest) |
| Batocera | 361 | `/userdata/bios/` | [Download](../../releases/latest) |
| BizHawk | 118 | `Firmware/` | [Download](../../releases/latest) |
| EmuDeck | 161 | `Emulation/bios/` | [Download](../../releases/latest) |
| Lakka | 448 | `system/` | [Download](../../releases/latest) |
| Recalbox | 346 | `/recalbox/share/bios/` | [Download](../../releases/latest) |
| RetroArch | 448 | `system/` | [Download](../../releases/latest) |
| RetroBat | 331 | `bios/` | [Download](../../releases/latest) |
| RetroDECK | 2007 | `~/retrodeck/bios/` | [Download](../../releases/latest) |
| RetroBat | 339 | `bios/` | [Download](../../releases/latest) |
| RetroDECK | 2006 | `~/retrodeck/bios/` | [Download](../../releases/latest) |
| RetroPie | 448 | `BIOS/` | [Download](../../releases/latest) |
| RomM | 374 | `bios/{platform_slug}/` | [Download](../../releases/latest) |
@@ -44,14 +44,14 @@ BIOS, firmware, and system files for consoles from Atari to PlayStation 3.
Each file is checked against the emulator's source code to match what the code actually loads at runtime.
- **10 platforms** supported with platform-specific verification
- **328 emulators** profiled from source (RetroArch cores + standalone)
- **387 systems** covered (NES, SNES, PlayStation, Saturn, Dreamcast, ...)
- **7,244 files** verified with MD5, SHA1, CRC32 checksums
- **9266 MB** total collection size
- **329 emulators** profiled from source (RetroArch cores + standalone)
- **396 systems** covered (NES, SNES, PlayStation, Saturn, Dreamcast, ...)
- **7,295 files** verified with MD5, SHA1, CRC32 checksums
- **8765 MB** total collection size
## Supported systems
NES, SNES, Nintendo 64, GameCube, Wii, Game Boy, Game Boy Advance, Nintendo DS, Nintendo 3DS, Switch, PlayStation, PlayStation 2, PlayStation 3, PSP, PS Vita, Mega Drive, Saturn, Dreamcast, Game Gear, Master System, Neo Geo, Atari 2600, Atari 7800, Atari Lynx, Atari ST, MSX, PC Engine, TurboGrafx-16, ColecoVision, Intellivision, Commodore 64, Amiga, ZX Spectrum, Arcade (MAME), and 353+ more.
NES, SNES, Nintendo 64, GameCube, Wii, Game Boy, Game Boy Advance, Nintendo DS, Nintendo 3DS, Switch, PlayStation, PlayStation 2, PlayStation 3, PSP, PS Vita, Mega Drive, Saturn, Dreamcast, Game Gear, Master System, Neo Geo, Atari 2600, Atari 7800, Atari Lynx, Atari ST, MSX, PC Engine, TurboGrafx-16, ColecoVision, Intellivision, Commodore 64, Amiga, ZX Spectrum, Arcade (MAME), and 362+ more.
Full list with per-file details: **[https://abdess.github.io/retrobios/](https://abdess.github.io/retrobios/)**
@@ -59,16 +59,16 @@ Full list with per-file details: **[https://abdess.github.io/retrobios/](https:/
| Platform | Coverage | Verified | Untested | Missing |
|----------|----------|----------|----------|---------|
| Batocera | 359/359 (100.0%) | 354 | 5 | 0 |
| Batocera | 361/361 (100.0%) | 361 | 0 | 0 |
| BizHawk | 118/118 (100.0%) | 118 | 0 | 0 |
| EmuDeck | 161/161 (100.0%) | 161 | 0 | 0 |
| Lakka | 443/448 (98.9%) | 443 | 0 | 5 |
| Recalbox | 276/346 (79.8%) | 273 | 3 | 70 |
| RetroArch | 443/448 (98.9%) | 443 | 0 | 5 |
| RetroBat | 330/331 (99.7%) | 326 | 4 | 1 |
| RetroDECK | 1958/2007 (97.6%) | 1932 | 26 | 49 |
| RetroPie | 443/448 (98.9%) | 443 | 0 | 5 |
| RomM | 372/374 (99.5%) | 372 | 0 | 2 |
| Lakka | 448/448 (100.0%) | 448 | 0 | 0 |
| Recalbox | 346/346 (100.0%) | 346 | 0 | 0 |
| RetroArch | 448/448 (100.0%) | 448 | 0 | 0 |
| RetroBat | 339/339 (100.0%) | 339 | 0 | 0 |
| RetroDECK | 2006/2006 (100.0%) | 2006 | 0 | 0 |
| RetroPie | 448/448 (100.0%) | 448 | 0 | 0 |
| RomM | 374/374 (100.0%) | 374 | 0 | 0 |
## Build your own pack
@@ -104,7 +104,7 @@ The [documentation site](https://abdess.github.io/retrobios/) provides:
- **Per-emulator profiles** with source code references for every file
- **Per-system pages** showing which emulators and platforms cover each console
- **Gap analysis** identifying missing files and undeclared core requirements
- **Cross-reference** mapping files across 10 platforms and 328 emulators
- **Cross-reference** mapping files across 10 platforms and 329 emulators
## How it works
@@ -130,4 +130,4 @@ See [CONTRIBUTING.md](CONTRIBUTING.md) for guidelines.
This repository provides BIOS files for personal backup and archival purposes.
*Auto-generated on 2026-03-29T21:00:40Z*
*Auto-generated on 2026-03-31T20:38:37Z*

Binary file not shown.

Binary file not shown.

View File

@@ -0,0 +1,65 @@
ИИ<EFBFBD>Ш
<EFBFBD>Щ<EFBFBD>Щ<EFBFBD>Ы<EFBFBD>Ы<EFBFBD>ШШ
<EFBFBD>Щ<EFBFBD>Щ<EFBFBD>Ы<EFBFBD>ЫИ=ИИ
<EFBFBD>й<EFBFBD>й<EFBFBD>л<EFBFBD>л<EFBFBD>н<EFBFBD>и
<EFBFBD>й<EFBFBD>й<EFBFBD>л<EFBFBD>лИИИИ
ЈшЈшЈшЈшЈшЈш
ЈшЈшЈшЈшЙ§Иј
ИјИјИјИјЙ§Pј
ИјИјИјИјИИHИ
H(H(H(H(H(H(
H(H(H(H(ИЙИИ
X8X8X8X8 ЩX8
X8X8X8X8ИИИИ
hhhhhh
hhhh<18>Нxp
xxxx
-xp

View File

@@ -0,0 +1,65 @@
Ш
99;;8(
99;;-Ш8H
(H(H(H(H-H8H
(H(H(H(HШШШШ
XxXxXxXxXxXx
XxXxXxXxШШШШ
hh€hh€h€h€
hh€hh€ШНШШ
<EFBFBD><EFBFBD><EFBFBD>»<EFBFBD>»<EFBFBD>Ѕ<EFBFBD>ё
<EFBFBD><EFBFBD><EFBFBD>»<EFBFBD>»ШЩШШ
ЁИЁИЁИЁИ)YЁИ
ЁИЁИЁИЁИЩэШш
ШшШшШшШшЩэ ш
ШшШшШшШшШЭиа
и€ии€иа
и€ии€и

Binary file not shown.

Binary file not shown.

Binary file not shown.

BIN
bios/Arcade/MAME/bk0010.zip Normal file

Binary file not shown.

Binary file not shown.

BIN
bios/Arcade/MAME/cp500.zip Normal file

Binary file not shown.

BIN
bios/Arcade/MAME/eg3003.zip Normal file

Binary file not shown.

BIN
bios/Arcade/MAME/fmnew7.zip Normal file

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

BIN
bios/Arcade/MAME/pc6601.zip Normal file

Binary file not shown.

Binary file not shown.

BIN
bios/Arcade/MAME/pc8001.zip Normal file

Binary file not shown.

Binary file not shown.

BIN
bios/Arcade/MAME/sys80.zip Normal file

Binary file not shown.

BIN
bios/Arcade/MAME/ti99_4.zip Normal file

Binary file not shown.

Binary file not shown.

BIN
bios/Arcade/MAME/tvc64.zip Normal file

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

BIN
bios/NEC/PC-8001/pc8001.zip Normal file

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

BIN
bios/Videoton/TVC/tvc64.zip Normal file

Binary file not shown.

File diff suppressed because it is too large Load Diff

View File

@@ -5,7 +5,7 @@ source: "https://github.com/libretro/FBNeo"
upstream: "https://github.com/finalburnneo/FBNeo"
logo: "https://raw.githubusercontent.com/finalburnneo/FBNeo/master/projectfiles/xcode/Emulator/Assets.xcassets/AppIcon.appiconset/icon_512.png"
profiled_date: "2026-03-23"
core_version: "v1.0.0.03"
core_version: "v1.0.0.2"
display_name: "Arcade (FinalBurn Neo)"
cores:
- fbneo
@@ -33,6 +33,8 @@ systems:
- taito-cchip
- ym2608
archive_prefix: fbneo
data_directories:
- ref: fbneo-cheats
destination: fbneo/cheats
@@ -1485,3 +1487,94 @@ files:
size: 155000000
note: "Two Tigers with Journey CD audio samples (2 WAVs)"
source_ref: "src/burn/snd/samples.cpp"
- name: "coleco.rom"
archive: cv_coleco.zip
required: true
size: 8192
crc32: "3aa93ef3"
source_ref: "src/burn/drv/coleco/d_coleco.cpp:1079"
- name: "colecoa.rom"
archive: cv_coleco.zip
required: true
size: 8192
crc32: "39bb16fc"
source_ref: "src/burn/drv/coleco/d_coleco.cpp:1079"
- name: "svi603.rom"
archive: cv_coleco.zip
required: true
size: 8192
crc32: "19e91b82"
source_ref: "src/burn/drv/coleco/d_coleco.cpp:1079"
- name: "czz50.rom"
archive: cv_coleco.zip
required: true
size: 16384
crc32: "4999abc6"
source_ref: "src/burn/drv/coleco/d_coleco.cpp:1079"
- name: "fdsbios.nes"
archive: fds_fdsbios.zip
required: true
size: 8192
crc32: "5e607dcf"
source_ref: "src/burn/drv/nes/d_nes.cpp:523"
- name: "st010.bin"
archive: snes_st010.zip
required: true
size: 69632
crc32: "aa11ee2d"
source_ref: "src/burn/drv/snes/d_snes.cpp:577"
- name: "st011.bin"
archive: snes_st011.zip
required: true
size: 69632
crc32: "34d2952c"
source_ref: "src/burn/drv/snes/d_snes.cpp:596"
- name: "msx.rom"
archive: msx_msx.zip
required: true
size: 32768
crc32: "a317e6b4"
source_ref: "src/burn/drv/msx/d_msx.cpp:1781"
- name: "msxj.rom"
archive: msx_msx.zip
required: true
size: 32768
crc32: "071135e0"
source_ref: "src/burn/drv/msx/d_msx.cpp:1781"
- name: "kanji.rom"
archive: msx_msx.zip
required: true
size: 262144
crc32: "1f6406fb"
source_ref: "src/burn/drv/msx/d_msx.cpp:1781"
- name: "supernova_modbios-japan.u10"
archive: skns.zip
required: true
size: 524288
crc32: "b8d3190c"
source_ref: "src/burn/drv/pst90s/d_suprnova.cpp:1865"
- name: "supernova-modbios-korea.u10"
archive: skns.zip
required: true
size: 524288
crc32: "1d90517c"
source_ref: "src/burn/drv/pst90s/d_suprnova.cpp:1865"
- name: "mcu"
archive: bubsys.zip
required: true
size: 4096
crc32: "00000000"
source_ref: "src/burn/drv/konami/d_nemesis.cpp:4539"

View File

@@ -32,6 +32,8 @@ notes: |
need_fullpath=false, extensions=zip|7z, savestate=deterministic.
archive_prefix: fbneo
files:
- name: "hiscore.dat"
path: "fbneo/hiscore.dat"

View File

@@ -38,6 +38,8 @@ notes: |
need_fullpath=false, extensions=zip|7z|cue|ccd, savestate=deterministic.
archive_prefix: fbneo
files:
# -------------------------------------------------------
# Neo Geo MVS/AES (neogeo.zip) — 68K BIOS ROMs

View File

@@ -38,11 +38,14 @@ notes: |
Standalone supports MPEG card ROM loading (Video CD card); disabled in
libretro port (mpegpath = NULL in libretro.c:1578).
archive_prefix: kronos
files:
# -----------------------------------------------------------
# Saturn BIOS - primary (any region)
# -----------------------------------------------------------
- name: "saturn_bios.bin"
path: "kronos/saturn_bios.bin"
system: sega-saturn
required: true
size: 524288

View File

@@ -5,6 +5,7 @@
emulator: LRPS2
type: libretro
core_classification: community_fork
bios_mode: agnostic
source: "https://github.com/libretro/ps2"
upstream: "https://github.com/PCSX2/pcsx2"
profiled_date: "2026-03-25"

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@@ -77,11 +77,14 @@ files:
source_ref: "src/SPI.cpp:197-211, src/frontend/Util_ROM.cpp:201-217"
- name: dsi_nand.bin
agnostic: true
system: nintendo-dsi
description: "DSi NAND dump"
required: true
source_ref: "src/frontend/Util_ROM.cpp:224-235, src/DSi_NAND.cpp"
note: "Uses AES keys from ARM7i BIOS offset 0x8308"
size: 251658304
storage: large_file
source_ref: "src/frontend/Util_ROM.cpp:224-235, src/DSi_NAND.cpp:58-97"
note: "Any regional dump works. Nocash footer required (DSi eMMC CID/CPU at EOF-0x40 or 0xFF800). AES keys derived from ARM7i BIOS offset 0x8308."
- name: dsi_sd_card.bin
system: nintendo-dsi

View File

@@ -1,219 +1,74 @@
# PCSX2 emulator BIOS profile
# Generated from source analysis of https://github.com/PCSX2/pcsx2
# Commit analyzed: HEAD as of 2026-03-17
emulator: PCSX2
type: standalone
core_classification: official_port
bios_mode: agnostic
source: "https://github.com/PCSX2/pcsx2"
logo: "https://raw.githubusercontent.com/PCSX2/pcsx2/master/pcsx2-qt/resources/icons/PCSX2logo.svg"
profiled_date: "2026-03-18"
upstream: "https://github.com/PCSX2/pcsx2"
cores:
- pcsx2
profiled_date: "2026-03-30"
core_version: "Git"
display_name: "Sony - PlayStation 2 (LRPS2)"
display_name: "Sony - PlayStation 2 (PCSX2)"
systems: [sony-playstation-2]
bios_directory: "bios/"
bios_detection: "romdir" # scans romdir structure inside binary, looks for RESET/ROMVER/EXTINFO entries
bios_selection: "automatic" # scans all files in bios dir matching 4-8 MB size, validates via romdir
validation:
method: "romdir_parse"
min_size: 4194304 # 4 MB (MIN_BIOS_SIZE = 4 * _1mb)
max_size: 8388608 # 8 MB (MAX_BIOS_SIZE = 8 * _1mb)
required_entries: ["RESET", "ROMVER"]
optional_entries: ["EXTINFO"]
note: "Any file in bios/ between 4-8 MB with valid romdir containing RESET+ROMVER is accepted"
regions:
J: {zone: "Japan", id: 0}
A: {zone: "USA", id: 1}
E: {zone: "Europe", id: 2}
H: {zone: "Asia", id: 4}
C: {zone: "China", id: 6}
T: {zone: "T10K/COH-H", id: 8}
X: {zone: "Test", id: 9}
P: {zone: "Free", id: 10}
notes: |
Filename-agnostic BIOS detection. Scans bios/ for any file between 4-8 MB
with valid romdir structure (RESET + ROMVER entries). No hash validation.
Companion files (.rom1, .rom2, .nvm, .mec) derive paths from selected BIOS.
ROM1 (DVD player) and ROM2 (Chinese extension) silently skipped if missing.
NVM and MEC auto-created with defaults if missing.
files:
# -- Main BIOS binary (required) --
- name: "<user-selected>.bin"
pattern: "*"
- name: ps2-0230a-20080220.bin
required: true
size_range: "4MB-8MB"
source_ref: "pcsx2/ps2/BiosTools.cpp:258-282"
note: >
PCSX2 does not mandate a specific filename. It scans the entire bios/ directory
for any file between 4-8 MB that contains a valid romdir structure (RESET + ROMVER entries).
Common filenames follow the SCPH-XXXXX_BIOS_VYYY_REGION_ZZZ.BIN convention but this is
not enforced. The file is loaded into the 4 MB ROM region of EE memory.
min_size: 4194304
max_size: 8388608
validation: [size]
source_ref: "pcsx2/ps2/BiosTools.cpp:258-362"
note: "Accepts any file 4-8 MB with valid romdir (RESET + ROMVER). Naming convention ps2-VVVVr-YYYYMMDD.bin (version, region, date)."
# -- ROM1 (optional, DVD player) --
- name: "<biosname>.rom1"
pattern: "{biosname}.rom1 or {biosbase}.rom1"
- name: rom1.bin
required: false
max_size: 4194304 # 4 MB (Ps2MemSize::Rom1)
source_ref: "pcsx2/ps2/BiosTools.cpp:214-241"
note: >
DVD player ROM. Loaded via LoadExtraRom("rom1"). PCSX2 tries two naming patterns:
1) Full bios path + ".rom1" appended (e.g. scph70004.bin.rom1)
2) Bios path with extension replaced (e.g. scph70004.rom1)
Mapped to EE memory at ROM1 region (0x1FC00000 + 4MB offset).
Contains DVD player and region detection data (DVDID).
max_size: 4194304
source_ref: "pcsx2/ps2/BiosTools.cpp:214-241,366"
note: "DVD player ROM. Tries {biospath}.rom1 then {biosbase}.rom1. Silently skipped if missing."
# -- ROM2 (optional, Chinese ROM extension) --
- name: "<biosname>.rom2"
pattern: "{biosname}.rom2 or {biosbase}.rom2"
- name: ROM2.BIN
required: false
max_size: 4194304 # 4 MB (Ps2MemSize::Rom2)
source_ref: "pcsx2/ps2/BiosTools.cpp:214-241"
note: >
Chinese ROM extension. Loaded via LoadExtraRom("rom2"). Same naming convention
as rom1: tries appended extension first, then replaced extension.
Only present on Chinese region consoles.
max_size: 4194304
source_ref: "pcsx2/ps2/BiosTools.cpp:214-241,367"
note: "Chinese ROM extension. Same naming convention as rom1. Only present on Chinese region consoles."
# -- NVM / NVRAM (optional, auto-created) --
- name: "<biosname>.nvm"
pattern: "{biosbase}.nvm"
- name: EROM.BIN
required: false
source_ref: "pcsx2/ps2/BiosTools.cpp"
note: "Extended ROM. Present in some BIOS dumps but not loaded by PCSX2 code via LoadExtraRom."
path: null
- name: eeprom.dat
required: false
hle_fallback: true
size: 1024 # NVRAM_SIZE = 1024 bytes
source_ref: "pcsx2/CDVD/CDVD.cpp:160-238"
note: >
EEPROM / NVRAM data. Path derived from BiosPath with extension replaced to ".nvm"
(cdvdGetNVRAMPath). Contains console configuration: language, timezone, iLink ID,
region parameters, OSD settings. Auto-created with defaults if missing.
Two NVM layouts exist: v0.00+ (biosVer 0x000) and v1.70+ (biosVer 0x146).
# -- MEC file (optional, auto-created) --
- name: "<biosname>.mec"
pattern: "{biosbase}.mec"
required: false
hle_fallback: true
size: 4 # u32 s_mecha_version
source_ref: "pcsx2/CDVD/CDVD.cpp:190-204"
note: >
Mechacon (mechanism controller) version file. 4 bytes containing the mecha version
as a u32 value. Auto-created with DEFAULT_MECHA_VERSION (0x00020603) if missing.
Path derived from BiosPath with extension replaced to ".mec".
# -- IRX override (optional, advanced) --
- name: "<custom>.irx"
pattern: "*.irx"
required: false
source_ref: "pcsx2/ps2/BiosTools.cpp:243-256,384-385"
note: >
Custom IOP Reboot eXecutable module. Loaded into ROM at offset 0x3C0000 if
EmuConfig.CurrentIRX is set (path length > 3). Injected at IOP reset (PC=0x1630).
Used for debugging/development, not needed for normal operation.
# -- DEV9 EEPROM (optional, network adapter) --
- name: "eeprom.dat"
required: false
hle_fallback: true
size: 64 # 64 bytes, mmap'd
size: 64
source_ref: "pcsx2/DEV9/DEV9.cpp:110-160"
note: >
DEV9 (network adapter / HDD expansion bay) EEPROM data. Fixed filename "eeprom.dat"
opened from working directory. Contains network adapter configuration.
Falls back to built-in defaults if file not found. Only relevant when using
DEV9 features (online play, HDD).
note: "DEV9 network adapter EEPROM. Falls back to built-in defaults if missing."
common_bios_filenames:
# Japan
- "SCPH-10000_BIOS_V1_JAP_100.BIN"
- "SCPH-15000_BIOS_V3_JAP_120.BIN"
- "SCPH-30000_BIOS_V4_JAP_150.BIN"
- "SCPH-30001R_BIOS_V7_JAP_160.BIN"
- "SCPH-30004R_BIOS_V7_JAP_160.BIN"
- "SCPH-35000_BIOS_V5_JAP_160.BIN"
- "SCPH-50000_BIOS_V9_JAP_170.BIN"
- "SCPH-50004_BIOS_V9_JAP_170.BIN"
- "SCPH-70000_BIOS_V12_JAP_200.BIN"
- "SCPH-75000_BIOS_V14_JAP_220.BIN"
- "SCPH-77000_BIOS_V14_JAP_220.BIN"
- "SCPH-90000_BIOS_V18_JAP_230.BIN"
# USA
- "SCPH-30001_BIOS_V4_USA_150.BIN"
- "SCPH-39001_BIOS_V6_USA_160.BIN"
- "SCPH-50001_BIOS_V9_USA_170.BIN"
- "SCPH-50003_BIOS_V9_USA_170.BIN"
- "SCPH-70002_BIOS_V12_USA_200.BIN"
- "SCPH-70004_BIOS_V12_USA_200.BIN"
- "SCPH-70012_BIOS_V12_USA_200.BIN"
- "SCPH-75001_BIOS_V14_USA_220.BIN"
- "SCPH-77001_BIOS_V14_USA_220.BIN"
- "SCPH-90001_BIOS_V18_USA_230.BIN"
# Europe
- "SCPH-30002_BIOS_V4_EUR_150.BIN"
- "SCPH-30003_BIOS_V4_EUR_150.BIN"
- "SCPH-30004_BIOS_V4_EUR_150.BIN"
- "SCPH-39002_BIOS_V6_EUR_160.BIN"
- "SCPH-39003_BIOS_V6_EUR_160.BIN"
- "SCPH-39004_BIOS_V6_EUR_160.BIN"
- "SCPH-50002_BIOS_V9_EUR_170.BIN"
- "SCPH-50004_BIOS_V9_EUR_170.BIN"
- "SCPH-70002_BIOS_V12_EUR_200.BIN"
- "SCPH-70003_BIOS_V12_EUR_200.BIN"
- "SCPH-70004_BIOS_V12_EUR_200.BIN"
- "SCPH-70008_BIOS_V12_EUR_200.BIN"
- "SCPH-75002_BIOS_V14_EUR_220.BIN"
- "SCPH-75003_BIOS_V14_EUR_220.BIN"
- "SCPH-75004_BIOS_V14_EUR_220.BIN"
- "SCPH-77002_BIOS_V14_EUR_220.BIN"
- "SCPH-77003_BIOS_V14_EUR_220.BIN"
- "SCPH-77004_BIOS_V14_EUR_220.BIN"
- "SCPH-90002_BIOS_V18_EUR_230.BIN"
- "SCPH-90003_BIOS_V18_EUR_230.BIN"
- "SCPH-90004_BIOS_V18_EUR_230.BIN"
# Asia
- "SCPH-50009_BIOS_V9_HK_170.BIN"
- "SCPH-70005_BIOS_V12_HK_200.BIN"
- "SCPH-70006_BIOS_V12_HK_200.BIN"
- "SCPH-70008_BIOS_V12_HK_200.BIN"
# China
- "SCPH-50009_BIOS_V9_CHN_170.BIN"
- "SCPH-70006_BIOS_V12_CHN_200.BIN"
- name: GameIndex.yaml
path: pcsx2/resources/GameIndex.yaml
required: false
mode: libretro
source_ref: "pcsx2/GameDatabase.cpp:48,880"
note: "Game compatibility database. OSD warning if missing."
memory_layout:
ROM: {offset: "0x1FC00000", size: "4 MB", purpose: "Main BIOS binary"}
ROM1: {offset: "ROM + 4MB", size: "4 MB", purpose: "DVD player"}
ROM2: {offset: "ROM + 8MB", size: "4 MB", purpose: "Chinese ROM extension"}
- name: cheats_ws.zip
path: pcsx2/resources/cheats_ws.zip
required: false
mode: libretro
source_ref: "pcsx2/VMManager.cpp:340-353"
note: "Widescreen patches archive."
nvm_layout:
format_0:
applies_to: "BIOS v0.00+"
biosVer: 0x000
config0: 0x280
config1: 0x300
config2: 0x200
consoleId: 0x1C8
ilinkId: 0x1C0
modelNum: 0x1A0
regparams: 0x180
mac: 0x198
format_1:
applies_to: "BIOS v1.70+"
biosVer: 0x146
config0: 0x270
config1: 0x2B0
config2: 0x200
consoleId: 0x1F0
ilinkId: 0x1E0
modelNum: 0x1B0
regparams: 0x180
mac: 0x198
notes: |
PCSX2 is filename-agnostic for the main BIOS. Detection relies on romdir structure
parsing inside the binary itself, not on filename or extension. Any file between 4-8 MB
with a valid romdir (containing at least RESET and ROMVER entries) is accepted.
The ROMVER entry encodes: version (2+2 digits), region letter, console/devel flag,
build date (YYYYMMDD), and is used to determine the BIOS description and region.
Companion files (.nvm, .mec) are auto-created with sane defaults if missing.
ROM1/ROM2 are silently skipped if not found - only the main BIOS binary is strictly required.
PCSX2 no longer ships as a libretro core in official builds. The standalone emulator
is the primary distribution channel.
Devel console BIOSes (< ~2.3 MB) lack the OSD and are handled with NoOSD=true flag.
- name: cheats_ni.zip
path: pcsx2/resources/cheats_ni.zip
required: false
mode: libretro
source_ref: "pcsx2/VMManager.cpp:375-388"
note: "No-interlacing patches archive."

View File

@@ -1,32 +1,21 @@
# RPCS3 emulator firmware profile
# Generated from source analysis of https://github.com/RPCS3/rpcs3
# Commit analyzed: HEAD as of 2026-03-17
emulator: RPCS3
type: standalone
core_classification: official_port
source: "https://github.com/RPCS3/rpcs3"
logo: "https://raw.githubusercontent.com/RPCS3/rpcs3/master/rpcs3/rpcs3.svg"
profiled_date: "2026-03-18"
upstream: "https://github.com/RPCS3/rpcs3"
cores:
- rpcs3
profiled_date: "2026-03-30"
core_version: "0.0.35"
display_name: "RPCS3 (PS3)"
display_name: "Sony - PlayStation 3 (RPCS3)"
systems: [sony-playstation-3]
firmware_file: "PS3UPDAT.PUP"
firmware_source: "https://www.playstation.com/en-us/support/hardware/ps3/system-software/"
firmware_detection: "pup_header" # validates PUP magic bytes, HMAC-SHA1 hash per entry
firmware_install: "extracts dev_flash_* TAR packages from PUP into dev_flash/"
validation:
method: "pup_object"
magic: "SCEUF"
hash_algo: "HMAC-SHA1"
source_ref: "rpcs3/Loader/PUP.cpp:8-114"
note: "PUP file is validated by magic header, file count, HMAC-SHA1 per entry against PUP_KEY"
firmware_version:
path: "dev_flash/vsh/etc/version.txt"
source_ref: "rpcs3/util/sysinfo.cpp:686"
note: "Read at startup, displayed as 'Firmware version: X.XX'. Missing = 'Missing Firmware'"
files:
- name: PS3UPDAT.PUP
required: true
storage: large_file
source_ref: "rpcs3/Loader/PUP.cpp:23-77"
note: "PUP firmware package. Validated via SCEUF magic + HMAC-SHA1 per entry. Extracted to dev_flash/ at install time."
# dev_flash filesystem layout extracted from PUP
dev_flash:

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@@ -37,7 +37,11 @@ markdown_extensions:
- toc:
permalink: true
- pymdownx.details
- pymdownx.superfences
- pymdownx.superfences:
custom_fences:
- name: mermaid
class: mermaid
format: !!python/name:pymdownx.superfences.fence_code_format
- pymdownx.tabbed:
alternate_style: true
plugins:
@@ -132,7 +136,7 @@ nav:
- ZC: systems/zc.md
- Emulators:
- Overview: emulators/index.md
- Official ports (61):
- Official ports (63):
- amiarcadia: emulators/amiarcadia.md
- Amiberry: emulators/amiberry.md
- Ardens: emulators/ardens.md
@@ -176,9 +180,11 @@ nav:
- mGBA: emulators/mgba.md
- Mr.Boom: emulators/mrboom.md
- Panda3DS: emulators/panda3ds.md
- PCSX2: emulators/pcsx2.md
- PicoDrive: emulators/picodrive.md
- play: emulators/play.md
- PPSSPP: emulators/ppsspp.md
- RPCS3: emulators/rpcs3.md
- Rustation: emulators/rustation.md
- RVVM: emulators/rvvm.md
- SameBoy: emulators/sameboy.md
@@ -428,7 +434,7 @@ nav:
- PCSX-ReARMed: emulators/pcsx_rearmed.md
- Launchers (1):
- Dolphin Launcher: emulators/dolphin_launcher.md
- Other (24):
- Other (23):
- ares: emulators/ares.md
- Beetle GBA (Mednafen): emulators/beetle_gba.md
- BigPEmu: emulators/bigpemu.md
@@ -440,12 +446,11 @@ nav:
- Lexaloffle: emulators/lexaloffle.md
- Model 2 Emulator: emulators/model2.md
- openMSX: emulators/openmsx.md
- PCSX2: emulators/pcsx2.md
- Redream: emulators/redream.md
- RPCS3: emulators/rpcs3.md
- Ryujinx: emulators/ryujinx.md
- shadps4: emulators/shadps4.md
- Supermodel: emulators/supermodel.md
- ti99sim: emulators/ti99sim.md
- tsugaru: emulators/tsugaru.md
- VBA-M: emulators/vba_m.md
- VICE: emulators/vice.md
@@ -457,8 +462,17 @@ nav:
- Gap Analysis: gaps.md
- Wiki:
- Overview: wiki/index.md
- Getting started: wiki/getting-started.md
- FAQ: wiki/faq.md
- Troubleshooting: wiki/troubleshooting.md
- Architecture: wiki/architecture.md
- Tools: wiki/tools.md
- Profiling guide: wiki/profiling.md
- Advanced usage: wiki/advanced-usage.md
- Verification modes: wiki/verification-modes.md
- Data model: wiki/data-model.md
- Profiling guide: wiki/profiling.md
- Adding a platform: wiki/adding-a-platform.md
- Adding a scraper: wiki/adding-a-scraper.md
- Testing guide: wiki/testing-guide.md
- Release process: wiki/release-process.md
- Contributing: contributing.md

View File

@@ -1,231 +1,870 @@
# Platform Registry
# Central configuration for all supported platforms and their scraper sources.
# Adding a new platform = adding an entry here + creating its YAML config.
#
# status: active | archived
# active -- included in automated releases, scraped weekly/monthly
# archived -- config preserved, user can generate pack manually, excluded from CI releases
platforms:
retroarch:
config: retroarch.yml
status: active
logo: "https://raw.githubusercontent.com/libretro/RetroArch/master/media/retroarch-vector_invader-only.svg"
logo: https://raw.githubusercontent.com/libretro/RetroArch/master/media/retroarch-vector_invader-only.svg
scraper: libretro
source_url: "https://raw.githubusercontent.com/libretro/libretro-database/master/dat/System.dat"
source_url: https://raw.githubusercontent.com/libretro/libretro-database/master/dat/System.dat
source_format: clrmamepro_dat
hash_type: sha1
verification_mode: existence
base_destination: system
case_insensitive_fs: true
schedule: weekly
cores: all_libretro
target_scraper: retroarch_targets
target_source: "https://buildbot.libretro.com/nightly/"
target_source: https://buildbot.libretro.com/nightly/
install:
detect:
- os: linux
method: config_file
config: "$HOME/.var/app/org.libretro.RetroArch/config/retroarch/retroarch.cfg"
parse_key: system_directory
- os: linux
method: config_file
config: "$HOME/.config/retroarch/retroarch.cfg"
parse_key: system_directory
- os: darwin
method: config_file
config: "$HOME/Library/Application Support/RetroArch/retroarch.cfg"
parse_key: system_directory
- os: windows
method: config_file
config: "%APPDATA%\\RetroArch\\retroarch.cfg"
parse_key: system_directory
- os: linux
method: config_file
config: $HOME/.var/app/org.libretro.RetroArch/config/retroarch/retroarch.cfg
parse_key: system_directory
- os: linux
method: config_file
config: $HOME/.config/retroarch/retroarch.cfg
parse_key: system_directory
- os: darwin
method: config_file
config: $HOME/Library/Application Support/RetroArch/retroarch.cfg
parse_key: system_directory
- os: windows
method: config_file
config: '%APPDATA%\RetroArch\retroarch.cfg'
parse_key: system_directory
batocera:
config: batocera.yml
status: active
logo: "https://raw.githubusercontent.com/batocera-linux/batocera-emulationstation/master/resources/splash_batocera.svg"
logo: https://raw.githubusercontent.com/batocera-linux/batocera-emulationstation/master/resources/splash_batocera.svg
scraper: batocera
source_url: "https://raw.githubusercontent.com/batocera-linux/batocera.linux/master/package/batocera/core/batocera-scripts/scripts/batocera-systems"
source_url: https://raw.githubusercontent.com/batocera-linux/batocera.linux/master/package/batocera/core/batocera-scripts/scripts/batocera-systems
source_format: python_dict
hash_type: md5
schedule: weekly
cores: [81, a5200, abuse, arduous, atari800, azahar, bennugd, bk, bluemsx, bsnes, bstone, cannonball, cap32, catacombgl, cdogs, cemu, cgenius, citron, clk, corsixth, demul, devilutionx, dhewm3, dice, dolphin, dosbox_pure, dxx-rebirth, easyrpg, ecwolf, eduke32, eka2l1, emuscv, etlegacy, fake08, fallout1-ce, fallout2-ce, fbneo, fceumm, flatpak, flycast, freechaf, freeintv, fury, fuse, gambatte, gearsystem, genesisplusgx, glide64mk2, gong, gsplus, gw, gzdoom, hatari, hcl, hurrican, hypseus-singe, ikemen, ioquake3, iortcw, jazz2-native, lindbergh-loader, lowresnx, lutro, mame, mame078plus, mednafen_lynx, mednafen_ngp, mednafen_supergrafx, mednafen_wswan, melonds, mgba, minivmac, model2emu, moonlight, mrboom, neocd, np2kai, nxengine, o2em, odcommander, openbor6412, openjazz, openjk, openjkdf2, openmohaa, opera, pce_fast, pcfx, pcsx2, pcsx_rearmed, pd777, picodrive, play, pokemini, potator, ppsspp, prboom, prosystem, puae, px68k, pygame, pyxel, quasi88, raze, reminiscence, rpcs3, ruffle, samcoupe, sameduck, scummvm, sdlpop, sh, shadps4, snes9x, solarus, sonic2013, sonic3-air, sonic-mania, steam, stella, superbroswar, supermodel, taradino, tgbdual, theforceengine, theodore, thextech, tic80, tr1x, tr2x, tsugaru, tyrian, tyrquake, uqm, uzem, vb, vecx, vice_x64, vircon32, virtualjaguar, vita3k, vox_official, vpinball, wasm4, wine-tkg, x1, x128, x16emu, xash3d_fwgs, xemu, xenia-canary, xpet, xplus4, xrick, xvic, yabasanshiro, yquake2, zc210]
cores:
- '81'
- a5200
- abuse
- amiberry
- applewin
- arduous
- atari800
- azahar
- beetle-saturn
- bennugd
- bigpemu
- bk
- blastem
- bluemsx
- boom3
- bsnes
- bstone
- cannonball
- cap32
- catacombgl
- cdogs
- cemu
- cgenius
- citron
- clk
- corsixth
- demul
- desmume
- devilutionx
- dhewm3
- dice
- dolphin
- dosbox
- dosbox_pure
- duckstation
- dxx-rebirth
- easyrpg
- ecwolf
- eduke32
- eka2l1
- emuscv
- ep128emu-core
- etlegacy
- fake08
- fallout1-ce
- fallout2-ce
- fbneo
- fceumm
- flatpak
- flycast
- fmsx
- freechaf
- freeintv
- freej2me
- fsuae
- fury
- fuse
- gambatte
- gearcoleco
- gearsystem
- genesisplusgx
- glide64mk2
- gong
- gpsp
- gsplus
- gw
- gzdoom
- handy
- hatari
- hcl
- holani
- hurrican
- hypseus-singe
- ikemen
- ioquake3
- iortcw
- jazz2-native
- kronos
- lindbergh-loader
- lowresnx
- lutro
- mame
- mame078plus
- mamemess
- mednafen_lynx
- mednafen_ngp
- mednafen_psx
- mednafen_supergrafx
- mednafen_wswan
- melonds
- mesen
- mesen-s
- mgba
- minivmac
- model2emu
- moonlight
- mrboom
- mupen64plus-next
- neocd
- nestopia
- np2kai
- nxengine
- o2em
- odcommander
- openbor6412
- openjazz
- openjk
- openjkdf2
- openmohaa
- openmsx
- opera
- parallel_n64
- pce_fast
- pcfx
- pcsx2
- pcsx_rearmed
- pd777
- picodrive
- play
- pokemini
- potator
- ppsspp
- prboom
- prosystem
- puae
- puae2021
- px68k
- pygame
- pyxel
- quasi88
- raze
- redream
- reminiscence
- rpcs3
- ruffle
- ryujinx
- samcoupe
- same_cdi
- sameduck
- scummvm
- sdlpop
- sh
- shadps4
- smsplus
- snes9x
- solarus
- sonic-mania
- sonic2013
- sonic3-air
- squirreljme
- steam
- stella
- stella2014
- superbroswar
- supermodel
- swanstation
- taradino
- tgbdual
- theforceengine
- theodore
- thextech
- tic80
- tr1x
- tr2x
- tsugaru
- tyrian
- tyrquake
- uae4arm
- uqm
- uzem
- vb
- vba-m
- vecx
- vemulator
- vice
- vice_x128
- vice_x64
- vice_x64sc
- vice_xpet
- vice_xplus4
- vice_xscpu64
- vice_xvic
- vircon32
- virtualjaguar
- vita3k
- vitaquake2
- vox_official
- vpinball
- wasm4
- wine-tkg
- x1
- x128
- x16emu
- xash3d_fwgs
- xemu
- xenia
- xenia-canary
- xpet
- xplus4
- xrick
- xroar
- xvic
- yabasanshiro
- ymir
- yquake2
- zc210
target_scraper: batocera_targets
target_source: "https://github.com/batocera-linux/batocera.linux"
target_source: https://github.com/batocera-linux/batocera.linux
install:
detect:
- os: linux
method: file_exists
file: /etc/batocera-version
bios_path: /userdata/bios
- os: linux
method: file_exists
file: /etc/batocera-version
bios_path: /userdata/bios
recalbox:
config: recalbox.yml
status: active
logo: "https://raw.githubusercontent.com/homarr-labs/dashboard-icons/main/svg/recalbox.svg"
logo: https://raw.githubusercontent.com/homarr-labs/dashboard-icons/main/svg/recalbox.svg
scraper: recalbox
source_url: "https://gitlab.com/recalbox/recalbox/-/raw/master/board/recalbox/fsoverlay/recalbox/share_init/system/.emulationstation/es_bios.xml"
source_url: https://gitlab.com/recalbox/recalbox/-/raw/master/board/recalbox/fsoverlay/recalbox/share_init/system/.emulationstation/es_bios.xml
source_format: xml
hash_type: md5
schedule: monthly
target_scraper: null
target_source: null
cores: ["2048", 81, a5200, advancemame, amiberry, applewin, arduous, atari800, b2, beebem, bk, bluemsx, boom3, bsnes, bsneshd, cannonball, cap32, cdi2015, corsixth, craft, crocods, daphne, desmume, dice, dinothawr, dirksimple, dolphin, dolphin-gui, dosbox, dosbox_pure, duckstation, easyrpg, ecwolf, emuscv, fake08, fba2x, fbneo, fceumm, flycast, flycast-next, fmsx, freechaf, freeintv, frotz, fuse, gambatte, gearcoleco, geargrafx, gearsystem, genesisplusgx, genesisplusgx_ex, genesisplusgxwide, geolith, glide64mk2, gliden64, gliden64_20, gong, gpsp, gsplus, gw, handy, hatari, hatarib, holani, imageviewer, julius, kronos, lowresnx, lutro, mame0258, mame0278, mame2000, mame2003, mame2003_plus, mame2010, mame2015, mame2016, mednafen_lynx, mednafen_ngp, mednafen_pce_fast, mednafen_pcfx, mednafen_psx, mednafen_psx_hw, mednafen_saturn, mednafen_supafaust, mednafen_supergrafx, mednafen_vb, mednafen_wswan, melonds, mesen, mesen_s, meteor, mgba, minivmac, mojozork, moonlight, mrboom, mu, mupen64plus, mupen64plus_next, n64_gles2, neocd, nestopia, np2kai, nxengine, o2em, openbor, openlara, opera, oricutron, parallel_n64, pcsx2, pcsx_rearmed, pico8, picodrive, pisnes, pokemini, potator, ppsspp, prboom, prosystem, ps2, puae, px68k, quasi88, quicknes, race, rb5000, reicast, reminiscence, retro8, retrodream, rice, rice_gles2, sameboy, same_cdi, sameduck, scummvm, sdlpop, simcoupe, snes9x, snes9x2002, snes9x2005, snes9x2010, solarus, stella, stella2014, stonesoup, supermodel, swanstation, tamalibretro, tgbdual, theodore, thepowdertoy, ti99sim, tic80, tyrquake, uae4all, uae4arm, uzem, vecx, vice_x128, vice_x64, vice_x64sc, vice_xcbm2, vice_xcbm5x0, vice_xpet, vice_xplus4, vice_xscpu64, vice_xvic, virtualjaguar, vitaquake2, vitaquake3, vitavoyager, vpinball, vvvvvv, wasm4, x1, x128, x64, x64sx, xcbm2, xcbm5x0, xemu, xpet, xplus4, xrick, xroar, xscpu64, xvic, yabasanshiro, yabause]
cores:
- '2048'
- '81'
- a5200
- advancemame
- amiberry
- applewin
- arduous
- atari800
- b2
- beebem
- bk
- bluemsx
- boom3
- bsnes
- bsneshd
- cannonball
- cap32
- cdi2015
- corsixth
- craft
- crocods
- daphne
- desmume
- dice
- dinothawr
- dirksimple
- dolphin
- dolphin-gui
- dosbox
- dosbox_pure
- duckstation
- easyrpg
- ecwolf
- emuscv
- fake08
- fba2x
- fbneo
- fceumm
- flycast
- flycast-next
- fmsx
- freechaf
- freeintv
- frotz
- fuse
- gambatte
- gearcoleco
- geargrafx
- gearsystem
- genesisplusgx
- genesisplusgx_ex
- genesisplusgxwide
- geolith
- glide64mk2
- gliden64
- gliden64_20
- gong
- gpsp
- gsplus
- gw
- handy
- hatari
- hatarib
- holani
- imageviewer
- julius
- kronos
- lowresnx
- lutro
- mame
- mame0258
- mame0278
- mame2000
- mame2003
- mame2003_plus
- mame2010
- mame2015
- mame2016
- mamemess
- mednafen_lynx
- mednafen_ngp
- mednafen_pce_fast
- mednafen_pcfx
- mednafen_psx
- mednafen_psx_hw
- mednafen_saturn
- mednafen_supafaust
- mednafen_supergrafx
- mednafen_vb
- mednafen_wswan
- melonds
- mesen
- mesen_s
- meteor
- mgba
- minivmac
- mojozork
- moonlight
- mrboom
- mu
- mupen64plus
- mupen64plus_next
- n64_gles2
- neocd
- nestopia
- np2kai
- nxengine
- o2em
- openbor
- openlara
- opera
- oricutron
- parallel_n64
- pcsx2
- pcsx_rearmed
- pico8
- picodrive
- pisnes
- pokemini
- potator
- ppsspp
- prboom
- prosystem
- ps2
- puae
- px68k
- quasi88
- quicknes
- race
- rb5000
- reicast
- reminiscence
- retro8
- retrodream
- rice
- rice_gles2
- same_cdi
- sameboy
- sameduck
- scummvm
- sdlpop
- simcoupe
- snes9x
- snes9x2002
- snes9x2005
- snes9x2010
- solarus
- stella
- stella2014
- stonesoup
- supermodel
- swanstation
- tamalibretro
- tgbdual
- theodore
- thepowdertoy
- ti99sim
- tic80
- tyrquake
- uae4all
- uae4arm
- uzem
- vecx
- vice_x128
- vice_x64
- vice_x64sc
- vice_xcbm2
- vice_xcbm5x0
- vice_xpet
- vice_xplus4
- vice_xscpu64
- vice_xvic
- virtualjaguar
- vitaquake2
- vitaquake3
- vitavoyager
- vpinball
- vvvvvv
- wasm4
- x1
- x128
- x64
- x64sx
- xcbm2
- xcbm5x0
- xemu
- xpet
- xplus4
- xrick
- xroar
- xscpu64
- xvic
- yabasanshiro
- yabause
install:
detect:
- os: linux
method: file_exists
file: /usr/bin/recalbox-settings
bios_path: /recalbox/share/bios
- os: linux
method: file_exists
file: /usr/bin/recalbox-settings
bios_path: /recalbox/share/bios
retrobat:
config: retrobat.yml
status: active
logo: "https://raw.githubusercontent.com/RetroBat-Official/retrobat/main/system/resources/retrobat_logo_notext.png"
logo: https://raw.githubusercontent.com/RetroBat-Official/retrobat/main/system/resources/retrobat_logo_notext.png
scraper: retrobat
source_url: "https://raw.githubusercontent.com/RetroBat-Official/emulatorlauncher/master/batocera-systems/Resources/batocera-systems.json"
source_url: https://raw.githubusercontent.com/RetroBat-Official/emulatorlauncher/master/batocera-systems/Resources/batocera-systems.json
source_format: json
hash_type: md5
schedule: weekly
cores: [81, a5200, abuse, arduous, atari800, azahar, bennugd, bk, bluemsx, bsnes, bstone, cannonball, cap32, catacombgl, cdogs, cemu, cgenius, citron, clk, corsixth, demul, devilutionx, dhewm3, dice, dolphin, dosbox_pure, dxx-rebirth, easyrpg, ecwolf, eduke32, eka2l1, emuscv, etlegacy, fake08, fallout1-ce, fallout2-ce, fbneo, fceumm, flatpak, flycast, freechaf, freeintv, fury, fuse, gambatte, gearsystem, genesisplusgx, glide64mk2, gong, gsplus, gw, gzdoom, hatari, hcl, hurrican, hypseus-singe, ikemen, ioquake3, iortcw, jazz2-native, lindbergh-loader, lowresnx, lutro, mame, mame078plus, mednafen_lynx, mednafen_ngp, mednafen_supergrafx, mednafen_wswan, melonds, mgba, minivmac, model2emu, moonlight, mrboom, neocd, np2kai, nxengine, o2em, odcommander, openbor6412, openjazz, openjk, openjkdf2, openmohaa, opera, pce_fast, pcfx, pcsx2, pcsx_rearmed, pd777, picodrive, play, pokemini, potator, ppsspp, prboom, prosystem, puae, px68k, pygame, pyxel, quasi88, raze, reminiscence, rpcs3, ruffle, samcoupe, sameduck, scummvm, sdlpop, sh, shadps4, snes9x, solarus, sonic2013, sonic3-air, sonic-mania, steam, stella, superbroswar, supermodel, taradino, tgbdual, theforceengine, theodore, thextech, tic80, tr1x, tr2x, tsugaru, tyrian, tyrquake, uqm, uzem, vb, vecx, vice_x64, vircon32, virtualjaguar, vita3k, vox_official, vpinball, wasm4, wine-tkg, x1, x128, x16emu, xash3d_fwgs, xemu, xenia-canary, xpet, xplus4, xrick, xvic, yabasanshiro, yquake2, zc210]
cores:
- '81'
- a5200
- abuse
- arduous
- ares
- atari800
- azahar
- bennugd
- bk
- bluemsx
- bsnes
- bstone
- cannonball
- cap32
- catacombgl
- cdogs
- cemu
- cgenius
- citron
- clk
- corsixth
- demul
- devilutionx
- dhewm3
- dice
- dolphin
- dosbox_pure
- dxx-rebirth
- easyrpg
- ecwolf
- eduke32
- eka2l1
- emuscv
- etlegacy
- fake08
- fallout1-ce
- fallout2-ce
- fbalpha2012
- fbalpha2012_neogeo
- fbneo
- fceumm
- flatpak
- flycast
- freechaf
- freeintv
- freej2me
- fury
- fuse
- gambatte
- geargrafx
- gearsystem
- genesisplusgx
- glide64mk2
- gong
- gsplus
- gw
- gzdoom
- hatari
- hcl
- hurrican
- hypseus-singe
- ikemen
- ioquake3
- iortcw
- jazz2-native
- lindbergh-loader
- lowresnx
- lutro
- mame
- mame078plus
- mamemess
- mednafen_lynx
- mednafen_ngp
- mednafen_supergrafx
- mednafen_wswan
- melonds
- mgba
- minivmac
- model2emu
- moonlight
- mrboom
- mupen64plus_next
- neocd
- np2kai
- nxengine
- o2em
- odcommander
- openbor6412
- openjazz
- openjk
- openjkdf2
- openmohaa
- opera
- parallel_n64
- pce_fast
- pcfx
- pcsx2
- pcsx_rearmed
- pd777
- picodrive
- play
- pokemini
- potator
- ppsspp
- prboom
- prosystem
- puae
- px68k
- pygame
- pyxel
- quasi88
- raze
- reminiscence
- rpcs3
- ruffle
- samcoupe
- sameduck
- scummvm
- sdlpop
- sh
- shadps4
- snes9x
- solarus
- sonic-mania
- sonic2013
- sonic3-air
- squirreljme
- steam
- stella
- superbroswar
- supermodel
- taradino
- tgbdual
- theforceengine
- theodore
- thextech
- tic80
- tr1x
- tr2x
- tsugaru
- tyrian
- tyrquake
- uqm
- uzem
- vb
- vecx
- vice_x64
- vircon32
- virtualjaguar
- vita3k
- vox_official
- vpinball
- wasm4
- wine-tkg
- x1
- x128
- x16emu
- xash3d_fwgs
- xemu
- xenia-canary
- xpet
- xplus4
- xrick
- xroar
- xvic
- yabasanshiro
- yquake2
- zc210
target_scraper: null
target_source: null
install:
detect:
- os: windows
method: path_exists
path: "%USERPROFILE%\\RetroBat\\bios"
- os: windows
method: path_exists
path: '%USERPROFILE%\RetroBat\bios'
emudeck:
config: emudeck.yml
status: active
logo: "https://raw.githubusercontent.com/dragoonDorise/EmuDeck/main/icons/EmuDeck.png"
logo: https://raw.githubusercontent.com/dragoonDorise/EmuDeck/main/icons/EmuDeck.png
scraper: emudeck
source_url: "https://raw.githubusercontent.com/dragoonDorise/EmuDeck/main/functions/checkBIOS.sh"
source_wiki: "https://raw.githubusercontent.com/EmuDeck/emudeck.github.io/main/docs/tables/"
source_url: https://raw.githubusercontent.com/dragoonDorise/EmuDeck/main/functions/checkBIOS.sh
source_wiki: https://raw.githubusercontent.com/EmuDeck/emudeck.github.io/main/docs/tables/
source_format: bash_script+csv
hash_type: md5
schedule: weekly
target_scraper: emudeck_targets
target_source: "https://github.com/dragoonDorise/EmuDeck"
# dragoonDorise/EmuDeck = official repo (creator's account, 3.4k stars)
# EmuDeck/emudeck.github.io = official wiki (org account)
target_source: https://github.com/dragoonDorise/EmuDeck
install:
detect:
- os: linux
method: config_file
config: "$HOME/.config/EmuDeck/settings.sh"
parse_key: emulationPath
bios_subdir: bios
- os: linux
method: path_exists
path: "$HOME/Emulation/bios"
- os: windows
method: config_file
config: "%APPDATA%\\EmuDeck\\settings.ps1"
parse_key: "$emulationPath"
bios_subdir: bios
- os: linux
method: config_file
config: $HOME/.config/EmuDeck/settings.sh
parse_key: emulationPath
bios_subdir: bios
- os: linux
method: path_exists
path: $HOME/Emulation/bios
- os: windows
method: config_file
config: '%APPDATA%\EmuDeck\settings.ps1'
parse_key: $emulationPath
bios_subdir: bios
standalone_copies:
- file: prod.keys
targets:
linux:
- "$HOME/.local/share/yuzu/keys"
- "$HOME/.local/share/eden/keys"
- "$HOME/.config/Ryujinx/system"
windows:
- "%APPDATA%\\yuzu\\keys"
- "%APPDATA%\\eden\\keys"
- file: aes_keys.txt
targets:
linux:
- "$HOME/Emulation/bios/citra/keys"
- file: prod.keys
targets:
linux:
- $HOME/.local/share/yuzu/keys
- $HOME/.local/share/eden/keys
- $HOME/.config/Ryujinx/system
windows:
- '%APPDATA%\yuzu\keys'
- '%APPDATA%\eden\keys'
- file: aes_keys.txt
targets:
linux:
- $HOME/Emulation/bios/citra/keys
lakka:
config: lakka.yml
status: active
logo: "https://raw.githubusercontent.com/libretro/retroarch-assets/master/src/xmb/flatui/lakka.svg"
logo: https://raw.githubusercontent.com/libretro/retroarch-assets/master/src/xmb/flatui/lakka.svg
scraper: libretro
inherits_from: retroarch
cores: all_libretro
schedule: weekly
target_scraper: lakka_targets
target_source: "https://buildbot.libretro.com/nightly/"
target_source: https://buildbot.libretro.com/nightly/
install:
detect:
- os: linux
method: os_release
id: lakka
bios_path: /storage/system
- os: linux
method: os_release
id: lakka
bios_path: /storage/system
retrodeck:
config: retrodeck.yml
status: active
logo: "https://raw.githubusercontent.com/RetroDECK/RetroDECK/main/res/icon.svg"
logo: https://raw.githubusercontent.com/RetroDECK/RetroDECK/main/res/icon.svg
scraper: retrodeck
source_url: "https://github.com/RetroDECK/components"
source_url: https://github.com/RetroDECK/components
source_format: github_component_manifests
hash_type: md5
schedule: monthly
cores: [azahar, cemu, dolphin, duckstation, gzdoom, mame, melonds, openbor, pcsx2, pico-8, ppsspp, primehack, retroarch, rpcs3, ruffle, solarus, vita3k, xemu, xroar]
cores:
- azahar
- cemu
- clk
- dolphin
- duckstation
- gsplus
- gzdoom
- mame
- melonds
- openbor
- pcsx2
- pico-8
- ppsspp
- primehack
- retroarch
- rpcs3
- ruffle
- solarus
- vita3k
- xemu
- xroar
target_scraper: null
target_source: null
# Each component/<name>/component_manifest.json declares BIOS requirements
# Scraper enumerates top-level dirs via GitHub API, fetches each manifest directly
install:
detect:
- os: linux
method: path_exists
path: "$HOME/.var/app/net.retrodeck.retrodeck"
bios_path: "$HOME/retrodeck/bios"
- os: linux
method: path_exists
path: $HOME/.var/app/net.retrodeck.retrodeck
bios_path: $HOME/retrodeck/bios
romm:
config: romm.yml
status: active
logo: "https://avatars.githubusercontent.com/u/168586850"
logo: https://avatars.githubusercontent.com/u/168586850
scraper: romm
source_url: "https://raw.githubusercontent.com/rommapp/romm/master/backend/models/fixtures/known_bios_files.json"
source_url: https://raw.githubusercontent.com/rommapp/romm/master/backend/models/fixtures/known_bios_files.json
source_format: json
hash_type: sha1
schedule: monthly
inherits_from: emulatorjs # cores inherited from emulatorjs.yml
inherits_from: emulatorjs
target_scraper: null
target_source: null
install:
detect:
- os: linux
method: path_exists
path: /romm/library/bios
- os: linux
method: path_exists
path: /romm/library/bios
cores:
- atari800
- clk
- directxbox
- dolphin
- dolphin_launcher
- ecwolf
- ep128emu
- ep128emu_core
- freej2me
- hatari
- ishiiruka
- lrps2
- minivmac
- nekop2
- np2kai
- o2em
- pcsx2
- play
- pokemini
- primehack
- px68k
- scummvm
- squirreljme
- x1
- xemu
retropie:
config: retropie.yml
status: archived # Last release: v4.8 (March 2022) - no update in 4 years
logo: "https://avatars.githubusercontent.com/u/11378204"
status: archived
logo: https://avatars.githubusercontent.com/u/11378204
scraper: null
cores: all_libretro
schedule: null
target_scraper: retropie_targets
target_source: "https://retropie.org.uk/stats/pkgflags/"
target_source: https://retropie.org.uk/stats/pkgflags/
install:
detect:
- os: linux
method: path_exists
path: "$HOME/RetroPie/BIOS"
- os: linux
method: path_exists
path: $HOME/RetroPie/BIOS
bizhawk:
config: bizhawk.yml
status: active
logo: "https://raw.githubusercontent.com/TASEmulators/BizHawk/master/Assets/bizhawk.ico"
logo: https://raw.githubusercontent.com/TASEmulators/BizHawk/master/Assets/bizhawk.ico
scraper: bizhawk
source_url: "https://raw.githubusercontent.com/TASEmulators/BizHawk/master/src/BizHawk.Emulation.Common/Database/FirmwareDatabase.cs"
source_url: https://raw.githubusercontent.com/TASEmulators/BizHawk/master/src/BizHawk.Emulation.Common/Database/FirmwareDatabase.cs
source_format: csharp_firmware_database
hash_type: sha1
schedule: monthly
cores: [gambatte, mgba, sameboy, melonds, snes9x, bsnes, beetle_psx, beetle_saturn, beetle_pce, beetle_pcfx, beetle_wswan, beetle_vb, beetle_ngp, opera, stella, picodrive, ppsspp, handy, quicknes, genesis_plus_gx, ares, mupen64plus_next, puae, prboom, virtualjaguar, vice_x64, mame]
cores:
- applewin
- ares
- azahar
- beetle_ngp
- beetle_pce
- beetle_pcfx
- beetle_psx
- beetle_saturn
- beetle_vb
- beetle_wswan
- bsnes
- citra
- citra2018
- citra_canary
- clk
- fbneo
- freechaf
- freeintv
- gambatte
- genesis_plus_gx
- handy
- mame
- melonds
- mgba
- mupen64plus_next
- numero
- o2em
- opera
- panda3ds
- picodrive
- ppsspp
- prboom
- prosystem
- puae
- quicknes
- sameboy
- snes9x
- stella
- trident
- vecx
- vice_x64
- virtualjaguar
target_scraper: null
target_source: null
install:
detect:
- os: windows
method: path_exists
path: "%USERPROFILE%\\BizHawk\\Firmware"
- os: linux
method: path_exists
path: "$HOME/.config/BizHawk/Firmware"
- os: windows
method: path_exists
path: '%USERPROFILE%\BizHawk\Firmware'
- os: linux
method: path_exists
path: $HOME/.config/BizHawk/Firmware

File diff suppressed because it is too large Load Diff

View File

@@ -4,10 +4,8 @@ dat_version: v1.19.0
homepage: https://www.retroarch.com
source: https://github.com/libretro/libretro-database/blob/master/dat/System.dat
base_destination: system
cores: all_libretro
hash_type: sha1
verification_mode: existence
case_insensitive_fs: true
systems:
3do:
files:
@@ -102,6 +100,7 @@ systems:
md5: 35fa1a1ebaaeea286dc5cd15487c13ea
crc32: d5cbc509
size: 1048576
native_id: 3DO Company, The - 3DO
core: opera
manufacturer: Panasonic|GoldStar|Sanyo
docs: https://docs.libretro.com/library/opera/
@@ -135,6 +134,7 @@ systems:
md5: 25629dfe870d097469c217b95fdc1c95
crc32: 1fe22ecd
size: 16384
native_id: Amstrad - CPC
arcade:
files:
- name: bubsys.zip
@@ -249,6 +249,10 @@ systems:
- name: aes.zip
destination: aes.zip
required: true
native_id: Arcade
core: fbneo
manufacturer: Various
docs: https://docs.libretro.com/library/fbneo/
data_directories:
- ref: fbneo-hiscore
destination: ''
@@ -256,9 +260,6 @@ systems:
destination: fbneo
- ref: fbneo-samples
destination: fbneo
core: fbneo
manufacturer: Various
docs: https://docs.libretro.com/library/fbneo/
atari-400-800:
files:
- name: ATARIBAS.ROM
@@ -303,6 +304,7 @@ systems:
md5: d7eb37aec6960cba36bc500e0e5d00bc
crc32: bdca01fb
size: 8192
native_id: Atari - 400-800
atari-5200:
files:
- name: 5200.rom
@@ -312,6 +314,7 @@ systems:
md5: 281f20ea4320404ec820fb7ec0693b38
crc32: 4248d3e3
size: 2048
native_id: Atari - 5200
core: a5200
manufacturer: Atari
docs: https://docs.libretro.com/library/a5200/
@@ -331,6 +334,7 @@ systems:
md5: 0763f1ffb006ddbe32e52d497ee848ae
crc32: 5d13730c
size: 4096
native_id: Atari - 7800
core: prosystem
manufacturer: Atari
docs: https://docs.libretro.com/library/prosystem/
@@ -343,6 +347,7 @@ systems:
md5: fcd403db69f54290b51035d82f835e7b
crc32: 0d973c9d
size: 512
native_id: Atari - Lynx
core: handy
manufacturer: Atari
docs: https://docs.libretro.com/library/handy/
@@ -355,6 +360,7 @@ systems:
md5: c1c57ce48e8ee4135885cee9e63a68a2
crc32: d3c32283
size: 196608
native_id: Atari - ST
core: hatari
manufacturer: Atari
docs: https://docs.libretro.com/library/hatari/
@@ -376,6 +382,7 @@ systems:
- name: bioscv.rom
destination: bioscv.rom
required: true
native_id: Coleco - ColecoVision
commodore-amiga:
files:
- name: kick33180.A500
@@ -462,6 +469,7 @@ systems:
md5: bb72565701b1b6faece07d68ea5da639
crc32: 87746be2
size: 524288
native_id: Commodore - Amiga
core: puae
manufacturer: Commodore
docs: https://docs.libretro.com/library/puae/
@@ -510,6 +518,7 @@ systems:
destination: scpu-dos-2.04.bin
required: true
md5: b2869f8678b8b274227f35aad26ba509
native_id: Commodore - C128
core: vice_x128
manufacturer: Commodore
docs: https://docs.libretro.com/library/vice_x128/
@@ -522,6 +531,7 @@ systems:
md5: a2e891e330d146c4046c2b622fc31462
crc32: 683ed4ad
size: 5763199
native_id: Dinothawr
dos:
files:
- name: MT32_CONTROL.ROM
@@ -552,6 +562,7 @@ systems:
md5: 08cdcfa0ed93e9cb16afa76e6ac5f0a4
crc32: 4b961eba
size: 1048576
native_id: DOS
elektronika-bk:
files:
- name: B11M_BOS.ROM
@@ -610,6 +621,7 @@ systems:
md5: 95f8c41c6abf7640e35a6a03cecebd01
crc32: 26c6e8a0
size: 8192
native_id: Elektronika - BK-0010/BK-0011(M)
enterprise-64-128:
files:
- name: hun.rom
@@ -696,6 +708,7 @@ systems:
md5: 55af78f877a21ca45eb2df68a74fcc60
crc32: c099a5e3
size: 65536
native_id: Enterprise - 64/128
includes:
- ep128emu
epoch-scv:
@@ -707,6 +720,7 @@ systems:
md5: 635a978fd40db9a18ee44eff449fc126
crc32: 7ac06182
size: 4096
native_id: EPOCH/YENO Super Cassette Vision
fairchild-channel-f:
files:
- name: sl31253.bin
@@ -730,6 +744,7 @@ systems:
md5: 95d339631d867c8f1d15a5f2ec26069d
crc32: 015c1e38
size: 1024
native_id: Fairchild Channel F
doom:
files:
- name: prboom.wad
@@ -739,6 +754,7 @@ systems:
md5: 72ae1b47820fcc93cc0df9c428d0face
crc32: a5751b99
size: 143312
native_id: Id Software - Doom
j2me:
files:
- name: freej2me-lr.jar
@@ -762,6 +778,7 @@ systems:
md5: 29a92d0867da2917275b7c6c805d256f
crc32: ffb98ffa
size: 552039
native_id: J2ME
core: freej2me
manufacturer: Java
docs: https://docs.libretro.com/library/freej2me/
@@ -774,6 +791,7 @@ systems:
md5: 66223be1497460f1e60885eeb35e03cc
crc32: 4df6d054
size: 262144
native_id: MacII
magnavox-odyssey2:
files:
- name: o2rom.bin
@@ -804,6 +822,7 @@ systems:
md5: 279008e4a0db2dc5f1c048853b033828
crc32: 11647ca5
size: 1024
native_id: Magnavox - Odyssey2
core: o2em
manufacturer: Magnavox|Philips
docs: https://docs.libretro.com/library/o2em/
@@ -823,6 +842,7 @@ systems:
md5: 0cd5946c6473e42e8e4c2137785e427f
crc32: 683a4158
size: 2048
native_id: Mattel - Intellivision
data_directories:
- ref: freeintv-overlays
destination: freeintv_overlays
@@ -933,6 +953,7 @@ systems:
md5: 279efd1eae0d358eecd4edc7d9adedf3
crc32: ab6874f8
size: 16640
native_id: Microsoft - MSX
core: bluemsx
manufacturer: Spectravideo|Philips|Al Alamiah|Sony|Sanyo|Mitsubishi|Toshiba|Hitachi|Panasonic|Canon|Casio|Pioneer|Fujitsu|Yamaha|JVC|Kyocera|GoldStar|Samsung|Daewoo|Gradiente|Sharp|Talent|NTT|ACVS/CIEL|DDX|AGE
Labs
@@ -991,6 +1012,7 @@ systems:
md5: 0754f903b52e3b3342202bdafb13efa5
crc32: 2b5b75fe
size: 262144
native_id: NEC - PC Engine - TurboGrafx 16 - SuperGrafx
core: mednafen_pce_fast
manufacturer: NEC
docs: https://docs.libretro.com/library/mednafen_pce_fast/
@@ -1073,6 +1095,7 @@ systems:
md5: 524473c1a5a03b17e21d86a0408ff827
crc32: fe9f57f2
size: 16384
native_id: NEC - PC-98
core: np2kai
manufacturer: NEC
docs: https://docs.libretro.com/library/np2kai/
@@ -1115,6 +1138,7 @@ systems:
md5: e2fb7c7220e3a7838c2dd7e401a7f3d8
crc32: 236102c9
size: 1048576
native_id: NEC - PC-FX
core: mednafen_pcfx
manufacturer: NEC
docs: https://docs.libretro.com/library/mednafen_pcfx/
@@ -1134,6 +1158,7 @@ systems:
md5: 7f98d77d7a094ad7d069b74bd553ec98
crc32: 4c514089
size: 24592
native_id: Nintendo - Famicom Disk System
nintendo-gb:
files:
- name: dmg_boot.bin
@@ -1150,6 +1175,7 @@ systems:
md5: 32fbbd84168d3482956eb3c5051637f5
crc32: 59c8598e
size: 256
native_id: Nintendo - Gameboy
core: gambatte
manufacturer: Nintendo
docs: https://docs.libretro.com/library/gambatte/
@@ -1162,6 +1188,7 @@ systems:
md5: a860e8c0b6d573d191e4ec7db1b1e4f6
crc32: '81977335'
size: 16384
native_id: Nintendo - Game Boy Advance
core: gpsp
manufacturer: Nintendo
docs: https://docs.libretro.com/library/gpsp/
@@ -1181,6 +1208,7 @@ systems:
md5: dbfce9db9deaa2567f6a84fde55f9680
crc32: 41884e46
size: 2304
native_id: Nintendo - Gameboy Color
nintendo-gamecube:
files:
- name: gc-dvd-20010608.bin
@@ -1274,6 +1302,7 @@ systems:
- name: font_japanese.bin
destination: dolphin-emu/Sys/GC/font_japanese.bin
required: false
native_id: Nintendo - GameCube
core: dolphin
manufacturer: Nintendo
docs: https://docs.libretro.com/library/dolphin/
@@ -1289,6 +1318,7 @@ systems:
md5: 8d3d9f294b6e174bc7b1d2fd1c727530
crc32: 7f933ce2
size: 4194304
native_id: Nintendo - Nintendo 64DD
nintendo-ds:
files:
- name: bios7.bin
@@ -1324,6 +1354,7 @@ systems:
- name: dsi_nand.bin
destination: dsi_nand.bin
required: true
native_id: Nintendo - Nintendo DS
core: desmume
manufacturer: Nintendo
docs: https://docs.libretro.com/library/desmume/
@@ -1332,10 +1363,11 @@ systems:
- name: NstDatabase.xml
destination: NstDatabase.xml
required: true
sha1: f92312bae56e29c5bf00a5103105fce78472bf5c
md5: 0ee6cbdc6f5c96ce9c8aa5edb59066f4
crc32: 0e4d552b
sha1: 26322f182540211e9b5e3647675b7c593706ae2b
md5: 7bfe8c0540ed4bd6a0f1e2a0f0118ced
crc32: ebb2196c
size: 1009534
native_id: Nintendo - Nintendo Entertainment System
core: fceumm
manufacturer: Nintendo
docs: https://docs.libretro.com/library/fceumm/
@@ -1348,6 +1380,7 @@ systems:
md5: 1e4fb124a3a886865acb574f388c803d
crc32: aed3c14d
size: 4096
native_id: Nintendo - Pokemon Mini
nintendo-satellaview:
files:
- name: BS-X.bin
@@ -1371,6 +1404,7 @@ systems:
md5: 4ed9648505ab33a4daec93707b16caba
crc32: 8c573c7e
size: 1048576
native_id: Nintendo - Satellaview
nintendo-sufami-turbo:
files:
- name: STBIOS.bin
@@ -1380,6 +1414,7 @@ systems:
md5: d3a44ba7d42a74d3ac58cb9c14c6a5ca
crc32: 9b4ca911
size: 262144
native_id: Nintendo - SuFami Turbo
nintendo-sgb:
files:
- name: SGB1.sfc
@@ -1441,6 +1476,7 @@ systems:
- name: sgb.boot.rom
destination: sgb.boot.rom
required: false
native_id: Nintendo - Super Game Boy
nintendo-snes:
files:
- name: cx4.data.rom
@@ -1562,6 +1598,7 @@ systems:
md5: dda40ccd57390c96e49d30a041f9a9e7
crc32: f73d5e10
size: 131072
native_id: Nintendo - Super Nintendo Entertainment System
core: bsnes
manufacturer: Nintendo
docs: https://docs.libretro.com/library/bsnes/
@@ -1588,6 +1625,7 @@ systems:
md5: 279008e4a0db2dc5f1c048853b033828
crc32: 11647ca5
size: 1024
native_id: Phillips - Videopac+
sega-dreamcast:
files:
- name: dc_boot.bin
@@ -1611,6 +1649,7 @@ systems:
md5: 0a93f7940c455905bea6e392dfde92a4
crc32: c611b498
size: 131072
native_id: Sega - Dreamcast
core: flycast
manufacturer: Sega
docs: https://docs.libretro.com/library/flycast/
@@ -1668,6 +1707,7 @@ systems:
- name: segasp.zip
destination: dc/segasp.zip
required: true
native_id: Sega - Dreamcast-based Arcade
sega-game-gear:
files:
- name: bios.gg
@@ -1677,6 +1717,7 @@ systems:
md5: 672e104c3be3a238301aceffc3b23fd6
crc32: 0ebea9d4
size: 1024
native_id: Sega - Game Gear
sega-master-system:
files:
- name: bios.sms
@@ -1707,6 +1748,7 @@ systems:
md5: 840481177270d5642a14ca71ee72844c
crc32: 0072ed54
size: 8192
native_id: Sega - Master System - Mark III
sega-mega-cd:
files:
- name: bios_CD_E.bin
@@ -1730,6 +1772,7 @@ systems:
md5: 2efd74e3232ff260e371b99f84024f7f
crc32: c6d10268
size: 131072
native_id: Sega - Mega CD - Sega CD
sega-mega-drive:
files:
- name: areplay.bin
@@ -1774,6 +1817,7 @@ systems:
md5: b4e76e416b887f4e7413ba76fa735f16
crc32: 4dcfd55c
size: 262144
native_id: Sega - Mega Drive - Genesis
core: genesis_plus_gx
manufacturer: Sega
docs: https://docs.libretro.com/library/genesis_plus_gx/
@@ -1859,6 +1903,7 @@ systems:
- name: stvbios.zip
destination: kronos/stvbios.zip
required: true
native_id: Sega - Saturn
core: kronos
manufacturer: Sega
docs: https://docs.libretro.com/library/kronos/
@@ -1880,6 +1925,7 @@ systems:
md5: 851e4a5936f17d13f8c39a980cf00d77
crc32: e3995a57
size: 2048
native_id: Sharp - X1
core: x1
manufacturer: Sharp
docs: https://docs.libretro.com/library/x1/
@@ -1920,6 +1966,7 @@ systems:
md5: 0617321daa182c3f3d6f41fd02fb3275
crc32: 00eeb408
size: 131072
native_id: Sharp - X68000
core: px68k
manufacturer: Sharp
docs: https://docs.libretro.com/library/px68k/
@@ -2270,6 +2317,7 @@ systems:
md5: 85fede415f4294cc777517d7eada482e
crc32: 2cbe8995
size: 32768
native_id: Sinclair - ZX Spectrum
core: fuse
manufacturer: Sinclair|Amstrad
docs: https://docs.libretro.com/library/fuse/
@@ -2352,6 +2400,7 @@ systems:
md5: 08ca8b2dba6662e8024f9e789711c6fc
crc32: ff3abc59
size: 524288
native_id: SNK - NeoGeo CD
core: neocd
manufacturer: SNK
docs: https://docs.libretro.com/library/neocd/
@@ -2511,6 +2560,7 @@ systems:
md5: 81bbe60ba7a3d1cea1d48c14cbcc647b
crc32: 2f53b852
size: 524288
native_id: Sony - PlayStation
core: duckstation
manufacturer: Sony
docs: https://docs.libretro.com/library/duckstation/
@@ -3027,6 +3077,7 @@ systems:
md5: d3e81e95db25f5a86a7b7474550a2155
crc32: 4e8c160c
size: 4194304
native_id: Sony - PlayStation 2
sony-psp:
files:
- name: ppge_atlas.zim
@@ -3036,6 +3087,7 @@ systems:
md5: 866855cc330b9b95cc69135fb7b41d38
crc32: 7b57fa78
size: 666530
native_id: Sony - PlayStation Portable
core: ppsspp
manufacturer: Sony
docs: https://docs.libretro.com/library/ppsspp/
@@ -3065,6 +3117,7 @@ systems:
md5: d4448d09bbfde687c04f9e3310e023ab
crc32: 4bf05697
size: 262144
native_id: Texas Instruments TI-83
core: numero
manufacturer: Texas Instruments
docs: https://docs.libretro.com/library/numero/
@@ -3098,6 +3151,7 @@ systems:
md5: 88dc7876d584f90e4106f91444ab23b7
crc32: 1466aed4
size: 16384
native_id: Videoton - TV Computer
wolfenstein-3d:
files:
- name: ecwolf.pk3
@@ -3107,6 +3161,7 @@ systems:
md5: c011b428819eea4a80b455c245a5a04d
crc32: 26dc3fba
size: 178755
native_id: Wolfenstein 3D
scummvm:
files:
- name: scummvm.zip
@@ -3116,6 +3171,7 @@ systems:
md5: a17e0e0150155400d8cced329563d9c8
crc32: a93f1c4b
size: 9523360
native_id: ScummVM
core: scummvm
manufacturer: Various
docs: https://docs.libretro.com/library/scummvm/
@@ -3141,3 +3197,5 @@ systems:
core: xrick
manufacturer: Other
docs: https://docs.libretro.com/library/xrick/
case_insensitive_fs: true
cores: all_libretro

View File

@@ -1,170 +1,10 @@
platform: RetroBat
version: 7.5.3
homepage: "https://www.retrobat.org"
source: "https://raw.githubusercontent.com/RetroBat-Official/emulatorlauncher/master/batocera-systems/Resources/batocera-systems.json"
homepage: https://www.retrobat.org
source: https://raw.githubusercontent.com/RetroBat-Official/emulatorlauncher/master/batocera-systems/Resources/batocera-systems.json
base_destination: bios
hash_type: md5
verification_mode: md5
case_insensitive_fs: true
cores:
- 81
- a5200
- abuse
- arduous
- atari800
- azahar
- bennugd
- bk
- bluemsx
- bsnes
- bstone
- cannonball
- cap32
- catacombgl
- cdogs
- cemu
- cgenius
- citron
- clk
- corsixth
- demul
- devilutionx
- dhewm3
- dice
- dolphin
- dosbox_pure
- dxx-rebirth
- easyrpg
- ecwolf
- eduke32
- eka2l1
- emuscv
- etlegacy
- fake08
- fallout1-ce
- fallout2-ce
- fbneo
- fceumm
- flatpak
- flycast
- freechaf
- freeintv
- fury
- fuse
- gambatte
- gearsystem
- genesisplusgx
- glide64mk2
- gong
- gsplus
- gw
- gzdoom
- hatari
- hcl
- hurrican
- hypseus-singe
- ikemen
- ioquake3
- iortcw
- jazz2-native
- lindbergh-loader
- lowresnx
- lutro
- mame
- mame078plus
- mednafen_lynx
- mednafen_ngp
- mednafen_supergrafx
- mednafen_wswan
- melonds
- mgba
- minivmac
- model2emu
- moonlight
- mrboom
- neocd
- np2kai
- nxengine
- o2em
- odcommander
- openbor6412
- openjazz
- openjk
- openjkdf2
- openmohaa
- opera
- pce_fast
- pcfx
- pcsx2
- pcsx_rearmed
- pd777
- picodrive
- play
- pokemini
- potator
- ppsspp
- prboom
- prosystem
- puae
- px68k
- pygame
- pyxel
- quasi88
- raze
- reminiscence
- rpcs3
- ruffle
- samcoupe
- sameduck
- scummvm
- sdlpop
- sh
- shadps4
- snes9x
- solarus
- sonic2013
- sonic3-air
- sonic-mania
- steam
- stella
- superbroswar
- supermodel
- taradino
- tgbdual
- theforceengine
- theodore
- thextech
- tic80
- tr1x
- tr2x
- tsugaru
- tyrian
- tyrquake
- uqm
- uzem
- vb
- vecx
- vice_x64
- vircon32
- virtualjaguar
- vita3k
- vox_official
- vpinball
- wasm4
- wine-tkg
- x1
- x128
- x16emu
- xash3d_fwgs
- xemu
- xenia-canary
- xpet
- xplus4
- xrick
- xvic
- yabasanshiro
- yquake2
- zc210
systems:
3do:
files:
@@ -425,12 +265,12 @@ systems:
md5: 281f20ea4320404ec820fb7ec0693b38
atari7800:
files:
- name: "7800 BIOS (E).rom"
destination: "7800 BIOS (E).rom"
- name: 7800 BIOS (E).rom
destination: 7800 BIOS (E).rom
required: true
md5: 397bb566584be7b9764e7a68974c4263
- name: "7800 BIOS (U).rom"
destination: "7800 BIOS (U).rom"
- name: 7800 BIOS (U).rom
destination: 7800 BIOS (U).rom
required: true
md5: 0763f1ffb006ddbe32e52d497ee848ae
- name: ProSystem.dat
@@ -548,6 +388,40 @@ systems:
- name: bbcmc_flop.xml
destination: mame/hash/bbcmc_flop.xml
required: true
bk:
files:
- name: B11M_BOS.ROM
destination: bk/B11M_BOS.ROM
required: true
md5: fe4627d1e3a1535874085050733263e7
- name: B11M_EXT.ROM
destination: bk/B11M_EXT.ROM
required: true
md5: dc52f365d56fa1951f5d35b1101b9e3f
- name: BAS11M_0.ROM
destination: bk/BAS11M_0.ROM
required: true
md5: 946f6f23ded03c0e26187f0b3ca75993
- name: BAS11M_1.ROM
destination: bk/BAS11M_1.ROM
required: true
md5: 1e6637f32aa7d1de03510030cac40bcf
- name: DISK_327.ROM
destination: bk/DISK_327.ROM
required: true
md5: 5015228eeeb238e65da8edcd1b6dfac7
- name: BASIC10.ROM
destination: bk/BASIC10.ROM
required: true
md5: 3fa774326d75410a065659aea80252f0
- name: FOCAL10.ROM
destination: bk/FOCAL10.ROM
required: true
md5: 5737f972e8638831ab71e9139abae052
- name: MONIT10.ROM
destination: bk/MONIT10.ROM
required: true
md5: 95f8c41c6abf7640e35a6a03cecebd01
loopy:
files:
- name: casloopy.zip
@@ -845,34 +719,30 @@ systems:
md5: a6f31483d1da4558cc19025e21f95c1d
jaguar:
files:
- name: "[BIOS] Atari Jaguar (World).j64"
destination: "[BIOS] Atari Jaguar (World).j64"
- name: '[BIOS] Atari Jaguar (World).j64'
destination: '[BIOS] Atari Jaguar (World).j64'
required: true
md5: bcfe348c565d9dedb173822ee6850dea
laseractive:
files:
- name: "[BIOS] LaserActive PAC-N1 (Japan) (v1.02).bin"
destination: "laseractive/[BIOS] LaserActive PAC-N1 (Japan) (v1.02).bin"
- name: '[BIOS] LaserActive PAC-N1 (Japan) (v1.02).bin'
destination: laseractive/[BIOS] LaserActive PAC-N1 (Japan) (v1.02).bin
required: true
md5: f69f173b251d8bf7649b10a9167a10bf
- name: "[BIOS] LaserActive PAC-N10 (US) (v1.02).bin"
destination: "laseractive/[BIOS] LaserActive PAC-N10 (US) (v1.02).bin"
- name: '[BIOS] LaserActive PAC-N10 (US) (v1.02).bin'
destination: laseractive/[BIOS] LaserActive PAC-N10 (US) (v1.02).bin
required: true
md5: f0fb8a4605ac7eefbafd4f2d5a793cc8
- name: "[BIOS] LaserActive PCE-LP1 (Japan) (v1.02).bin"
destination: "laseractive/[BIOS] LaserActive PCE-LP1 (Japan) (v1.02).bin"
- name: '[BIOS] LaserActive PCE-LP1 (Japan) (v1.02).bin'
destination: laseractive/[BIOS] LaserActive PCE-LP1 (Japan) (v1.02).bin
required: true
md5: 761fea207d0eafd4cfd78da7c44cac88
- name: "Pioneer LaserActive Sega PAC Boot ROM v1.02 (1993)(Pioneer - Sega)(JP)(en-ja).bin"
destination: "laseractive/Pioneer LaserActive Sega PAC Boot ROM v1.02 (1993)(Pioneer\
\ - Sega)(JP)(en-ja).bin"
- name: '[BIOS] LaserActive PAC-S10 (US) (v1.04).bin'
destination: laseractive/[BIOS] LaserActive PAC-S10 (US) (v1.04).bin
required: true
md5: a5a2f9aae57d464bc66b80ee79c3da6e
- name: "Pioneer LaserActive Sega PAC Boot ROM v1.04 (1993)(Pioneer - Sega)(US).bin"
destination: "laseractive/Pioneer LaserActive Sega PAC Boot ROM v1.04 (1993)(Pioneer\
\ - Sega)(US).bin"
- name: '[BIOS] LaserActive PAC-S1 (Japan) (v1.05).bin'
destination: laseractive/[BIOS] LaserActive PAC-S1 (Japan) (v1.05).bin
required: true
md5: 0e7393cd0951d6dde818fcd4cd819466
lynx:
files:
- name: lynxboot.img
@@ -916,11 +786,11 @@ systems:
required: true
mastersystem:
files:
- name: "[BIOS] Sega Master System (USA, Europe) (v1.3).sms"
destination: "[BIOS] Sega Master System (USA, Europe) (v1.3).sms"
- name: '[BIOS] Sega Master System (USA, Europe) (v1.3).sms'
destination: '[BIOS] Sega Master System (USA, Europe) (v1.3).sms'
required: true
- name: "[BIOS] Sega Master System (Japan) (v2.1).sms"
destination: "[BIOS] Sega Master System (Japan) (v2.1).sms"
- name: '[BIOS] Sega Master System (Japan) (v2.1).sms'
destination: '[BIOS] Sega Master System (Japan) (v2.1).sms'
required: true
msx:
files:
@@ -1205,13 +1075,13 @@ systems:
md5: 64a95a4a884cf4cc15a566b856603193
ngp:
files:
- name: "[BIOS] SNK Neo Geo Pocket (Japan, Europe) (En,Ja).ngp"
destination: "[BIOS] SNK Neo Geo Pocket (Japan, Europe) (En,Ja).ngp"
- name: '[BIOS] SNK Neo Geo Pocket (Japan, Europe) (En,Ja).ngp'
destination: '[BIOS] SNK Neo Geo Pocket (Japan, Europe) (En,Ja).ngp'
required: true
ngpc:
files:
- name: "[BIOS] SNK Neo Geo Pocket (Japan, Europe) (En,Ja).ngp"
destination: "[BIOS] SNK Neo Geo Pocket (Japan, Europe) (En,Ja).ngp"
- name: '[BIOS] SNK Neo Geo Pocket (Japan, Europe) (En,Ja).ngp'
destination: '[BIOS] SNK Neo Geo Pocket (Japan, Europe) (En,Ja).ngp'
required: true
odyssey2:
files:
@@ -1319,7 +1189,7 @@ systems:
destination: bios.min
required: true
md5: 1e4fb124a3a886865acb574f388c803d
ps2:
sony-playstation-2:
files:
- name: ps2-0230a-20080220.bin
destination: pcsx2/bios/ps2-0230a-20080220.bin

View File

@@ -4372,7 +4372,7 @@ systems:
- name: peribox_ev.zip
destination: bios/peribox_ev.zip
required: true
md5: e32bdbc9488e706ab0360db52e0eee63
md5: e32bdbc9488e706a30533540e059e0dc
- name: permedia2.zip
destination: bios/permedia2.zip
required: true
@@ -4384,7 +4384,7 @@ systems:
- name: peribox_gen.zip
destination: bios/peribox_gen.zip
required: true
md5: c35855fdc7f6a72fa11f80cfb94b3c80
md5: c35855fdc7f6a72f1e4c56a0e2eabf88
- name: peribox_sg.zip
destination: bios/peribox_sg.zip
required: true

View File

@@ -21,12 +21,17 @@ import json
import os
import subprocess
import sys
import urllib.request
import urllib.error
import urllib.request
from pathlib import Path
sys.path.insert(0, os.path.dirname(os.path.abspath(__file__)))
from common import list_registered_platforms, load_database, load_platform_config, require_yaml
from common import (
list_registered_platforms,
load_database,
load_platform_config,
require_yaml,
)
yaml = require_yaml()
@@ -83,14 +88,16 @@ def find_missing(config: dict, db: dict) -> list[dict]:
found = any(m in by_md5 for m in md5_list)
if not found:
missing.append({
"name": name,
"system": sys_id,
"sha1": sha1,
"md5": md5,
"size": file_entry.get("size"),
"destination": file_entry.get("destination", name),
})
missing.append(
{
"name": name,
"system": sys_id,
"sha1": sha1,
"md5": md5,
"size": file_entry.get("size"),
"destination": file_entry.get("destination", name),
}
)
return missing
@@ -139,14 +146,16 @@ def step2_scan_branches(entry: dict) -> bytes | None:
try:
subprocess.run(
["git", "rev-parse", "--verify", ref],
capture_output=True, check=True,
capture_output=True,
check=True,
)
except subprocess.CalledProcessError:
continue
result = subprocess.run(
["git", "ls-tree", "-r", "--name-only", ref],
capture_output=True, text=True,
capture_output=True,
text=True,
)
for filepath in result.stdout.strip().split("\n"):
@@ -154,7 +163,8 @@ def step2_scan_branches(entry: dict) -> bytes | None:
try:
blob = subprocess.run(
["git", "show", f"{ref}:{filepath}"],
capture_output=True, check=True,
capture_output=True,
check=True,
)
if verify_content(blob.stdout, entry):
return blob.stdout
@@ -172,7 +182,9 @@ def step3_search_public_repos(entry: dict) -> bytes | None:
for url_template in PUBLIC_REPOS:
url = url_template.format(name=name)
try:
req = urllib.request.Request(url, headers={"User-Agent": "retrobios-fetch/1.0"})
req = urllib.request.Request(
url, headers={"User-Agent": "retrobios-fetch/1.0"}
)
with urllib.request.urlopen(req, timeout=30) as resp:
data = _read_limited(resp)
if data is None:
@@ -185,7 +197,9 @@ def step3_search_public_repos(entry: dict) -> bytes | None:
if "/" in destination:
url = url_template.format(name=destination)
try:
req = urllib.request.Request(url, headers={"User-Agent": "retrobios-fetch/1.0"})
req = urllib.request.Request(
url, headers={"User-Agent": "retrobios-fetch/1.0"}
)
with urllib.request.urlopen(req, timeout=30) as resp:
data = _read_limited(resp)
if data is None:
@@ -206,7 +220,9 @@ def step4_search_archive_org(entry: dict) -> bytes | None:
for path in [name, f"system/{name}", f"bios/{name}"]:
url = f"https://archive.org/download/{collection_id}/{path}"
try:
req = urllib.request.Request(url, headers={"User-Agent": "retrobios-fetch/1.0"})
req = urllib.request.Request(
url, headers={"User-Agent": "retrobios-fetch/1.0"}
)
with urllib.request.urlopen(req, timeout=30) as resp:
data = _read_limited(resp)
if data is None:
@@ -221,12 +237,13 @@ def step4_search_archive_org(entry: dict) -> bytes | None:
return None
search_url = (
f"https://archive.org/advancedsearch.php?"
f"q=sha1:{sha1}&output=json&rows=1"
f"https://archive.org/advancedsearch.php?q=sha1:{sha1}&output=json&rows=1"
)
try:
req = urllib.request.Request(search_url, headers={"User-Agent": "retrobios-fetch/1.0"})
req = urllib.request.Request(
search_url, headers={"User-Agent": "retrobios-fetch/1.0"}
)
with urllib.request.urlopen(req, timeout=30) as resp:
result = json.loads(resp.read())
docs = result.get("response", {}).get("docs", [])
@@ -235,7 +252,9 @@ def step4_search_archive_org(entry: dict) -> bytes | None:
if identifier:
dl_url = f"https://archive.org/download/{identifier}/{name}"
try:
req2 = urllib.request.Request(dl_url, headers={"User-Agent": "retrobios-fetch/1.0"})
req2 = urllib.request.Request(
dl_url, headers={"User-Agent": "retrobios-fetch/1.0"}
)
with urllib.request.urlopen(req2, timeout=30) as resp2:
data = _read_limited(resp2)
if data is not None and verify_content(data, entry):
@@ -297,7 +316,7 @@ def fetch_missing(
continue
if dry_run:
print(f" [DRY RUN] Would search branches, repos, archive.org")
print(" [DRY RUN] Would search branches, repos, archive.org")
still_missing.append(entry)
stats["not_found"] += 1
continue
@@ -323,7 +342,7 @@ def fetch_missing(
stats["found"] += 1
continue
print(f" [5] Not found - needs community contribution")
print(" [5] Not found - needs community contribution")
still_missing.append(entry)
stats["not_found"] += 1
@@ -345,16 +364,20 @@ def generate_issue_body(missing: list[dict], platform: str) -> str:
for entry in missing:
sha1 = entry.get("sha1") or "N/A"
md5 = entry.get("md5") or "N/A"
lines.append(f"| `{entry['name']}` | {entry['system']} | `{sha1[:12]}...` | `{md5[:12]}...` |")
lines.append(
f"| `{entry['name']}` | {entry['system']} | `{sha1[:12]}...` | `{md5[:12]}...` |"
)
lines.extend([
"",
"### How to Contribute",
"",
"1. Fork this repository",
"2. Add the BIOS file to `bios/Manufacturer/Console/`",
"3. Create a Pull Request - checksums are verified automatically",
])
lines.extend(
[
"",
"### How to Contribute",
"",
"1. Fork this repository",
"2. Add the BIOS file to `bios/Manufacturer/Console/`",
"3. Create a Pull Request - checksums are verified automatically",
]
)
return "\n".join(lines)
@@ -363,11 +386,15 @@ def main():
parser = argparse.ArgumentParser(description="Auto-fetch missing BIOS files")
parser.add_argument("--platform", "-p", help="Platform to check")
parser.add_argument("--all", action="store_true", help="Check all platforms")
parser.add_argument("--dry-run", action="store_true", help="Don't download, just report")
parser.add_argument(
"--dry-run", action="store_true", help="Don't download, just report"
)
parser.add_argument("--db", default=DEFAULT_DB)
parser.add_argument("--platforms-dir", default=DEFAULT_PLATFORMS_DIR)
parser.add_argument("--bios-dir", default=DEFAULT_BIOS_DIR)
parser.add_argument("--create-issues", action="store_true", help="Output GitHub Issue bodies")
parser.add_argument(
"--create-issues", action="store_true", help="Output GitHub Issue bodies"
)
args = parser.parse_args()
if not os.path.exists(args.db):
@@ -378,7 +405,8 @@ def main():
if args.all:
platforms = list_registered_platforms(
args.platforms_dir, include_archived=True,
args.platforms_dir,
include_archived=True,
)
elif args.platform:
platforms = [args.platform]
@@ -389,19 +417,19 @@ def main():
all_still_missing = {}
for platform in sorted(platforms):
print(f"\n{'='*60}")
print(f"\n{'=' * 60}")
print(f"Platform: {platform}")
print(f"{'='*60}")
print(f"{'=' * 60}")
try:
config = load_platform_config(platform, args.platforms_dir)
except FileNotFoundError:
print(f" Config not found, skipping")
print(" Config not found, skipping")
continue
missing = find_missing(config, db)
if not missing:
print(f" All BIOS files present!")
print(" All BIOS files present!")
continue
print(f" {len(missing)} missing files")
@@ -414,9 +442,9 @@ def main():
print(f"\n Results: {stats['found']} found, {stats['not_found']} not found")
if args.create_issues and all_still_missing:
print(f"\n{'='*60}")
print(f"\n{'=' * 60}")
print("GitHub Issue Bodies")
print(f"{'='*60}")
print(f"{'=' * 60}")
for platform, missing in all_still_missing.items():
print(f"\n--- Issue for {platform} ---\n")
print(generate_issue_body(missing, platform))

View File

@@ -9,6 +9,7 @@ Usage:
python scripts/check_buildbot_system.py --update
python scripts/check_buildbot_system.py --json
"""
from __future__ import annotations
import argparse
@@ -36,10 +37,14 @@ def fetch_index() -> set[str]:
"""Fetch .index from buildbot, return set of ZIP filenames."""
req = urllib.request.Request(INDEX_URL, headers={"User-Agent": USER_AGENT})
with urllib.request.urlopen(req, timeout=REQUEST_TIMEOUT) as resp:
return {line.strip() for line in resp.read().decode().splitlines() if line.strip()}
return {
line.strip() for line in resp.read().decode().splitlines() if line.strip()
}
def load_tracked_entries(registry_path: str = DEFAULT_REGISTRY) -> dict[str, tuple[str, str]]:
def load_tracked_entries(
registry_path: str = DEFAULT_REGISTRY,
) -> dict[str, tuple[str, str]]:
"""Load buildbot entries from _data_dirs.yml.
Returns {decoded_zip_name: (key, source_url)}.
@@ -64,8 +69,9 @@ def load_tracked_entries(registry_path: str = DEFAULT_REGISTRY) -> dict[str, tup
def get_remote_etag(url: str) -> str | None:
"""HEAD request to get ETag."""
try:
req = urllib.request.Request(url, method="HEAD",
headers={"User-Agent": USER_AGENT})
req = urllib.request.Request(
url, method="HEAD", headers={"User-Agent": USER_AGENT}
)
with urllib.request.urlopen(req, timeout=REQUEST_TIMEOUT) as resp:
return resp.headers.get("ETag") or resp.headers.get("Last-Modified") or ""
except (urllib.error.URLError, OSError):
@@ -114,8 +120,15 @@ def check(registry_path: str = DEFAULT_REGISTRY) -> dict:
status = "OK"
else:
status = "UPDATED"
results.append({"zip": z, "status": status, "key": key,
"stored_etag": stored, "remote_etag": remote or ""})
results.append(
{
"zip": z,
"status": status,
"key": key,
"stored_etag": stored,
"remote_etag": remote or "",
}
)
return {"entries": results}
@@ -144,8 +157,13 @@ def update_changed(report: dict) -> None:
if e["status"] == "UPDATED" and e.get("key"):
log.info("refreshing %s ...", e["key"])
subprocess.run(
[sys.executable, "scripts/refresh_data_dirs.py",
"--force", "--key", e["key"]],
[
sys.executable,
"scripts/refresh_data_dirs.py",
"--force",
"--key",
e["key"],
],
check=False,
)
@@ -155,10 +173,15 @@ def main() -> None:
parser = argparse.ArgumentParser(
description="Check buildbot system directory for changes",
)
parser.add_argument("--update", action="store_true",
help="Auto-refresh changed entries")
parser.add_argument("--json", action="store_true", dest="json_output",
help="Machine-readable JSON output")
parser.add_argument(
"--update", action="store_true", help="Auto-refresh changed entries"
)
parser.add_argument(
"--json",
action="store_true",
dest="json_output",
help="Machine-readable JSON output",
)
parser.add_argument("--registry", default=DEFAULT_REGISTRY)
args = parser.parse_args()

View File

@@ -26,9 +26,11 @@ def require_yaml():
"""Import and return yaml, exiting if PyYAML is not installed."""
try:
import yaml as _yaml
return _yaml
except ImportError:
import sys
print("Error: PyYAML required (pip install pyyaml)", file=sys.stderr)
sys.exit(1)
@@ -154,12 +156,17 @@ def load_platform_config(platform_name: str, platforms_dir: str = "platforms") -
if "inherits" in config:
parent = load_platform_config(config["inherits"], platforms_dir)
merged = {**parent}
merged.update({k: v for k, v in config.items() if k not in ("inherits", "overrides")})
merged.update(
{k: v for k, v in config.items() if k not in ("inherits", "overrides")}
)
if "overrides" in config and "systems" in config["overrides"]:
merged.setdefault("systems", {})
for sys_id, override in config["overrides"]["systems"].items():
if sys_id in merged["systems"]:
merged["systems"][sys_id] = {**merged["systems"][sys_id], **override}
merged["systems"][sys_id] = {
**merged["systems"][sys_id],
**override,
}
else:
merged["systems"][sys_id] = override
config = merged
@@ -191,6 +198,37 @@ def load_platform_config(platform_name: str, platforms_dir: str = "platforms") -
system.setdefault("files", []).append(gf)
existing.add(key)
# Merge metadata from _registry.yml. The registry is our curated source;
# the scraped YAML may be incomplete (missing cores, metadata fields).
# Registry fields supplement (not replace) the scraped config.
registry_path = os.path.join(platforms_dir, "_registry.yml")
if os.path.exists(registry_path):
reg_real = os.path.realpath(registry_path)
if reg_real not in _shared_yml_cache:
with open(registry_path) as f:
_shared_yml_cache[reg_real] = yaml.safe_load(f) or {}
reg = _shared_yml_cache[reg_real]
reg_entry = reg.get("platforms", {}).get(platform_name, {})
# Merge cores (union for lists, override for all_libretro)
reg_cores = reg_entry.get("cores")
if reg_cores is not None:
cfg_cores = config.get("cores")
if reg_cores == "all_libretro":
config["cores"] = "all_libretro"
elif isinstance(reg_cores, list) and isinstance(cfg_cores, list):
merged_set = {str(c) for c in cfg_cores} | {str(c) for c in reg_cores}
config["cores"] = sorted(merged_set)
elif isinstance(reg_cores, list) and cfg_cores is None:
config["cores"] = reg_cores
# Merge all registry fields absent from config (except cores,
# handled above with union logic). No hardcoded list — any field
# added to the registry is automatically available in the config.
for key, val in reg_entry.items():
if key != "cores" and key not in config:
config[key] = val
_platform_config_cache[cache_key] = config
return config
@@ -315,12 +353,14 @@ def list_available_targets(
result = []
for tname, tdata in sorted(data.get("targets", {}).items()):
aliases = overrides.get(tname, {}).get("aliases", [])
result.append({
"name": tname,
"architecture": tdata.get("architecture", ""),
"core_count": len(tdata.get("cores", [])),
"aliases": aliases,
})
result.append(
{
"name": tname,
"architecture": tdata.get("architecture", ""),
"core_count": len(tdata.get("cores", [])),
"aliases": aliases,
}
)
return result
@@ -367,7 +407,9 @@ def resolve_local_file(
if hint_base and hint_base not in names_to_try:
names_to_try.append(hint_base)
md5_list = [m.strip().lower() for m in md5_raw.split(",") if m.strip()] if md5_raw else []
md5_list = (
[m.strip().lower() for m in md5_raw.split(",") if m.strip()] if md5_raw else []
)
files_db = db.get("files", {})
by_md5 = db.get("indexes", {}).get("by_md5", {})
by_name = db.get("indexes", {}).get("by_name", {})
@@ -405,8 +447,12 @@ def resolve_local_file(
sha1_match = by_md5.get(md5_candidate)
if sha1_match and sha1_match in files_db:
path = files_db[sha1_match]["path"]
if os.path.exists(path) and _md5_name_ok(path):
return path, "md5_exact"
# Full MD5 (32 chars) is a strong identifier: trust it
# without name guard. Truncated MD5 still needs name check
# to avoid cross-contamination.
if os.path.exists(path):
if len(md5_candidate) >= 32 or _md5_name_ok(path):
return path, "md5_exact"
if len(md5_candidate) < 32:
for db_md5, db_sha1 in by_md5.items():
if db_md5.startswith(md5_candidate) and db_sha1 in files_db:
@@ -445,7 +491,9 @@ def resolve_local_file(
if candidates:
if zipped_file:
candidates = [(p, m) for p, m in candidates if ".zip" in os.path.basename(p)]
candidates = [
(p, m) for p, m in candidates if ".zip" in os.path.basename(p)
]
if md5_set:
for path, db_md5 in candidates:
if ".zip" in os.path.basename(path):
@@ -495,7 +543,11 @@ def resolve_local_file(
if canonical and canonical != name:
canonical_entry = {"name": canonical}
result = resolve_local_file(
canonical_entry, db, zip_contents, dest_hint, _depth=_depth + 1,
canonical_entry,
db,
zip_contents,
dest_hint,
_depth=_depth + 1,
data_dir_registry=data_dir_registry,
)
if result[0]:
@@ -522,6 +574,25 @@ def resolve_local_file(
if fn.casefold() in basename_targets:
return os.path.join(root, fn), "data_dir"
# Agnostic fallback: for filename-agnostic files, find any DB file
# matching the system path prefix and size criteria
if file_entry.get("agnostic"):
agnostic_prefix = file_entry.get("agnostic_path_prefix", "")
min_size = file_entry.get("min_size", 0)
max_size = file_entry.get("max_size", float("inf"))
exact_size = file_entry.get("size")
if exact_size and not min_size:
min_size = exact_size
max_size = exact_size
if agnostic_prefix:
for _sha1, entry in files_db.items():
path = entry.get("path", "")
if not path.startswith(agnostic_prefix):
continue
size = entry.get("size", 0)
if min_size <= size <= max_size and os.path.exists(path):
return path, "agnostic_fallback"
return None, "not_found"
@@ -589,9 +660,7 @@ def build_zip_contents_index(db: dict, max_entry_size: int = 512 * 1024 * 1024)
if path.endswith(".zip") and os.path.exists(path):
zip_entries.append((path, sha1))
fingerprint = frozenset(
(path, os.path.getmtime(path)) for path, _ in zip_entries
)
fingerprint = frozenset((path, os.path.getmtime(path)) for path, _ in zip_entries)
if _zip_contents_cache is not None and _zip_contents_cache[0] == fingerprint:
return _zip_contents_cache[1]
@@ -618,7 +687,8 @@ _emulator_profiles_cache: dict[tuple[str, bool], dict[str, dict]] = {}
def load_emulator_profiles(
emulators_dir: str, skip_aliases: bool = True,
emulators_dir: str,
skip_aliases: bool = True,
) -> dict[str, dict]:
"""Load all emulator YAML profiles from a directory (cached)."""
cache_key = (os.path.realpath(emulators_dir), skip_aliases)
@@ -633,6 +703,8 @@ def load_emulator_profiles(
if not emu_path.exists():
return profiles
for f in sorted(emu_path.glob("*.yml")):
if f.name.endswith(".old.yml"):
continue
with open(f) as fh:
profile = yaml.safe_load(fh) or {}
if "emulator" not in profile:
@@ -645,7 +717,8 @@ def load_emulator_profiles(
def group_identical_platforms(
platforms: list[str], platforms_dir: str,
platforms: list[str],
platforms_dir: str,
target_cores_cache: dict[str, set[str] | None] | None = None,
) -> list[tuple[list[str], str]]:
"""Group platforms that produce identical packs (same files + base_destination).
@@ -688,7 +761,9 @@ def group_identical_platforms(
fp = hashlib.sha1(f"{fp}|{tc_str}".encode()).hexdigest()
fingerprints.setdefault(fp, []).append(platform)
# Prefer the root platform (no inherits) as representative
if fp not in representatives or (not inherits[platform] and inherits.get(representatives[fp], False)):
if fp not in representatives or (
not inherits[platform] and inherits.get(representatives[fp], False)
):
representatives[fp] = platform
result = []
@@ -700,7 +775,8 @@ def group_identical_platforms(
def resolve_platform_cores(
config: dict, profiles: dict[str, dict],
config: dict,
profiles: dict[str, dict],
target_cores: set[str] | None = None,
) -> set[str]:
"""Resolve which emulator profiles are relevant for a platform.
@@ -717,9 +793,9 @@ def resolve_platform_cores(
if cores_config == "all_libretro":
result = {
name for name, p in profiles.items()
if "libretro" in p.get("type", "")
and p.get("type") != "alias"
name
for name, p in profiles.items()
if "libretro" in p.get("type", "") and p.get("type") != "alias"
}
elif isinstance(cores_config, list):
core_set = {str(c) for c in cores_config}
@@ -730,16 +806,22 @@ def resolve_platform_cores(
core_to_profile[name] = name
for core_name in p.get("cores", []):
core_to_profile[str(core_name)] = name
result = {
core_to_profile[c]
for c in core_set
if c in core_to_profile
}
result = {core_to_profile[c] for c in core_set if c in core_to_profile}
# Support "all_libretro" as a list element: combines all libretro
# profiles with explicitly listed standalone cores (e.g. RetroDECK
# ships RetroArch + standalone emulators)
if "all_libretro" in core_set or "retroarch" in core_set:
result |= {
name
for name, p in profiles.items()
if "libretro" in p.get("type", "") and p.get("type") != "alias"
}
else:
# Fallback: system ID intersection with normalization
norm_plat_systems = {_norm_system_id(s) for s in config.get("systems", {})}
result = {
name for name, p in profiles.items()
name
for name, p in profiles.items()
if {_norm_system_id(s) for s in p.get("systems", [])} & norm_plat_systems
and p.get("type") != "alias"
}
@@ -761,11 +843,34 @@ def resolve_platform_cores(
MANUFACTURER_PREFIXES = (
"acorn-", "apple-", "microsoft-", "nintendo-", "sony-", "sega-",
"snk-", "panasonic-", "nec-", "epoch-", "mattel-", "fairchild-",
"hartung-", "tiger-", "magnavox-", "philips-", "bandai-", "casio-",
"coleco-", "commodore-", "sharp-", "sinclair-", "atari-", "sammy-",
"gce-", "interton-", "texas-instruments-", "videoton-",
"acorn-",
"apple-",
"microsoft-",
"nintendo-",
"sony-",
"sega-",
"snk-",
"panasonic-",
"nec-",
"epoch-",
"mattel-",
"fairchild-",
"hartung-",
"tiger-",
"magnavox-",
"philips-",
"bandai-",
"casio-",
"coleco-",
"commodore-",
"sharp-",
"sinclair-",
"atari-",
"sammy-",
"gce-",
"interton-",
"texas-instruments-",
"videoton-",
)
@@ -812,7 +917,7 @@ def _norm_system_id(sid: str) -> str:
s = SYSTEM_ALIASES.get(s, s)
for prefix in MANUFACTURER_PREFIXES:
if s.startswith(prefix):
s = s[len(prefix):]
s = s[len(prefix) :]
break
return s.replace("-", "")
@@ -882,6 +987,72 @@ def filter_systems_by_target(
return filtered
def expand_platform_declared_names(config: dict, db: dict) -> set[str]:
"""Build set of file names declared by a platform config.
Enriches the set with canonical names and aliases from the database
by resolving each platform file's MD5 through by_md5. This handles
cases where a platform declares a file under a different name than
the emulator profile (e.g. Batocera ROM1 vs gsplus ROM).
"""
declared: set[str] = set()
by_md5 = db.get("indexes", {}).get("by_md5", {})
files_db = db.get("files", {})
for system in config.get("systems", {}).values():
for fe in system.get("files", []):
name = fe.get("name", "")
if name:
declared.add(name)
md5 = fe.get("md5", "")
if not md5:
continue
# Skip multi-hash and zippedFile entries (inner ROM MD5, not file MD5)
if "," in md5 or fe.get("zippedFile"):
continue
sha1 = by_md5.get(md5.lower())
if not sha1:
continue
entry = files_db.get(sha1, {})
db_name = entry.get("name", "")
if db_name:
declared.add(db_name)
for alias in entry.get("aliases", []):
declared.add(alias)
return declared
import re
_TIMESTAMP_PATTERNS = [
re.compile(r'"generated_at":\s*"[^"]*"'), # database.json
re.compile(r"\*Auto-generated on [^*]*\*"), # README.md
re.compile(r"\*Generated on [^*]*\*"), # docs site pages
]
def write_if_changed(path: str, content: str) -> bool:
"""Write content to path only if the non-timestamp content differs.
Compares new and existing content after stripping timestamp lines.
Returns True if the file was written, False if skipped (unchanged).
"""
if os.path.exists(path):
with open(path) as f:
existing = f.read()
if _strip_timestamps(existing) == _strip_timestamps(content):
return False
with open(path, "w") as f:
f.write(content)
return True
def _strip_timestamps(text: str) -> str:
"""Remove known timestamp patterns for content comparison."""
result = text
for pattern in _TIMESTAMP_PATTERNS:
result = pattern.sub("", result)
return result
# Validation and mode filtering -extracted to validation.py for SoC.
# Re-exported below for backward compatibility.
@@ -892,8 +1063,12 @@ LARGE_FILES_REPO = "Abdess/retrobios"
LARGE_FILES_CACHE = ".cache/large"
def fetch_large_file(name: str, dest_dir: str = LARGE_FILES_CACHE,
expected_sha1: str = "", expected_md5: str = "") -> str | None:
def fetch_large_file(
name: str,
dest_dir: str = LARGE_FILES_CACHE,
expected_sha1: str = "",
expected_md5: str = "",
) -> str | None:
"""Download a large file from the 'large-files' GitHub release if not cached."""
cached = os.path.join(dest_dir, name)
if os.path.exists(cached):
@@ -902,7 +1077,9 @@ def fetch_large_file(name: str, dest_dir: str = LARGE_FILES_CACHE,
if expected_sha1 and hashes["sha1"].lower() != expected_sha1.lower():
os.unlink(cached)
elif expected_md5:
md5_list = [m.strip().lower() for m in expected_md5.split(",") if m.strip()]
md5_list = [
m.strip().lower() for m in expected_md5.split(",") if m.strip()
]
if hashes["md5"].lower() not in md5_list:
os.unlink(cached)
else:
@@ -991,8 +1168,9 @@ def list_platform_system_ids(platform_name: str, platforms_dir: str) -> None:
file_count = len(systems[sys_id].get("files", []))
mfr = systems[sys_id].get("manufacturer", "")
mfr_display = f" [{mfr.split('|')[0]}]" if mfr else ""
print(f" {sys_id:35s} ({file_count} file{'s' if file_count != 1 else ''}){mfr_display}")
print(
f" {sys_id:35s} ({file_count} file{'s' if file_count != 1 else ''}){mfr_display}"
)
def build_target_cores_cache(

View File

@@ -19,7 +19,13 @@ import sys
from pathlib import Path
sys.path.insert(0, os.path.dirname(__file__))
from common import list_registered_platforms, load_database, load_emulator_profiles, load_platform_config, require_yaml
from common import (
list_registered_platforms,
load_database,
load_emulator_profiles,
load_platform_config,
require_yaml,
)
yaml = require_yaml()
@@ -28,11 +34,15 @@ DEFAULT_PLATFORMS_DIR = "platforms"
DEFAULT_DB = "database.json"
def load_platform_files(platforms_dir: str) -> tuple[dict[str, set[str]], dict[str, set[str]]]:
def load_platform_files(
platforms_dir: str,
) -> tuple[dict[str, set[str]], dict[str, set[str]]]:
"""Load all platform configs and collect declared filenames + data_directories per system."""
declared = {}
platform_data_dirs = {}
for platform_name in list_registered_platforms(platforms_dir, include_archived=True):
for platform_name in list_registered_platforms(
platforms_dir, include_archived=True
):
config = load_platform_config(platform_name, platforms_dir)
for sys_id, system in config.get("systems", {}).items():
for fe in system.get("files", []):
@@ -46,8 +56,9 @@ def load_platform_files(platforms_dir: str) -> tuple[dict[str, set[str]], dict[s
return declared, platform_data_dirs
def _build_supplemental_index(data_root: str = "data",
bios_root: str = "bios") -> set[str]:
def _build_supplemental_index(
data_root: str = "data", bios_root: str = "bios"
) -> set[str]:
"""Build a set of filenames and directory names in data/ and inside bios/ ZIPs."""
names: set[str] = set()
root_path = Path(data_root)
@@ -76,12 +87,15 @@ def _build_supplemental_index(data_root: str = "data",
names.add(dpath.name + "/")
names.add(dpath.name.lower() + "/")
import zipfile
for zpath in bios_path.rglob("*.zip"):
try:
with zipfile.ZipFile(zpath) as zf:
for member in zf.namelist():
if not member.endswith("/"):
basename = member.rsplit("/", 1)[-1] if "/" in member else member
basename = (
member.rsplit("/", 1)[-1] if "/" in member else member
)
names.add(basename)
names.add(basename.lower())
except (zipfile.BadZipFile, OSError):
@@ -89,8 +103,12 @@ def _build_supplemental_index(data_root: str = "data",
return names
def _find_in_repo(fname: str, by_name: dict[str, list], by_name_lower: dict[str, str],
data_names: set[str] | None = None) -> bool:
def _find_in_repo(
fname: str,
by_name: dict[str, list],
by_name_lower: dict[str, str],
data_names: set[str] | None = None,
) -> bool:
if fname in by_name:
return True
# For directory entries or paths, extract the meaningful basename
@@ -170,7 +188,9 @@ def cross_reference(
if not in_repo:
path_field = f.get("path", "")
if path_field and path_field != fname:
in_repo = _find_in_repo(path_field, by_name, by_name_lower, data_names)
in_repo = _find_in_repo(
path_field, by_name, by_name_lower, data_names
)
# Try MD5 hash match (handles files that exist under different names)
if not in_repo:
md5_raw = f.get("md5", "")
@@ -231,9 +251,11 @@ def print_report(report: dict) -> None:
status = f"{data['gap_in_repo']} in repo, {data['gap_missing']} missing"
print(f"\n{data['emulator']} ({', '.join(data['systems'])})")
print(f" {data['total_files']} files in profile, "
f"{data['platform_covered']} declared by platforms, "
f"{gaps} undeclared")
print(
f" {data['total_files']} files in profile, "
f"{data['platform_covered']} declared by platforms, "
f"{gaps} undeclared"
)
if gaps > 0:
print(f" Gaps: {status}")
@@ -259,7 +281,9 @@ def main():
parser.add_argument("--platforms-dir", default=DEFAULT_PLATFORMS_DIR)
parser.add_argument("--db", default=DEFAULT_DB)
parser.add_argument("--emulator", "-e", help="Analyze single emulator")
parser.add_argument("--platform", "-p", help="Platform name (required for --target)")
parser.add_argument(
"--platform", "-p", help="Platform name (required for --target)"
)
parser.add_argument("--target", "-t", help="Hardware target (e.g., switch, rpi4)")
parser.add_argument("--json", action="store_true", help="JSON output")
args = parser.parse_args()
@@ -272,7 +296,10 @@ def main():
if not args.platform:
parser.error("--target requires --platform")
from common import load_target_config, resolve_platform_cores
target_cores = load_target_config(args.platform, args.target, args.platforms_dir)
target_cores = load_target_config(
args.platform, args.target, args.platforms_dir
)
config = load_platform_config(args.platform, args.platforms_dir)
relevant = resolve_platform_cores(config, profiles, target_cores=target_cores)
profiles = {k: v for k, v in profiles.items() if k in relevant}

View File

@@ -14,6 +14,7 @@ Source refs:
Azahar src/core/hw/rsa/rsa.cpp
Azahar src/core/file_sys/otp.cpp
"""
from __future__ import annotations
import hashlib
@@ -22,9 +23,9 @@ import subprocess
from collections.abc import Callable
from pathlib import Path
# Key file parsing (keys.txt / aes_keys.txt format)
def parse_keys_file(path: str | Path) -> dict[str, dict[str, bytes]]:
"""Parse a 3DS keys file with :AES, :RSA, :ECC sections.
@@ -67,6 +68,7 @@ def find_keys_file(bios_dir: str | Path) -> Path | None:
# Pure Python RSA-2048 PKCS1v15 SHA256 verification (zero dependencies)
def _rsa_verify_pkcs1v15_sha256(
message: bytes,
signature: bytes,
@@ -98,14 +100,29 @@ def _rsa_verify_pkcs1v15_sha256(
# PKCS#1 v1.5 signature encoding: 0x00 0x01 [0xFF padding] 0x00 [DigestInfo]
# DigestInfo for SHA-256:
# SEQUENCE { SEQUENCE { OID sha256, NULL }, OCTET STRING hash }
digest_info_prefix = bytes([
0x30, 0x31, # SEQUENCE (49 bytes)
0x30, 0x0D, # SEQUENCE (13 bytes)
0x06, 0x09, # OID (9 bytes)
0x60, 0x86, 0x48, 0x01, 0x65, 0x03, 0x04, 0x02, 0x01, # sha256
0x05, 0x00, # NULL
0x04, 0x20, # OCTET STRING (32 bytes)
])
digest_info_prefix = bytes(
[
0x30,
0x31, # SEQUENCE (49 bytes)
0x30,
0x0D, # SEQUENCE (13 bytes)
0x06,
0x09, # OID (9 bytes)
0x60,
0x86,
0x48,
0x01,
0x65,
0x03,
0x04,
0x02,
0x01, # sha256
0x05,
0x00, # NULL
0x04,
0x20, # OCTET STRING (32 bytes)
]
)
sha256_hash = hashlib.sha256(message).digest()
expected_digest_info = digest_info_prefix + sha256_hash
@@ -122,11 +139,13 @@ def _rsa_verify_pkcs1v15_sha256(
# AES-128-CBC decryption (with fallback)
def _aes_128_cbc_decrypt(data: bytes, key: bytes, iv: bytes) -> bytes:
"""Decrypt AES-128-CBC without padding."""
# Try cryptography library first
try:
from cryptography.hazmat.primitives.ciphers import Cipher, algorithms, modes
cipher = Cipher(algorithms.AES(key), modes.CBC(iv))
decryptor = cipher.decryptor()
return decryptor.update(data) + decryptor.finalize()
@@ -136,6 +155,7 @@ def _aes_128_cbc_decrypt(data: bytes, key: bytes, iv: bytes) -> bytes:
# Try pycryptodome
try:
from Crypto.Cipher import AES # type: ignore[import-untyped]
cipher = AES.new(key, AES.MODE_CBC, iv)
return cipher.decrypt(data)
except ImportError:
@@ -145,8 +165,15 @@ def _aes_128_cbc_decrypt(data: bytes, key: bytes, iv: bytes) -> bytes:
try:
result = subprocess.run(
[
"openssl", "enc", "-aes-128-cbc", "-d",
"-K", key.hex(), "-iv", iv.hex(), "-nopad",
"openssl",
"enc",
"-aes-128-cbc",
"-d",
"-K",
key.hex(),
"-iv",
iv.hex(),
"-nopad",
],
input=data,
capture_output=True,
@@ -162,6 +189,7 @@ def _aes_128_cbc_decrypt(data: bytes, key: bytes, iv: bytes) -> bytes:
# File verification functions
def verify_secure_info_a(
filepath: str | Path,
keys: dict[str, dict[str, bytes]],
@@ -204,7 +232,10 @@ def verify_secure_info_a(
continue
modified_body = bytes([test_region]) + body[1:]
if _rsa_verify_pkcs1v15_sha256(modified_body, signature, modulus, exponent):
return False, f"signature invalid (region changed from {test_region} to {region_byte})"
return (
False,
f"signature invalid (region changed from {test_region} to {region_byte})",
)
return False, "signature invalid"
@@ -307,7 +338,7 @@ def verify_otp(
Returns (valid, reason_string).
"""
from sect233r1 import ecdsa_verify_sha256, _ec_mul, _Gx, _Gy, _N
from sect233r1 import _N, _ec_mul, _Gx, _Gy, ecdsa_verify_sha256
data = bytearray(Path(filepath).read_bytes())
@@ -322,7 +353,10 @@ def verify_otp(
magic = struct.unpack_from("<I", data, 0)[0]
if magic != 0xDEADB00F:
if not otp_key or not otp_iv:
return False, "encrypted OTP but missing AES keys (otpKey/otpIV) in keys file"
return (
False,
"encrypted OTP but missing AES keys (otpKey/otpIV) in keys file",
)
try:
data = bytearray(_aes_128_cbc_decrypt(bytes(data), otp_key, otp_iv))
except RuntimeError as e:
@@ -343,7 +377,10 @@ def verify_otp(
ecc_keys = keys.get("ECC", {})
root_public_xy = ecc_keys.get("rootPublicXY")
if not root_public_xy or len(root_public_xy) != 60:
return True, "decrypted, magic valid, SHA-256 valid (ECC skipped: no rootPublicXY)"
return (
True,
"decrypted, magic valid, SHA-256 valid (ECC skipped: no rootPublicXY)",
)
# Extract CTCert fields from OTP body
device_id = struct.unpack_from("<I", data, 0x04)[0]
@@ -368,9 +405,7 @@ def verify_otp(
pub_point = _ec_mul(priv_key_int, (_Gx, _Gy))
if pub_point is None:
return False, "ECC cert: derived public key is point at infinity"
pub_key_xy = (
pub_point[0].to_bytes(30, "big") + pub_point[1].to_bytes(30, "big")
)
pub_key_xy = pub_point[0].to_bytes(30, "big") + pub_point[1].to_bytes(30, "big")
# Build certificate body (what was signed)
# Issuer: "Nintendo CA - G3_NintendoCTR2prod" or "...dev"
@@ -379,12 +414,12 @@ def verify_otp(
issuer_str = b"Nintendo CA - G3_NintendoCTR2prod"
else:
issuer_str = b"Nintendo CA - G3_NintendoCTR2dev"
issuer[:len(issuer_str)] = issuer_str
issuer[: len(issuer_str)] = issuer_str
# Name: "CT{device_id:08X}-{system_type:02X}"
name = bytearray(0x40)
name_str = f"CT{device_id:08X}-{system_type:02X}".encode()
name[:len(name_str)] = name_str
name[: len(name_str)] = name_str
# Key type = 2 (ECC), big-endian u32
key_type = struct.pack(">I", 2)

Some files were not shown because too many files have changed in this diff Show More