mirror of
https://github.com/Abdess/retroarch_system.git
synced 2026-10-10 13:33:24 -05:00
Compare commits
3
Commits
4f67e3cad3
...
68960b1457
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
68960b1457 | ||
|
|
5bd98fbe3a | ||
|
|
08bce47668 |
No files matched your search
+5
-9
@@ -15,10 +15,6 @@ node_modules/
|
||||
docs/
|
||||
|
||||
# Large files stored as GitHub Release assets (> 50MB)
|
||||
bios/Arcade/Arcade/Firmware.19.0.0.zip
|
||||
bios/Arcade/Arcade/maclc3.zip
|
||||
bios/Nintendo/Nintendo DS/dsi_nand.bin
|
||||
bios/Other/Batocera42/dsi_nand.bin
|
||||
bios/Sony/PlayStation 3/PS3UPDAT.PUP
|
||||
bios/Sony/PlayStation 3/.variants/PS3UPDAT.PUP.ed8ab192
|
||||
bios/Sony/PlayStation Vita/PSVUPDAT.PUP
|
||||
@@ -66,20 +62,20 @@ tmp/
|
||||
# FBA2012 Toaplan samples (>100MB)
|
||||
bios/Arcade/fba2012/samples/fireshrk.zip
|
||||
bios/Arcade/fba2012/samples/ghox.zip
|
||||
bios/Arcade/fba2012/samples/samesame.zip
|
||||
bios/Arcade/fba2012/samples/tekipaki.zip
|
||||
bios/Arcade/fba2012/samples/vimana.zip
|
||||
bios/Arcade/fba2012/samples/fireshrk.zip
|
||||
bios/Arcade/fba2012/samples/samesame.zip
|
||||
bios/Arcade/fba2012/samples/vimana.zip
|
||||
bios/Nintendo/Switch/Firmware_batocera43.zip
|
||||
bios/Nintendo/DS/.variants/dsi_nand.bin.8b79a73c
|
||||
|
||||
# Wii NAND backup (528MB, fetched from large-files release)
|
||||
bios/Nintendo/Wii/nand.bin
|
||||
|
||||
# FBNeo audio samples (97MB and 155MB, fetched from large-files release)
|
||||
# FBNeo audio samples (96MB, 148MB and 199MB, fetched from large-files release)
|
||||
bios/Other/fbneo/fbneo/samples/donpachi.zip
|
||||
bios/Other/fbneo/fbneo/samples/sfz3mix.zip
|
||||
bios/Other/fbneo/fbneo/samples/twotiger.zip
|
||||
bios/Other/starboard/starboard-rootfs.tar.gz
|
||||
bios/Other/cspect/cspect-next-8gb.zip
|
||||
|
||||
# Output-directory locks (artifact_lock)
|
||||
.lock
|
||||
@@ -39,18 +39,18 @@ Every release ships `SHA256SUMS.txt` and a detached signature of it, checkable a
|
||||
|
||||
| Platform | Extracted size | Extract to | Download |
|
||||
|----------|---------------:|-----------|----------|
|
||||
| Batocera | 4.0 GB | `/userdata/bios/` | [Download](../../releases/latest) |
|
||||
| BizHawk | 2.2 GB | `Firmware/` | [Download](../../releases/latest) |
|
||||
| Batocera | 4.2 GB | `/userdata/bios/` | [Download](../../releases/latest) |
|
||||
| BizHawk | 2.4 GB | `Firmware/` | [Download](../../releases/latest) |
|
||||
| EmuDeck | 3.2 GB | `~/Emulation/bios/` | [Download](../../releases/latest) |
|
||||
| Lakka | 5.5 GB | `/storage/system/` | [Download](../../releases/latest) |
|
||||
| Lakka | 5.7 GB | `/storage/system/` | [Download](../../releases/latest) |
|
||||
| MiSTer FPGA | 24 MB | `/media/fat/games/` | [Download](../../releases/latest) |
|
||||
| ROCKNIX | 5.3 GB | `/storage/roms/bios/` | [Download](../../releases/latest) |
|
||||
| Recalbox | 3.6 GB | `/recalbox/share/bios/` | [Download](../../releases/latest) |
|
||||
| RetroArch | 5.5 GB | `system/` | [Download](../../releases/latest) |
|
||||
| RetroBat | 4.4 GB | `bios/` | [Download](../../releases/latest) |
|
||||
| RetroDECK | 6.2 GB | `~/retrodeck/` | [Download](../../releases/latest) |
|
||||
| RetroPie * | 5.5 GB | `~/RetroPie/BIOS/` | [Download](../../releases/latest) |
|
||||
| RomM | 1.3 GB | `bios/{platform_slug}/` | [Download](../../releases/latest) |
|
||||
| ROCKNIX | 5.5 GB | `/storage/roms/bios/` | [Download](../../releases/latest) |
|
||||
| Recalbox | 3.8 GB | `/recalbox/share/bios/` | [Download](../../releases/latest) |
|
||||
| RetroArch | 5.7 GB | `system/` | [Download](../../releases/latest) |
|
||||
| RetroBat | 4.6 GB | `bios/` | [Download](../../releases/latest) |
|
||||
| RetroDECK | 6.4 GB | `~/retrodeck/` | [Download](../../releases/latest) |
|
||||
| RetroPie * | 5.7 GB | `~/RetroPie/BIOS/` | [Download](../../releases/latest) |
|
||||
| RomM | 1.5 GB | `bios/{platform_slug}/` | [Download](../../releases/latest) |
|
||||
|
||||
The RetroDECK pack already contains its own `bios/` folder, so it extracts into `~/retrodeck/` rather than into the BIOS folder.
|
||||
|
||||
@@ -65,11 +65,11 @@ Each file is checked the way your platform checks it. Most compare a checksum, t
|
||||
|
||||
- **6 files** the platforms' emulators load are still to be found, and 21 more cannot be sourced at all (per-user keys, user-filled slots, dumps nobody has made); both are named in the [gap analysis](https://abdess.github.io/retrobios/gaps/)
|
||||
- **12 platforms** supported with platform-specific verification
|
||||
- **449 emulators** profiled from source (RetroArch cores + standalone)
|
||||
- **450 emulators** profiled from source (RetroArch cores + standalone)
|
||||
- **470 systems** handled by those emulators (NES, SNES, PlayStation, Saturn, Dreamcast, ...)
|
||||
- **10,330 files**, each with its SHA1, MD5, SHA256, CRC32 and Adler-32 fingerprints: 4,985 system files, 2,806 arcade ROM sets, 2,539 game and engine data files
|
||||
- **553 of 4,985 system files** matched to dump-preservation catalogs (No-Intro, Redump, TOSEC); arcade sets and engine data fall outside what those catalogs index
|
||||
- **12706 MB** total collection size
|
||||
- **10,357 files**, each with its SHA1, MD5, SHA256, CRC32 and Adler-32 fingerprints: 5,012 system files, 2,806 arcade ROM sets, 2,539 game and engine data files
|
||||
- **554 of 5,012 system files** matched to dump-preservation catalogs (No-Intro, Redump, TOSEC); arcade sets and engine data fall outside what those catalogs index
|
||||
- **12909 MB** total collection size
|
||||
|
||||
## Supported systems
|
||||
|
||||
@@ -136,7 +136,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 12 platforms and 449 emulators
|
||||
- **Cross-reference** mapping files across 12 platforms and 450 emulators
|
||||
- **Versioned data access** through JSON, CSV and SQLite exports with published SHA-256 checksums
|
||||
|
||||
## How it works
|
||||
@@ -174,4 +174,4 @@ The scripts and tooling are released under the [MIT License](LICENSE).
|
||||
The BIOS and firmware files are not covered by that license: they are third-party system software, preserved and provided for personal backup, archival, and interoperability with emulation software. [NOTICE](NOTICE) sets out their status and how to ask for a file to be removed.
|
||||
The reasoning, and where it is weakest, is in the [FAQ](https://abdess.github.io/retrobios/wiki/faq/#is-this-legal).
|
||||
|
||||
*Auto-generated on 2026-09-07T02:33:05Z*
|
||||
*Auto-generated on 2026-09-14T03:24:09Z*
|
||||
+1
-15
@@ -173,20 +173,6 @@
|
||||
"sha1": "2d7d999e2acb4da55c26d1517934d39e7d0a0c86",
|
||||
"total_copies": 1
|
||||
},
|
||||
"bbb.zip": {
|
||||
"clones": [
|
||||
"aaa_long_name.zip"
|
||||
],
|
||||
"sha1": "0ebda75e11e0fdce192562b5bb65a00e3e3bf240",
|
||||
"total_copies": 1
|
||||
},
|
||||
"bbc_m87.zip": {
|
||||
"clones": [
|
||||
"bbc_24bbc.zip"
|
||||
],
|
||||
"sha1": "0ebda75e11e0fdce192562b5bb65a00e3e3bf240",
|
||||
"total_copies": 1
|
||||
},
|
||||
"beebsid.zip": {
|
||||
"clones": [
|
||||
"bbc_opus3.zip"
|
||||
@@ -607,4 +593,4 @@
|
||||
"sha1": "9139c00e5986b7a86c7e8dcbce39986126ab7db4",
|
||||
"total_copies": 1
|
||||
}
|
||||
}
|
||||
}
|
||||
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.
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.
+765
-19
File diff suppressed because it is too large.
Load diff
@@ -0,0 +1,664 @@
|
||||
emulator: POM2
|
||||
type: standalone
|
||||
core_classification: other
|
||||
source: "https://github.com/habib256/pom2"
|
||||
upstream: "https://github.com/habib256/pom2"
|
||||
profiled_date: "2026-09-14"
|
||||
source_commit: "78aa14c1135ea9eaf3e68f09d624fab788aab236"
|
||||
core_version: "0.9.2"
|
||||
display_name: "Apple - Apple II (POM2)"
|
||||
cores:
|
||||
- pom2
|
||||
systems:
|
||||
- apple-ii
|
||||
mode: standalone
|
||||
|
||||
notes: |
|
||||
Apple ][, ][+, //e, //c and //c+ emulator by Arnaud Verhille, C++ with an
|
||||
ImGui frontend, plus a browser build and a headless CLI. Nine machine
|
||||
profiles (SystemProfile.cpp:32-300): Apple ][ Original, ][+, //e
|
||||
Unenhanced, //e Enhanced, //c, //c Plus, and PAL variants of the //e
|
||||
Unenhanced, //e Enhanced (the default) and //c (Le Chat Mauve).
|
||||
|
||||
Every file is looked up by a relative name through findResource
|
||||
(ResourcePaths.cpp:173-246): the per-user data directory
|
||||
(~/.local/share/POM2, ~/Library/Application Support/POM2,
|
||||
%LOCALAPPDATA%\POM2), the executable directory, its parent,
|
||||
../share/POM2, then the working directory and its two parents. The
|
||||
first hit wins. Release packages ship the whole roms/ tree, the fonts and
|
||||
the two photos (packaging/bundle.manifest).
|
||||
|
||||
Machine firmware is a probe chain per profile, first name found wins
|
||||
(SystemProfile.cpp romProbeOrder, MainWindow_Slots.cpp:1458-1481):
|
||||
][ Original apple2o.rom, apple2.rom
|
||||
][+ apple2p.rom, apple2.rom
|
||||
//e Unenhanced apple2e_unenh.rom, 342-0135-b.64.rom, apple2e.rom
|
||||
//e Enhanced apple2e.rom
|
||||
//c apple2c-32Kv0.rom, apple2c-16K.rom, 3420033a.256
|
||||
//c Plus apple2cp.rom, apple2c-plus.rom, apple2c-32Kv0.rom
|
||||
With no candidate the machine runs on a $D000-$FFFF stub and the Welcome
|
||||
panel opens (MainWindow.cpp:318-326). A first run with no //e image falls
|
||||
back to the ][+ chain (MainWindow.cpp:223-236). Memory::loadAppleIIRom
|
||||
(Memory.cpp:174-224) maps 12 KB at $D000, 16 KB at $C000, skips the 4 KB
|
||||
pad of a 20 KB ][+ dump, and slices a 32 KB dump by profile: //e images
|
||||
carry the firmware in the upper half, //c and //c+ images are two firmware
|
||||
banks with bank 0 in the lower half (SystemProfile.cpp:432).
|
||||
|
||||
Character generators follow charRomProbeOrder per profile, or the locale
|
||||
picked in the toolbar (CharRomCatalog.cpp:42-79, MainWindow_Slots.cpp:
|
||||
1489-1505). Memory::loadCharRom accepts 2 KB, 4 KB and 8 KB dumps
|
||||
(Memory.cpp:313-345); an 8 KB dump is two 4 KB banks, loaded as one bank
|
||||
or kept dual-bank with annunciator 2 selecting the live set.
|
||||
|
||||
Peripheral ROMs are read when the card is plugged (SlotCardFactory.cpp).
|
||||
The Disk II carries the 341-0027-A boot PROM and the 16-sector P6
|
||||
sequencer built in (DiskIICard.cpp:135-150). CFFA, Liron, Workstation and
|
||||
the MC68705 mouse card leave the slot empty without their dump; Grappler+,
|
||||
ThunderClock+ and TransWarp run a synthetic ROM instead. The catalogue
|
||||
behind the ROM Status panel (RomCatalog.h) lists every name in probe
|
||||
order with the size the loader enforces and, where POM2 vouches for a
|
||||
dump, its CRC32; the panel hashes each present file
|
||||
(RomStatus_ImGui.cpp:169-181, 306).
|
||||
|
||||
Help > Download missing ROMs (RomFetch.cpp:61-141) fetches 18 dumps with
|
||||
curl from raw.githubusercontent.com/Abdess/retrobios and installs a
|
||||
download only when its size, CRC32 and SHA-256 match the catalogue
|
||||
(RomFetch.cpp:398-431); a present local file is re-checked with the same
|
||||
gate (RomFetch.cpp:583-603). Unavailable in the browser build.
|
||||
|
||||
The floppy mechanical sounds are MAME's samples/floppy set, read from
|
||||
roms/floppy_samples/ as two banks of ten WAV files prefixed 525_ and 35_
|
||||
(FloppySoundDevice.cpp:80-118, MainWindow.cpp:335-348); a missing sample
|
||||
is logged and the drive stays silent.
|
||||
|
||||
Media named by the code are not firmware and are not listed here: the
|
||||
browser demo boots floppyemu/DIX.po (wasm/shell.html:89) or, when the
|
||||
shell passes no disk, floppyemu/Total Replay v6.1.hdv (main.cpp:281-285);
|
||||
the headless CLI mounts disks_5.4/dos33_master.dsk by default
|
||||
(pom2_headless.cpp:263). Disk, tape and hard-disk images are browsed
|
||||
from disks_5.4/, disks_3.5/, hdv/, floppyemu/, cassettes/ and
|
||||
prodos_folder/ next to the executable.
|
||||
|
||||
files:
|
||||
- name: "apple2o.rom"
|
||||
path: "roms/apple2o.rom"
|
||||
description: "Apple ][ Original monitor and Integer BASIC, $D000-$FFFF"
|
||||
required: false
|
||||
priority: 1
|
||||
size: 12288
|
||||
sha256: "68d9db6bb4c305d40c3fa89fa0f2d7b7f71516a9431e3138859f23bc5bddb2d1"
|
||||
sha1: "78008be557f643e956a106121bcc182c0fb9ea6d"
|
||||
validation: [size, sha256]
|
||||
source_ref: "src/SystemProfile.cpp:38, src/Memory.cpp:174-224, src/RomFetch.cpp:61-63"
|
||||
note: "First candidate of the Apple ][ Original profile; apple2.rom is probed next."
|
||||
- name: "apple2.rom"
|
||||
path: "roms/apple2.rom"
|
||||
description: "Apple ][ generic 12 KB fallback, Autostart monitor and Applesoft"
|
||||
required: false
|
||||
priority: 2
|
||||
size: 12288
|
||||
sha256: "fc3e9d41e9428534a883df5aa10eb55b73ea53d2fcbb3ee4f39bed1b07a82905"
|
||||
sha1: "33a24f5489ba9195b44be77d9afb2252594cb5c7"
|
||||
validation: [size, sha256]
|
||||
source_ref: "src/SystemProfile.cpp:38, src/SystemProfile.cpp:54, src/MainWindow_Slots.cpp:1470-1477, src/RomFetch.cpp:65-67"
|
||||
note: "Probed after the profile image for the ][ and ][+ profiles. When it resolves in place of that image the loader logs that the ROM identity may not match the machine."
|
||||
- name: "apple2p.rom"
|
||||
path: "roms/apple2p.rom"
|
||||
description: "Apple ][+ Autostart monitor and Applesoft, 4 KB pad then $C000-$FFFF"
|
||||
required: false
|
||||
priority: 1
|
||||
size_options: [12288, 20480]
|
||||
sha1: "29a53f3bb158b160433369e8e4a1d7cd5bf68ac6"
|
||||
validation: [size]
|
||||
source_ref: "src/SystemProfile.cpp:54, src/Memory.cpp:209-219, src/RomFetch.cpp:69-79"
|
||||
note: "First candidate of the ][+ profile and of the first-run fallback (MainWindow.cpp:234). The loader drops the leading 4 KB of a 20 KB dump. The fetcher builds a 12 KB image from the six 2 KB chips of the MAME apple2p set and accepts either size as present; it carries no digest for this file."
|
||||
- name: "apple2e.rom"
|
||||
path: "roms/apple2e.rom"
|
||||
description: "Apple //e Enhanced firmware, 32 KB dump with the 16 KB firmware in the upper half"
|
||||
required: true
|
||||
priority: 1
|
||||
size: 32768
|
||||
sha256: "c17bc38c75ba96c33a30c688a1efd60144811073423533fe7f8453cdd9457aab"
|
||||
sha1: "d756eba578a6c5a4807510dfee30ee585c63755e"
|
||||
validation: [size, sha256]
|
||||
source_ref: "src/SystemProfile.cpp:101, src/SystemProfile.cpp:239-251, src/Memory.cpp:189-201, src/Memory.cpp:220-222, src/MainWindow.cpp:223-226, src/RomFetch.cpp:80-83"
|
||||
note: "Sole candidate of the //e Enhanced profiles, NTSC and PAL, PAL being the default machine. Also the last fallback of the //e Unenhanced chain."
|
||||
- name: "apple2e_unenh.rom"
|
||||
path: "roms/apple2e_unenh.rom"
|
||||
description: "Apple //e Unenhanced firmware, 4 KB internal $Cx00 ROM then $D000-$FFFF"
|
||||
required: false
|
||||
priority: 1
|
||||
aliases: ["342-0135-b.64.rom"]
|
||||
size: 16384
|
||||
sha256: "1fb812584c6633fa16b77b20915986ed1178d1e6fc07a647f7ee8d4e6ab9d40b"
|
||||
sha1: "61fa9254628e5bb7236fb474006116d67684d747"
|
||||
validation: [size, sha256]
|
||||
source_ref: "src/SystemProfile.cpp:78-79, src/SystemProfile.cpp:265-277, src/RomFetch.cpp:84-87"
|
||||
note: "First candidate of the //e Unenhanced profiles; 342-0135-b.64.rom is probed second, apple2e.rom third."
|
||||
- name: "apple2c-32Kv0.rom"
|
||||
path: "roms/apple2c-32Kv0.rom"
|
||||
description: "Apple //c two-bank firmware, bank 0 in the lower 16 KB"
|
||||
required: false
|
||||
priority: 1
|
||||
size: 32768
|
||||
crc32: "323952d1"
|
||||
sha1: "fb0d644aafaff1352d0816bc8494f6c9913809d5"
|
||||
source_ref: "src/SystemProfile.cpp:142-143, src/SystemProfile.cpp:204-205, src/SystemProfile.cpp:432-438, src/Memory.cpp:189-201, src/Memory.cpp:220-222"
|
||||
note: "First candidate of the //c and //c PAL profiles, third of the //c Plus chain. Bank 0 is mapped at reset, the $C028 ROMBANK switch selects the other. Identical to 3420033a.256 with its first 256 bytes zeroed."
|
||||
- name: "apple2c-16K.rom"
|
||||
path: "roms/apple2c-16K.rom"
|
||||
description: "Apple //c ROM 255, 16 KB, MAME apple2c a2c.128"
|
||||
required: false
|
||||
priority: 2
|
||||
size: 16384
|
||||
crc32: "f0edaa1b"
|
||||
sha1: "1a9b8aca5e32bb702ddb7791daddd60a89655729"
|
||||
source_ref: "src/SystemProfile.cpp:142-143, src/Memory.cpp:207-208"
|
||||
note: "Second candidate of the //c chain, loaded at $C000."
|
||||
- name: "3420033a.256"
|
||||
path: "roms/3420033a.256"
|
||||
description: "Apple //c ROM 0, UniDisk 3.5 firmware, MAME apple2c0 342-0033-A"
|
||||
required: false
|
||||
priority: 3
|
||||
size: 32768
|
||||
crc32: "c8b979b3"
|
||||
sha1: "10767e96cc17bad0970afda3a4146564e6272ba1"
|
||||
source_ref: "src/SystemProfile.cpp:142-143"
|
||||
note: "Third candidate of the //c chain."
|
||||
- name: "apple2cp.rom"
|
||||
path: "roms/apple2cp.rom"
|
||||
description: "Apple //c Plus two-bank firmware, MAME apple2cp 341-0625-a.256"
|
||||
required: false
|
||||
priority: 1
|
||||
aliases: ["apple2c-plus.rom"]
|
||||
size: 32768
|
||||
crc32: "0b996420"
|
||||
sha1: "1a27ae26966bbafd825d08ad1a24742d3e33557c"
|
||||
source_ref: "src/SystemProfile.cpp:204-205, src/SystemProfile.cpp:432-438"
|
||||
note: "First candidate of the //c Plus profile; apple2c-plus.rom is probed second and apple2c-32Kv0.rom third."
|
||||
- name: "apple2_char.rom"
|
||||
path: "roms/apple2_char.rom"
|
||||
description: "Apple ][ and ][+ character generator, 2 KB uppercase set"
|
||||
required: false
|
||||
priority: 1
|
||||
size: 2048
|
||||
sha256: "08f5d22230481019844492dde0a29a018cb193712a9e4a43770a3870608f28de"
|
||||
sha1: "f9d312f128c9557d9d6ac03bfad6c3ddf83e5659"
|
||||
validation: [size, sha256]
|
||||
source_ref: "src/SystemProfile.cpp:39, src/SystemProfile.cpp:55, src/CharRomCatalog.cpp:42-43, src/RomFetch.cpp:90-93, src/Memory.cpp:313-345"
|
||||
note: "Sole candidate of the ][ and ][+ profiles and the last fallback of every //e-class chain."
|
||||
- name: "apple2e_char.rom"
|
||||
path: "roms/apple2e_char.rom"
|
||||
description: "Apple //e Enhanced character generator 342-0265-A, 4 KB with MouseText"
|
||||
required: false
|
||||
priority: 1
|
||||
aliases: ["apple2e_char_us.rom"]
|
||||
size: 4096
|
||||
sha256: "52c3b87900ac939f6525402cab1ccfd8f8259290fc6df54da48fb4c98ae3ed0f"
|
||||
sha1: "b2b5d87f52693817fc747df087a4aa1ddcdb1f10"
|
||||
validation: [size, sha256]
|
||||
source_ref: "src/SystemProfile.cpp:105, src/SystemProfile.cpp:144, src/SystemProfile.cpp:206, src/CharRomCatalog.cpp:48-49, src/RomFetch.cpp:94-97, src/Memory.cpp:313-345"
|
||||
note: "First candidate of the //e Enhanced, //c and //c Plus profiles; the same dump answers to apple2e_char_us.rom in the locale picker."
|
||||
- name: "apple2e_char_us_unenh.rom"
|
||||
path: "roms/apple2e_char_us_unenh.rom"
|
||||
description: "Apple //e Unenhanced character generator 342-0133-A, 4 KB"
|
||||
required: false
|
||||
priority: 1
|
||||
aliases: ["apple2e_char_2k.rom", "341-0265-a.chr.rom"]
|
||||
size: 4096
|
||||
sha256: "ed5bdd4afa509134e85f1d020685af7ff50e279226eb869a17825b471cc1634c"
|
||||
sha1: "58ad0008df72896a18601e090ee0d58155ffa5be"
|
||||
validation: [size, sha256]
|
||||
source_ref: "src/SystemProfile.cpp:83-84, src/CharRomCatalog.cpp:50-51, src/RomFetch.cpp:98-101, src/Memory.cpp:313-345"
|
||||
note: "The //e Unenhanced profile probes apple2e_char_2k.rom then 341-0265-a.chr.rom then apple2_char.rom; the same dump ships under both names."
|
||||
- name: "apple2e_char_fr.rom"
|
||||
path: "roms/apple2e_char_fr.rom"
|
||||
description: "Apple //e French character generator, 4 KB"
|
||||
required: false
|
||||
aliases: ["apple2e_char_frca_unenh.rom"]
|
||||
size: 4096
|
||||
crc32: "ab0be706"
|
||||
sha1: "42afb02aab4146f781ac52803a2733adc4da834e"
|
||||
validation: [size]
|
||||
source_ref: "src/CharRomCatalog.cpp:52-53, src/CharRomCatalog.cpp:56-57, src/CharRomCatalog.cpp:151-165, src/Memory.cpp:313-345"
|
||||
note: "Locale picker entry. The same dump is also listed as the FR Canadian unenhanced set 341-0168-A."
|
||||
- name: "apple2e_char_frca.rom"
|
||||
path: "roms/apple2e_char_frca.rom"
|
||||
description: "Apple //e French Canadian Enhanced character generator, 4 KB"
|
||||
required: false
|
||||
size: 4096
|
||||
crc32: "2c8fc403"
|
||||
sha1: "4043e0808af8be096660827445e41149d16c5c85"
|
||||
validation: [size]
|
||||
source_ref: "src/CharRomCatalog.cpp:54-55, src/CharRomCatalog.cpp:151-165, src/Memory.cpp:313-345"
|
||||
note: "Locale picker entry; equals the low bank of 342-0274-a.e9."
|
||||
- name: "apple2e_char_uk.rom"
|
||||
path: "roms/apple2e_char_uk.rom"
|
||||
description: "Apple //e UK Enhanced character generator 342-0273-A, 4 KB"
|
||||
required: false
|
||||
size: 4096
|
||||
crc32: "dda11653"
|
||||
sha1: "d19c2e2cc12b27d77edc403d5d0701186a4ed988"
|
||||
validation: [size]
|
||||
source_ref: "src/CharRomCatalog.cpp:58-59, src/CharRomCatalog.cpp:151-165, src/Memory.cpp:313-345"
|
||||
note: "Locale picker entry."
|
||||
- name: "apple2e_char_uk_unenh.rom"
|
||||
path: "roms/apple2e_char_uk_unenh.rom"
|
||||
description: "Apple //e UK Unenhanced character generator 341-0160-A, 4 KB"
|
||||
required: false
|
||||
size: 4096
|
||||
crc32: "7a9a91ef"
|
||||
sha1: "6ca9767e0f47f642d1caab6ed41b8f58c58bb9eb"
|
||||
validation: [size]
|
||||
source_ref: "src/CharRomCatalog.cpp:60-61, src/CharRomCatalog.cpp:151-165, src/Memory.cpp:313-345"
|
||||
note: "Locale picker entry."
|
||||
- name: "apple2e_char_de.rom"
|
||||
path: "roms/apple2e_char_de.rom"
|
||||
description: "Apple //e German character generator 341-0161-A, 4 KB"
|
||||
required: false
|
||||
size: 4096
|
||||
crc32: "0d72f153"
|
||||
sha1: "a7fd75ae8611572b0b4d99ad54562014b879dbbf"
|
||||
validation: [size]
|
||||
source_ref: "src/CharRomCatalog.cpp:62-63, src/CharRomCatalog.cpp:151-165, src/Memory.cpp:313-345"
|
||||
note: "Locale picker entry."
|
||||
- name: "apple2e_char_de_improved.rom"
|
||||
path: "roms/apple2e_char_de_improved.rom"
|
||||
description: "Apple //e German Improved character generator, 4 KB"
|
||||
required: false
|
||||
size: 4096
|
||||
crc32: "d345d332"
|
||||
sha1: "12ce44f02bd28c350e2b0723d94ab8d9066f8798"
|
||||
validation: [size]
|
||||
source_ref: "src/CharRomCatalog.cpp:64-65, src/CharRomCatalog.cpp:151-165, src/Memory.cpp:313-345"
|
||||
note: "Locale picker entry."
|
||||
- name: "342-0274-a.e9"
|
||||
path: "roms/342-0274-a.e9"
|
||||
description: "Apple //e international video ROM 342-0274-A, 8 KB, French Canadian bank then US bank, MAME apple2eefr"
|
||||
required: false
|
||||
size: 8192
|
||||
crc32: "8f342081"
|
||||
sha1: "c81c1bbf237e70f8c3e5eef3c8fd5bd9b9f54d1e"
|
||||
validation: [size]
|
||||
source_ref: "src/CharRomCatalog.cpp:73-76, src/CharRomCatalog.cpp:144-149, src/Memory.cpp:313-345"
|
||||
note: "Locale picker entries select bank 0 or bank 1; loaded whole, both banks stay live and annunciator 2 picks the set."
|
||||
- name: "apple2e_char_ft_blockascii.rom"
|
||||
path: "roms/apple2e_char_ft_blockascii.rom"
|
||||
description: "French Touch Block ASCII dual-bank character generator, 8 KB"
|
||||
required: false
|
||||
size: 8192
|
||||
crc32: "1eae3944"
|
||||
sha1: "f79815457437e50404f4f537d8aabe34bff3a220"
|
||||
validation: [size]
|
||||
source_ref: "src/CharRomCatalog.cpp:77-78, src/Memory.cpp:313-345"
|
||||
note: "Locale picker entry loaded dual-bank: annunciator 2 flips between the text set and the block glyphs."
|
||||
- name: "Videx Lower Case Chip ROM.bin"
|
||||
path: "roms/Videx Lower Case Chip ROM.bin"
|
||||
description: "Videx LOWER CASE CHIP character generator for the ][ and ][+, 2 KB"
|
||||
required: false
|
||||
size: 2048
|
||||
crc32: "00f68076"
|
||||
sha1: "447874fe0850c8add3fd5b13fa98f6648fe6f999"
|
||||
validation: [size, crc32]
|
||||
source_ref: "src/CharRomCatalog.cpp:44-45, src/RomCatalog.h:143-148, src/RomStatus_ImGui.cpp:306"
|
||||
note: "Locale picker entry for the ][ and ][+ profiles; without it the picker keeps the stock uppercase set."
|
||||
- name: "disk2.rom"
|
||||
path: "roms/disk2.rom"
|
||||
description: "Disk II 16-sector boot PROM 341-0027-A"
|
||||
required: false
|
||||
has_builtin: true
|
||||
size: 256
|
||||
sha256: "de1e3e035878bab43d0af8fe38f5839c527e9548647036598ee6fe7ec74d2a7d"
|
||||
sha1: "d4181c9f046aafc3fb326b381baac809d9e38d16"
|
||||
validation: [size, sha256]
|
||||
source_ref: "src/SlotCardFactory.cpp:93-106, src/DiskIICard.cpp:135-140, src/DiskIICard.cpp:150-172, src/RomFetch.cpp:104-107"
|
||||
note: "The card carries the same PROM built in; the file replaces it when present."
|
||||
- name: "diskii_p6.rom"
|
||||
path: "roms/diskii_p6.rom"
|
||||
description: "Disk II 16-sector P6 logic state sequencer PROM 341-0028-A"
|
||||
required: false
|
||||
has_builtin: true
|
||||
size: 256
|
||||
sha256: "e5e30615040567c1e7a2d21599681f8dac820edbdcda177b816a64d74b3a12f2"
|
||||
sha1: "bc39fbd5b9a8d2287ac5d0a42e639fc4d3c2f9d4"
|
||||
validation: [size, sha256]
|
||||
source_ref: "src/SlotCardFactory.cpp:93-106, src/DiskIICard.cpp:141-148, src/DiskIICard.cpp:175-197, src/DiskIICard.cpp:245-262, src/RomFetch.cpp:108-111"
|
||||
note: "Loading the file switches the bit-level LSS path on for every image; without it the legacy 32-cycle nibble gate serves non-WOZ images and the built-in PROM serves WOZ images."
|
||||
- name: "disk2_13.rom"
|
||||
path: "roms/disk2_13.rom"
|
||||
description: "Disk II 13-sector boot PROM 341-0009"
|
||||
required: false
|
||||
size: 256
|
||||
sha256: "2d2599521fc5763d4e8c308c2ee7c5c4d5c93785b8fb9a4f7d0381dfd5eb60b6"
|
||||
sha1: "afd060e6f35faf3bb0146fa889fc787adf56330a"
|
||||
validation: [size, sha256]
|
||||
source_ref: "src/SlotCardFactory.cpp:93-106, src/DiskIICard.cpp:203-220, src/RomCatalog.h:79-81, src/RomFetch.cpp:112-115"
|
||||
note: "13-sector disks mount but cannot boot without it."
|
||||
- name: "diskii_p6_13.rom"
|
||||
path: "roms/diskii_p6_13.rom"
|
||||
description: "Disk II 13-sector P6 logic state sequencer PROM 341-0010"
|
||||
required: false
|
||||
size: 256
|
||||
sha256: "383c55f5333cbfde39dd41528186631e5aca2eddfec30716344f03b6a4d44655"
|
||||
sha1: "e3d6d1c30653572b49ecc2dc54ce073978411a04"
|
||||
validation: [size, sha256]
|
||||
source_ref: "src/SlotCardFactory.cpp:93-106, src/DiskIICard.cpp:222-239, src/RomCatalog.h:82-84, src/RomFetch.cpp:116-119"
|
||||
note: "Paired with disk2_13.rom; the card never switches to the 13-sector pair without both."
|
||||
- name: "cffa20eec02.bin"
|
||||
path: "roms/cffa20eec02.bin"
|
||||
description: "CFFA 2.0 firmware, 65C02 build"
|
||||
required: false
|
||||
size: 4096
|
||||
crc32: "fb3726f8"
|
||||
sha1: "080ff88f19de22328e162954ee2b51ee65f9d5cd"
|
||||
validation: [size, crc32]
|
||||
source_ref: "src/SlotCardFactory.cpp:115-139, src/CffaCard.cpp:26-40, src/RomCatalog.h:103-106"
|
||||
note: "Preferred when the CPU is a 65C02, the 6502 build is the fallback; the slot stays empty when neither is found."
|
||||
- name: "cffa20ee02.bin"
|
||||
path: "roms/cffa20ee02.bin"
|
||||
description: "CFFA 2.0 firmware, 6502 build"
|
||||
required: false
|
||||
size: 4096
|
||||
crc32: "3ecafce5"
|
||||
sha256: "3d7f6918f9af3828f5a6299299a817df0d354ee62e547bc0238755de66162a88"
|
||||
sha1: "d600692ed9626668233a22a48236af639410cb7b"
|
||||
validation: [size, crc32, sha256]
|
||||
source_ref: "src/SlotCardFactory.cpp:115-139, src/CffaCard.cpp:26-40, src/RomCatalog.h:107-110, src/RomFetch.cpp:122-126"
|
||||
note: "Preferred on an NMOS 6502, fallback for a 65C02."
|
||||
- name: "mouse_341-0270-c.bin"
|
||||
path: "roms/mouse_341-0270-c.bin"
|
||||
description: "AppleMouse II card slot EPROM 341-0270-C"
|
||||
required: false
|
||||
size: 2048
|
||||
sha256: "7f8e50c0e8a409991264201f9300f109b872b68e09c43f3e6c26af35fd8b89af"
|
||||
sha1: "3a9d881a8a8d30f55b9719aceebbcf717f829d6f"
|
||||
validation: [size, sha256]
|
||||
source_ref: "src/SlotCardFactory.cpp:51-83, src/SlotCardFactory.cpp:232-247, src/MouseCard.cpp:115-149, src/MouseCardAppleWin.cpp:87-100, src/RomFetch.cpp:127-130"
|
||||
note: "Needed by both mouse cards: the MC68705 card also needs the MCU ROM, the AppleWin HLE card needs this one only."
|
||||
- name: "mouse_341-0269.bin"
|
||||
path: "roms/mouse_341-0269.bin"
|
||||
description: "AppleMouse II card MC68705P3 MCU mask ROM 341-0269"
|
||||
required: false
|
||||
size: 2048
|
||||
sha256: "66480812edad5f6bd70349949cf8bd8fbafee2dc8bf396541d4e78bac2629ec0"
|
||||
sha1: "3a2baa6648efe4456d3ec3721216e57c64f7acfc"
|
||||
validation: [size, sha256]
|
||||
source_ref: "src/SlotCardFactory.cpp:51-83, src/MouseCard.cpp:146-149, src/M68705P3.cpp:85-104, src/RomFetch.cpp:131-134"
|
||||
note: "The MC68705 mouse card leaves its slot empty without it."
|
||||
- name: "grappler_plus.bin"
|
||||
path: "roms/grappler_plus.bin"
|
||||
description: "Orange Micro Grappler+ parallel printer EPROM 3.2"
|
||||
required: false
|
||||
aliases: ["grappler+.bin", "grappler.bin"]
|
||||
size: 4096
|
||||
sha256: "9be4dea7722ad8928aee64c2ae708f365a6d66c50a63bff8a3c1a4e7596d44c6"
|
||||
sha1: "829072cc19a58b24d36c2af972abaad6f9ba35d9"
|
||||
validation: [size, sha256]
|
||||
source_ref: "src/SlotCardFactory.cpp:147-166, src/GrapplerCard.cpp:29-52, src/RomCatalog.h:113-118, src/RomFetch.cpp:135-138"
|
||||
note: "Without it the card runs a stub ROM: PR#n prints, the graphics dump commands are absent."
|
||||
- name: "ae_transwarp_1.4.bin"
|
||||
path: "roms/ae_transwarp_1.4.bin"
|
||||
description: "Applied Engineering TransWarp accelerator ROM v1.4, MAME warprom"
|
||||
required: false
|
||||
aliases: ["ae transwarp rom v1.4.bin"]
|
||||
size: 4096
|
||||
crc32: "afe37f55"
|
||||
sha1: "7b75534e7895e04859a0b1337801c6eeb0cef52a"
|
||||
validation: [size, crc32]
|
||||
source_ref: "src/TranswarpCard.h:166, src/TranswarpCard.cpp:200-218, src/RomCatalog.h:119-125"
|
||||
note: "Not shipped by POM2. The card accelerates without it and only shadows $F000-$FFFF with the speed-corrected monitor when the dump is present."
|
||||
- name: "thunderclock_u9_v1.3.bin"
|
||||
path: "roms/thunderclock_u9_v1.3.bin"
|
||||
description: "Thunderware ThunderClock+ slot ROM rev 1.3, U9"
|
||||
required: false
|
||||
aliases: ["thunderclock_u9.bin", "thunderclock.rom", "Thunderware_REV_1.3_ROM_U9.bin"]
|
||||
size_options: [256, 2048]
|
||||
sha1: "60f434f5325899d7ea257a6e56e6f53eae65146a"
|
||||
validation: [size]
|
||||
source_ref: "src/ClockCard.cpp:469-524, src/RomCatalog.h:150-160"
|
||||
note: "A 2 KB dump supplies the $C800 expansion ROM as well. The first four even bytes must read $08, $28, $58, $70, the ProDOS clock signature, or the synthetic ROM stays in place."
|
||||
- name: "liron.rom"
|
||||
path: "roms/liron.rom"
|
||||
description: "Apple Liron SmartPort controller firmware, 4 KB"
|
||||
required: false
|
||||
size: 4096
|
||||
sha1: "fa94ecc2aa23f336f7da9e18bc8f4a6cfbb4ea60"
|
||||
validation: [size]
|
||||
source_ref: "src/SlotCardFactory.cpp:194-220, src/LironCard.cpp:61-85, src/SmartPortCard.cpp:80-97, src/RomCatalog.h:87-90"
|
||||
note: "The Liron card refuses to plug without it. The SmartPort 3.5 card loads it on machines with physical slots and otherwise presents a synthetic identity."
|
||||
- name: "341-0358-A.bin"
|
||||
path: "roms/341-0358-A.bin"
|
||||
description: "Apple II Workstation Card firmware 341-0358-A, 64 KB"
|
||||
required: false
|
||||
aliases: ["341-0358-a.bin"]
|
||||
size: 65536
|
||||
crc32: "63819dcb"
|
||||
sha1: "59c8e8c88bac5c31ada1306b412edfcf5912a720"
|
||||
validation: [size, crc32]
|
||||
source_ref: "src/SlotCardFactory.cpp:169-192, src/WorkstationCard.cpp:60-74, src/RomCatalog.h:133-142"
|
||||
note: "The Workstation card leaves its slot empty without it; the card runs its own 65C02 on the upper 32 KB."
|
||||
- name: "341-0438-a.bin"
|
||||
path: "roms/341-0438-a.bin"
|
||||
description: "Apple II 3.5 Disk Controller SuperDrive firmware 341-0438-A, MAME a2superdrive"
|
||||
required: false
|
||||
size: 32768
|
||||
crc32: "c73ff25b"
|
||||
sha1: "440c3f84176c7b9f542da0b6ddf4fb13ec326c46"
|
||||
validation: [size, crc32, sha256]
|
||||
source_ref: "src/RomCatalog.h:91-96, src/RomStatus_ImGui.cpp:169-181, src/RomFetch.cpp:139-141"
|
||||
note: "No card reads it; the ROM Status panel and the fetch gate check it."
|
||||
- name: "342-0326-a.f12"
|
||||
path: "roms/342-0326-a.f12"
|
||||
description: "Apple //e French keyboard decode ROM 342-0326-A, MAME apple2eefr"
|
||||
required: false
|
||||
size: 2048
|
||||
crc32: "f04970a9"
|
||||
sha1: "806a602195c18ffec637c03b6bb3405188b0dc1e"
|
||||
validation: [size, crc32]
|
||||
source_ref: "src/RomCatalog.h:97-102, src/RomStatus_ImGui.cpp:169-181, src/RomStatus_ImGui.cpp:306"
|
||||
note: "Host keys are mapped directly, no keyboard decode ROM is emulated; the ROM Status panel checks the file only."
|
||||
- name: "525_seek_2ms.wav"
|
||||
path: "roms/floppy_samples/525_seek_2ms.wav"
|
||||
description: "MAME floppy sample, 5.25 inch drive, 2 ms head seek"
|
||||
category: game_data
|
||||
required: false
|
||||
size: 5336
|
||||
sha1: "2d046a880476218685ed738fe8c8381962afd74a"
|
||||
source_ref: "src/FloppySoundDevice.cpp:80-118, src/MainWindow.cpp:335-348"
|
||||
note: "One of ten samples per drive bank; a missing sample is logged and that sound stays silent."
|
||||
- name: "525_seek_6ms.wav"
|
||||
path: "roms/floppy_samples/525_seek_6ms.wav"
|
||||
description: "MAME floppy sample, 5.25 inch drive, 6 ms head seek"
|
||||
category: game_data
|
||||
required: false
|
||||
size: 14860
|
||||
sha1: "6f698055fa6e9da6c5ae3fd6fb05de76b92a45a9"
|
||||
source_ref: "src/FloppySoundDevice.cpp:80-118, src/MainWindow.cpp:335-348"
|
||||
- name: "525_seek_12ms.wav"
|
||||
path: "roms/floppy_samples/525_seek_12ms.wav"
|
||||
description: "MAME floppy sample, 5.25 inch drive, 12 ms head seek"
|
||||
category: game_data
|
||||
required: false
|
||||
size: 22764
|
||||
sha1: "fbbbb5e8724c076d194e66a4443d299d54a8efd6"
|
||||
source_ref: "src/FloppySoundDevice.cpp:80-118, src/MainWindow.cpp:335-348"
|
||||
- name: "525_seek_20ms.wav"
|
||||
path: "roms/floppy_samples/525_seek_20ms.wav"
|
||||
description: "MAME floppy sample, 5.25 inch drive, 20 ms head seek"
|
||||
category: game_data
|
||||
required: false
|
||||
size: 30060
|
||||
sha1: "b6cd14944454c743861196edb4fcab1cc9b586d4"
|
||||
source_ref: "src/FloppySoundDevice.cpp:80-118, src/MainWindow.cpp:335-348"
|
||||
- name: "525_spin_empty.wav"
|
||||
path: "roms/floppy_samples/525_spin_empty.wav"
|
||||
description: "MAME floppy sample, 5.25 inch drive, motor running, no disk"
|
||||
category: game_data
|
||||
required: false
|
||||
size: 8864
|
||||
sha1: "4b13701d9a7f8ab0f0827f17ba80b5c32b4e0fa7"
|
||||
source_ref: "src/FloppySoundDevice.cpp:80-118, src/MainWindow.cpp:335-348"
|
||||
- name: "525_spin_loaded.wav"
|
||||
path: "roms/floppy_samples/525_spin_loaded.wav"
|
||||
description: "MAME floppy sample, 5.25 inch drive, motor running, disk loaded"
|
||||
category: game_data
|
||||
required: false
|
||||
size: 17708
|
||||
sha1: "875f90538a3ff5db863ad4c384e1808841ddea9b"
|
||||
source_ref: "src/FloppySoundDevice.cpp:80-118, src/MainWindow.cpp:335-348"
|
||||
- name: "525_spin_start_empty.wav"
|
||||
path: "roms/floppy_samples/525_spin_start_empty.wav"
|
||||
description: "MAME floppy sample, 5.25 inch drive, motor start, no disk"
|
||||
category: game_data
|
||||
required: false
|
||||
size: 11180
|
||||
sha1: "b87d89c4b46c36dd78dec3dc5170ca61501e7cd9"
|
||||
source_ref: "src/FloppySoundDevice.cpp:80-118, src/MainWindow.cpp:335-348"
|
||||
- name: "525_spin_start_loaded.wav"
|
||||
path: "roms/floppy_samples/525_spin_start_loaded.wav"
|
||||
description: "MAME floppy sample, 5.25 inch drive, motor start, disk loaded"
|
||||
category: game_data
|
||||
required: false
|
||||
size: 17708
|
||||
sha1: "510476098848e2b5cdfe9f1608f8dfa3207fe9b4"
|
||||
source_ref: "src/FloppySoundDevice.cpp:80-118, src/MainWindow.cpp:335-348"
|
||||
- name: "525_spin_end.wav"
|
||||
path: "roms/floppy_samples/525_spin_end.wav"
|
||||
description: "MAME floppy sample, 5.25 inch drive, motor stop"
|
||||
category: game_data
|
||||
required: false
|
||||
size: 8864
|
||||
sha1: "f8d9b94c4d92d35d9ffb1117b693fc74a93f613f"
|
||||
source_ref: "src/FloppySoundDevice.cpp:80-118, src/MainWindow.cpp:335-348"
|
||||
- name: "525_step_1_1.wav"
|
||||
path: "roms/floppy_samples/525_step_1_1.wav"
|
||||
description: "MAME floppy sample, 5.25 inch drive, single track step"
|
||||
category: game_data
|
||||
required: false
|
||||
size: 6628
|
||||
sha1: "669ee98fb9fac4371c72ed0b60be1bc8470bc7f8"
|
||||
source_ref: "src/FloppySoundDevice.cpp:80-118, src/MainWindow.cpp:335-348"
|
||||
- name: "35_seek_2ms.wav"
|
||||
path: "roms/floppy_samples/35_seek_2ms.wav"
|
||||
description: "MAME floppy sample, 3.5 inch drive, 2 ms head seek"
|
||||
category: game_data
|
||||
required: false
|
||||
size: 7450
|
||||
sha1: "55caafbd19486b8d517e4b33a6fa65250df55e25"
|
||||
source_ref: "src/FloppySoundDevice.cpp:80-118, src/MainWindow.cpp:335-348"
|
||||
note: "One of ten samples per drive bank; a missing sample is logged and that sound stays silent."
|
||||
- name: "35_seek_6ms.wav"
|
||||
path: "roms/floppy_samples/35_seek_6ms.wav"
|
||||
description: "MAME floppy sample, 3.5 inch drive, 6 ms head seek"
|
||||
category: game_data
|
||||
required: false
|
||||
size: 22230
|
||||
sha1: "87e5dec269e67497681c15849777ebfc301131c1"
|
||||
source_ref: "src/FloppySoundDevice.cpp:80-118, src/MainWindow.cpp:335-348"
|
||||
- name: "35_seek_12ms.wav"
|
||||
path: "roms/floppy_samples/35_seek_12ms.wav"
|
||||
description: "MAME floppy sample, 3.5 inch drive, 12 ms head seek"
|
||||
category: game_data
|
||||
required: false
|
||||
size: 26540
|
||||
sha1: "c6b34fc61496943134ac45cc836a24e743caf794"
|
||||
source_ref: "src/FloppySoundDevice.cpp:80-118, src/MainWindow.cpp:335-348"
|
||||
- name: "35_seek_20ms.wav"
|
||||
path: "roms/floppy_samples/35_seek_20ms.wav"
|
||||
description: "MAME floppy sample, 3.5 inch drive, 20 ms head seek"
|
||||
category: game_data
|
||||
required: false
|
||||
size: 44144
|
||||
sha1: "b2fe4c3a4185146a7d11483d92d4412dd79dbc78"
|
||||
source_ref: "src/FloppySoundDevice.cpp:80-118, src/MainWindow.cpp:335-348"
|
||||
- name: "35_spin_empty.wav"
|
||||
path: "roms/floppy_samples/35_spin_empty.wav"
|
||||
description: "MAME floppy sample, 3.5 inch drive, motor running, no disk"
|
||||
category: game_data
|
||||
required: false
|
||||
size: 17708
|
||||
sha1: "db04fc097bdd0411cff232f57525ded491b48c6c"
|
||||
source_ref: "src/FloppySoundDevice.cpp:80-118, src/MainWindow.cpp:335-348"
|
||||
- name: "35_spin_loaded.wav"
|
||||
path: "roms/floppy_samples/35_spin_loaded.wav"
|
||||
description: "MAME floppy sample, 3.5 inch drive, motor running, disk loaded"
|
||||
category: game_data
|
||||
required: false
|
||||
size: 17708
|
||||
sha1: "96ce04a5b02af0da6d311f06fc4906a3cf71c78f"
|
||||
source_ref: "src/FloppySoundDevice.cpp:80-118, src/MainWindow.cpp:335-348"
|
||||
- name: "35_spin_start_empty.wav"
|
||||
path: "roms/floppy_samples/35_spin_start_empty.wav"
|
||||
description: "MAME floppy sample, 3.5 inch drive, motor start, no disk"
|
||||
category: game_data
|
||||
required: false
|
||||
size: 17708
|
||||
sha1: "af770fd9261a8efee23d66cd39b27be7b2ab7853"
|
||||
source_ref: "src/FloppySoundDevice.cpp:80-118, src/MainWindow.cpp:335-348"
|
||||
- name: "35_spin_start_loaded.wav"
|
||||
path: "roms/floppy_samples/35_spin_start_loaded.wav"
|
||||
description: "MAME floppy sample, 3.5 inch drive, motor start, disk loaded"
|
||||
category: game_data
|
||||
required: false
|
||||
size: 35308
|
||||
sha1: "c82b1714378bf2507ed86dea1e9fe743c380abab"
|
||||
source_ref: "src/FloppySoundDevice.cpp:80-118, src/MainWindow.cpp:335-348"
|
||||
- name: "35_spin_end.wav"
|
||||
path: "roms/floppy_samples/35_spin_end.wav"
|
||||
description: "MAME floppy sample, 3.5 inch drive, motor stop"
|
||||
category: game_data
|
||||
required: false
|
||||
size: 17684
|
||||
sha1: "a8901b692de15eb7a9052f61283f0e7a2b63d67d"
|
||||
source_ref: "src/FloppySoundDevice.cpp:80-118, src/MainWindow.cpp:335-348"
|
||||
- name: "35_step_1_1.wav"
|
||||
path: "roms/floppy_samples/35_step_1_1.wav"
|
||||
description: "MAME floppy sample, 3.5 inch drive, single track step"
|
||||
category: game_data
|
||||
required: false
|
||||
size: 6878
|
||||
sha1: "40d756d0cb5f7998ca26ac1de142a96a83fa2b97"
|
||||
source_ref: "src/FloppySoundDevice.cpp:80-118, src/MainWindow.cpp:335-348"
|
||||
- name: "DejaVuSans.ttf"
|
||||
path: "fonts/DejaVuSans.ttf"
|
||||
description: "DejaVu Sans, the frontend text font"
|
||||
category: game_data
|
||||
required: false
|
||||
bundled: true
|
||||
unsourceable: "host program component shipped inside every POM2 package, not emulation data"
|
||||
size: 759720
|
||||
sha1: "3061cf7af25793a655a1ff5a509385f3620f3eb3"
|
||||
source_ref: "src/main.cpp:522-535"
|
||||
note: "Falls back to the system DejaVu, Arial Unicode or Segoe UI, then to the ImGui bitmap font."
|
||||
- name: "fa-solid-900.ttf"
|
||||
path: "fonts/fa-solid-900.ttf"
|
||||
description: "Font Awesome 6 Free Solid, the frontend icon font"
|
||||
category: game_data
|
||||
required: false
|
||||
bundled: true
|
||||
unsourceable: "host program component shipped inside every POM2 package, not emulation data"
|
||||
size: 426112
|
||||
sha1: "0c8c9706abc0116f08b66d11a69da6aa9ef7e6bf"
|
||||
source_ref: "src/main.cpp:582-600"
|
||||
note: "Without it every icon renders as an empty box."
|
||||
- name: "Apple_II_plus.jpg"
|
||||
path: "pic/Apple_II_plus.jpg"
|
||||
description: "Apple ][+ photograph shown in Help > About"
|
||||
category: game_data
|
||||
required: false
|
||||
bundled: true
|
||||
unsourceable: "host program component shipped inside every POM2 package, not emulation data"
|
||||
size: 102046
|
||||
sha1: "69358dd499148deae4112b49cedb7bec220584e2"
|
||||
source_ref: "src/MainWindow_MiscPanels.cpp:621"
|
||||
- name: "Keyboard_AppleIIe.jpeg"
|
||||
path: "pic/Keyboard_AppleIIe.jpeg"
|
||||
description: "Apple //e keyboard photograph the clickable keyboard window is built on"
|
||||
category: game_data
|
||||
required: false
|
||||
bundled: true
|
||||
unsourceable: "host program component shipped inside every POM2 package, not emulation data"
|
||||
size: 794259
|
||||
sha1: "a178f37661078739637ff7642cd6450c762993aa"
|
||||
source_ref: "src/MainWindow_MiscPanels.cpp:480"
|
||||
note: "The window hotspots are fractions of this image; without it the window has nothing to click."
|
||||
+18
-16
@@ -5,7 +5,7 @@
|
||||
"platform": "batocera",
|
||||
"display_name": "Batocera",
|
||||
"version": "1.0",
|
||||
"generated": "2026-09-05T09:26:20Z",
|
||||
"generated": "2026-09-13T22:10:18Z",
|
||||
"base_destination": "bios",
|
||||
"detect": [
|
||||
{
|
||||
@@ -238,7 +238,7 @@
|
||||
}
|
||||
],
|
||||
"total_files": 1832,
|
||||
"total_size": 4314998020,
|
||||
"total_size": 4522217423,
|
||||
"total_omitted": 9,
|
||||
"omitted_files": [
|
||||
{
|
||||
@@ -2271,10 +2271,10 @@
|
||||
},
|
||||
{
|
||||
"dest": "firmware.bin",
|
||||
"sha1": "5b2acbd499b39fb1af1b36ef7de5eb047d83401c",
|
||||
"sha256": "7ea4f06ca110f8b7ff7c946f6e4e228d94977dadd4bb51570d14c68488edb32a",
|
||||
"sha1": "cfe072921ee3fb93f688743f8beef89043c3e9ad",
|
||||
"sha256": "57a1d6b43c1399d219ea18644240c4d4c6787c829f0a67ded216472867857cd0",
|
||||
"size": 262144,
|
||||
"repo_path": "bios/Arcade/Arcade/firmware.bin",
|
||||
"repo_path": "bios/Nintendo/Nintendo DS/firmware.bin",
|
||||
"cores": null
|
||||
},
|
||||
{
|
||||
@@ -2311,10 +2311,10 @@
|
||||
},
|
||||
{
|
||||
"dest": "dsi_firmware.bin",
|
||||
"sha1": "93c0598b08192a1f630e5edb2cd9f60d1e3ea7b3",
|
||||
"sha256": "1f89935da2888cd3e401af2774e06a6b587ca059e85f922826494f317d31c6ae",
|
||||
"sha1": "d2a5af338f09c5cbdd5d7628db5b9c075c69b616",
|
||||
"sha256": "1d7c771de535e6e07182fc9820ac32e76c6f0b5bcefd256a861fdfab144761ec",
|
||||
"size": 131072,
|
||||
"repo_path": "bios/Arcade/Arcade/dsi_firmware.bin",
|
||||
"repo_path": "bios/Nintendo/Nintendo DS/dsi_firmware.bin",
|
||||
"cores": null
|
||||
},
|
||||
{
|
||||
@@ -8041,19 +8041,21 @@
|
||||
},
|
||||
{
|
||||
"dest": "fbneo/samples/donpachi.zip",
|
||||
"sha1": "c0c0b5db93a61276a6fe6842049cb53e564b8413",
|
||||
"sha256": "a686ebf893d511b5b7667176cd6844593e914595a8bb9ab656b2c66969013b5c",
|
||||
"size": 5641310,
|
||||
"repo_path": "bios/Other/fbneo/donpachi.zip",
|
||||
"sha1": "d380fb29287eb7fc9ff901a7653ad40785f7deb1",
|
||||
"sha256": "78a237f1e2774eb396e2f14999f1270597e0767a392729e7a4539455888b6fe0",
|
||||
"size": 208549253,
|
||||
"repo_path": "bios/Other/fbneo/fbneo/samples/donpachi.zip",
|
||||
"cores": [
|
||||
"fbneo"
|
||||
]
|
||||
],
|
||||
"storage": "release",
|
||||
"release_asset": "donpachi.zip"
|
||||
},
|
||||
{
|
||||
"dest": "fbneo/samples/sfz3mix.zip",
|
||||
"sha1": "227815ce9e55db427d68e075182caffe6ad60ad1",
|
||||
"sha256": "6a720035646b3488a047ab163a6975b7be82fe75c5eec88155c8503c93a631fe",
|
||||
"size": 96705917,
|
||||
"sha1": "e39ee9abb19076ef095f67469ca95ff5e7f600dc",
|
||||
"sha256": "2c2e67ab762102f50df641280721164ddff0316e71081d5fa62f2a67365dea66",
|
||||
"size": 101017377,
|
||||
"repo_path": "bios/Other/fbneo/fbneo/samples/sfz3mix.zip",
|
||||
"cores": [
|
||||
"fbneo"
|
||||
|
||||
+18
-16
@@ -5,7 +5,7 @@
|
||||
"platform": "bizhawk",
|
||||
"display_name": "BizHawk",
|
||||
"version": "1.0",
|
||||
"generated": "2026-09-05T09:26:20Z",
|
||||
"generated": "2026-09-13T22:10:18Z",
|
||||
"base_destination": "Firmware",
|
||||
"detect": [
|
||||
{
|
||||
@@ -21,7 +21,7 @@
|
||||
],
|
||||
"standalone_copies": [],
|
||||
"total_files": 539,
|
||||
"total_size": 2328691103,
|
||||
"total_size": 2535910506,
|
||||
"total_omitted": 1,
|
||||
"omitted_files": [
|
||||
{
|
||||
@@ -1464,19 +1464,21 @@
|
||||
},
|
||||
{
|
||||
"dest": "fbneo/samples/donpachi.zip",
|
||||
"sha1": "c0c0b5db93a61276a6fe6842049cb53e564b8413",
|
||||
"sha256": "a686ebf893d511b5b7667176cd6844593e914595a8bb9ab656b2c66969013b5c",
|
||||
"size": 5641310,
|
||||
"repo_path": "bios/Other/fbneo/donpachi.zip",
|
||||
"sha1": "d380fb29287eb7fc9ff901a7653ad40785f7deb1",
|
||||
"sha256": "78a237f1e2774eb396e2f14999f1270597e0767a392729e7a4539455888b6fe0",
|
||||
"size": 208549253,
|
||||
"repo_path": "bios/Other/fbneo/fbneo/samples/donpachi.zip",
|
||||
"cores": [
|
||||
"fbneo"
|
||||
]
|
||||
],
|
||||
"storage": "release",
|
||||
"release_asset": "donpachi.zip"
|
||||
},
|
||||
{
|
||||
"dest": "fbneo/samples/sfz3mix.zip",
|
||||
"sha1": "227815ce9e55db427d68e075182caffe6ad60ad1",
|
||||
"sha256": "6a720035646b3488a047ab163a6975b7be82fe75c5eec88155c8503c93a631fe",
|
||||
"size": 96705917,
|
||||
"sha1": "e39ee9abb19076ef095f67469ca95ff5e7f600dc",
|
||||
"sha256": "2c2e67ab762102f50df641280721164ddff0316e71081d5fa62f2a67365dea66",
|
||||
"size": 101017377,
|
||||
"repo_path": "bios/Other/fbneo/fbneo/samples/sfz3mix.zip",
|
||||
"cores": [
|
||||
"fbneo"
|
||||
@@ -3348,10 +3350,10 @@
|
||||
},
|
||||
{
|
||||
"dest": "firmware.bin",
|
||||
"sha1": "5b2acbd499b39fb1af1b36ef7de5eb047d83401c",
|
||||
"sha256": "7ea4f06ca110f8b7ff7c946f6e4e228d94977dadd4bb51570d14c68488edb32a",
|
||||
"sha1": "cfe072921ee3fb93f688743f8beef89043c3e9ad",
|
||||
"sha256": "57a1d6b43c1399d219ea18644240c4d4c6787c829f0a67ded216472867857cd0",
|
||||
"size": 262144,
|
||||
"repo_path": "bios/Arcade/Arcade/firmware.bin",
|
||||
"repo_path": "bios/Nintendo/Nintendo DS/firmware.bin",
|
||||
"cores": [
|
||||
"melonds"
|
||||
]
|
||||
@@ -3378,10 +3380,10 @@
|
||||
},
|
||||
{
|
||||
"dest": "dsi_firmware.bin",
|
||||
"sha1": "93c0598b08192a1f630e5edb2cd9f60d1e3ea7b3",
|
||||
"sha256": "1f89935da2888cd3e401af2774e06a6b587ca059e85f922826494f317d31c6ae",
|
||||
"sha1": "d2a5af338f09c5cbdd5d7628db5b9c075c69b616",
|
||||
"sha256": "1d7c771de535e6e07182fc9820ac32e76c6f0b5bcefd256a861fdfab144761ec",
|
||||
"size": 131072,
|
||||
"repo_path": "bios/Arcade/Arcade/dsi_firmware.bin",
|
||||
"repo_path": "bios/Nintendo/Nintendo DS/dsi_firmware.bin",
|
||||
"cores": [
|
||||
"melonds"
|
||||
]
|
||||
|
||||
@@ -5,7 +5,7 @@
|
||||
"platform": "emudeck",
|
||||
"display_name": "EmuDeck",
|
||||
"version": "1.0",
|
||||
"generated": "2026-09-03T20:45:52Z",
|
||||
"generated": "2026-09-13T17:22:08Z",
|
||||
"base_destination": "bios",
|
||||
"detect": [
|
||||
{
|
||||
@@ -313,10 +313,10 @@
|
||||
},
|
||||
{
|
||||
"dest": "firmware.bin",
|
||||
"sha1": "5b2acbd499b39fb1af1b36ef7de5eb047d83401c",
|
||||
"sha256": "7ea4f06ca110f8b7ff7c946f6e4e228d94977dadd4bb51570d14c68488edb32a",
|
||||
"sha1": "cfe072921ee3fb93f688743f8beef89043c3e9ad",
|
||||
"sha256": "57a1d6b43c1399d219ea18644240c4d4c6787c829f0a67ded216472867857cd0",
|
||||
"size": 262144,
|
||||
"repo_path": "bios/Arcade/Arcade/firmware.bin",
|
||||
"repo_path": "bios/Nintendo/Nintendo DS/firmware.bin",
|
||||
"cores": null
|
||||
},
|
||||
{
|
||||
@@ -3991,10 +3991,10 @@
|
||||
},
|
||||
{
|
||||
"dest": "dsi_firmware.bin",
|
||||
"sha1": "93c0598b08192a1f630e5edb2cd9f60d1e3ea7b3",
|
||||
"sha256": "1f89935da2888cd3e401af2774e06a6b587ca059e85f922826494f317d31c6ae",
|
||||
"sha1": "d2a5af338f09c5cbdd5d7628db5b9c075c69b616",
|
||||
"sha256": "1d7c771de535e6e07182fc9820ac32e76c6f0b5bcefd256a861fdfab144761ec",
|
||||
"size": 131072,
|
||||
"repo_path": "bios/Arcade/Arcade/dsi_firmware.bin",
|
||||
"repo_path": "bios/Nintendo/Nintendo DS/dsi_firmware.bin",
|
||||
"cores": [
|
||||
"melonds"
|
||||
]
|
||||
|
||||
+23
-23
@@ -5,7 +5,7 @@
|
||||
"platform": "lakka",
|
||||
"display_name": "Lakka",
|
||||
"version": "1.0",
|
||||
"generated": "2026-09-05T09:26:20Z",
|
||||
"generated": "2026-09-13T22:10:18Z",
|
||||
"base_destination": "system",
|
||||
"detect": [
|
||||
{
|
||||
@@ -17,7 +17,7 @@
|
||||
],
|
||||
"standalone_copies": [],
|
||||
"total_files": 1871,
|
||||
"total_size": 5865446694,
|
||||
"total_size": 6072666103,
|
||||
"total_omitted": 1,
|
||||
"omitted_files": [
|
||||
{
|
||||
@@ -1626,10 +1626,10 @@
|
||||
},
|
||||
{
|
||||
"dest": "dsi_firmware.bin",
|
||||
"sha1": "93c0598b08192a1f630e5edb2cd9f60d1e3ea7b3",
|
||||
"sha256": "1f89935da2888cd3e401af2774e06a6b587ca059e85f922826494f317d31c6ae",
|
||||
"sha1": "d2a5af338f09c5cbdd5d7628db5b9c075c69b616",
|
||||
"sha256": "1d7c771de535e6e07182fc9820ac32e76c6f0b5bcefd256a861fdfab144761ec",
|
||||
"size": 131072,
|
||||
"repo_path": "bios/Arcade/Arcade/dsi_firmware.bin",
|
||||
"repo_path": "bios/Nintendo/Nintendo DS/dsi_firmware.bin",
|
||||
"cores": null
|
||||
},
|
||||
{
|
||||
@@ -6912,19 +6912,21 @@
|
||||
},
|
||||
{
|
||||
"dest": "fbneo/samples/donpachi.zip",
|
||||
"sha1": "c0c0b5db93a61276a6fe6842049cb53e564b8413",
|
||||
"sha256": "a686ebf893d511b5b7667176cd6844593e914595a8bb9ab656b2c66969013b5c",
|
||||
"size": 5641310,
|
||||
"repo_path": "bios/Other/fbneo/donpachi.zip",
|
||||
"sha1": "d380fb29287eb7fc9ff901a7653ad40785f7deb1",
|
||||
"sha256": "78a237f1e2774eb396e2f14999f1270597e0767a392729e7a4539455888b6fe0",
|
||||
"size": 208549253,
|
||||
"repo_path": "bios/Other/fbneo/fbneo/samples/donpachi.zip",
|
||||
"cores": [
|
||||
"fbneo"
|
||||
]
|
||||
],
|
||||
"storage": "release",
|
||||
"release_asset": "donpachi.zip"
|
||||
},
|
||||
{
|
||||
"dest": "fbneo/samples/sfz3mix.zip",
|
||||
"sha1": "227815ce9e55db427d68e075182caffe6ad60ad1",
|
||||
"sha256": "6a720035646b3488a047ab163a6975b7be82fe75c5eec88155c8503c93a631fe",
|
||||
"size": 96705917,
|
||||
"sha1": "e39ee9abb19076ef095f67469ca95ff5e7f600dc",
|
||||
"sha256": "2c2e67ab762102f50df641280721164ddff0316e71081d5fa62f2a67365dea66",
|
||||
"size": 101017377,
|
||||
"repo_path": "bios/Other/fbneo/fbneo/samples/sfz3mix.zip",
|
||||
"cores": [
|
||||
"fbneo"
|
||||
@@ -9368,10 +9370,10 @@
|
||||
},
|
||||
{
|
||||
"dest": "d2fdc.zip",
|
||||
"sha1": "bc39fbd5b9a8d2287ac5d0a42e639fc4d3c2f9d4",
|
||||
"sha256": "e5e30615040567c1e7a2d21599681f8dac820edbdcda177b816a64d74b3a12f2",
|
||||
"size": 256,
|
||||
"repo_path": "bios/Apple/Apple II/DiskII/state-machine-16.rom",
|
||||
"sha1": "af56c948598291b284a528f3fce06b961dba55e3",
|
||||
"sha256": "69ee0f8f0862e1a623bcbe9870f9531f7976312f292a20d1aff7ed61b6085a69",
|
||||
"size": 262,
|
||||
"repo_path": "bios/Arcade/Arcade/a3fdc.zip",
|
||||
"cores": [
|
||||
"mamemess"
|
||||
]
|
||||
@@ -13380,9 +13382,7 @@
|
||||
"repo_path": "bios/Other/sdlpal/sdlpal/5.avi",
|
||||
"cores": [
|
||||
"sdlpal"
|
||||
],
|
||||
"storage": "release",
|
||||
"release_asset": "5.avi"
|
||||
]
|
||||
},
|
||||
{
|
||||
"dest": "sdlpal/6.avi",
|
||||
@@ -15966,10 +15966,10 @@
|
||||
},
|
||||
{
|
||||
"dest": "SkyEmu/firmware.bin",
|
||||
"sha1": "5b2acbd499b39fb1af1b36ef7de5eb047d83401c",
|
||||
"sha256": "7ea4f06ca110f8b7ff7c946f6e4e228d94977dadd4bb51570d14c68488edb32a",
|
||||
"sha1": "cfe072921ee3fb93f688743f8beef89043c3e9ad",
|
||||
"sha256": "57a1d6b43c1399d219ea18644240c4d4c6787c829f0a67ded216472867857cd0",
|
||||
"size": 262144,
|
||||
"repo_path": "bios/Arcade/Arcade/firmware.bin",
|
||||
"repo_path": "bios/Nintendo/Nintendo DS/firmware.bin",
|
||||
"cores": [
|
||||
"skyemu"
|
||||
]
|
||||
|
||||
+19
-17
@@ -5,7 +5,7 @@
|
||||
"platform": "recalbox",
|
||||
"display_name": "Recalbox",
|
||||
"version": "1.0",
|
||||
"generated": "2026-09-05T09:26:20Z",
|
||||
"generated": "2026-09-13T22:10:18Z",
|
||||
"base_destination": "bios",
|
||||
"detect": [
|
||||
{
|
||||
@@ -238,7 +238,7 @@
|
||||
}
|
||||
],
|
||||
"total_files": 1328,
|
||||
"total_size": 3900250204,
|
||||
"total_size": 4107469613,
|
||||
"total_omitted": 4,
|
||||
"omitted_files": [
|
||||
{
|
||||
@@ -5927,19 +5927,21 @@
|
||||
},
|
||||
{
|
||||
"dest": "fbneo/samples/donpachi.zip",
|
||||
"sha1": "c0c0b5db93a61276a6fe6842049cb53e564b8413",
|
||||
"sha256": "a686ebf893d511b5b7667176cd6844593e914595a8bb9ab656b2c66969013b5c",
|
||||
"size": 5641310,
|
||||
"repo_path": "bios/Other/fbneo/donpachi.zip",
|
||||
"sha1": "d380fb29287eb7fc9ff901a7653ad40785f7deb1",
|
||||
"sha256": "78a237f1e2774eb396e2f14999f1270597e0767a392729e7a4539455888b6fe0",
|
||||
"size": 208549253,
|
||||
"repo_path": "bios/Other/fbneo/fbneo/samples/donpachi.zip",
|
||||
"cores": [
|
||||
"fbneo"
|
||||
]
|
||||
],
|
||||
"storage": "release",
|
||||
"release_asset": "donpachi.zip"
|
||||
},
|
||||
{
|
||||
"dest": "fbneo/samples/sfz3mix.zip",
|
||||
"sha1": "227815ce9e55db427d68e075182caffe6ad60ad1",
|
||||
"sha256": "6a720035646b3488a047ab163a6975b7be82fe75c5eec88155c8503c93a631fe",
|
||||
"size": 96705917,
|
||||
"sha1": "e39ee9abb19076ef095f67469ca95ff5e7f600dc",
|
||||
"sha256": "2c2e67ab762102f50df641280721164ddff0316e71081d5fa62f2a67365dea66",
|
||||
"size": 101017377,
|
||||
"repo_path": "bios/Other/fbneo/fbneo/samples/sfz3mix.zip",
|
||||
"cores": [
|
||||
"fbneo"
|
||||
@@ -8191,10 +8193,10 @@
|
||||
},
|
||||
{
|
||||
"dest": "d2fdc.zip",
|
||||
"sha1": "bc39fbd5b9a8d2287ac5d0a42e639fc4d3c2f9d4",
|
||||
"sha256": "e5e30615040567c1e7a2d21599681f8dac820edbdcda177b816a64d74b3a12f2",
|
||||
"size": 256,
|
||||
"repo_path": "bios/Apple/Apple II/DiskII/state-machine-16.rom",
|
||||
"sha1": "af56c948598291b284a528f3fce06b961dba55e3",
|
||||
"sha256": "69ee0f8f0862e1a623bcbe9870f9531f7976312f292a20d1aff7ed61b6085a69",
|
||||
"size": 262,
|
||||
"repo_path": "bios/Arcade/Arcade/a3fdc.zip",
|
||||
"cores": [
|
||||
"mamemess"
|
||||
]
|
||||
@@ -8681,10 +8683,10 @@
|
||||
},
|
||||
{
|
||||
"dest": "dsi_firmware.bin",
|
||||
"sha1": "93c0598b08192a1f630e5edb2cd9f60d1e3ea7b3",
|
||||
"sha256": "1f89935da2888cd3e401af2774e06a6b587ca059e85f922826494f317d31c6ae",
|
||||
"sha1": "d2a5af338f09c5cbdd5d7628db5b9c075c69b616",
|
||||
"sha256": "1d7c771de535e6e07182fc9820ac32e76c6f0b5bcefd256a861fdfab144761ec",
|
||||
"size": 131072,
|
||||
"repo_path": "bios/Arcade/Arcade/dsi_firmware.bin",
|
||||
"repo_path": "bios/Nintendo/Nintendo DS/dsi_firmware.bin",
|
||||
"cores": [
|
||||
"melonds"
|
||||
]
|
||||
|
||||
+23
-23
@@ -5,7 +5,7 @@
|
||||
"platform": "retroarch",
|
||||
"display_name": "RetroArch",
|
||||
"version": "1.0",
|
||||
"generated": "2026-09-05T09:26:20Z",
|
||||
"generated": "2026-09-13T22:10:18Z",
|
||||
"base_destination": "system",
|
||||
"detect": [
|
||||
{
|
||||
@@ -256,7 +256,7 @@
|
||||
}
|
||||
],
|
||||
"total_files": 1871,
|
||||
"total_size": 5865446694,
|
||||
"total_size": 6072666103,
|
||||
"total_omitted": 1,
|
||||
"omitted_files": [
|
||||
{
|
||||
@@ -1865,10 +1865,10 @@
|
||||
},
|
||||
{
|
||||
"dest": "dsi_firmware.bin",
|
||||
"sha1": "93c0598b08192a1f630e5edb2cd9f60d1e3ea7b3",
|
||||
"sha256": "1f89935da2888cd3e401af2774e06a6b587ca059e85f922826494f317d31c6ae",
|
||||
"sha1": "d2a5af338f09c5cbdd5d7628db5b9c075c69b616",
|
||||
"sha256": "1d7c771de535e6e07182fc9820ac32e76c6f0b5bcefd256a861fdfab144761ec",
|
||||
"size": 131072,
|
||||
"repo_path": "bios/Arcade/Arcade/dsi_firmware.bin",
|
||||
"repo_path": "bios/Nintendo/Nintendo DS/dsi_firmware.bin",
|
||||
"cores": null
|
||||
},
|
||||
{
|
||||
@@ -7151,19 +7151,21 @@
|
||||
},
|
||||
{
|
||||
"dest": "fbneo/samples/donpachi.zip",
|
||||
"sha1": "c0c0b5db93a61276a6fe6842049cb53e564b8413",
|
||||
"sha256": "a686ebf893d511b5b7667176cd6844593e914595a8bb9ab656b2c66969013b5c",
|
||||
"size": 5641310,
|
||||
"repo_path": "bios/Other/fbneo/donpachi.zip",
|
||||
"sha1": "d380fb29287eb7fc9ff901a7653ad40785f7deb1",
|
||||
"sha256": "78a237f1e2774eb396e2f14999f1270597e0767a392729e7a4539455888b6fe0",
|
||||
"size": 208549253,
|
||||
"repo_path": "bios/Other/fbneo/fbneo/samples/donpachi.zip",
|
||||
"cores": [
|
||||
"fbneo"
|
||||
]
|
||||
],
|
||||
"storage": "release",
|
||||
"release_asset": "donpachi.zip"
|
||||
},
|
||||
{
|
||||
"dest": "fbneo/samples/sfz3mix.zip",
|
||||
"sha1": "227815ce9e55db427d68e075182caffe6ad60ad1",
|
||||
"sha256": "6a720035646b3488a047ab163a6975b7be82fe75c5eec88155c8503c93a631fe",
|
||||
"size": 96705917,
|
||||
"sha1": "e39ee9abb19076ef095f67469ca95ff5e7f600dc",
|
||||
"sha256": "2c2e67ab762102f50df641280721164ddff0316e71081d5fa62f2a67365dea66",
|
||||
"size": 101017377,
|
||||
"repo_path": "bios/Other/fbneo/fbneo/samples/sfz3mix.zip",
|
||||
"cores": [
|
||||
"fbneo"
|
||||
@@ -9607,10 +9609,10 @@
|
||||
},
|
||||
{
|
||||
"dest": "d2fdc.zip",
|
||||
"sha1": "bc39fbd5b9a8d2287ac5d0a42e639fc4d3c2f9d4",
|
||||
"sha256": "e5e30615040567c1e7a2d21599681f8dac820edbdcda177b816a64d74b3a12f2",
|
||||
"size": 256,
|
||||
"repo_path": "bios/Apple/Apple II/DiskII/state-machine-16.rom",
|
||||
"sha1": "af56c948598291b284a528f3fce06b961dba55e3",
|
||||
"sha256": "69ee0f8f0862e1a623bcbe9870f9531f7976312f292a20d1aff7ed61b6085a69",
|
||||
"size": 262,
|
||||
"repo_path": "bios/Arcade/Arcade/a3fdc.zip",
|
||||
"cores": [
|
||||
"mamemess"
|
||||
]
|
||||
@@ -13619,9 +13621,7 @@
|
||||
"repo_path": "bios/Other/sdlpal/sdlpal/5.avi",
|
||||
"cores": [
|
||||
"sdlpal"
|
||||
],
|
||||
"storage": "release",
|
||||
"release_asset": "5.avi"
|
||||
]
|
||||
},
|
||||
{
|
||||
"dest": "sdlpal/6.avi",
|
||||
@@ -16205,10 +16205,10 @@
|
||||
},
|
||||
{
|
||||
"dest": "SkyEmu/firmware.bin",
|
||||
"sha1": "5b2acbd499b39fb1af1b36ef7de5eb047d83401c",
|
||||
"sha256": "7ea4f06ca110f8b7ff7c946f6e4e228d94977dadd4bb51570d14c68488edb32a",
|
||||
"sha1": "cfe072921ee3fb93f688743f8beef89043c3e9ad",
|
||||
"sha256": "57a1d6b43c1399d219ea18644240c4d4c6787c829f0a67ded216472867857cd0",
|
||||
"size": 262144,
|
||||
"repo_path": "bios/Arcade/Arcade/firmware.bin",
|
||||
"repo_path": "bios/Nintendo/Nintendo DS/firmware.bin",
|
||||
"cores": [
|
||||
"skyemu"
|
||||
]
|
||||
|
||||
+22
-20
@@ -5,7 +5,7 @@
|
||||
"platform": "retrobat",
|
||||
"display_name": "RetroBat",
|
||||
"version": "1.0",
|
||||
"generated": "2026-09-05T09:26:20Z",
|
||||
"generated": "2026-09-13T22:10:18Z",
|
||||
"base_destination": "bios",
|
||||
"detect": [
|
||||
{
|
||||
@@ -237,7 +237,7 @@
|
||||
}
|
||||
],
|
||||
"total_files": 1464,
|
||||
"total_size": 4733583386,
|
||||
"total_size": 4940802795,
|
||||
"total_omitted": 3,
|
||||
"omitted_files": [
|
||||
{
|
||||
@@ -514,10 +514,10 @@
|
||||
},
|
||||
{
|
||||
"dest": "d2fdc.zip",
|
||||
"sha1": "bc39fbd5b9a8d2287ac5d0a42e639fc4d3c2f9d4",
|
||||
"sha256": "e5e30615040567c1e7a2d21599681f8dac820edbdcda177b816a64d74b3a12f2",
|
||||
"size": 256,
|
||||
"repo_path": "bios/Apple/Apple II/DiskII/state-machine-16.rom",
|
||||
"sha1": "af56c948598291b284a528f3fce06b961dba55e3",
|
||||
"sha256": "69ee0f8f0862e1a623bcbe9870f9531f7976312f292a20d1aff7ed61b6085a69",
|
||||
"size": 262,
|
||||
"repo_path": "bios/Arcade/Arcade/a3fdc.zip",
|
||||
"cores": null
|
||||
},
|
||||
{
|
||||
@@ -2282,10 +2282,10 @@
|
||||
},
|
||||
{
|
||||
"dest": "firmware.bin",
|
||||
"sha1": "5b2acbd499b39fb1af1b36ef7de5eb047d83401c",
|
||||
"sha256": "7ea4f06ca110f8b7ff7c946f6e4e228d94977dadd4bb51570d14c68488edb32a",
|
||||
"sha1": "cfe072921ee3fb93f688743f8beef89043c3e9ad",
|
||||
"sha256": "57a1d6b43c1399d219ea18644240c4d4c6787c829f0a67ded216472867857cd0",
|
||||
"size": 262144,
|
||||
"repo_path": "bios/Arcade/Arcade/firmware.bin",
|
||||
"repo_path": "bios/Nintendo/Nintendo DS/firmware.bin",
|
||||
"cores": null
|
||||
},
|
||||
{
|
||||
@@ -2322,10 +2322,10 @@
|
||||
},
|
||||
{
|
||||
"dest": "dsi_firmware.bin",
|
||||
"sha1": "93c0598b08192a1f630e5edb2cd9f60d1e3ea7b3",
|
||||
"sha256": "1f89935da2888cd3e401af2774e06a6b587ca059e85f922826494f317d31c6ae",
|
||||
"sha1": "d2a5af338f09c5cbdd5d7628db5b9c075c69b616",
|
||||
"sha256": "1d7c771de535e6e07182fc9820ac32e76c6f0b5bcefd256a861fdfab144761ec",
|
||||
"size": 131072,
|
||||
"repo_path": "bios/Arcade/Arcade/dsi_firmware.bin",
|
||||
"repo_path": "bios/Nintendo/Nintendo DS/dsi_firmware.bin",
|
||||
"cores": null
|
||||
},
|
||||
{
|
||||
@@ -5430,19 +5430,21 @@
|
||||
},
|
||||
{
|
||||
"dest": "fbneo/samples/donpachi.zip",
|
||||
"sha1": "c0c0b5db93a61276a6fe6842049cb53e564b8413",
|
||||
"sha256": "a686ebf893d511b5b7667176cd6844593e914595a8bb9ab656b2c66969013b5c",
|
||||
"size": 5641310,
|
||||
"repo_path": "bios/Other/fbneo/donpachi.zip",
|
||||
"sha1": "d380fb29287eb7fc9ff901a7653ad40785f7deb1",
|
||||
"sha256": "78a237f1e2774eb396e2f14999f1270597e0767a392729e7a4539455888b6fe0",
|
||||
"size": 208549253,
|
||||
"repo_path": "bios/Other/fbneo/fbneo/samples/donpachi.zip",
|
||||
"cores": [
|
||||
"fbneo"
|
||||
]
|
||||
],
|
||||
"storage": "release",
|
||||
"release_asset": "donpachi.zip"
|
||||
},
|
||||
{
|
||||
"dest": "fbneo/samples/sfz3mix.zip",
|
||||
"sha1": "227815ce9e55db427d68e075182caffe6ad60ad1",
|
||||
"sha256": "6a720035646b3488a047ab163a6975b7be82fe75c5eec88155c8503c93a631fe",
|
||||
"size": 96705917,
|
||||
"sha1": "e39ee9abb19076ef095f67469ca95ff5e7f600dc",
|
||||
"sha256": "2c2e67ab762102f50df641280721164ddff0316e71081d5fa62f2a67365dea66",
|
||||
"size": 101017377,
|
||||
"repo_path": "bios/Other/fbneo/fbneo/samples/sfz3mix.zip",
|
||||
"cores": [
|
||||
"fbneo"
|
||||
|
||||
+19
-19
@@ -5,7 +5,7 @@
|
||||
"platform": "retrodeck",
|
||||
"display_name": "RetroDECK",
|
||||
"version": "1.0",
|
||||
"generated": "2026-09-05T09:26:20Z",
|
||||
"generated": "2026-09-13T22:10:18Z",
|
||||
"base_destination": "",
|
||||
"detect": [
|
||||
{
|
||||
@@ -238,7 +238,7 @@
|
||||
}
|
||||
],
|
||||
"total_files": 3515,
|
||||
"total_size": 6656314549,
|
||||
"total_size": 6863533952,
|
||||
"total_omitted": 4,
|
||||
"omitted_files": [
|
||||
{
|
||||
@@ -19433,19 +19433,21 @@
|
||||
},
|
||||
{
|
||||
"dest": "bios/fbneo/samples/donpachi.zip",
|
||||
"sha1": "c0c0b5db93a61276a6fe6842049cb53e564b8413",
|
||||
"sha256": "a686ebf893d511b5b7667176cd6844593e914595a8bb9ab656b2c66969013b5c",
|
||||
"size": 5641310,
|
||||
"repo_path": "bios/Other/fbneo/donpachi.zip",
|
||||
"sha1": "d380fb29287eb7fc9ff901a7653ad40785f7deb1",
|
||||
"sha256": "78a237f1e2774eb396e2f14999f1270597e0767a392729e7a4539455888b6fe0",
|
||||
"size": 208549253,
|
||||
"repo_path": "bios/Other/fbneo/fbneo/samples/donpachi.zip",
|
||||
"cores": [
|
||||
"fbneo"
|
||||
]
|
||||
],
|
||||
"storage": "release",
|
||||
"release_asset": "donpachi.zip"
|
||||
},
|
||||
{
|
||||
"dest": "bios/fbneo/samples/sfz3mix.zip",
|
||||
"sha1": "227815ce9e55db427d68e075182caffe6ad60ad1",
|
||||
"sha256": "6a720035646b3488a047ab163a6975b7be82fe75c5eec88155c8503c93a631fe",
|
||||
"size": 96705917,
|
||||
"sha1": "e39ee9abb19076ef095f67469ca95ff5e7f600dc",
|
||||
"sha256": "2c2e67ab762102f50df641280721164ddff0316e71081d5fa62f2a67365dea66",
|
||||
"size": 101017377,
|
||||
"repo_path": "bios/Other/fbneo/fbneo/samples/sfz3mix.zip",
|
||||
"cores": [
|
||||
"fbneo"
|
||||
@@ -21549,10 +21551,10 @@
|
||||
},
|
||||
{
|
||||
"dest": "bios/dsi_firmware.bin",
|
||||
"sha1": "93c0598b08192a1f630e5edb2cd9f60d1e3ea7b3",
|
||||
"sha256": "1f89935da2888cd3e401af2774e06a6b587ca059e85f922826494f317d31c6ae",
|
||||
"sha1": "d2a5af338f09c5cbdd5d7628db5b9c075c69b616",
|
||||
"sha256": "1d7c771de535e6e07182fc9820ac32e76c6f0b5bcefd256a861fdfab144761ec",
|
||||
"size": 131072,
|
||||
"repo_path": "bios/Arcade/Arcade/dsi_firmware.bin",
|
||||
"repo_path": "bios/Nintendo/Nintendo DS/dsi_firmware.bin",
|
||||
"cores": [
|
||||
"melonds"
|
||||
]
|
||||
@@ -25815,9 +25817,7 @@
|
||||
"repo_path": "bios/Other/sdlpal/sdlpal/5.avi",
|
||||
"cores": [
|
||||
"sdlpal"
|
||||
],
|
||||
"storage": "release",
|
||||
"release_asset": "5.avi"
|
||||
]
|
||||
},
|
||||
{
|
||||
"dest": "bios/sdlpal/6.avi",
|
||||
@@ -29865,10 +29865,10 @@
|
||||
},
|
||||
{
|
||||
"dest": "bios/SkyEmu/firmware.bin",
|
||||
"sha1": "5b2acbd499b39fb1af1b36ef7de5eb047d83401c",
|
||||
"sha256": "7ea4f06ca110f8b7ff7c946f6e4e228d94977dadd4bb51570d14c68488edb32a",
|
||||
"sha1": "cfe072921ee3fb93f688743f8beef89043c3e9ad",
|
||||
"sha256": "57a1d6b43c1399d219ea18644240c4d4c6787c829f0a67ded216472867857cd0",
|
||||
"size": 262144,
|
||||
"repo_path": "bios/Arcade/Arcade/firmware.bin",
|
||||
"repo_path": "bios/Nintendo/Nintendo DS/firmware.bin",
|
||||
"cores": [
|
||||
"skyemu"
|
||||
]
|
||||
|
||||
+23
-23
@@ -5,7 +5,7 @@
|
||||
"platform": "retropie",
|
||||
"display_name": "RetroPie",
|
||||
"version": "1.0",
|
||||
"generated": "2026-09-05T09:26:20Z",
|
||||
"generated": "2026-09-13T22:10:18Z",
|
||||
"base_destination": "system",
|
||||
"detect": [
|
||||
{
|
||||
@@ -16,7 +16,7 @@
|
||||
],
|
||||
"standalone_copies": [],
|
||||
"total_files": 1871,
|
||||
"total_size": 5865446694,
|
||||
"total_size": 6072666103,
|
||||
"total_omitted": 1,
|
||||
"omitted_files": [
|
||||
{
|
||||
@@ -1625,10 +1625,10 @@
|
||||
},
|
||||
{
|
||||
"dest": "dsi_firmware.bin",
|
||||
"sha1": "93c0598b08192a1f630e5edb2cd9f60d1e3ea7b3",
|
||||
"sha256": "1f89935da2888cd3e401af2774e06a6b587ca059e85f922826494f317d31c6ae",
|
||||
"sha1": "d2a5af338f09c5cbdd5d7628db5b9c075c69b616",
|
||||
"sha256": "1d7c771de535e6e07182fc9820ac32e76c6f0b5bcefd256a861fdfab144761ec",
|
||||
"size": 131072,
|
||||
"repo_path": "bios/Arcade/Arcade/dsi_firmware.bin",
|
||||
"repo_path": "bios/Nintendo/Nintendo DS/dsi_firmware.bin",
|
||||
"cores": null
|
||||
},
|
||||
{
|
||||
@@ -6911,19 +6911,21 @@
|
||||
},
|
||||
{
|
||||
"dest": "fbneo/samples/donpachi.zip",
|
||||
"sha1": "c0c0b5db93a61276a6fe6842049cb53e564b8413",
|
||||
"sha256": "a686ebf893d511b5b7667176cd6844593e914595a8bb9ab656b2c66969013b5c",
|
||||
"size": 5641310,
|
||||
"repo_path": "bios/Other/fbneo/donpachi.zip",
|
||||
"sha1": "d380fb29287eb7fc9ff901a7653ad40785f7deb1",
|
||||
"sha256": "78a237f1e2774eb396e2f14999f1270597e0767a392729e7a4539455888b6fe0",
|
||||
"size": 208549253,
|
||||
"repo_path": "bios/Other/fbneo/fbneo/samples/donpachi.zip",
|
||||
"cores": [
|
||||
"fbneo"
|
||||
]
|
||||
],
|
||||
"storage": "release",
|
||||
"release_asset": "donpachi.zip"
|
||||
},
|
||||
{
|
||||
"dest": "fbneo/samples/sfz3mix.zip",
|
||||
"sha1": "227815ce9e55db427d68e075182caffe6ad60ad1",
|
||||
"sha256": "6a720035646b3488a047ab163a6975b7be82fe75c5eec88155c8503c93a631fe",
|
||||
"size": 96705917,
|
||||
"sha1": "e39ee9abb19076ef095f67469ca95ff5e7f600dc",
|
||||
"sha256": "2c2e67ab762102f50df641280721164ddff0316e71081d5fa62f2a67365dea66",
|
||||
"size": 101017377,
|
||||
"repo_path": "bios/Other/fbneo/fbneo/samples/sfz3mix.zip",
|
||||
"cores": [
|
||||
"fbneo"
|
||||
@@ -9367,10 +9369,10 @@
|
||||
},
|
||||
{
|
||||
"dest": "d2fdc.zip",
|
||||
"sha1": "bc39fbd5b9a8d2287ac5d0a42e639fc4d3c2f9d4",
|
||||
"sha256": "e5e30615040567c1e7a2d21599681f8dac820edbdcda177b816a64d74b3a12f2",
|
||||
"size": 256,
|
||||
"repo_path": "bios/Apple/Apple II/DiskII/state-machine-16.rom",
|
||||
"sha1": "af56c948598291b284a528f3fce06b961dba55e3",
|
||||
"sha256": "69ee0f8f0862e1a623bcbe9870f9531f7976312f292a20d1aff7ed61b6085a69",
|
||||
"size": 262,
|
||||
"repo_path": "bios/Arcade/Arcade/a3fdc.zip",
|
||||
"cores": [
|
||||
"mamemess"
|
||||
]
|
||||
@@ -13379,9 +13381,7 @@
|
||||
"repo_path": "bios/Other/sdlpal/sdlpal/5.avi",
|
||||
"cores": [
|
||||
"sdlpal"
|
||||
],
|
||||
"storage": "release",
|
||||
"release_asset": "5.avi"
|
||||
]
|
||||
},
|
||||
{
|
||||
"dest": "sdlpal/6.avi",
|
||||
@@ -15965,10 +15965,10 @@
|
||||
},
|
||||
{
|
||||
"dest": "SkyEmu/firmware.bin",
|
||||
"sha1": "5b2acbd499b39fb1af1b36ef7de5eb047d83401c",
|
||||
"sha256": "7ea4f06ca110f8b7ff7c946f6e4e228d94977dadd4bb51570d14c68488edb32a",
|
||||
"sha1": "cfe072921ee3fb93f688743f8beef89043c3e9ad",
|
||||
"sha256": "57a1d6b43c1399d219ea18644240c4d4c6787c829f0a67ded216472867857cd0",
|
||||
"size": 262144,
|
||||
"repo_path": "bios/Arcade/Arcade/firmware.bin",
|
||||
"repo_path": "bios/Nintendo/Nintendo DS/firmware.bin",
|
||||
"cores": [
|
||||
"skyemu"
|
||||
]
|
||||
|
||||
+20
-20
@@ -5,7 +5,7 @@
|
||||
"platform": "rocknix",
|
||||
"display_name": "ROCKNIX",
|
||||
"version": "1.0",
|
||||
"generated": "2026-09-05T09:26:20Z",
|
||||
"generated": "2026-09-13T22:10:18Z",
|
||||
"base_destination": "bios",
|
||||
"detect": [
|
||||
{
|
||||
@@ -18,7 +18,7 @@
|
||||
],
|
||||
"standalone_copies": [],
|
||||
"total_files": 1738,
|
||||
"total_size": 5743476850,
|
||||
"total_size": 5950696259,
|
||||
"total_omitted": 1,
|
||||
"omitted_files": [
|
||||
{
|
||||
@@ -4015,19 +4015,21 @@
|
||||
},
|
||||
{
|
||||
"dest": "fbneo/samples/donpachi.zip",
|
||||
"sha1": "c0c0b5db93a61276a6fe6842049cb53e564b8413",
|
||||
"sha256": "a686ebf893d511b5b7667176cd6844593e914595a8bb9ab656b2c66969013b5c",
|
||||
"size": 5641310,
|
||||
"repo_path": "bios/Other/fbneo/donpachi.zip",
|
||||
"sha1": "d380fb29287eb7fc9ff901a7653ad40785f7deb1",
|
||||
"sha256": "78a237f1e2774eb396e2f14999f1270597e0767a392729e7a4539455888b6fe0",
|
||||
"size": 208549253,
|
||||
"repo_path": "bios/Other/fbneo/fbneo/samples/donpachi.zip",
|
||||
"cores": [
|
||||
"fbneo"
|
||||
]
|
||||
],
|
||||
"storage": "release",
|
||||
"release_asset": "donpachi.zip"
|
||||
},
|
||||
{
|
||||
"dest": "fbneo/samples/sfz3mix.zip",
|
||||
"sha1": "227815ce9e55db427d68e075182caffe6ad60ad1",
|
||||
"sha256": "6a720035646b3488a047ab163a6975b7be82fe75c5eec88155c8503c93a631fe",
|
||||
"size": 96705917,
|
||||
"sha1": "e39ee9abb19076ef095f67469ca95ff5e7f600dc",
|
||||
"sha256": "2c2e67ab762102f50df641280721164ddff0316e71081d5fa62f2a67365dea66",
|
||||
"size": 101017377,
|
||||
"repo_path": "bios/Other/fbneo/fbneo/samples/sfz3mix.zip",
|
||||
"cores": [
|
||||
"fbneo"
|
||||
@@ -7211,10 +7213,10 @@
|
||||
},
|
||||
{
|
||||
"dest": "d2fdc.zip",
|
||||
"sha1": "bc39fbd5b9a8d2287ac5d0a42e639fc4d3c2f9d4",
|
||||
"sha256": "e5e30615040567c1e7a2d21599681f8dac820edbdcda177b816a64d74b3a12f2",
|
||||
"size": 256,
|
||||
"repo_path": "bios/Apple/Apple II/DiskII/state-machine-16.rom",
|
||||
"sha1": "af56c948598291b284a528f3fce06b961dba55e3",
|
||||
"sha256": "69ee0f8f0862e1a623bcbe9870f9531f7976312f292a20d1aff7ed61b6085a69",
|
||||
"size": 262,
|
||||
"repo_path": "bios/Arcade/Arcade/a3fdc.zip",
|
||||
"cores": [
|
||||
"mamemess"
|
||||
]
|
||||
@@ -12543,9 +12545,7 @@
|
||||
"repo_path": "bios/Other/sdlpal/sdlpal/5.avi",
|
||||
"cores": [
|
||||
"sdlpal"
|
||||
],
|
||||
"storage": "release",
|
||||
"release_asset": "5.avi"
|
||||
]
|
||||
},
|
||||
{
|
||||
"dest": "sdlpal/6.avi",
|
||||
@@ -15389,10 +15389,10 @@
|
||||
},
|
||||
{
|
||||
"dest": "SkyEmu/firmware.bin",
|
||||
"sha1": "5b2acbd499b39fb1af1b36ef7de5eb047d83401c",
|
||||
"sha256": "7ea4f06ca110f8b7ff7c946f6e4e228d94977dadd4bb51570d14c68488edb32a",
|
||||
"sha1": "cfe072921ee3fb93f688743f8beef89043c3e9ad",
|
||||
"sha256": "57a1d6b43c1399d219ea18644240c4d4c6787c829f0a67ded216472867857cd0",
|
||||
"size": 262144,
|
||||
"repo_path": "bios/Arcade/Arcade/firmware.bin",
|
||||
"repo_path": "bios/Nintendo/Nintendo DS/firmware.bin",
|
||||
"cores": [
|
||||
"skyemu"
|
||||
]
|
||||
|
||||
+15
-13
@@ -5,7 +5,7 @@
|
||||
"platform": "romm",
|
||||
"display_name": "RomM",
|
||||
"version": "1.0",
|
||||
"generated": "2026-09-03T20:45:52Z",
|
||||
"generated": "2026-09-13T22:10:18Z",
|
||||
"base_destination": "bios",
|
||||
"detect": [
|
||||
{
|
||||
@@ -16,7 +16,7 @@
|
||||
],
|
||||
"standalone_copies": [],
|
||||
"total_files": 615,
|
||||
"total_size": 1366505831,
|
||||
"total_size": 1573725234,
|
||||
"total_omitted": 0,
|
||||
"omitted_files": [],
|
||||
"files": [
|
||||
@@ -3332,19 +3332,21 @@
|
||||
},
|
||||
{
|
||||
"dest": "colecovision/fbneo/samples/donpachi.zip",
|
||||
"sha1": "c0c0b5db93a61276a6fe6842049cb53e564b8413",
|
||||
"sha256": "a686ebf893d511b5b7667176cd6844593e914595a8bb9ab656b2c66969013b5c",
|
||||
"size": 5641310,
|
||||
"repo_path": "bios/Other/fbneo/donpachi.zip",
|
||||
"sha1": "d380fb29287eb7fc9ff901a7653ad40785f7deb1",
|
||||
"sha256": "78a237f1e2774eb396e2f14999f1270597e0767a392729e7a4539455888b6fe0",
|
||||
"size": 208549253,
|
||||
"repo_path": "bios/Other/fbneo/fbneo/samples/donpachi.zip",
|
||||
"cores": [
|
||||
"fbneo"
|
||||
]
|
||||
],
|
||||
"storage": "release",
|
||||
"release_asset": "donpachi.zip"
|
||||
},
|
||||
{
|
||||
"dest": "colecovision/fbneo/samples/sfz3mix.zip",
|
||||
"sha1": "227815ce9e55db427d68e075182caffe6ad60ad1",
|
||||
"sha256": "6a720035646b3488a047ab163a6975b7be82fe75c5eec88155c8503c93a631fe",
|
||||
"size": 96705917,
|
||||
"sha1": "e39ee9abb19076ef095f67469ca95ff5e7f600dc",
|
||||
"sha256": "2c2e67ab762102f50df641280721164ddff0316e71081d5fa62f2a67365dea66",
|
||||
"size": 101017377,
|
||||
"repo_path": "bios/Other/fbneo/fbneo/samples/sfz3mix.zip",
|
||||
"cores": [
|
||||
"fbneo"
|
||||
@@ -3808,10 +3810,10 @@
|
||||
},
|
||||
{
|
||||
"dest": "nds/dsi_firmware.bin",
|
||||
"sha1": "93c0598b08192a1f630e5edb2cd9f60d1e3ea7b3",
|
||||
"sha256": "1f89935da2888cd3e401af2774e06a6b587ca059e85f922826494f317d31c6ae",
|
||||
"sha1": "d2a5af338f09c5cbdd5d7628db5b9c075c69b616",
|
||||
"sha256": "1d7c771de535e6e07182fc9820ac32e76c6f0b5bcefd256a861fdfab144761ec",
|
||||
"size": 131072,
|
||||
"repo_path": "bios/Arcade/Arcade/dsi_firmware.bin",
|
||||
"repo_path": "bios/Nintendo/Nintendo DS/dsi_firmware.bin",
|
||||
"cores": [
|
||||
"melonds"
|
||||
]
|
||||
|
||||
+2
-1
@@ -601,7 +601,7 @@ nav:
|
||||
- Dolphin Launcher: emulators/dolphin_launcher.md
|
||||
- Parallel Launcher: emulators/parallel-launcher.md
|
||||
- SWF Player: emulators/swf-player.md
|
||||
- Other (56):
|
||||
- Other (57):
|
||||
- ares: emulators/ares.md
|
||||
- Basilisk II: emulators/basiliskii.md
|
||||
- beebem: emulators/beebem.md
|
||||
@@ -635,6 +635,7 @@ nav:
|
||||
- Oricutron: emulators/oricutron.md
|
||||
- Pizza Boy SC: emulators/pizza-boy-sc.md
|
||||
- Plastic: emulators/plastic.md
|
||||
- POM2: emulators/pom2.md
|
||||
- project64: emulators/project64.md
|
||||
- puNES: emulators/punes.md
|
||||
- Real3DOPlayer: emulators/real3doplayer.md
|
||||
|
||||
@@ -0,0 +1,336 @@
|
||||
#!/usr/bin/env python3
|
||||
"""Compare the large-files release with the files the collection keeps out of git.
|
||||
|
||||
Every gitignored file under bios/ is served to the installer as an asset of
|
||||
the large-files release, and install.py refuses a download whose
|
||||
Content-Length differs from the manifest size. The manifest size is that of
|
||||
the local copy, so an asset uploaded before the local file was rebuilt fails
|
||||
every install of it until it is uploaded again.
|
||||
|
||||
Usage:
|
||||
python scripts/check_release_assets.py
|
||||
python scripts/check_release_assets.py --json
|
||||
"""
|
||||
|
||||
from __future__ import annotations
|
||||
|
||||
import argparse
|
||||
import hashlib
|
||||
import json
|
||||
import os
|
||||
import re
|
||||
import subprocess
|
||||
import sys
|
||||
|
||||
sys.path.insert(0, os.path.dirname(__file__))
|
||||
from common import load_database
|
||||
from largefiles import LARGE_FILES_RELEASE, LARGE_FILES_REPO
|
||||
|
||||
Finding = tuple[str, str, int, int | None]
|
||||
|
||||
|
||||
def expected_assets(db: dict, gitignore_text: str) -> dict[str, int]:
|
||||
"""Map each gitignored database path to the size the manifests carry."""
|
||||
ignored = {
|
||||
line.strip()
|
||||
for line in gitignore_text.splitlines()
|
||||
if line.strip().startswith("bios/")
|
||||
}
|
||||
return {
|
||||
entry["path"]: entry["size"]
|
||||
for entry in db.get("files", {}).values()
|
||||
if entry.get("path") in ignored
|
||||
}
|
||||
|
||||
|
||||
def _asset_names(path: str) -> list[str]:
|
||||
"""Names the release may publish a file under.
|
||||
|
||||
GitHub rewrites spaces to dots in asset names, so a file whose name
|
||||
carries spaces is published under the dotted form.
|
||||
"""
|
||||
name = os.path.basename(path)
|
||||
return [name, name.replace(" ", ".")] if " " in name else [name]
|
||||
|
||||
|
||||
def compare(
|
||||
expected: dict[str, int], assets: dict[str, int], notes_current: bool = True
|
||||
) -> list[Finding]:
|
||||
"""Files the release lacks or serves at another size, sorted by kind.
|
||||
|
||||
A release description that no longer matches what render_notes() would
|
||||
write is a finding of its own: the page is what a reader checks a
|
||||
download against.
|
||||
"""
|
||||
findings: list[Finding] = []
|
||||
if not notes_current:
|
||||
findings.append(("notes", "release description", 0, None))
|
||||
for path, size in sorted(expected.items()):
|
||||
published = next(
|
||||
(assets[name] for name in _asset_names(path) if name in assets), None
|
||||
)
|
||||
if published is None:
|
||||
findings.append(("missing", path, size, None))
|
||||
elif published != size:
|
||||
findings.append(("size", path, size, published))
|
||||
return sorted(findings)
|
||||
|
||||
|
||||
ASSET_URL = f"https://github.com/{LARGE_FILES_REPO}/releases/download/{LARGE_FILES_RELEASE}/"
|
||||
NOT_INDEXED = "Not indexed"
|
||||
SECTIONS = (
|
||||
"Console firmware",
|
||||
"Arcade",
|
||||
"Computer",
|
||||
"Game engine data",
|
||||
"Virtual machine firmware",
|
||||
"Other",
|
||||
NOT_INDEXED,
|
||||
)
|
||||
_ROW = re.compile(
|
||||
r"^\| \[(?P<name>[^\]]+)\]\([^)]*\) \| (?P<desc>[^|]*?) \| [^|]* \|"
|
||||
r"(?: `(?P<sha1>[0-9a-f]{40})` \|)?$",
|
||||
re.M,
|
||||
)
|
||||
_HEADING = re.compile(r"^## (.+)$", re.M)
|
||||
|
||||
|
||||
def parse_notes(body: str) -> dict[str, tuple[str, str, str]]:
|
||||
"""Name -> (section, description, sha1) for every row of a release page."""
|
||||
rows: dict[str, tuple[str, str, str]] = {}
|
||||
section = ""
|
||||
for line in body.splitlines():
|
||||
heading = _HEADING.match(line)
|
||||
if heading:
|
||||
section = heading.group(1).strip()
|
||||
continue
|
||||
row = _ROW.match(line)
|
||||
if row:
|
||||
rows[row.group("name")] = (
|
||||
section, row.group("desc").strip(), row.group("sha1") or ""
|
||||
)
|
||||
return rows
|
||||
|
||||
|
||||
def _section_for(path: str) -> str:
|
||||
parts = path.split("/")
|
||||
top = parts[1] if len(parts) > 1 else ""
|
||||
if top in ("Nintendo", "Sony", "Sega", "Microsoft", "NEC", "SNK"):
|
||||
return "Console firmware"
|
||||
if top == "Arcade" or "/samples/" in path:
|
||||
return "Arcade"
|
||||
if top == "QEMU":
|
||||
return "Virtual machine firmware"
|
||||
if top in ("RPG Maker", "ScummVM"):
|
||||
return "Game engine data"
|
||||
if top in ("Apple", "Commodore", "Atari", "Sinclair", "Amstrad"):
|
||||
return "Computer"
|
||||
return "Other"
|
||||
|
||||
|
||||
def _mib(size: int) -> str:
|
||||
return f"{round(size / 1048576)} MB"
|
||||
|
||||
|
||||
def render_notes(
|
||||
db: dict,
|
||||
gitignore_text: str,
|
||||
assets: dict[str, int],
|
||||
previous: str,
|
||||
descriptions: dict[str, str],
|
||||
bundles: dict[str, str],
|
||||
cache_sha1: dict[str, str],
|
||||
) -> str:
|
||||
"""The release page, from what the release actually serves.
|
||||
|
||||
Every asset gets one row. A file the database indexes carries its
|
||||
database SHA1; a data-directory bundle carries the hash of its cached
|
||||
copy when one exists; anything else is listed apart with its size only,
|
||||
so the page never vouches for bytes nobody indexed. Descriptions and
|
||||
sections already written by hand are kept by name.
|
||||
"""
|
||||
known = parse_notes(previous)
|
||||
ignored = {
|
||||
line.strip()
|
||||
for line in gitignore_text.splitlines()
|
||||
if line.strip().startswith("bios/")
|
||||
}
|
||||
indexed: dict[str, tuple[str, str]] = {}
|
||||
for sha1, entry in db.get("files", {}).items():
|
||||
path = entry.get("path", "")
|
||||
if path in ignored:
|
||||
name = os.path.basename(path)
|
||||
for candidate in (name, name.replace(" ", ".")):
|
||||
indexed[candidate] = (sha1, path)
|
||||
|
||||
rows: dict[str, list[tuple[int, str]]] = {section: [] for section in SECTIONS}
|
||||
for name, size in assets.items():
|
||||
section, description, previous_sha1 = known.get(name, ("", "", ""))
|
||||
if name in indexed:
|
||||
sha1, path = indexed[name]
|
||||
section = section if section in SECTIONS[:-1] else _section_for(path)
|
||||
stem = name.split(".")[0] + "." + name.split(".")[1] if name.count(".") > 1 else name
|
||||
description = description or descriptions.get(name) or descriptions.get(stem) or path
|
||||
elif name in bundles:
|
||||
sha1 = cache_sha1.get(name, previous_sha1)
|
||||
section = section if section in SECTIONS[:-1] else "Game engine data"
|
||||
description = description or bundles[name]
|
||||
else:
|
||||
sha1 = ""
|
||||
section = NOT_INDEXED
|
||||
description = description or name
|
||||
link = f"[{name}]({ASSET_URL}{name})"
|
||||
if section == NOT_INDEXED:
|
||||
line = f"| {link} | {description} | {_mib(size)} |"
|
||||
else:
|
||||
line = f"| {link} | {description} | {_mib(size)} | `{sha1}` |"
|
||||
rows[section].append((-size, line))
|
||||
|
||||
out = [
|
||||
"Files too large for the git repository (GitHub 100MB limit), plus game engine data packs.",
|
||||
"Downloaded automatically by `generate_pack.py` when not present locally.",
|
||||
"Manual: `gh release download large-files`",
|
||||
]
|
||||
for section in SECTIONS:
|
||||
if not rows[section]:
|
||||
continue
|
||||
out += ["", f"## {section}", ""]
|
||||
if section == NOT_INDEXED:
|
||||
out += [
|
||||
"Assets the collection does not index: no database entry names them, "
|
||||
"so no hash is vouched for here.",
|
||||
"",
|
||||
"| File | Description | Size |",
|
||||
"|------|-------------|-----:|",
|
||||
]
|
||||
else:
|
||||
out += ["| File | Description | Size | SHA1 |", "|------|-------------|-----:|------|"]
|
||||
out += [line for _, line in sorted(rows[section])]
|
||||
total = sum(assets.values())
|
||||
out += ["", f"{len(assets)} files, {total / 1073741824:.1f} GB total. Verify a download with `sha1sum <file>`.", ""]
|
||||
return "\n".join(out)
|
||||
|
||||
|
||||
def profile_descriptions(emulators_dir: str = "emulators") -> dict[str, str]:
|
||||
"""Name -> description, from the first profile that declares the file."""
|
||||
from common import load_emulator_profiles
|
||||
|
||||
found: dict[str, str] = {}
|
||||
for profile in load_emulator_profiles(emulators_dir).values():
|
||||
for entry in profile.get("files", []):
|
||||
name = str(entry.get("name") or "")
|
||||
if name and entry.get("description"):
|
||||
found.setdefault(name, str(entry["description"]))
|
||||
return found
|
||||
|
||||
|
||||
def registry_bundles(registry_path: str = "platforms/_data_dirs.yml") -> dict[str, str]:
|
||||
"""Asset name -> description for data directories served from the release."""
|
||||
from common import yaml_load
|
||||
|
||||
with open(registry_path, encoding="utf-8") as handle:
|
||||
registry = yaml_load(handle) or {}
|
||||
bundles: dict[str, str] = {}
|
||||
for entry in (registry.get("data_directories") or registry).values():
|
||||
if not isinstance(entry, dict):
|
||||
continue
|
||||
url = str(entry.get("source_url") or "")
|
||||
if url.startswith(ASSET_URL):
|
||||
bundles[url[len(ASSET_URL):]] = str(entry.get("description") or "")
|
||||
return bundles
|
||||
|
||||
|
||||
def cache_hashes(names: set[str], cache_dir: str = ".cache/large") -> dict[str, str]:
|
||||
"""SHA1 of the cached copy of each named asset that the cache holds."""
|
||||
hashes: dict[str, str] = {}
|
||||
for name in names:
|
||||
path = os.path.join(cache_dir, name)
|
||||
if os.path.isfile(path):
|
||||
digest = hashlib.sha1()
|
||||
with open(path, "rb") as handle:
|
||||
for chunk in iter(lambda: handle.read(1 << 20), b""):
|
||||
digest.update(chunk)
|
||||
hashes[name] = digest.hexdigest()
|
||||
return hashes
|
||||
|
||||
|
||||
def fetch_release() -> tuple[dict[str, int], str]:
|
||||
"""Name and size of every asset of the large-files release, and its page."""
|
||||
result = subprocess.run(
|
||||
[
|
||||
"gh", "release", "view", LARGE_FILES_RELEASE,
|
||||
"-R", LARGE_FILES_REPO, "--json", "assets,body",
|
||||
],
|
||||
capture_output=True, text=True, check=True,
|
||||
)
|
||||
data = json.loads(result.stdout)
|
||||
return {a["name"]: a["size"] for a in data["assets"]}, data.get("body", "")
|
||||
|
||||
|
||||
def fetch_assets() -> dict[str, int]:
|
||||
"""Name and size of every asset of the large-files release."""
|
||||
result = subprocess.run(
|
||||
[
|
||||
"gh", "release", "view", LARGE_FILES_RELEASE,
|
||||
"-R", LARGE_FILES_REPO, "--json", "assets",
|
||||
],
|
||||
capture_output=True, text=True, check=True,
|
||||
)
|
||||
return {a["name"]: a["size"] for a in json.loads(result.stdout)["assets"]}
|
||||
|
||||
|
||||
def main() -> int:
|
||||
parser = argparse.ArgumentParser(description=__doc__.split("\n")[0])
|
||||
parser.add_argument("--db", default="database.json")
|
||||
parser.add_argument("--gitignore", default=".gitignore")
|
||||
parser.add_argument("--json", action="store_true")
|
||||
parser.add_argument(
|
||||
"--notes", metavar="FILE",
|
||||
help="write the release page rendered from the collection to FILE",
|
||||
)
|
||||
args = parser.parse_args()
|
||||
|
||||
with open(args.gitignore, encoding="utf-8") as handle:
|
||||
gitignore_text = handle.read()
|
||||
db = load_database(args.db)
|
||||
expected = expected_assets(db, gitignore_text)
|
||||
try:
|
||||
assets, body = fetch_release()
|
||||
except (subprocess.CalledProcessError, FileNotFoundError, KeyError) as exc:
|
||||
print(f"ERROR: cannot list release assets: {exc}", file=sys.stderr)
|
||||
return 2
|
||||
bundles = registry_bundles()
|
||||
rendered = render_notes(
|
||||
db, gitignore_text, assets, body, profile_descriptions(), bundles,
|
||||
cache_hashes(set(bundles)),
|
||||
)
|
||||
if args.notes:
|
||||
with open(args.notes, "w", encoding="utf-8") as handle:
|
||||
handle.write(rendered)
|
||||
findings = compare(expected, assets, notes_current=rendered.strip() == body.strip())
|
||||
|
||||
if args.json:
|
||||
print(json.dumps(
|
||||
[
|
||||
{"kind": kind, "path": path, "expected": size, "published": published}
|
||||
for kind, path, size, published in findings
|
||||
],
|
||||
indent=2,
|
||||
))
|
||||
else:
|
||||
print(f"{len(expected)} gitignored files, {len(assets)} release assets")
|
||||
for kind, path, size, published in findings:
|
||||
if kind == "missing":
|
||||
print(f" MISSING {path} ({size} bytes)")
|
||||
elif kind == "size":
|
||||
print(f" SIZE {path}: local {size} != release {published}")
|
||||
else:
|
||||
print(" NOTES release description differs from the rendered page"
|
||||
" (--notes FILE, then gh release edit large-files --notes-file FILE)")
|
||||
if not findings:
|
||||
print(" release assets and description match the collection")
|
||||
return 1 if findings else 0
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
sys.exit(main())
|
||||
+6
-1
@@ -230,7 +230,12 @@ def deduplicate(bios_dir: str, dry_run: bool = False) -> dict:
|
||||
|
||||
# Write MAME clone mapping
|
||||
if mame_clones:
|
||||
clone_path = "_mame_clones.json"
|
||||
# Beside the scanned tree, where get_mame_clone_map() reads it for
|
||||
# the real layout. A path relative to the working directory let a
|
||||
# scan of a fixture tree rewrite the repository's own map.
|
||||
clone_path = os.path.join(
|
||||
os.path.dirname(os.path.abspath(bios_dir)), "_mame_clones.json"
|
||||
)
|
||||
# A group is only visible while both copies are on disk, and this run
|
||||
# has just deleted the clone. Writing only what was seen this time
|
||||
# therefore erases every mapping an earlier run recorded, and the
|
||||
|
||||
@@ -2707,13 +2707,16 @@ def _load_gitignore_entries(repo_root: str) -> set[str]:
|
||||
return entries
|
||||
|
||||
|
||||
def _is_large_file(local_path: str, repo_root: str) -> bool:
|
||||
"""Check if a file is a large file (>50MB or in .gitignore)."""
|
||||
if local_path and os.path.exists(local_path):
|
||||
if os.path.getsize(local_path) > 50_000_000:
|
||||
return True
|
||||
def _is_release_asset(local_path: str, repo_root: str) -> bool:
|
||||
"""Whether the installer fetches this file from the large-files release.
|
||||
|
||||
The repository serves every committed file from its raw URL; only the
|
||||
files kept out of git live as release assets, and .gitignore is the
|
||||
ledger of those. Size is not the criterion: a committed file over 50 MB
|
||||
is still served by the repository, and announcing it as a release asset
|
||||
sends the installer to an asset nobody uploaded.
|
||||
"""
|
||||
gitignore = _load_gitignore_entries(repo_root)
|
||||
# Check if the path relative to repo root is in .gitignore
|
||||
try:
|
||||
rel = os.path.relpath(local_path, repo_root)
|
||||
except ValueError:
|
||||
@@ -2826,7 +2829,7 @@ def _manifest_core_entries(
|
||||
"cores": [source_emu] if source_emu else [],
|
||||
}
|
||||
|
||||
if _is_large_file(local_path or "", repo_root):
|
||||
if _is_release_asset(local_path or "", repo_root):
|
||||
entry["storage"] = "release"
|
||||
entry["release_asset"] = (
|
||||
os.path.basename(local_path) if local_path else fe["name"]
|
||||
@@ -3021,7 +3024,7 @@ def generate_manifest(
|
||||
sha256 = hashes["sha256"]
|
||||
|
||||
repo_path = _get_repo_path(sha1, db) if sha1 else ""
|
||||
is_release_asset = _is_large_file(local_path or "", repo_root)
|
||||
is_release_asset = _is_release_asset(local_path or "", repo_root)
|
||||
|
||||
# An entry needs somewhere to be fetched from. Resolution can
|
||||
# land on a file the database does not index -- a data
|
||||
|
||||
@@ -6,6 +6,7 @@ Steps:
|
||||
1b. provenance_report.py (dump-catalog coverage from provenance/)
|
||||
1c. romset_recipes.py (archive identification, reconstruction targets)
|
||||
2. refresh_data_dirs.py (update Dolphin Sys, PPSSPP, etc.)
|
||||
2b2. check_release_assets.py (large-files release vs gitignored files, online)
|
||||
3. verify.py --all (check all platforms)
|
||||
4. generate_pack.py --all (build ZIP packs)
|
||||
4b. generate install manifests
|
||||
@@ -346,6 +347,20 @@ def main():
|
||||
elif args.check_buildbot:
|
||||
print("\n--- 2b check buildbot system: SKIPPED (--offline) ---")
|
||||
|
||||
# Step 2b2: The release must serve the bytes the manifests describe. The
|
||||
# installer compares Content-Length with the manifest size, so an asset
|
||||
# uploaded before its local file was rebuilt fails every install of it.
|
||||
if not args.offline:
|
||||
ok, _ = run(
|
||||
[sys.executable, "scripts/check_release_assets.py"],
|
||||
"2b2 check release assets",
|
||||
)
|
||||
results["check_release_assets"] = ok
|
||||
all_ok = all_ok and ok
|
||||
else:
|
||||
print("\n--- 2b2 check release assets: SKIPPED (--offline) ---")
|
||||
results["check_release_assets"] = SKIPPED
|
||||
|
||||
# Step 2c: Generate truth YAMLs
|
||||
# A targeted run writes its model in a subdirectory of its own, and the
|
||||
# diff has to read the same one or it compares a narrowed model against
|
||||
|
||||
@@ -1184,6 +1184,211 @@ class EveryManifestEntryIsFetchable(unittest.TestCase):
|
||||
for entry in data.get("omitted_files", []):
|
||||
self.assertIn(entry.get("reason"), allowed)
|
||||
|
||||
def _manifests(self) -> list[Path]:
|
||||
paths = sorted((ROOT / "install").glob("*.json"))
|
||||
paths += sorted((ROOT / "install" / "targets").glob("*.json"))
|
||||
self.assertTrue(paths, "no install manifests to check")
|
||||
return paths
|
||||
|
||||
def test_repo_paths_name_the_file_the_database_holds(self):
|
||||
"""A manifest written before a file moved sends the installer to 404.
|
||||
|
||||
database.json is regenerated whenever a file is refiled; the manifests
|
||||
are a separate artefact and were left behind once (the two DS
|
||||
firmware dumps of the 7 September refile). The installer fetches
|
||||
repo_path from raw.githubusercontent.com, so a stale one is a
|
||||
download that can never succeed.
|
||||
"""
|
||||
database = ROOT / "database.json"
|
||||
if not database.is_file():
|
||||
self.skipTest("database.json not generated")
|
||||
files = json.loads(database.read_text(encoding="utf-8"))["files"]
|
||||
for path in self._manifests():
|
||||
with self.subTest(manifest=path.name):
|
||||
data = json.loads(path.read_text(encoding="utf-8"))
|
||||
stale = [
|
||||
(entry["dest"], entry["repo_path"], files.get(entry["sha1"], {}).get("path"))
|
||||
for entry in data.get("files", [])
|
||||
if entry.get("repo_path")
|
||||
and files.get(entry.get("sha1", ""), {}).get("path") != entry["repo_path"]
|
||||
]
|
||||
self.assertEqual(stale, [], f"{path.name} names moved files: {stale[:3]}")
|
||||
|
||||
def test_release_entries_are_exactly_the_files_git_does_not_hold(self):
|
||||
"""The installer has two sources, and the manifest must pick the right one.
|
||||
|
||||
A committed file is served by the repository; a gitignored one by
|
||||
the large-files release. Marking a committed file as a release asset
|
||||
sends the installer to an asset nobody uploaded (sdlpal/5.avi, 83 MB
|
||||
in git, was announced as release asset `5.avi`). Marking a gitignored
|
||||
file as a repo file sends it to a raw URL that has no content.
|
||||
"""
|
||||
tracked = set(
|
||||
subprocess.run(
|
||||
["git", "ls-files", "-z", "--", "bios"],
|
||||
capture_output=True, text=True, cwd=ROOT, check=True,
|
||||
).stdout.split("\0")
|
||||
)
|
||||
if not tracked:
|
||||
self.skipTest("not a git checkout")
|
||||
for path in self._manifests():
|
||||
with self.subTest(manifest=path.name):
|
||||
data = json.loads(path.read_text(encoding="utf-8"))
|
||||
wrong = []
|
||||
for entry in data.get("files", []):
|
||||
repo_path = entry.get("repo_path")
|
||||
if not repo_path:
|
||||
continue
|
||||
committed = repo_path in tracked
|
||||
if bool(entry.get("release_asset")) == committed:
|
||||
wrong.append((entry["dest"], repo_path, "committed" if committed else "gitignored"))
|
||||
self.assertEqual(wrong, [], f"{path.name} picks the wrong source: {wrong[:3]}")
|
||||
|
||||
|
||||
class ReleaseAssetCriterion(unittest.TestCase):
|
||||
"""What decides whether the installer fetches from the release is git, not size.
|
||||
|
||||
Files over 50 MB are supposed to be gitignored and uploaded to the
|
||||
large-files release, but four committed files break that rule and one of
|
||||
them reached a manifest as a release asset that does not exist. The
|
||||
truthful question is whether the repository serves the bytes, and the
|
||||
ledger of what it does not serve is .gitignore.
|
||||
"""
|
||||
|
||||
def _repo(self, directory: str, ignored: str) -> str:
|
||||
Path(directory, ".gitignore").write_text(ignored + "\n", encoding="utf-8")
|
||||
return directory
|
||||
|
||||
def test_a_large_committed_file_is_served_by_the_repository(self):
|
||||
from scripts import generate_pack
|
||||
|
||||
with tempfile.TemporaryDirectory(dir=TMP_ROOT) as directory:
|
||||
root = self._repo(directory, "bios/elsewhere.bin")
|
||||
big = Path(root, "bios", "big.avi")
|
||||
big.parent.mkdir()
|
||||
with big.open("wb") as handle:
|
||||
handle.truncate(60_000_000)
|
||||
generate_pack._GITIGNORE_ENTRIES = None
|
||||
try:
|
||||
self.assertFalse(generate_pack._is_release_asset(str(big), root))
|
||||
finally:
|
||||
generate_pack._GITIGNORE_ENTRIES = None
|
||||
|
||||
def test_a_gitignored_file_is_served_by_the_release_whatever_its_size(self):
|
||||
from scripts import generate_pack
|
||||
|
||||
with tempfile.TemporaryDirectory(dir=TMP_ROOT) as directory:
|
||||
root = self._repo(directory, "bios/small.zip")
|
||||
small = Path(root, "bios", "small.zip")
|
||||
small.parent.mkdir()
|
||||
small.write_bytes(b"PK")
|
||||
generate_pack._GITIGNORE_ENTRIES = None
|
||||
try:
|
||||
self.assertTrue(generate_pack._is_release_asset(str(small), root))
|
||||
finally:
|
||||
generate_pack._GITIGNORE_ENTRIES = None
|
||||
|
||||
|
||||
class ReleaseAssetsMatchTheCollection(unittest.TestCase):
|
||||
"""The bytes the release serves must be the bytes the manifests describe.
|
||||
|
||||
install.py checks Content-Length against the manifest size before it
|
||||
downloads, and the manifest size is that of the local copy. Both FBNeo
|
||||
sample archives were rebuilt locally after their upload and never
|
||||
re-uploaded: same members, different container, every install of them
|
||||
failed. The comparison is offline here on a fixture; the script runs it
|
||||
against the live release.
|
||||
"""
|
||||
|
||||
def test_missing_and_resized_assets_are_reported_and_nothing_else(self):
|
||||
from scripts import check_release_assets
|
||||
|
||||
expected = {
|
||||
"bios/Other/fbneo/fbneo/samples/twotiger.zip": 154985212,
|
||||
"bios/Arcade/MAME/MAME 0.174 Arcade XML.dat": 53677408,
|
||||
"bios/Other/sdlpal/sdlpal/5.avi": 82833972,
|
||||
}
|
||||
assets = {
|
||||
"twotiger.zip": 154888877,
|
||||
"MAME.0.174.Arcade.XML.dat": 53677408,
|
||||
"unrelated.zip": 1,
|
||||
}
|
||||
findings = check_release_assets.compare(expected, assets)
|
||||
self.assertEqual(
|
||||
findings,
|
||||
[
|
||||
("missing", "bios/Other/sdlpal/sdlpal/5.avi", 82833972, None),
|
||||
("size", "bios/Other/fbneo/fbneo/samples/twotiger.zip", 154985212, 154888877),
|
||||
],
|
||||
)
|
||||
|
||||
def test_expected_assets_are_the_gitignored_database_entries(self):
|
||||
from scripts import check_release_assets
|
||||
|
||||
db = {
|
||||
"files": {
|
||||
"a" * 40: {"path": "bios/Other/x/big.zip", "size": 10},
|
||||
"b" * 40: {"path": "bios/Other/x/small.bin", "size": 2},
|
||||
}
|
||||
}
|
||||
gitignore = "# large\nbios/Other/x/big.zip\ntmp/\n"
|
||||
self.assertEqual(
|
||||
check_release_assets.expected_assets(db, gitignore),
|
||||
{"bios/Other/x/big.zip": 10},
|
||||
)
|
||||
|
||||
def test_release_notes_are_rendered_from_the_collection(self):
|
||||
"""The release page is written by hand and drifts; it is rendered instead.
|
||||
|
||||
Three assets had no row, three rows carried the SHA1 of an asset
|
||||
that had since been replaced, and the footer counted 41 files for 44.
|
||||
Hand-written descriptions survive by name; a new row takes its
|
||||
description from the profile that declares the file; an asset the
|
||||
collection does not index is listed apart, with its size only.
|
||||
"""
|
||||
from scripts import check_release_assets
|
||||
|
||||
db = {"files": {
|
||||
"a" * 40: {"path": "bios/Nintendo/Wii/nand.bin", "size": 553649152},
|
||||
"b" * 40: {"path": "bios/Other/fbneo/fbneo/samples/twotiger.zip", "size": 154985212},
|
||||
"c" * 40: {"path": "bios/Other/x/small.bin", "size": 2},
|
||||
}}
|
||||
gitignore = "bios/Nintendo/Wii/nand.bin\nbios/Other/fbneo/fbneo/samples/twotiger.zip\n"
|
||||
assets = {"nand.bin": 553649152, "twotiger.zip": 154985212,
|
||||
"sdlpal-data.zip": 140773720, "whoopee.zip": 222665810}
|
||||
previous = (
|
||||
"## Arcade\n\n| File | Description | Size | SHA1 |\n|---|---|---|---|\n"
|
||||
"| [twotiger.zip](u) | Two Tigers samples | 148 MB | `" + "0" * 40 + "` |\n"
|
||||
"| [whoopee.zip](u) | Toaplan Whoopee samples | 212 MB | `" + "9" * 40 + "` |\n"
|
||||
)
|
||||
descriptions = {"nand.bin": "BootMii NAND backup"}
|
||||
bundles = {"sdlpal-data.zip": "SDLPAL Chinese Paladin game data (.mkf archives)"}
|
||||
body = check_release_assets.render_notes(
|
||||
db, gitignore, assets, previous, descriptions, bundles, {"sdlpal-data.zip": "d" * 40}
|
||||
)
|
||||
self.assertIn("| [twotiger.zip](https://github.com/Abdess/retrobios/releases/download/large-files/twotiger.zip) | Two Tigers samples | 148 MB | `" + "b" * 40 + "` |", body)
|
||||
self.assertIn("| [nand.bin](https://github.com/Abdess/retrobios/releases/download/large-files/nand.bin) | BootMii NAND backup | 528 MB | `" + "a" * 40 + "` |", body)
|
||||
self.assertIn("| [sdlpal-data.zip](https://github.com/Abdess/retrobios/releases/download/large-files/sdlpal-data.zip) | SDLPAL Chinese Paladin game data (.mkf archives) | 134 MB | `" + "d" * 40 + "` |", body)
|
||||
self.assertIn("## Not indexed", body)
|
||||
self.assertIn("| [whoopee.zip](https://github.com/Abdess/retrobios/releases/download/large-files/whoopee.zip) | Toaplan Whoopee samples | 212 MB |", body)
|
||||
self.assertNotIn("9" * 40, body)
|
||||
self.assertNotIn("small.bin", body)
|
||||
self.assertIn("4 files, 1.0 GB total", body)
|
||||
self.assertEqual(body.index("## Console firmware"), min(
|
||||
body.index(h) for h in ("## Console firmware", "## Arcade", "## Not indexed")
|
||||
))
|
||||
|
||||
def test_stale_notes_are_a_finding(self):
|
||||
from scripts import check_release_assets
|
||||
|
||||
findings = check_release_assets.compare({}, {}, notes_current=False)
|
||||
self.assertEqual(findings, [("notes", "release description", 0, None)])
|
||||
|
||||
def test_pipeline_runs_the_check_online_and_marks_it_skipped_offline(self):
|
||||
source = (ROOT / "scripts" / "pipeline.py").read_text(encoding="utf-8")
|
||||
self.assertIn("check_release_assets.py", source)
|
||||
self.assertIn('results["check_release_assets"] = SKIPPED', source)
|
||||
|
||||
|
||||
class PreservedBytesAreNeverNormalised(unittest.TestCase):
|
||||
"""git must not rewrite a preserved file's line endings.
|
||||
|
||||
@@ -204,6 +204,23 @@ class CloneMapSurvivesASecondRun(_Bios):
|
||||
path = Path(self._tmp.name) / "_mame_clones.json"
|
||||
return json.loads(path.read_text()) if path.exists() else {}
|
||||
|
||||
def test_the_map_is_written_beside_the_scanned_tree_not_the_cwd(self):
|
||||
"""A test or a run from another directory must not touch the repo's map.
|
||||
|
||||
The map was written to the working directory. The test suite runs
|
||||
from the repo root, so a fixture scan of a temporary tree rewrote the
|
||||
committed _mame_clones.json with two fixture entries, and a later
|
||||
rewrite left 2 of its 71 parents.
|
||||
"""
|
||||
elsewhere = Path(self._tmp.name) / "elsewhere"
|
||||
elsewhere.mkdir()
|
||||
os.chdir(elsewhere)
|
||||
self.write("Arcade/MAME/bbc_m87.zip")
|
||||
self.write("Arcade/MAME/bbc_24bbc.zip")
|
||||
self.run_dedup()
|
||||
self.assertFalse((elsewhere / "_mame_clones.json").exists())
|
||||
self.assertIn("bbc_m87.zip", self._map())
|
||||
|
||||
def test_a_recorded_mapping_survives_a_later_run(self):
|
||||
self.write("Arcade/MAME/bbc_m87.zip")
|
||||
self.write("Arcade/MAME/bbc_24bbc.zip")
|
||||
|
||||
@@ -132,6 +132,22 @@ gh release upload large-files "bios/Sony/PS3/PS3UPDAT.PUP#PS3UPDAT.PUP"
|
||||
**Local cache.** `generate_pack.py` calls `fetch_large_file()` which downloads
|
||||
from the release and caches in `.cache/large/` for subsequent runs.
|
||||
|
||||
**Check.** The installer refuses a download whose `Content-Length` differs
|
||||
from the manifest size, and the manifest size is that of the local file. A
|
||||
file rebuilt locally after its upload therefore fails every install until it
|
||||
is uploaded again (`--clobber`). `python scripts/check_release_assets.py`
|
||||
compares every gitignored `bios/` path in the database with the asset of the
|
||||
same name, and the release page with the one it renders from the collection;
|
||||
the online pipeline runs it as step 2b2. To refresh the page:
|
||||
|
||||
```bash
|
||||
python scripts/check_release_assets.py --notes tmp/notes.md
|
||||
gh release edit large-files --notes-file tmp/notes.md
|
||||
```
|
||||
|
||||
An asset no database entry names is listed on the page under "Not indexed",
|
||||
with its size only: the collection vouches for no hash it does not hold.
|
||||
|
||||
## Cutting a release
|
||||
|
||||
Releasing is deliberate and local. Nothing on GitHub builds a pack: the
|
||||
|
||||
Reference in new issue
Block a user