mirror of
https://github.com/Abdess/retroarch_system.git
synced 2026-10-10 13:33:24 -05:00
Compare commits
7
Commits
c64e146a43
...
main
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
527526a8e2 | ||
|
|
f5a5d6f4bd | ||
|
|
840f9ceaf6 | ||
|
|
40b46d1d78 | ||
|
|
6a39264fa6 | ||
|
|
fd8db894d8 | ||
|
|
15842d6402 |
No files matched your search
@@ -68,7 +68,7 @@ These are the files an emulator loads from disk instead of carrying inside itsel
|
||||
|
||||
Each file is checked the way your platform checks it. Most compare a checksum, the fingerprint of a file's contents, which catches a corrupt or unexpected copy. RetroArch, Lakka and RetroPie only look for the filename, because that is all their code does: the Coverage table says which applies to you. Independently of that, the collection records five fingerprints per file, and wherever an emulator's code states an expected size or hash, that value is read from its source and rechecked here.
|
||||
|
||||
- **392 files** the platforms' emulators load are still to be found, and 51 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/)
|
||||
- **393 files** the platforms' emulators load are still to be found, and 51 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
|
||||
- **506 emulators** profiled from source (RetroArch cores + standalone)
|
||||
- **544 systems** handled by those emulators (NES, SNES, PlayStation, Saturn, Dreamcast, ...)
|
||||
@@ -94,10 +94,10 @@ Full list with per-file details: **[https://abdess.github.io/retrobios/](https:/
|
||||
| ROCKNIX | 38/38 | 5,697/5,727 | MD5 hash |
|
||||
| Recalbox | 351/351 | 2,731/2,739 | MD5 hash |
|
||||
| RetroArch | 526/526 | 5,260/5,290 | file presence |
|
||||
| RetroBat | 348/348 | 11,880/12,310 | MD5 hash |
|
||||
| RetroBat | 348/348 | 11,885/12,316 | MD5 hash |
|
||||
| RetroDECK | 2,008/2,008 | 5,400/5,450 | MD5 hash |
|
||||
| RetroPie * | 526/526 | 9,181/9,323 | file presence |
|
||||
| RomM | 381/381 | 748/754 | MD5 hash |
|
||||
| RomM | 381/381 | 753/760 | MD5 hash |
|
||||
|
||||
Each fraction is what the pack has over what is needed, counting required and optional files alike since both ship. The first column is the BIOS list the platform publishes. The second counts files its emulators load that this list never mentions, found by reading their source code, and it is routinely several times larger. A short fraction means files are still missing, and they are named in the [gap analysis](https://abdess.github.io/retrobios/gaps/).
|
||||
That second number is a floor, not a ceiling: an emulator that accepts any file handed to it names none in its code, so nothing there can be counted.
|
||||
@@ -180,4 +180,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-10-10T09:28:18Z*
|
||||
*Auto-generated on 2026-10-10T10:40:24Z*
|
||||
@@ -58,6 +58,7 @@ files:
|
||||
# -------------------------------------------------------
|
||||
- name: ROM311
|
||||
path: Archimedes/ROM311
|
||||
system: acorn-archimedes
|
||||
description: "RISC OS v3.11"
|
||||
size: 2097152
|
||||
crc32: "54c0c963"
|
||||
@@ -78,6 +79,7 @@ files:
|
||||
|
||||
- name: os12.rom
|
||||
path: BBCMicro/os12.rom
|
||||
system: acorn-bbc-micro
|
||||
description: "BBC MOS v1.2"
|
||||
size: 16384
|
||||
crc32: "3c14fc70"
|
||||
@@ -95,6 +97,7 @@ files:
|
||||
|
||||
- name: dfs-2.26.rom
|
||||
path: BBCMicro/dfs-2.26.rom
|
||||
system: acorn-bbc-micro
|
||||
description: "Acorn 1770 DFS 2.26 ROM"
|
||||
size: 16384
|
||||
crc32: "5ae33e94"
|
||||
@@ -104,6 +107,7 @@ files:
|
||||
|
||||
- name: adfs-1.30.rom
|
||||
path: BBCMicro/adfs-1.30.rom
|
||||
system: acorn-bbc-micro
|
||||
description: "Acorn ADFS 1.30 ROM"
|
||||
size: 16384
|
||||
crc32: "d3855588"
|
||||
@@ -113,6 +117,7 @@ files:
|
||||
|
||||
- name: ADT-1.40.rom
|
||||
path: BBCMicro/ADT-1.40.rom
|
||||
system: acorn-bbc-micro
|
||||
description: "Advanced Disc Toolkit 1.40 ROM"
|
||||
size: 16384
|
||||
crc32: "8314fed0"
|
||||
@@ -122,6 +127,7 @@ files:
|
||||
|
||||
- name: TUBE110.rom
|
||||
path: BBCMicro/TUBE110.rom
|
||||
system: acorn-bbc-micro
|
||||
description: "6502 Tube 1.10 Boot ROM"
|
||||
size: 2048
|
||||
crc32: "9ec2dbd0"
|
||||
@@ -131,6 +137,7 @@ files:
|
||||
|
||||
- name: Z80_122.rom
|
||||
path: BBCMicro/Z80_122.rom
|
||||
system: acorn-bbc-micro
|
||||
description: "Z80 Tube 1.22 Boot ROM"
|
||||
size: 4096
|
||||
crc32: "b5851efc"
|
||||
@@ -151,6 +158,7 @@ files:
|
||||
|
||||
- name: os.rom
|
||||
path: Electron/os.rom
|
||||
system: acorn-electron
|
||||
description: "Electron MOS ROM v1.00"
|
||||
size: 16384
|
||||
crc32: "bf63fb1f"
|
||||
@@ -163,6 +171,7 @@ files:
|
||||
|
||||
- name: ADFS-E00_1.rom
|
||||
path: Electron/ADFS-E00_1.rom
|
||||
system: acorn-electron
|
||||
description: "E00 ADFS ROM, first slot"
|
||||
size: 16384
|
||||
crc32: "51523993"
|
||||
@@ -172,6 +181,7 @@ files:
|
||||
|
||||
- name: ADFS-E00_2.rom
|
||||
path: Electron/ADFS-E00_2.rom
|
||||
system: acorn-electron
|
||||
description: "E00 ADFS ROM, second slot"
|
||||
size: 16384
|
||||
crc32: "8d17de0e"
|
||||
@@ -181,6 +191,7 @@ files:
|
||||
|
||||
- name: adfs.rom
|
||||
path: Electron/adfs.rom
|
||||
system: acorn-electron
|
||||
description: "Acorn ADFS ROM"
|
||||
size: 16384
|
||||
crc32: "3289bdc6"
|
||||
@@ -190,6 +201,7 @@ files:
|
||||
|
||||
- name: DFS-1770-2.20.rom
|
||||
path: Electron/DFS-1770-2.20.rom
|
||||
system: acorn-electron
|
||||
description: "1770 DFS ROM"
|
||||
size: 16384
|
||||
crc32: "f3dc9bc5"
|
||||
@@ -208,6 +220,7 @@ files:
|
||||
|
||||
- name: AP6v133.rom
|
||||
path: Electron/AP6v133.rom
|
||||
system: acorn-electron
|
||||
description: "Advanced Plus 6 ROM"
|
||||
size: 7772
|
||||
crc32: "e0013cfc"
|
||||
@@ -220,6 +233,7 @@ files:
|
||||
# -------------------------------------------------------
|
||||
- name: Kickstart-v1.3-rev34.5-1987-Commodore-A500-A1000-A2000-CDTV.rom
|
||||
path: Amiga/Kickstart-v1.3-rev34.5-1987-Commodore-A500-A1000-A2000-CDTV.rom
|
||||
system: amiga
|
||||
description: "A500/A1000/A2000/CDTV Kickstart 1.3 ROM"
|
||||
size: 262144
|
||||
crc32: "c4f0f55f"
|
||||
@@ -232,6 +246,7 @@ files:
|
||||
# -------------------------------------------------------
|
||||
- name: os464.rom
|
||||
path: AmstradCPC/os464.rom
|
||||
system: amstrad-cpc
|
||||
description: "CPC 464 firmware"
|
||||
size: 16384
|
||||
crc32: "815752df"
|
||||
@@ -241,6 +256,7 @@ files:
|
||||
|
||||
- name: basic464.rom
|
||||
path: AmstradCPC/basic464.rom
|
||||
system: amstrad-cpc
|
||||
description: "CPC 464 BASIC ROM"
|
||||
size: 16384
|
||||
crc32: "7d9a3bac"
|
||||
@@ -250,6 +266,7 @@ files:
|
||||
|
||||
- name: os664.rom
|
||||
path: AmstradCPC/os664.rom
|
||||
system: amstrad-cpc
|
||||
description: "CPC 664 firmware"
|
||||
size: 16384
|
||||
crc32: "3f5a6dc4"
|
||||
@@ -259,6 +276,7 @@ files:
|
||||
|
||||
- name: basic664.rom
|
||||
path: AmstradCPC/basic664.rom
|
||||
system: amstrad-cpc
|
||||
description: "CPC 664 BASIC ROM"
|
||||
size: 16384
|
||||
crc32: "32fee492"
|
||||
@@ -268,6 +286,7 @@ files:
|
||||
|
||||
- name: os6128.rom
|
||||
path: AmstradCPC/os6128.rom
|
||||
system: amstrad-cpc
|
||||
description: "CPC 6128 firmware"
|
||||
size: 16384
|
||||
crc32: "0219bb74"
|
||||
@@ -277,6 +296,7 @@ files:
|
||||
|
||||
- name: basic6128.rom
|
||||
path: AmstradCPC/basic6128.rom
|
||||
system: amstrad-cpc
|
||||
description: "CPC 6128 BASIC ROM"
|
||||
size: 16384
|
||||
crc32: "ca6af63d"
|
||||
@@ -286,6 +306,7 @@ files:
|
||||
|
||||
- name: amsdos.rom
|
||||
path: AmstradCPC/amsdos.rom
|
||||
system: amstrad-cpc
|
||||
description: "Amstrad Disk Operating System"
|
||||
size: 16384
|
||||
crc32: "1fe22ecd"
|
||||
@@ -298,6 +319,7 @@ files:
|
||||
# -------------------------------------------------------
|
||||
- name: apple2o.rom
|
||||
path: AppleII/apple2o.rom
|
||||
system: apple-ii
|
||||
description: "Original Apple II ROM"
|
||||
size: 12288
|
||||
crc32: "ba210588"
|
||||
@@ -307,6 +329,7 @@ files:
|
||||
|
||||
- name: apple2.rom
|
||||
path: AppleII/apple2.rom
|
||||
system: apple-ii
|
||||
description: "Apple II+ ROM"
|
||||
size: 12288
|
||||
crc32: "f66f9c26"
|
||||
@@ -316,6 +339,7 @@ files:
|
||||
|
||||
- name: apple2eu.rom
|
||||
path: AppleII/apple2eu.rom
|
||||
system: apple-ii
|
||||
description: "Apple IIe ROM"
|
||||
size: 32768
|
||||
crc32: "e12be18d"
|
||||
@@ -325,6 +349,7 @@ files:
|
||||
|
||||
- name: apple2e.rom
|
||||
path: AppleII/apple2e.rom
|
||||
system: apple-ii
|
||||
description: "Enhanced Apple IIe ROM"
|
||||
size: 32768
|
||||
crc32: "65989942"
|
||||
@@ -334,6 +359,7 @@ files:
|
||||
|
||||
- name: apple2-character.rom
|
||||
path: AppleII/apple2-character.rom
|
||||
system: apple-ii
|
||||
description: "Apple II/II+ character ROM"
|
||||
size: 2048
|
||||
crc32: "64f415c6"
|
||||
@@ -343,6 +369,7 @@ files:
|
||||
|
||||
- name: apple2eu-character.rom
|
||||
path: AppleII/apple2eu-character.rom
|
||||
system: apple-ii
|
||||
description: "Apple IIe character ROM"
|
||||
size: 4096
|
||||
crc32: "816a86f1"
|
||||
@@ -361,6 +388,7 @@ files:
|
||||
|
||||
- name: scsi.rom
|
||||
path: AppleII/scsi.rom
|
||||
system: apple-ii
|
||||
description: "Apple II SCSI card ROM"
|
||||
size: 16384
|
||||
crc32: "5aff85d3"
|
||||
@@ -373,6 +401,7 @@ files:
|
||||
# -------------------------------------------------------
|
||||
- name: apple2gs.rom
|
||||
path: AppleIIgs/apple2gs.rom
|
||||
system: apple-iigs
|
||||
description: "Apple IIgs ROM01"
|
||||
size: 131072
|
||||
crc32: "42f124b0"
|
||||
@@ -382,6 +411,7 @@ files:
|
||||
|
||||
- name: apple2gs.rom2
|
||||
path: AppleIIgs/apple2gs.rom2
|
||||
system: apple-iigs
|
||||
description: "Apple IIgs ROM03"
|
||||
size: 262144
|
||||
crc32: "de7ddf29"
|
||||
@@ -399,6 +429,7 @@ files:
|
||||
|
||||
- name: "341s0632-2"
|
||||
path: "AppleIIgs/341s0632-2"
|
||||
system: apple-iigs
|
||||
description: "Apple IIgs ROM03 ADB microcontroller ROM"
|
||||
size: 4096
|
||||
crc32: "e1c11fb0"
|
||||
@@ -410,6 +441,7 @@ files:
|
||||
# -------------------------------------------------------
|
||||
- name: tos100.img
|
||||
path: AtariST/tos100.img
|
||||
system: atari-st
|
||||
description: "UK TOS 1.00 ROM"
|
||||
size: 196608
|
||||
crc32: "1a586c64"
|
||||
@@ -421,6 +453,7 @@ files:
|
||||
# -------------------------------------------------------
|
||||
- name: coleco.rom
|
||||
path: ColecoVision/coleco.rom
|
||||
system: colecovision
|
||||
description: "ColecoVision BIOS"
|
||||
size: 8192
|
||||
crc32: "3aa93ef3"
|
||||
@@ -455,6 +488,7 @@ files:
|
||||
# -------------------------------------------------------
|
||||
- name: boot-16.rom
|
||||
path: DiskII/boot-16.rom
|
||||
system: apple-ii
|
||||
description: "Disk II 16-sector boot ROM"
|
||||
size: 256
|
||||
crc32: "ce7144f6"
|
||||
@@ -480,6 +514,7 @@ files:
|
||||
|
||||
- name: boot-13.rom
|
||||
path: DiskII/boot-13.rom
|
||||
system: apple-ii
|
||||
description: "Disk II 13-sector boot ROM"
|
||||
size: 256
|
||||
crc32: "d34eb2ff"
|
||||
@@ -501,6 +536,7 @@ files:
|
||||
# -------------------------------------------------------
|
||||
- name: exos10.bin
|
||||
path: Enterprise/exos10.bin
|
||||
system: enterprise-64-128
|
||||
description: "Enterprise EXOS ROM v1.0"
|
||||
size: 32768
|
||||
crc32: "30b26387"
|
||||
@@ -511,6 +547,7 @@ files:
|
||||
|
||||
- name: exos20.bin
|
||||
path: Enterprise/exos20.bin
|
||||
system: enterprise-64-128
|
||||
description: "Enterprise EXOS ROM v2.0"
|
||||
size: 32768
|
||||
crc32: "d421795f"
|
||||
@@ -521,6 +558,7 @@ files:
|
||||
|
||||
- name: exos21.bin
|
||||
path: Enterprise/exos21.bin
|
||||
system: enterprise-64-128
|
||||
description: "Enterprise EXOS ROM v2.1"
|
||||
size: 32768
|
||||
crc32: "982a3b44"
|
||||
@@ -531,6 +569,7 @@ files:
|
||||
|
||||
- name: exos23.bin
|
||||
path: Enterprise/exos23.bin
|
||||
system: enterprise-64-128
|
||||
description: "Enterprise EXOS ROM v2.3"
|
||||
size: 65536
|
||||
crc32: "24838410"
|
||||
@@ -541,6 +580,7 @@ files:
|
||||
|
||||
- name: basic10.bin
|
||||
path: Enterprise/basic10.bin
|
||||
system: enterprise-64-128
|
||||
description: "Enterprise BASIC ROM v1.0"
|
||||
size: 16384
|
||||
crc32: "d62e4fb7"
|
||||
@@ -550,6 +590,7 @@ files:
|
||||
|
||||
- name: "BASIC 1.0 - EPROM 1-2 (198x)(Enterprise).bin"
|
||||
path: "Enterprise/BASIC 1.0 - EPROM 1-2 (198x)(Enterprise).bin"
|
||||
system: enterprise-64-128
|
||||
description: "Enterprise BASIC ROM v1.0, Part 1"
|
||||
size: 8193
|
||||
crc32: "37bf48e1"
|
||||
@@ -559,6 +600,7 @@ files:
|
||||
|
||||
- name: "BASIC 1.0 - EPROM 2-2 (198x)(Enterprise).bin"
|
||||
path: "Enterprise/BASIC 1.0 - EPROM 2-2 (198x)(Enterprise).bin"
|
||||
system: enterprise-64-128
|
||||
description: "Enterprise BASIC ROM v1.0, Part 2"
|
||||
size: 8193
|
||||
crc32: "c5298c79"
|
||||
@@ -568,6 +610,7 @@ files:
|
||||
|
||||
- name: basic11.bin
|
||||
path: Enterprise/basic11.bin
|
||||
system: enterprise-64-128
|
||||
description: "Enterprise BASIC ROM v1.1"
|
||||
size: 16384
|
||||
crc32: "683cf455"
|
||||
@@ -577,6 +620,7 @@ files:
|
||||
|
||||
- name: "BASIC 1.1 - EPROM 1.1 (198x)(Enterprise).bin"
|
||||
path: "Enterprise/BASIC 1.1 - EPROM 1.1 (198x)(Enterprise).bin"
|
||||
system: enterprise-64-128
|
||||
description: "Enterprise BASIC ROM v1.1, with trailing byte"
|
||||
size: 16385
|
||||
crc32: "c96b7602"
|
||||
@@ -586,6 +630,7 @@ files:
|
||||
|
||||
- name: basic21.bin
|
||||
path: Enterprise/basic21.bin
|
||||
system: enterprise-64-128
|
||||
description: "Enterprise BASIC ROM v2.1"
|
||||
size: 16384
|
||||
crc32: "55f96251"
|
||||
@@ -598,6 +643,7 @@ files:
|
||||
|
||||
- name: epdos.bin
|
||||
path: Enterprise/epdos.bin
|
||||
system: enterprise-64-128
|
||||
description: "Enterprise EPDOS ROM"
|
||||
size: 32768
|
||||
crc32: "201319eb"
|
||||
@@ -608,6 +654,7 @@ files:
|
||||
|
||||
- name: exdos.bin
|
||||
path: Enterprise/exdos.bin
|
||||
system: enterprise-64-128
|
||||
description: "Enterprise EXDOS ROM"
|
||||
size: 16384
|
||||
crc32: "e6daa0e9"
|
||||
@@ -621,6 +668,7 @@ files:
|
||||
# -------------------------------------------------------
|
||||
- name: mac128k.rom
|
||||
path: Macintosh/mac128k.rom
|
||||
system: apple-macintosh
|
||||
description: "Macintosh 128k ROM"
|
||||
size: 65536
|
||||
crc32: "6d0c8a28"
|
||||
@@ -630,6 +678,7 @@ files:
|
||||
|
||||
- name: mac512k.rom
|
||||
path: Macintosh/mac512k.rom
|
||||
system: apple-macintosh
|
||||
description: "Macintosh 512k ROM"
|
||||
size: 65536
|
||||
crc32: "cf759e0d"
|
||||
@@ -639,6 +688,7 @@ files:
|
||||
|
||||
- name: macplus.rom
|
||||
path: Macintosh/macplus.rom
|
||||
system: apple-macintosh
|
||||
description: "Macintosh Plus ROM"
|
||||
size: 131072
|
||||
crc32: "b2102e8e"
|
||||
@@ -656,6 +706,7 @@ files:
|
||||
# -------------------------------------------------------
|
||||
- name: bios.sms
|
||||
path: MasterSystem/bios.sms
|
||||
system: sega-mastersystem
|
||||
description: "European/US Master System BIOS"
|
||||
region: [north-america, europe]
|
||||
size: 8192
|
||||
@@ -666,6 +717,7 @@ files:
|
||||
|
||||
- name: japanese-bios.sms
|
||||
path: MasterSystem/japanese-bios.sms
|
||||
system: sega-mastersystem
|
||||
description: "Japanese Master System BIOS"
|
||||
region: [japan]
|
||||
size: 8192
|
||||
@@ -680,6 +732,7 @@ files:
|
||||
- name: msx.rom
|
||||
aliases: [MSX.ROM]
|
||||
path: MSX/MSX.ROM
|
||||
system: microsoft-msx
|
||||
description: "Generic MSX BIOS"
|
||||
size: 32768
|
||||
crc32: "94ee12f3"
|
||||
@@ -689,6 +742,7 @@ files:
|
||||
|
||||
- name: msx-japanese.rom
|
||||
path: MSX/msx-japanese.rom
|
||||
system: microsoft-msx
|
||||
description: "Japanese MSX BIOS"
|
||||
region: [japan]
|
||||
size: 32768
|
||||
@@ -699,6 +753,7 @@ files:
|
||||
|
||||
- name: msx-american.rom
|
||||
path: MSX/msx-american.rom
|
||||
system: microsoft-msx
|
||||
description: "American MSX BIOS"
|
||||
region: [north-america]
|
||||
size: 32768
|
||||
@@ -708,6 +763,7 @@ files:
|
||||
|
||||
- name: msx-european.rom
|
||||
path: MSX/msx-european.rom
|
||||
system: microsoft-msx
|
||||
description: "European MSX BIOS"
|
||||
region: [europe]
|
||||
size: 32768
|
||||
@@ -727,6 +783,7 @@ files:
|
||||
- name: msx2.rom
|
||||
aliases: [MSX2.ROM]
|
||||
path: MSX/MSX2.ROM
|
||||
system: microsoft-msx2
|
||||
description: "Generic MSX2 BIOS"
|
||||
size: 32768
|
||||
crc32: "6cdaf3a5"
|
||||
@@ -737,6 +794,7 @@ files:
|
||||
- name: msx2ext.rom
|
||||
aliases: [MSX2EXT.ROM]
|
||||
path: MSX/MSX2EXT.ROM
|
||||
system: microsoft-msx2
|
||||
description: "MSX2 extension ROM"
|
||||
size: 16384
|
||||
crc32: "66237ecf"
|
||||
@@ -758,6 +816,7 @@ files:
|
||||
# -------------------------------------------------------
|
||||
- name: basic10.rom
|
||||
path: Oric/basic10.rom
|
||||
system: oric
|
||||
description: "Oric BASIC 1.0"
|
||||
size: 16384
|
||||
crc32: "f18710b4"
|
||||
@@ -767,6 +826,7 @@ files:
|
||||
|
||||
- name: basic11.rom
|
||||
path: Oric/basic11.rom
|
||||
system: oric
|
||||
description: "Oric BASIC 1.1"
|
||||
size: 16384
|
||||
crc32: "c3a92bef"
|
||||
@@ -776,6 +836,7 @@ files:
|
||||
|
||||
- name: pravetz.rom
|
||||
path: Oric/pravetz.rom
|
||||
system: oric
|
||||
description: "Pravetz BASIC"
|
||||
size: 16384
|
||||
crc32: "58079502"
|
||||
@@ -785,6 +846,7 @@ files:
|
||||
|
||||
- name: colour.rom
|
||||
path: Oric/colour.rom
|
||||
system: oric
|
||||
description: "Oric colour ROM (128-byte version)"
|
||||
size: 128
|
||||
crc32: "d50fca65"
|
||||
@@ -794,6 +856,7 @@ files:
|
||||
|
||||
- name: ORIC.PAL-PROM-TBP24S10-1ab9b572.bin
|
||||
path: Oric/ORIC.PAL-PROM-TBP24S10-1ab9b572.bin
|
||||
system: oric
|
||||
description: "Oric colour ROM (256-byte version)"
|
||||
size: 256
|
||||
crc32: "1ab9b572"
|
||||
@@ -803,6 +866,7 @@ files:
|
||||
|
||||
- name: PRAVETZ-8D.PAL-PROM-82S129-1576a69b.bin
|
||||
path: Oric/PRAVETZ-8D.PAL-PROM-82S129-1576a69b.bin
|
||||
system: oric
|
||||
description: "Pravetz 8D colour ROM"
|
||||
size: 256
|
||||
crc32: "1576a69b"
|
||||
@@ -812,6 +876,7 @@ files:
|
||||
|
||||
- name: bd500.rom
|
||||
path: Oric/bd500.rom
|
||||
system: oric
|
||||
description: "Oric Byte Drive 500 ROM"
|
||||
size: 8192
|
||||
crc32: "61952e34"
|
||||
@@ -821,6 +886,7 @@ files:
|
||||
|
||||
- name: jasmin.rom
|
||||
path: Oric/jasmin.rom
|
||||
system: oric
|
||||
description: "Oric Jasmin ROM"
|
||||
size: 2048
|
||||
crc32: "37220e89"
|
||||
@@ -830,6 +896,7 @@ files:
|
||||
|
||||
- name: microdisc.rom
|
||||
path: Oric/microdisc.rom
|
||||
system: oric
|
||||
description: "Oric Microdisc ROM"
|
||||
size: 8192
|
||||
crc32: "a9664a9c"
|
||||
@@ -839,6 +906,7 @@ files:
|
||||
|
||||
- name: 8dos.rom
|
||||
path: Oric/8dos.rom
|
||||
system: oric
|
||||
description: "8DOS boot ROM"
|
||||
size: 512
|
||||
crc32: "49a74c06"
|
||||
@@ -851,6 +919,7 @@ files:
|
||||
# -------------------------------------------------------
|
||||
- name: GLABIOS_0.2.5_8T.ROM
|
||||
path: PCCompatible/GLABIOS_0.2.5_8T.ROM
|
||||
system: pc-compatible
|
||||
description: "8088 GLaBIOS 0.2.5"
|
||||
size: 8192
|
||||
crc32: "9576944c"
|
||||
@@ -860,6 +929,7 @@ files:
|
||||
|
||||
- name: GLaTICK_0.8.5_AT.ROM
|
||||
path: PCCompatible/GLaTICK_0.8.5_AT.ROM
|
||||
system: pc-compatible
|
||||
description: "AT GLaTICK 0.8.5 RTC option ROM"
|
||||
size: 2048
|
||||
crc32: "371ea3f1"
|
||||
@@ -869,6 +939,7 @@ files:
|
||||
|
||||
- name: "Phoenix 80286 ROM BIOS Version 3.05.bin"
|
||||
path: "PCCompatible/Phoenix 80286 ROM BIOS Version 3.05.bin"
|
||||
system: pc-compatible
|
||||
description: "Phoenix 80286 BIOS 3.05"
|
||||
size: 32768
|
||||
crc32: "8d0d318a"
|
||||
@@ -878,6 +949,7 @@ files:
|
||||
|
||||
- name: at-bios.bin
|
||||
path: PCCompatible/at-bios.bin
|
||||
system: pc-compatible
|
||||
description: "IBM PC AT BIOS v3"
|
||||
size: 65536
|
||||
crc32: "674426be"
|
||||
@@ -887,6 +959,7 @@ files:
|
||||
|
||||
- name: BIOS_5170_15NOV85_U27_61X9266_27256.BIN
|
||||
path: PCCompatible/BIOS_5170_15NOV85_U27_61X9266_27256.BIN
|
||||
system: pc-compatible
|
||||
description: "IBM PC AT BIOS, Nov 1985, U27 chip"
|
||||
size: 32768
|
||||
crc32: "4995be7a"
|
||||
@@ -896,6 +969,7 @@ files:
|
||||
|
||||
- name: BIOS_5170_15NOV85_U47_61X9265_27256.BIN
|
||||
path: PCCompatible/BIOS_5170_15NOV85_U47_61X9265_27256.BIN
|
||||
system: pc-compatible
|
||||
description: "IBM PC AT BIOS, Nov 1985, U47 chip"
|
||||
size: 32768
|
||||
crc32: "c32713e4"
|
||||
@@ -905,6 +979,7 @@ files:
|
||||
|
||||
- name: CGA.F08
|
||||
path: PCCompatible/CGA.F08
|
||||
system: pc-compatible
|
||||
description: "IBM CGA font"
|
||||
size: 2048
|
||||
crc32: "a362ffe6"
|
||||
@@ -914,6 +989,7 @@ files:
|
||||
|
||||
- name: EUMDA9.F14
|
||||
path: PCCompatible/EUMDA9.F14
|
||||
system: pc-compatible
|
||||
description: "IBM MDA font"
|
||||
size: 3584
|
||||
crc32: "7754882a"
|
||||
@@ -941,6 +1017,7 @@ files:
|
||||
|
||||
- name: ibm-basic-1.10.rom
|
||||
path: PCCompatible/ibm-basic-1.10.rom
|
||||
system: pc-compatible
|
||||
description: "IBM ROM BASIC 1.10"
|
||||
size: 32768
|
||||
crc32: "ebacb791"
|
||||
@@ -953,6 +1030,7 @@ files:
|
||||
# -------------------------------------------------------
|
||||
- name: basic.318006-01.bin
|
||||
path: Plus4/basic.318006-01.bin
|
||||
system: commodore-plus4
|
||||
description: "C16+4 BASIC ROM"
|
||||
size: 16384
|
||||
crc32: "74eaae87"
|
||||
@@ -961,6 +1039,7 @@ files:
|
||||
|
||||
- name: kernal.318004-05.bin
|
||||
path: Plus4/kernal.318004-05.bin
|
||||
system: commodore-plus4
|
||||
description: "C16+4 kernel, PAL-G revision 5"
|
||||
size: 16384
|
||||
crc32: "71c07bd4"
|
||||
@@ -991,6 +1070,7 @@ files:
|
||||
# -------------------------------------------------------
|
||||
- name: mo5-v1.0.rom
|
||||
path: Thomson/mo5-v1.0.rom
|
||||
system: thomson-mo5
|
||||
description: "Thomson MO5 ROM, version 1"
|
||||
size: 16384
|
||||
crc32: "f62d2f3a"
|
||||
@@ -999,6 +1079,7 @@ files:
|
||||
|
||||
- name: mo5-v1.1.rom
|
||||
path: Thomson/mo5-v1.1.rom
|
||||
system: thomson-mo5
|
||||
description: "Thomson MO5 ROM, version 1.1"
|
||||
size: 16384
|
||||
crc32: "237c60bf"
|
||||
@@ -1007,6 +1088,7 @@ files:
|
||||
|
||||
- name: mo6-v1.rom
|
||||
path: Thomson/mo6-v1.rom
|
||||
system: thomson-mo6
|
||||
description: "Thomson MO6 ROM, version 1"
|
||||
size: 65536
|
||||
crc32: "45e859c6"
|
||||
@@ -1015,6 +1097,7 @@ files:
|
||||
|
||||
- name: mo6-v2.rom
|
||||
path: Thomson/mo6-v2.rom
|
||||
system: thomson-mo6
|
||||
description: "Thomson MO6 ROM, version 2"
|
||||
size: 65536
|
||||
crc32: "b4430a3b"
|
||||
@@ -1023,6 +1106,7 @@ files:
|
||||
|
||||
- name: mo6-v3.rom
|
||||
path: Thomson/mo6-v3.rom
|
||||
system: thomson-mo6
|
||||
description: "Thomson MO6 ROM, version 3"
|
||||
size: 65536
|
||||
crc32: "7a012322"
|
||||
@@ -1051,6 +1135,7 @@ files:
|
||||
# -------------------------------------------------------
|
||||
- name: basic.bin
|
||||
path: Vic20/basic.bin
|
||||
system: commodore-vic20
|
||||
description: "VIC-20 BASIC ROM"
|
||||
size: 8192
|
||||
crc32: "db4c43c1"
|
||||
@@ -1059,6 +1144,7 @@ files:
|
||||
|
||||
- name: characters-english.bin
|
||||
path: Vic20/characters-english.bin
|
||||
system: commodore-vic20
|
||||
description: "English-language VIC-20 character ROM"
|
||||
region: [north-america, europe]
|
||||
size: 4096
|
||||
@@ -1069,6 +1155,7 @@ files:
|
||||
|
||||
- name: kernel-pal.bin
|
||||
path: Vic20/kernel-pal.bin
|
||||
system: commodore-vic20
|
||||
description: "English-language PAL VIC-20 kernel ROM"
|
||||
region: [europe]
|
||||
size: 8192
|
||||
@@ -1079,6 +1166,7 @@ files:
|
||||
|
||||
- name: kernel-ntsc.bin
|
||||
path: Vic20/kernel-ntsc.bin
|
||||
system: commodore-vic20
|
||||
description: "English-language NTSC VIC-20 kernel ROM"
|
||||
region: [north-america]
|
||||
size: 8192
|
||||
@@ -1089,6 +1177,7 @@ files:
|
||||
|
||||
- name: characters-danish.bin
|
||||
path: Vic20/characters-danish.bin
|
||||
system: commodore-vic20
|
||||
description: "Danish VIC-20 character ROM"
|
||||
region: [denmark]
|
||||
size: 4096
|
||||
@@ -1099,6 +1188,7 @@ files:
|
||||
|
||||
- name: kernel-danish.bin
|
||||
path: Vic20/kernel-danish.bin
|
||||
system: commodore-vic20
|
||||
description: "Danish VIC-20 kernel ROM"
|
||||
region: [denmark]
|
||||
size: 8192
|
||||
@@ -1109,6 +1199,7 @@ files:
|
||||
|
||||
- name: characters-japanese.bin
|
||||
path: Vic20/characters-japanese.bin
|
||||
system: commodore-vic20
|
||||
description: "Japanese VIC-20 character ROM"
|
||||
region: [japan]
|
||||
size: 4096
|
||||
@@ -1119,6 +1210,7 @@ files:
|
||||
|
||||
- name: kernel-japanese.bin
|
||||
path: Vic20/kernel-japanese.bin
|
||||
system: commodore-vic20
|
||||
description: "Japanese VIC-20 kernel ROM"
|
||||
region: [japan]
|
||||
size: 8192
|
||||
@@ -1129,6 +1221,7 @@ files:
|
||||
|
||||
- name: characters-swedish.bin
|
||||
path: Vic20/characters-swedish.bin
|
||||
system: commodore-vic20
|
||||
description: "Swedish VIC-20 character ROM"
|
||||
region: [sweden]
|
||||
size: 4096
|
||||
@@ -1139,6 +1232,7 @@ files:
|
||||
|
||||
- name: kernel-swedish.bin
|
||||
path: Vic20/kernel-swedish.bin
|
||||
system: commodore-vic20
|
||||
description: "Swedish VIC-20 kernel ROM"
|
||||
region: [sweden]
|
||||
size: 8192
|
||||
@@ -1153,6 +1247,7 @@ files:
|
||||
# -------------------------------------------------------
|
||||
- name: 48.rom
|
||||
path: ZXSpectrum/48.rom
|
||||
system: sinclair-zx-spectrum
|
||||
description: "ZX Spectrum 48K ROM"
|
||||
size: 16384
|
||||
crc32: "ddee531f"
|
||||
@@ -1162,6 +1257,7 @@ files:
|
||||
|
||||
- name: 128.rom
|
||||
path: ZXSpectrum/128.rom
|
||||
system: sinclair-zx-spectrum
|
||||
description: "ZX Spectrum 128K ROM"
|
||||
size: 32768
|
||||
crc32: "2cbe8995"
|
||||
@@ -1171,6 +1267,7 @@ files:
|
||||
|
||||
- name: plus2.rom
|
||||
path: ZXSpectrum/plus2.rom
|
||||
system: sinclair-zx-spectrum
|
||||
description: "ZX Spectrum +2 ROM"
|
||||
size: 32768
|
||||
crc32: "e7a517dc"
|
||||
@@ -1180,6 +1277,7 @@ files:
|
||||
|
||||
- name: plus3.rom
|
||||
path: ZXSpectrum/plus3.rom
|
||||
system: sinclair-zx-spectrum
|
||||
description: "ZX Spectrum +2a/+3 ROM"
|
||||
size: 65536
|
||||
crc32: "96e3c17a"
|
||||
@@ -1193,6 +1291,7 @@ files:
|
||||
# -------------------------------------------------------
|
||||
- name: zx80.rom
|
||||
path: ZX8081/zx80.rom
|
||||
system: sinclair-zx80-81
|
||||
description: "ZX80 BASIC ROM"
|
||||
size: 4096
|
||||
crc32: "4c7fc597"
|
||||
@@ -1202,6 +1301,7 @@ files:
|
||||
|
||||
- name: zx81.rom
|
||||
path: ZX8081/zx81.rom
|
||||
system: sinclair-zx80-81
|
||||
description: "ZX81 BASIC ROM"
|
||||
size: 8192
|
||||
crc32: "4b1dd6eb"
|
||||
|
||||
@@ -135,8 +135,8 @@ files:
|
||||
required: false
|
||||
hle_fallback: true
|
||||
size: 8192
|
||||
validation: [size]
|
||||
known_hash_adler32: "0x66f334fe"
|
||||
validation: [size, adler32]
|
||||
known_hash_adler32: ["0x66f334fe", "0x128ea7a2"]
|
||||
adler32_byteswap: true
|
||||
description: "DSP instruction ROM"
|
||||
note: "DSP LLE only, and LLE aborts when the file is absent or not 8192 bytes. The adler32 is taken over the byte-swapped image and the value here is the Nintendo pair; five replacement pairs are also accepted."
|
||||
@@ -147,12 +147,12 @@ files:
|
||||
required: false
|
||||
hle_fallback: true
|
||||
size: 4096
|
||||
validation: [size]
|
||||
known_hash_adler32: "0xf3b93527"
|
||||
validation: [size, adler32]
|
||||
known_hash_adler32: ["0xf3b93527", "0xa4a575f5"]
|
||||
adler32_byteswap: true
|
||||
description: "DSP coefficient ROM"
|
||||
note: "Read by DSP LLE alongside the instruction ROM, and by the AX ucode under HLE for polyphase resampling, which drops any file that is not 0x1000 bytes and plays on without it."
|
||||
source_ref: "Source/Core/Common/CommonPaths.h:109, Source/Core/Core/HW/DSPLLE/DSPLLE.cpp:120-152, Source/Core/Core/HW/DSPHLE/UCodes/AX.cpp:45-70, Source/Core/Core/DSP/DSPCore.h:49"
|
||||
source_ref: "Source/Core/Common/CommonPaths.h:109, Source/Core/Core/HW/DSPLLE/DSPLLE.cpp:120-152, Source/Core/Core/HW/DSPHLE/UCodes/AX.cpp:45-70, Source/Core/Core/DSP/DSPCore.h:49, Source/Core/Core/DSP/DSPCore.cpp:38-105"
|
||||
|
||||
- name: codehandler.bin
|
||||
path: null
|
||||
|
||||
@@ -171,8 +171,8 @@ files:
|
||||
required: false
|
||||
hle_fallback: true
|
||||
size: 8192
|
||||
validation: [size]
|
||||
known_hash_adler32: "0x66f334fe"
|
||||
validation: [size, adler32]
|
||||
known_hash_adler32: ["0x66f334fe", "0xe789b5a5"]
|
||||
adler32_byteswap: true
|
||||
description: "DSP instruction ROM"
|
||||
note: "DSP LLE only, and a file that is absent or not 8192 bytes fails initialisation, which aborts the emulation thread. The adler32 is taken over the byte-swapped image and the value here is the Nintendo pair; six replacement pairs are also accepted."
|
||||
@@ -183,12 +183,12 @@ files:
|
||||
required: false
|
||||
hle_fallback: true
|
||||
size: 4096
|
||||
validation: [size]
|
||||
known_hash_adler32: "0xf3b93527"
|
||||
validation: [size, adler32]
|
||||
known_hash_adler32: ["0xf3b93527", "0xa4a575f5"]
|
||||
adler32_byteswap: true
|
||||
description: "DSP coefficient ROM"
|
||||
note: "Read by DSP LLE alongside the instruction ROM, and by the AX ucode under HLE for polyphase resampling, which drops any file that is not 0x1000 bytes and plays on without it."
|
||||
source_ref: "Source/Core/Common/CommonPaths.h:121, Source/Core/Core/HW/DSPLLE/DSPLLE.cpp:87-120, Source/Core/Core/HW/DSPHLE/UCodes/AX.cpp:42-69, Source/Core/Core/DSP/DSPCore.h:58"
|
||||
source_ref: "Source/Core/Common/CommonPaths.h:121, Source/Core/Core/HW/DSPLLE/DSPLLE.cpp:87-120, Source/Core/Core/HW/DSPHLE/UCodes/AX.cpp:42-69, Source/Core/Core/DSP/DSPCore.h:58, Source/Core/Core/DSP/DSPCore.cpp:28-102"
|
||||
|
||||
- name: codehandler.bin
|
||||
path: null
|
||||
|
||||
@@ -67,22 +67,22 @@ files:
|
||||
size: 8192
|
||||
required: false
|
||||
hle_fallback: true
|
||||
validation: [size]
|
||||
known_hash_adler32: "0x66f334fe"
|
||||
validation: [size, adler32]
|
||||
known_hash_adler32: ["0x66f334fe", "0xe789b5a5"]
|
||||
adler32_byteswap: true
|
||||
note: "DSP instruction ROM for LLE audio. Free replacement (v0.4) included"
|
||||
source_ref: "Source/Core/Common/CommonPaths.h:136, Source/Core/Core/HW/DSPLLE/DSPLLE.cpp:84-117"
|
||||
source_ref: "Source/Core/Common/CommonPaths.h:136, Source/Core/Core/HW/DSPLLE/DSPLLE.cpp:84-117, Source/Core/Core/DSP/DSPCore.cpp:28-102"
|
||||
|
||||
- name: "dsp_coef.bin"
|
||||
path: "GC/dsp_coef.bin"
|
||||
size: 4096
|
||||
required: false
|
||||
hle_fallback: true
|
||||
validation: [size]
|
||||
known_hash_adler32: "0xf3b93527"
|
||||
validation: [size, adler32]
|
||||
known_hash_adler32: ["0xf3b93527", "0xa4a575f5"]
|
||||
adler32_byteswap: true
|
||||
note: "DSP coefficient ROM for LLE audio and HLE polyphase resampling. Free replacement included"
|
||||
source_ref: "Source/Core/Common/CommonPaths.h:137, Source/Core/Core/DSP/DSPCore.cpp:32-33, Source/Core/Core/HW/DSPHLE/UCodes/AX.cpp:55-62"
|
||||
source_ref: "Source/Core/Common/CommonPaths.h:137, Source/Core/Core/DSP/DSPCore.cpp:32-33, Source/Core/Core/HW/DSPHLE/UCodes/AX.cpp:55-62, Source/Core/Core/DSP/DSPCore.cpp:28-102"
|
||||
|
||||
# -- GameCube Fonts --
|
||||
# Bundled free alternatives exist but have padding differences causing misplaced text.
|
||||
|
||||
+86
-13
@@ -5,38 +5,51 @@ source: "https://github.com/libretro/dosbox-pure"
|
||||
upstream: "https://codeberg.org/schelling/dosbox-pure"
|
||||
logo: "https://raw.githubusercontent.com/schellingb/dosbox-pure/main/images/logo.png"
|
||||
profiled_date: "2026-03-23"
|
||||
source_commit: "a4a0bab7f8931433588f2fcad9045c85b277373d"
|
||||
core_version: "1.0-preview5"
|
||||
source_commit: "cdaea10ce8cac231bc341ca05d4c5e4e5fe0fbd5"
|
||||
core_version: "1.0-preview7"
|
||||
display_name: "DOS (DOSBox-Pure)"
|
||||
cores: [dosbox_pure]
|
||||
systems: [dos]
|
||||
verification: sha1
|
||||
notes: |
|
||||
No BIOS required. MT-32 and SoundFont support is optional for MIDI music.
|
||||
No BIOS required. MT-32, Sound Canvas and SoundFont support is optional for
|
||||
MIDI music.
|
||||
|
||||
ROM scanning (both modes):
|
||||
Recursive scan of system directory for *_CONTROL.ROM and *.SF2/*.SF3.
|
||||
ref: dosbox_pure_libretro.cpp:1399-1410
|
||||
MT-32 requires matched pair: *_CONTROL.ROM + *_PCM.ROM (PCM name derived
|
||||
from CONTROL name by replacing CONTROL with PCM, preserving case).
|
||||
ref: midi_mt32.h:189-199
|
||||
ref: src/gui/midi_mt32.h:189-199
|
||||
ZIP archives also supported — scanned for files by size (65536/131072 =
|
||||
control, 524288/1048576 = PCM), not by name.
|
||||
ref: midi_mt32.h:160-166
|
||||
Files can also be on mounted C: drive (DOSBOX.SF2, MT32_CONTROL.ROM).
|
||||
ref: dosbox_pure_libretro.cpp:2803-2805
|
||||
ref: src/gui/midi_mt32.h:160-166
|
||||
Files can also be on mounted C: drive (DOSBOX.SF2, MT32_CONTROL.ROM,
|
||||
ROM1.BIN).
|
||||
ref: dosbox_pure_libretro.cpp:2806-2813
|
||||
Cache file DOSBoxPureMidiCache.txt written when scan >2s.
|
||||
ref: dosbox_pure_libretro.cpp:1425-1445
|
||||
ref: dosbox_pure_libretro.cpp:1449-1464
|
||||
|
||||
Sound Canvas: the scan also lists every file whose name ends in ROM1.BIN,
|
||||
WAVEROM1.BIN excepted, as "Sound Canvas SC-55". Selected, the Nuked-SC55
|
||||
driver opens it at exactly 32768 bytes, then ROM2, ROM2_ST, ROM_SM,
|
||||
WAVEROM1, WAVEROM2 and WAVEROM3 beside it, spelled with the capitalization
|
||||
and extension of ROM1.BIN. Each file fills the slot its size names. Byte 67
|
||||
of ROM1 selects the model, SC-55mkII/SC-55st, SC-55/SC-155, CM-300/SCC-1,
|
||||
JV-880 or SCB-55, and the sizes the other ROMs must have. The driver does
|
||||
not open without ROM1 and ROM2.
|
||||
ref: dosbox_pure_libretro.cpp:1405, src/gui/midi_sc55.h:38-47,
|
||||
src/gui/midi_sc55.h:71-95, src/gui/midi_sc55.h:97-134
|
||||
|
||||
Bundled MUNT (header-only mt32emu.h) for MT-32 emulation.
|
||||
SHA1+size validation at load: unrecognized ROMs rejected (Synth::open fails).
|
||||
ref: mt32emu.h:2982-2988,3016-3019,5183-5187
|
||||
ref: src/gui/mt32emu.h:2982-2988,3016-3019,5183-5187
|
||||
12 full control ROMs + 2 PCM ROMs supported (no split ROMs in this MUNT).
|
||||
TinySoundFont (tsf.h) for SF2/SF3 playback.
|
||||
No firmware entries in .info file — all MIDI files optional.
|
||||
|
||||
DBP_STANDALONE build mode exists (same MIDI logic, different I/O layer).
|
||||
ref: dosbox_pure_libretro.cpp:81,1590,2302
|
||||
ref: dosbox_pure_libretro.cpp:81,1588,2302
|
||||
|
||||
files:
|
||||
# -- MT-32 Control ROMs (64 KB) --
|
||||
@@ -168,7 +181,7 @@ files:
|
||||
note: >
|
||||
accepted by every MT-32 control ROM, v1.x and v2.x. Each control ROM
|
||||
fixes the PCM size it accepts through its pcmCount: 128 requires this
|
||||
524288 byte image. ref: mt32emu.h:2586-2598,3167,3025
|
||||
524288 byte image. ref: src/gui/mt32emu.h:2586-2598,3167,3025
|
||||
|
||||
- name: "CM32L_PCM.ROM"
|
||||
description: "CM-32L/CM-64/LAPC-I PCM ROM"
|
||||
@@ -183,7 +196,7 @@ files:
|
||||
accepted by the CM-32L and CM-32LN control ROMs, which carry pcmCount
|
||||
256 and require this 1048576 byte image. The alias covers the name
|
||||
derived from CM32LN_CONTROL.ROM.
|
||||
ref: mt32emu.h:2586-2598,3167,3025, midi_mt32.h:194-195
|
||||
ref: src/gui/mt32emu.h:2586-2598,3167,3025, src/gui/midi_mt32.h:194-195
|
||||
|
||||
# -- General MIDI SoundFont --
|
||||
|
||||
@@ -191,8 +204,68 @@ files:
|
||||
description: "General MIDI SoundFont (any .sf2/.sf3 accepted)"
|
||||
required: false
|
||||
hle_fallback: true
|
||||
source_ref: "dosbox_pure_libretro.cpp:1410 (scan classifies .SF* as a SoundFont), dosbox_pure_libretro.cpp:2492-2495 (path taken from the system directory), dosbox_pure_libretro.cpp:2803-2805 (auto-detected on the mounted C: drive)"
|
||||
source_ref: "dosbox_pure_libretro.cpp:1405 (scan classifies .SF* as a SoundFont), dosbox_pure_libretro.cpp:2495-2499 (path taken from the system directory), dosbox_pure_libretro.cpp:2806-2813 (auto-detected on the mounted C: drive)"
|
||||
note: >
|
||||
Any .SF2 or .SF3 file in the system directory works. The core lists all
|
||||
found SoundFonts in the MIDI config dropdown. DOSBOX.SF2 is the conventional
|
||||
name and is also auto-detected when placed inside game content on C: drive.
|
||||
|
||||
# -- Roland SC-55 family ROMs (Nuked-SC55 driver) --
|
||||
|
||||
- name: "ROM1.BIN"
|
||||
path: "SC-55/ROM1.BIN"
|
||||
aliases: ["rom1.bin"]
|
||||
description: "SC-55 family program ROM 1"
|
||||
required: false
|
||||
size: 32768
|
||||
validation: [size]
|
||||
source_ref: "dosbox_pure_libretro.cpp:1405, src/gui/midi_sc55.h:71-75, src/gui/midi_sc55.h:97-101"
|
||||
note: >-
|
||||
Any name ending in ROM1.BIN anywhere under the system directory is
|
||||
listed; byte 67 selects the emulated model.
|
||||
|
||||
- name: "ROM2.BIN"
|
||||
path: "SC-55/ROM2.BIN"
|
||||
aliases: ["rom2.bin", "ROM2_ST.BIN", "rom2_st.bin"]
|
||||
description: "SC-55 family program ROM 2"
|
||||
required: false
|
||||
size: [262144, 524288]
|
||||
validation: [size]
|
||||
source_ref: "src/gui/midi_sc55.h:41, src/gui/midi_sc55.h:78-93, src/gui/midi_sc55.h:95"
|
||||
note: "The driver does not open without ROM1 and ROM2. ROM2_ST fills the same slot when ROM2 did not."
|
||||
|
||||
- name: "ROM_SM.BIN"
|
||||
path: "SC-55/ROM_SM.BIN"
|
||||
aliases: ["rom_sm.bin"]
|
||||
description: "SC-55mkII/SC-55st sub-MCU ROM"
|
||||
required: false
|
||||
size: 4096
|
||||
validation: [size]
|
||||
source_ref: "src/gui/midi_sc55.h:42, src/gui/midi_sc55.h:78-93, src/gui/midi_sc55.h:113-116"
|
||||
|
||||
- name: "WAVEROM1.BIN"
|
||||
path: "SC-55/WAVEROM1.BIN"
|
||||
aliases: ["waverom1.bin"]
|
||||
description: "SC-55 family wave ROM 1"
|
||||
required: false
|
||||
size: [1048576, 2097152]
|
||||
validation: [size]
|
||||
source_ref: "src/gui/midi_sc55.h:43-45, src/gui/midi_sc55.h:78-93, src/gui/midi_sc55.h:111-134"
|
||||
|
||||
- name: "WAVEROM2.BIN"
|
||||
path: "SC-55/WAVEROM2.BIN"
|
||||
aliases: ["waverom2.bin"]
|
||||
description: "SC-55 family wave ROM 2"
|
||||
required: false
|
||||
size: [1048576, 2097152]
|
||||
validation: [size]
|
||||
source_ref: "src/gui/midi_sc55.h:43-45, src/gui/midi_sc55.h:78-93, src/gui/midi_sc55.h:111-134"
|
||||
|
||||
- name: "WAVEROM3.BIN"
|
||||
path: "SC-55/WAVEROM3.BIN"
|
||||
aliases: ["waverom3.bin"]
|
||||
description: "SC-55/SC-155/CM-300 wave ROM 3"
|
||||
required: false
|
||||
size: 1048576
|
||||
validation: [size]
|
||||
source_ref: "src/gui/midi_sc55.h:43-45, src/gui/midi_sc55.h:78-93, src/gui/midi_sc55.h:117-125"
|
||||
@@ -64,22 +64,22 @@ files:
|
||||
size: 8192
|
||||
required: false
|
||||
hle_fallback: true
|
||||
validation: [size]
|
||||
known_hash_adler32: "0x66f334fe"
|
||||
validation: [size, adler32]
|
||||
known_hash_adler32: ["0x66f334fe", "0x128ea7a2"]
|
||||
adler32_byteswap: true
|
||||
note: "DSP instruction ROM for LLE audio. Free replacement included"
|
||||
source_ref: "Source/Core/Common/CommonPaths.h:112, Source/Core/Core/HW/DSPLLE/DSPLLE.cpp:142-150, Source/Core/Core/DSP/DSPCore.cpp:48,67"
|
||||
source_ref: "Source/Core/Common/CommonPaths.h:112, Source/Core/Core/HW/DSPLLE/DSPLLE.cpp:142-150, Source/Core/Core/DSP/DSPCore.cpp:48,67, Source/Core/Core/DSP/DSPCore.cpp:38-105"
|
||||
|
||||
- name: "dsp_coef.bin"
|
||||
path: "GC/dsp_coef.bin"
|
||||
size: 4096
|
||||
required: false
|
||||
hle_fallback: true
|
||||
validation: [size]
|
||||
known_hash_adler32: "0xf3b93527"
|
||||
validation: [size, adler32]
|
||||
known_hash_adler32: ["0xf3b93527", "0xa4a575f5"]
|
||||
adler32_byteswap: true
|
||||
note: "DSP coefficient ROM for LLE audio and HLE polyphase resampling. Free replacement included"
|
||||
source_ref: "Source/Core/Common/CommonPaths.h:113, Source/Core/Core/HW/DSPLLE/DSPLLE.cpp:143-153, Source/Core/Core/HW/DSPHLE/UCodes/AX.cpp:43-72, Source/Core/Core/DSP/DSPCore.cpp:48,68"
|
||||
source_ref: "Source/Core/Common/CommonPaths.h:113, Source/Core/Core/HW/DSPLLE/DSPLLE.cpp:143-153, Source/Core/Core/HW/DSPHLE/UCodes/AX.cpp:43-72, Source/Core/Core/DSP/DSPCore.cpp:48,68, Source/Core/Core/DSP/DSPCore.cpp:38-105"
|
||||
|
||||
# -- GameCube Fonts --
|
||||
# Bundled free alternatives exist but have padding differences causing misplaced text.
|
||||
|
||||
@@ -68,22 +68,22 @@ files:
|
||||
size: 8192
|
||||
required: false
|
||||
hle_fallback: true
|
||||
validation: [size]
|
||||
known_hash_adler32: "0x66f334fe"
|
||||
validation: [size, adler32]
|
||||
known_hash_adler32: ["0x66f334fe", "0xe789b5a5"]
|
||||
adler32_byteswap: true
|
||||
note: "DSP instruction ROM for LLE audio. Free replacement (v0.4) included"
|
||||
source_ref: "Source/Core/Common/CommonPaths.h:135, Source/Core/Core/HW/DSPLLE/DSPLLE.cpp:87-117"
|
||||
source_ref: "Source/Core/Common/CommonPaths.h:135, Source/Core/Core/HW/DSPLLE/DSPLLE.cpp:87-117, Source/Core/Core/DSP/DSPCore.cpp:28-102"
|
||||
|
||||
- name: "dsp_coef.bin"
|
||||
path: "GC/dsp_coef.bin"
|
||||
size: 4096
|
||||
required: false
|
||||
hle_fallback: true
|
||||
validation: [size]
|
||||
known_hash_adler32: "0xf3b93527"
|
||||
validation: [size, adler32]
|
||||
known_hash_adler32: ["0xf3b93527", "0xa4a575f5"]
|
||||
adler32_byteswap: true
|
||||
note: "DSP coefficient ROM for LLE audio. Free replacement included"
|
||||
source_ref: "Source/Core/Common/CommonPaths.h:138, Source/Core/Core/DSP/DSPCore.cpp:32-38"
|
||||
source_ref: "Source/Core/Common/CommonPaths.h:138, Source/Core/Core/DSP/DSPCore.cpp:32-38, Source/Core/Core/DSP/DSPCore.cpp:28-102"
|
||||
|
||||
# -- GameCube Fonts --
|
||||
# Bundled free alternatives exist but have padding differences causing misplaced text.
|
||||
|
||||
@@ -227,12 +227,12 @@ files:
|
||||
path: "GC/dsp_rom.bin"
|
||||
description: "DSP instruction ROM"
|
||||
size: 8192
|
||||
validation: [size]
|
||||
known_hash_adler32: "0x66f334fe"
|
||||
validation: [size, adler32]
|
||||
known_hash_adler32: ["0x66f334fe", "0xe789b5a5"]
|
||||
adler32_byteswap: true
|
||||
required: false
|
||||
hle_fallback: true
|
||||
source_ref: "Source/Core/Common/CommonPaths.h:145, Source/Core/Core/HW/DSPLLE/DSPLLE.cpp:87-105,109-118, Source/Core/Core/DSP/DSPCore.h:44, Source/Core/Core/DSP/DSPCore.cpp:36-38"
|
||||
source_ref: "Source/Core/Common/CommonPaths.h:145, Source/Core/Core/HW/DSPLLE/DSPLLE.cpp:87-105,109-118, Source/Core/Core/DSP/DSPCore.h:44, Source/Core/Core/DSP/DSPCore.cpp:36-38, Source/Core/Core/DSP/DSPCore.cpp:28-102"
|
||||
note: >
|
||||
LoadDSPRom rejects any file whose length differs from DSP_IROM_BYTE_SIZE and
|
||||
swaps every 16 bit word before storing it, so the Adler32 in the source is
|
||||
@@ -245,12 +245,12 @@ files:
|
||||
path: "GC/dsp_coef.bin"
|
||||
description: "DSP coefficient ROM"
|
||||
size: 4096
|
||||
validation: [size]
|
||||
known_hash_adler32: "0xf3b93527"
|
||||
validation: [size, adler32]
|
||||
known_hash_adler32: ["0xf3b93527", "0xa4a575f5"]
|
||||
adler32_byteswap: true
|
||||
required: false
|
||||
hle_fallback: true
|
||||
source_ref: "Source/Core/Common/CommonPaths.h:146, Source/Core/Core/HW/DSPLLE/DSPLLE.cpp:87-105,110-119, Source/Core/Core/DSP/DSPCore.h:58, Source/Core/Core/HW/DSPHLE/UCodes/AX.cpp:61-62"
|
||||
source_ref: "Source/Core/Common/CommonPaths.h:146, Source/Core/Core/HW/DSPLLE/DSPLLE.cpp:87-105,110-119, Source/Core/Core/DSP/DSPCore.h:58, Source/Core/Core/HW/DSPHLE/UCodes/AX.cpp:61-62, Source/Core/Core/DSP/DSPCore.cpp:28-102"
|
||||
note: >
|
||||
Also read by the HLE AX ucode for polyphase resampling. Adler32 is taken over
|
||||
the byte-swapped data (Source/Core/Core/HW/DSPLLE/DSPLLE.cpp:100-102).
|
||||
|
||||
+56
-1034
File diff suppressed because it is too large.
Load diff
+34
-771
File diff suppressed because it is too large.
Load diff
@@ -1036,10 +1036,10 @@
|
||||
},
|
||||
{
|
||||
"dest": "sysdata/otp.bin",
|
||||
"sha1": "f0332b7252e9c01b30bf5d5a63ceb22dc47968aa",
|
||||
"sha256": "93c2e20cc377f2cb0fa9a2ee58c39be22e00baa94b890545e585e53b3eb4039f",
|
||||
"sha1": "49489245b400f62c62faf1736b7f0a70714d3c49",
|
||||
"sha256": "e2f1810ceff3d1fd4f1c08ffc1f4d47aa8efca551edd24cd5686205c71a3b13b",
|
||||
"size": 256,
|
||||
"repo_path": "bios/Nintendo/3DS/Citra/sysdata/otp.bin",
|
||||
"repo_path": "bios/Nintendo/3DS/otp.bin",
|
||||
"cores": [
|
||||
"azahar"
|
||||
],
|
||||
@@ -1270,10 +1270,10 @@
|
||||
},
|
||||
{
|
||||
"dest": "GC/dsp_rom.bin",
|
||||
"sha1": "f4f683a49d7eb4155566f793f2c1c27e90159992",
|
||||
"sha256": "7f33e6600722791ccee5fd15d4330af8d8f74165f7d1ded6738684c0294aaffe",
|
||||
"sha1": "3c6cc6e04fdd0b2a392d7a6ed769455444846be7",
|
||||
"sha256": "49d987ee1eab29a157425b82d54516957a81e1bac247c8834e494642605c3e8c",
|
||||
"size": 8192,
|
||||
"repo_path": "bios/Nintendo/GameCube/Sys/GC/dsp_rom.bin",
|
||||
"repo_path": "bios/Nintendo/GameCube/.variants/dsp_rom.bin.3c6cc6e0",
|
||||
"cores": [
|
||||
"dolphin"
|
||||
],
|
||||
|
||||
+6
-6
@@ -6110,10 +6110,10 @@
|
||||
},
|
||||
{
|
||||
"dest": "sysdata/otp.bin",
|
||||
"sha1": "f0332b7252e9c01b30bf5d5a63ceb22dc47968aa",
|
||||
"sha256": "93c2e20cc377f2cb0fa9a2ee58c39be22e00baa94b890545e585e53b3eb4039f",
|
||||
"sha1": "49489245b400f62c62faf1736b7f0a70714d3c49",
|
||||
"sha256": "e2f1810ceff3d1fd4f1c08ffc1f4d47aa8efca551edd24cd5686205c71a3b13b",
|
||||
"size": 256,
|
||||
"repo_path": "bios/Nintendo/3DS/Citra/sysdata/otp.bin",
|
||||
"repo_path": "bios/Nintendo/3DS/otp.bin",
|
||||
"cores": [
|
||||
"azahar"
|
||||
]
|
||||
@@ -61637,10 +61637,10 @@
|
||||
},
|
||||
{
|
||||
"dest": "GC/dsp_rom.bin",
|
||||
"sha1": "f4f683a49d7eb4155566f793f2c1c27e90159992",
|
||||
"sha256": "7f33e6600722791ccee5fd15d4330af8d8f74165f7d1ded6738684c0294aaffe",
|
||||
"sha1": "3c6cc6e04fdd0b2a392d7a6ed769455444846be7",
|
||||
"sha256": "49d987ee1eab29a157425b82d54516957a81e1bac247c8834e494642605c3e8c",
|
||||
"size": 8192,
|
||||
"repo_path": "bios/Nintendo/GameCube/Sys/GC/dsp_rom.bin",
|
||||
"repo_path": "bios/Nintendo/GameCube/.variants/dsp_rom.bin.3c6cc6e0",
|
||||
"cores": [
|
||||
"dolphin"
|
||||
],
|
||||
|
||||
@@ -9824,10 +9824,10 @@
|
||||
},
|
||||
{
|
||||
"dest": "GC/dsp_rom.bin",
|
||||
"sha1": "f4f683a49d7eb4155566f793f2c1c27e90159992",
|
||||
"sha256": "7f33e6600722791ccee5fd15d4330af8d8f74165f7d1ded6738684c0294aaffe",
|
||||
"sha1": "3c6cc6e04fdd0b2a392d7a6ed769455444846be7",
|
||||
"sha256": "49d987ee1eab29a157425b82d54516957a81e1bac247c8834e494642605c3e8c",
|
||||
"size": 8192,
|
||||
"repo_path": "bios/Nintendo/GameCube/Sys/GC/dsp_rom.bin",
|
||||
"repo_path": "bios/Nintendo/GameCube/.variants/dsp_rom.bin.3c6cc6e0",
|
||||
"cores": [
|
||||
"dolphin"
|
||||
],
|
||||
|
||||
@@ -6349,10 +6349,10 @@
|
||||
},
|
||||
{
|
||||
"dest": "sysdata/otp.bin",
|
||||
"sha1": "f0332b7252e9c01b30bf5d5a63ceb22dc47968aa",
|
||||
"sha256": "93c2e20cc377f2cb0fa9a2ee58c39be22e00baa94b890545e585e53b3eb4039f",
|
||||
"sha1": "49489245b400f62c62faf1736b7f0a70714d3c49",
|
||||
"sha256": "e2f1810ceff3d1fd4f1c08ffc1f4d47aa8efca551edd24cd5686205c71a3b13b",
|
||||
"size": 256,
|
||||
"repo_path": "bios/Nintendo/3DS/Citra/sysdata/otp.bin",
|
||||
"repo_path": "bios/Nintendo/3DS/otp.bin",
|
||||
"cores": [
|
||||
"azahar"
|
||||
]
|
||||
@@ -61876,10 +61876,10 @@
|
||||
},
|
||||
{
|
||||
"dest": "GC/dsp_rom.bin",
|
||||
"sha1": "f4f683a49d7eb4155566f793f2c1c27e90159992",
|
||||
"sha256": "7f33e6600722791ccee5fd15d4330af8d8f74165f7d1ded6738684c0294aaffe",
|
||||
"sha1": "3c6cc6e04fdd0b2a392d7a6ed769455444846be7",
|
||||
"sha256": "49d987ee1eab29a157425b82d54516957a81e1bac247c8834e494642605c3e8c",
|
||||
"size": 8192,
|
||||
"repo_path": "bios/Nintendo/GameCube/Sys/GC/dsp_rom.bin",
|
||||
"repo_path": "bios/Nintendo/GameCube/.variants/dsp_rom.bin.3c6cc6e0",
|
||||
"cores": [
|
||||
"dolphin"
|
||||
],
|
||||
|
||||
+95
-976
File diff suppressed because it is too large.
Load diff
+60
-1128
File diff suppressed because it is too large.
Load diff
@@ -6423,10 +6423,10 @@
|
||||
},
|
||||
{
|
||||
"dest": "sysdata/otp.bin",
|
||||
"sha1": "f0332b7252e9c01b30bf5d5a63ceb22dc47968aa",
|
||||
"sha256": "93c2e20cc377f2cb0fa9a2ee58c39be22e00baa94b890545e585e53b3eb4039f",
|
||||
"sha1": "49489245b400f62c62faf1736b7f0a70714d3c49",
|
||||
"sha256": "e2f1810ceff3d1fd4f1c08ffc1f4d47aa8efca551edd24cd5686205c71a3b13b",
|
||||
"size": 256,
|
||||
"repo_path": "bios/Nintendo/3DS/Citra/sysdata/otp.bin",
|
||||
"repo_path": "bios/Nintendo/3DS/otp.bin",
|
||||
"cores": [
|
||||
"azahar"
|
||||
]
|
||||
@@ -101392,10 +101392,10 @@
|
||||
},
|
||||
{
|
||||
"dest": "GC/dsp_rom.bin",
|
||||
"sha1": "f4f683a49d7eb4155566f793f2c1c27e90159992",
|
||||
"sha256": "7f33e6600722791ccee5fd15d4330af8d8f74165f7d1ded6738684c0294aaffe",
|
||||
"sha1": "3c6cc6e04fdd0b2a392d7a6ed769455444846be7",
|
||||
"sha256": "49d987ee1eab29a157425b82d54516957a81e1bac247c8834e494642605c3e8c",
|
||||
"size": 8192,
|
||||
"repo_path": "bios/Nintendo/GameCube/Sys/GC/dsp_rom.bin",
|
||||
"repo_path": "bios/Nintendo/GameCube/.variants/dsp_rom.bin.3c6cc6e0",
|
||||
"cores": [
|
||||
"dolphin"
|
||||
],
|
||||
|
||||
@@ -801,10 +801,10 @@
|
||||
},
|
||||
{
|
||||
"dest": "sysdata/otp.bin",
|
||||
"sha1": "f0332b7252e9c01b30bf5d5a63ceb22dc47968aa",
|
||||
"sha256": "93c2e20cc377f2cb0fa9a2ee58c39be22e00baa94b890545e585e53b3eb4039f",
|
||||
"sha1": "49489245b400f62c62faf1736b7f0a70714d3c49",
|
||||
"sha256": "e2f1810ceff3d1fd4f1c08ffc1f4d47aa8efca551edd24cd5686205c71a3b13b",
|
||||
"size": 256,
|
||||
"repo_path": "bios/Nintendo/3DS/Citra/sysdata/otp.bin",
|
||||
"repo_path": "bios/Nintendo/3DS/otp.bin",
|
||||
"cores": [
|
||||
"azahar"
|
||||
]
|
||||
@@ -2779,10 +2779,10 @@
|
||||
},
|
||||
{
|
||||
"dest": "GC/dsp_rom.bin",
|
||||
"sha1": "f4f683a49d7eb4155566f793f2c1c27e90159992",
|
||||
"sha256": "7f33e6600722791ccee5fd15d4330af8d8f74165f7d1ded6738684c0294aaffe",
|
||||
"sha1": "3c6cc6e04fdd0b2a392d7a6ed769455444846be7",
|
||||
"sha256": "49d987ee1eab29a157425b82d54516957a81e1bac247c8834e494642605c3e8c",
|
||||
"size": 8192,
|
||||
"repo_path": "bios/Nintendo/GameCube/Sys/GC/dsp_rom.bin",
|
||||
"repo_path": "bios/Nintendo/GameCube/.variants/dsp_rom.bin.3c6cc6e0",
|
||||
"cores": [
|
||||
"dolphin"
|
||||
],
|
||||
|
||||
+112
-925
File diff suppressed because it is too large.
Load diff
@@ -515,9 +515,24 @@
|
||||
"pattern": "^[a-fA-F0-9]{8}$"
|
||||
},
|
||||
"known_hash_adler32": {
|
||||
"type": [
|
||||
"string",
|
||||
"integer"
|
||||
"description": "Adler-32 values the code accepts; a list when several revisions pass.",
|
||||
"oneOf": [
|
||||
{
|
||||
"type": [
|
||||
"string",
|
||||
"integer"
|
||||
]
|
||||
},
|
||||
{
|
||||
"type": "array",
|
||||
"items": {
|
||||
"type": [
|
||||
"string",
|
||||
"integer"
|
||||
]
|
||||
},
|
||||
"minItems": 1
|
||||
}
|
||||
]
|
||||
},
|
||||
"validation": {
|
||||
@@ -648,12 +663,26 @@
|
||||
"if": {
|
||||
"anyOf": [
|
||||
{
|
||||
"required": ["path"],
|
||||
"properties": {"path": {"type": "string", "pattern": "/$"}}
|
||||
"required": [
|
||||
"path"
|
||||
],
|
||||
"properties": {
|
||||
"path": {
|
||||
"type": "string",
|
||||
"pattern": "/$"
|
||||
}
|
||||
}
|
||||
},
|
||||
{
|
||||
"required": ["standalone_path"],
|
||||
"properties": {"standalone_path": {"type": "string", "pattern": "/$"}}
|
||||
"required": [
|
||||
"standalone_path"
|
||||
],
|
||||
"properties": {
|
||||
"standalone_path": {
|
||||
"type": "string",
|
||||
"pattern": "/$"
|
||||
}
|
||||
}
|
||||
}
|
||||
]
|
||||
},
|
||||
|
||||
+10
-7
@@ -88,13 +88,16 @@ class Pack:
|
||||
def get_latest_release() -> dict:
|
||||
"""Fetch latest release info from GitHub API."""
|
||||
url = f"{API}/repos/{REPO}/releases/latest"
|
||||
req = urllib.request.Request(
|
||||
url,
|
||||
headers={
|
||||
"User-Agent": "retrobios-downloader/1.0",
|
||||
"Accept": "application/vnd.github.v3+json",
|
||||
},
|
||||
)
|
||||
headers = {
|
||||
"User-Agent": "retrobios-downloader/1.0",
|
||||
"Accept": "application/vnd.github.v3+json",
|
||||
}
|
||||
# The anonymous quota is 60 calls an hour per address. The token goes to
|
||||
# GitHub's API only: RETROBIOS_API can name any host.
|
||||
token = os.environ.get("GITHUB_TOKEN")
|
||||
if token and urllib.parse.urlsplit(url).hostname == "api.github.com":
|
||||
headers["Authorization"] = f"Bearer {token}"
|
||||
req = urllib.request.Request(url, headers=headers)
|
||||
|
||||
try:
|
||||
with urllib.request.urlopen(req, timeout=30) as resp:
|
||||
|
||||
@@ -1068,6 +1068,16 @@ def generate_pack(
|
||||
)
|
||||
if status in ("not_found", "external", "user_provided") or not local_path:
|
||||
continue
|
||||
# The emulator's own check picks the copy, as for a declared file
|
||||
# and in the emulator pack: the name led RetroArch's GC/dsp_rom.bin
|
||||
# to Dolphin's obsolete v0.3.1 free ROM, beside Nintendo's coef
|
||||
# ROM, a pair Dolphin warns about at every start.
|
||||
local_path, disagreement = validated_choice(
|
||||
fe, local_path, db, validation_index, bios_dir, None, dest,
|
||||
validation_owners,
|
||||
)
|
||||
if disagreement:
|
||||
core_discrepancies.append(f"{full_dest} -{disagreement}")
|
||||
if status == "hash_mismatch":
|
||||
# The core's declared hash comes from its source, the local dump
|
||||
# is what the collection holds. Shipping it keeps the emulator
|
||||
@@ -3100,6 +3110,8 @@ def _manifest_core_entries(
|
||||
pack_only_sizes: list[int],
|
||||
selection: SelectionIndex,
|
||||
required_only: bool = False,
|
||||
validation_index: dict | None = None,
|
||||
owners: dict | None = None,
|
||||
) -> int:
|
||||
"""Add the files a platform's cores need but its list does not name.
|
||||
|
||||
@@ -3153,6 +3165,10 @@ def _manifest_core_entries(
|
||||
[source_emu] if source_emu else [],
|
||||
)
|
||||
continue
|
||||
# The copy the emulator accepts, as the pack ships it.
|
||||
local_path, _disagreement = validated_choice(
|
||||
fe, local_path, db, validation_index or {}, bios_dir, None, dest, owners,
|
||||
)
|
||||
|
||||
source_emu = fe.get("source_profile") or fe.get("source_emulator", "")
|
||||
|
||||
@@ -3479,7 +3495,7 @@ def generate_manifest(
|
||||
zip_contents, offline, region_drops, case_insensitive,
|
||||
seen_destinations, seen_lower, seen_parents, manifest_files,
|
||||
omitted_by_destination, record_omission, pack_only_sizes, selection,
|
||||
required_only,
|
||||
required_only, manifest_validation, manifest_owners,
|
||||
)
|
||||
|
||||
# Phase 3: data directories. The installer does not fetch them, so they
|
||||
@@ -3798,7 +3814,6 @@ from packextras import ( # noqa: E402,F401
|
||||
_detect_extras_prefix,
|
||||
_detect_slug_structure,
|
||||
_map_emulator_to_slug,
|
||||
_emulator_systems_index,
|
||||
_collect_emulator_extras,
|
||||
_extra_system_ids,
|
||||
platform_region_groups,
|
||||
|
||||
@@ -15,22 +15,7 @@ from common import runs_standalone
|
||||
from common import sanitize_pack_path
|
||||
from common import size_fits
|
||||
from validation import read_from_system_dir
|
||||
def _emulator_systems_index(emu_profiles: dict | None) -> dict[str, list[str]]:
|
||||
"""Map both the profile key and its display name to the profile's systems.
|
||||
|
||||
find_undeclared_files reports the display name ("Beetle PSX (Mednafen
|
||||
PSX)"), while the profile dictionary is keyed by slug. A key-only lookup
|
||||
therefore missed almost every core, dropping its files into one shared
|
||||
bucket and losing the per-system grouping the narrowing passes rely on.
|
||||
"""
|
||||
index: dict[str, list[str]] = {}
|
||||
for key, profile in (emu_profiles or {}).items():
|
||||
systems = list(profile.get("systems", []))
|
||||
index[key] = systems
|
||||
display = profile.get("emulator", "")
|
||||
if display:
|
||||
index.setdefault(display, systems)
|
||||
return index
|
||||
|
||||
def _detect_extras_prefix(config: dict, base_dest: str) -> str:
|
||||
"""The prefix core-extra destinations take (may be empty).
|
||||
|
||||
@@ -20,7 +20,12 @@ import urllib.error
|
||||
import urllib.request
|
||||
|
||||
try:
|
||||
from .base_scraper import BaseScraper, BiosRequirement, fetch_github_latest_version
|
||||
from .base_scraper import (
|
||||
BaseScraper,
|
||||
BiosRequirement,
|
||||
fetch_github_latest_version,
|
||||
github_headers,
|
||||
)
|
||||
except ImportError:
|
||||
# Allow running directly: python scripts/scraper/coreinfo_scraper.py
|
||||
import os
|
||||
@@ -30,6 +35,7 @@ except ImportError:
|
||||
BaseScraper,
|
||||
BiosRequirement,
|
||||
fetch_github_latest_version,
|
||||
github_headers,
|
||||
)
|
||||
|
||||
PLATFORM_NAME = "libretro_coreinfo"
|
||||
@@ -209,13 +215,7 @@ class Scraper(BaseScraper):
|
||||
# Use the tree API to get all files at once
|
||||
url = f"{GITHUB_API}/git/trees/master?recursive=1"
|
||||
try:
|
||||
req = urllib.request.Request(
|
||||
url,
|
||||
headers={
|
||||
"User-Agent": "retrobios-scraper/1.0",
|
||||
"Accept": "application/vnd.github.v3+json",
|
||||
},
|
||||
)
|
||||
req = urllib.request.Request(url, headers=github_headers())
|
||||
with urllib.request.urlopen(req, timeout=30) as resp:
|
||||
data = json.loads(resp.read())
|
||||
|
||||
|
||||
@@ -318,7 +318,9 @@ FBNEO_DATS_API = "https://api.github.com/repos/libretro/FBNeo/contents/dats"
|
||||
|
||||
|
||||
def _api_json(url: str) -> object:
|
||||
request = urllib.request.Request(url, headers={"User-Agent": "retrobios"})
|
||||
from .base_scraper import github_headers
|
||||
|
||||
request = urllib.request.Request(url, headers=github_headers())
|
||||
with urllib.request.urlopen(request, timeout=60) as response:
|
||||
return json.load(response)
|
||||
|
||||
|
||||
+118
-6
@@ -56,6 +56,84 @@ def _parse_validation(validation: list | dict | None) -> list[str]:
|
||||
return []
|
||||
|
||||
|
||||
def _entry_rule(emu_name: str, f: dict, checks: set[str]) -> dict:
|
||||
"""One profile entry's own checks, kept apart from the merged view.
|
||||
|
||||
Merged by name, Azahar's crypto check on the 3DS otp.bin judged Cemu's
|
||||
1 KiB Wii U otp.bin, and the variant search handed Cemu the 3DS file.
|
||||
"""
|
||||
def values(field: str) -> set[str]:
|
||||
raw = f.get(field)
|
||||
if not raw or field not in checks:
|
||||
return set()
|
||||
items = raw if isinstance(raw, list) else str(raw).split(",")
|
||||
out = set()
|
||||
for item in items:
|
||||
norm = str(item).strip().lower()
|
||||
if field == "crc32" and norm.startswith("0x"):
|
||||
norm = norm[2:]
|
||||
if norm:
|
||||
out.add(norm)
|
||||
return out
|
||||
|
||||
raw_size = f.get("size") if "size" in checks else None
|
||||
adler = f.get("known_hash_adler32") or f.get("adler32")
|
||||
adler_values = adler if isinstance(adler, list) else [adler] if adler else []
|
||||
return {
|
||||
"emulator": emu_name,
|
||||
"checks": set(checks),
|
||||
"sizes": set(raw_size if isinstance(raw_size, list) else [raw_size])
|
||||
- {None},
|
||||
"min_size": f.get("min_size") if "size" in checks else None,
|
||||
"max_size": f.get("max_size") if "size" in checks else None,
|
||||
"crc32": values("crc32"),
|
||||
"md5": values("md5"),
|
||||
"sha1": values("sha1"),
|
||||
"sha256": values("sha256"),
|
||||
"adler32": {
|
||||
str(v).lower().removeprefix("0x") for v in adler_values if v
|
||||
},
|
||||
"adler32_byteswap": bool(f.get("adler32_byteswap")),
|
||||
"crypto": {c for c in checks if c in _CRYPTO_CHECKS},
|
||||
}
|
||||
|
||||
|
||||
def _rule_failure(
|
||||
rule: dict, local_path: str, filename: str, bios_dir: str, hashes: dict,
|
||||
) -> str | None:
|
||||
"""Why one entry's checks reject a file, or None when they accept it."""
|
||||
actual_size = os.path.getsize(local_path)
|
||||
if rule["sizes"] and actual_size not in rule["sizes"]:
|
||||
accepted = ",".join(str(s) for s in sorted(rule["sizes"]))
|
||||
return f"size mismatch: got {actual_size}, accepted [{accepted}]"
|
||||
if rule["min_size"] is not None and actual_size < rule["min_size"]:
|
||||
return f"size too small: min {rule['min_size']}, got {actual_size}"
|
||||
if rule["max_size"] is not None and actual_size > rule["max_size"]:
|
||||
return f"size too large: max {rule['max_size']}, got {actual_size}"
|
||||
for hash_type in ("crc32", "md5", "sha1", "sha256"):
|
||||
if rule[hash_type]:
|
||||
if not hashes:
|
||||
hashes.update(compute_hashes(local_path))
|
||||
if hashes[hash_type].lower() not in rule[hash_type]:
|
||||
accepted = ",".join(sorted(rule[hash_type]))
|
||||
return f"{hash_type} mismatch: got {hashes[hash_type]}, accepted [{accepted}]"
|
||||
if rule["adler32"]:
|
||||
if rule["adler32_byteswap"]:
|
||||
actual = _adler32_byteswapped(local_path)
|
||||
else:
|
||||
if not hashes:
|
||||
hashes.update(compute_hashes(local_path))
|
||||
actual = hashes["adler32"].lower()
|
||||
if actual not in rule["adler32"]:
|
||||
accepted = ",".join(sorted(rule["adler32"]))
|
||||
return f"adler32 mismatch: got 0x{actual}, accepted [{accepted}]"
|
||||
if rule["crypto"]:
|
||||
from crypto_verify import check_crypto_validation
|
||||
|
||||
return check_crypto_validation(local_path, filename, bios_dir)
|
||||
return None
|
||||
|
||||
|
||||
def _build_validation_index(profiles: dict) -> dict[str, dict]:
|
||||
"""Build per-filename validation rules from emulator profiles.
|
||||
|
||||
@@ -98,7 +176,9 @@ def _build_validation_index(profiles: dict) -> dict[str, dict]:
|
||||
"crypto_only": set(),
|
||||
"emulators": set(),
|
||||
"per_emulator": {},
|
||||
"rules": [],
|
||||
}
|
||||
index[fname]["rules"].append(_entry_rule(emu_name, f, checks))
|
||||
index[fname]["emulators"].add(emu_name)
|
||||
index[fname]["checks"].update(checks)
|
||||
# Track non-reproducible crypto checks
|
||||
@@ -143,8 +223,8 @@ def _build_validation_index(profiles: dict) -> dict[str, dict]:
|
||||
# Adler32 -stored as known_hash_adler32 field (not in validation: list
|
||||
# for Dolphin, but support it in both forms for future profiles)
|
||||
adler_val = f.get("known_hash_adler32") or f.get("adler32")
|
||||
if adler_val:
|
||||
norm = adler_val.lower()
|
||||
for value in adler_val if isinstance(adler_val, list) else [adler_val] if adler_val else []:
|
||||
norm = str(value).lower()
|
||||
if norm.startswith("0x"):
|
||||
norm = norm[2:]
|
||||
index[fname]["adler32"].add(norm)
|
||||
@@ -233,12 +313,18 @@ def check_file_validation(
|
||||
filename: str,
|
||||
validation_index: dict[str, dict],
|
||||
bios_dir: str = "bios",
|
||||
emulators: set[str] | None = None,
|
||||
) -> tuple[str, list[str]] | None:
|
||||
"""Check emulator-level validation on a resolved file.
|
||||
|
||||
Supports: size (exact/min/max), crc32, md5, sha1, adler32,
|
||||
signature (RSA-2048 PKCS1v15 SHA256), crypto (AES-128-CBC + SHA256).
|
||||
|
||||
With ``emulators``, the cores that read the file's destination, each of
|
||||
them must accept it through one of its own entries for the name, the
|
||||
way each runs its own check. Without, the checks of every core naming
|
||||
the file are merged.
|
||||
|
||||
Returns None if all checks pass or no validation applies.
|
||||
Returns (reason, emulators) tuple on failure, where *emulators*
|
||||
lists only those cores whose check actually failed.
|
||||
@@ -246,6 +332,23 @@ def check_file_validation(
|
||||
entry = validation_index.get(filename)
|
||||
if not entry:
|
||||
return None
|
||||
if emulators is not None:
|
||||
hashes: dict = {}
|
||||
failures: dict[str, str] = {}
|
||||
for emu in sorted(emulators):
|
||||
rules = [r for r in entry.get("rules", []) if r["emulator"] == emu]
|
||||
if not rules:
|
||||
continue
|
||||
reasons = [
|
||||
_rule_failure(rule, local_path, filename, bios_dir, hashes)
|
||||
for rule in rules
|
||||
]
|
||||
if all(reasons):
|
||||
failures[emu] = reasons[0]
|
||||
if not failures:
|
||||
return None
|
||||
first = sorted(failures)[0]
|
||||
return failures[first], sorted(failures)
|
||||
checks = entry["checks"]
|
||||
pe = entry.get("per_emulator", {})
|
||||
|
||||
@@ -366,6 +469,7 @@ def find_validated_variant(
|
||||
validation_index: dict,
|
||||
bios_dir: str = "bios",
|
||||
platform_digest: str | None = None,
|
||||
emulators: set[str] | None = None,
|
||||
) -> str | None:
|
||||
"""A held file the emulator's own checks accept, in place of current_path.
|
||||
|
||||
@@ -424,7 +528,9 @@ def find_validated_variant(
|
||||
seen.add(real)
|
||||
if accepted and str(entry.get(platform_digest, "")).lower() not in accepted:
|
||||
continue
|
||||
if check_file_validation(path, fname, validation_index, bios_dir) is None:
|
||||
if check_file_validation(
|
||||
path, fname, validation_index, bios_dir, emulators
|
||||
) is None:
|
||||
return path
|
||||
return None
|
||||
|
||||
@@ -575,18 +681,24 @@ def validated_choice(
|
||||
return local_path, None
|
||||
name = file_entry.get("name", "")
|
||||
rules = validation_index.get(name)
|
||||
judges: set[str] | None = None
|
||||
if rules and owners and destination:
|
||||
owning = _owners_of(destination, name, owners)
|
||||
if owning and not owning & set(rules["emulators"]):
|
||||
if not owning & set(rules["emulators"]):
|
||||
# No core that checks this name reads this destination: PC-98's
|
||||
# bios.rom rules have no say over roms/ibmpcjr/bios.rom.
|
||||
return local_path, None
|
||||
# The cores that read this destination judge it, each by its own
|
||||
# entries.
|
||||
judges = owning & set(rules["emulators"])
|
||||
check = check_file_validation(
|
||||
local_path, file_entry.get("name", ""), validation_index, bios_dir
|
||||
local_path, file_entry.get("name", ""), validation_index, bios_dir, judges
|
||||
)
|
||||
if not check:
|
||||
return local_path, None
|
||||
better = find_validated_variant(
|
||||
file_entry, db, local_path, validation_index, bios_dir,
|
||||
platform_digest=platform_digest,
|
||||
platform_digest=platform_digest, emulators=judges,
|
||||
)
|
||||
if better:
|
||||
return better, None
|
||||
|
||||
+33
-16
@@ -6151,26 +6151,43 @@ struct BurnDriver BurnDrvneogeo = {
|
||||
self.assertIn("sony-playstation", readme)
|
||||
|
||||
def test_extras_group_under_their_system_not_a_shared_bucket(self):
|
||||
"""find_undeclared_files reports the display name, the profiles are
|
||||
keyed by slug; a key-only lookup put nearly every core extra in one
|
||||
bucket and lost the per-system grouping both narrowing passes need."""
|
||||
from generate_pack import _emulator_systems_index
|
||||
"""A core extra competes in its system's group: the chain from the
|
||||
gap report (system, systems) to platform_region_groups, not a
|
||||
dictionary built by hand. Without it every extra stood alone and
|
||||
--region compared nothing."""
|
||||
import hashlib # noqa: PLC0415
|
||||
|
||||
index = _emulator_systems_index(
|
||||
{
|
||||
"beetle_psx": {
|
||||
"emulator": "Beetle PSX (Mednafen PSX)",
|
||||
"systems": ["sony-playstation"],
|
||||
},
|
||||
"beebem": {"emulator": "beebem", "systems": ["bbc-micro-b"]},
|
||||
}
|
||||
from packextras import platform_region_groups # noqa: PLC0415
|
||||
|
||||
files, by_name = {}, {}
|
||||
for name in ("core_us.bin", "core_jp.bin"):
|
||||
payload = name.encode()
|
||||
path = os.path.join(self.bios_dir, name)
|
||||
with open(path, "wb") as handle:
|
||||
handle.write(payload)
|
||||
sha1 = hashlib.sha1(payload).hexdigest()
|
||||
files[sha1] = {"path": path, "name": name, "size": len(payload),
|
||||
"md5": hashlib.md5(payload).hexdigest()}
|
||||
by_name[name] = [sha1]
|
||||
db = {"files": files, "indexes": {"by_name": by_name, "by_md5": {},
|
||||
"by_crc32": {}, "by_path_suffix": {}}}
|
||||
profiles = {"psxcore": {
|
||||
"emulator": "PSX Core (Display Name)", "type": "libretro",
|
||||
"systems": ["sony-playstation"],
|
||||
"files": [{"name": "core_us.bin", "region": ["north-america"]},
|
||||
{"name": "core_jp.bin", "region": ["japan"]}],
|
||||
}}
|
||||
config = {"platform": "P", "cores": ["psxcore"], "base_destination": "system",
|
||||
"systems": {"sony-playstation": {"files": [
|
||||
{"name": "declared.bin", "destination": "declared.bin"}]}}}
|
||||
groups, _ = platform_region_groups(
|
||||
config, config["systems"], self.emulators_dir, db, "system", profiles,
|
||||
)
|
||||
self.assertEqual(index["beetle_psx"], ["sony-playstation"])
|
||||
self.assertEqual(
|
||||
index["Beetle PSX (Mednafen PSX)"], ["sony-playstation"]
|
||||
sorted(groups["sony-playstation"]),
|
||||
[("core_jp.bin", "core_jp.bin"), ("core_us.bin", "core_us.bin"),
|
||||
("declared.bin", "declared.bin")],
|
||||
)
|
||||
self.assertEqual(index["beebem"], ["bbc-micro-b"])
|
||||
self.assertNotIn("_extras", index)
|
||||
|
||||
def test_slot_narrowed_pack_gets_its_own_name(self):
|
||||
names = {
|
||||
|
||||
@@ -26,6 +26,7 @@ from common import ( # noqa: E402
|
||||
load_data_dir_registry,
|
||||
load_database,
|
||||
load_emulator_profiles,
|
||||
resolution_is_hash_exact,
|
||||
resolve_local_file,
|
||||
)
|
||||
|
||||
@@ -36,7 +37,12 @@ def homonyms(claims: list[tuple[str, str, str, str]]) -> list[tuple[str, str, st
|
||||
|
||||
claims: (profile, destination, status, local file).
|
||||
"""
|
||||
by_path = {local for _, _, status, local in claims if status == "path_exact"}
|
||||
# Reached by its path or by its content: a hash is at least as strong a
|
||||
# proof, and an owner that gained a sha1 stopped protecting its file.
|
||||
by_path = {
|
||||
local for _, _, status, local in claims
|
||||
if status == "path_exact" or resolution_is_hash_exact(status)
|
||||
}
|
||||
found = []
|
||||
for profile, dest, status, local in claims:
|
||||
if status != "name_exact" or local not in by_path:
|
||||
@@ -60,6 +66,15 @@ class HomonymRule(unittest.TestCase):
|
||||
homonyms(claims), [("halflife", "valve/pak0.pak", "bios/Q2/baseq2/pak0.pak")]
|
||||
)
|
||||
|
||||
def test_an_owner_proven_by_hash_still_protects_its_file(self):
|
||||
claims = [
|
||||
("quake2", "baseq2/pak0.pak", "sha1_exact", "bios/Q2/baseq2/pak0.pak"),
|
||||
("halflife", "valve/pak0.pak", "name_exact", "bios/Q2/baseq2/pak0.pak"),
|
||||
]
|
||||
self.assertEqual(
|
||||
homonyms(claims), [("halflife", "valve/pak0.pak", "bios/Q2/baseq2/pak0.pak")]
|
||||
)
|
||||
|
||||
def test_a_file_only_ever_found_by_name_is_not_judged(self):
|
||||
claims = [
|
||||
("mame2003", "mame2003/cheat.dat", "name_exact", "bios/Arcade/cheat.dat"),
|
||||
|
||||
@@ -285,5 +285,22 @@ class UnreadableReleaseStopsTheScrape(unittest.TestCase):
|
||||
libretro_scraper.Scraper()._fetch_core_metadata()
|
||||
|
||||
|
||||
|
||||
class EveryGitHubApiCallerSendsTheToken(unittest.TestCase):
|
||||
"""romset_dat_importer and coreinfo_scraper called api.github.com with no
|
||||
token: past the anonymous quota, --fetch failed with 403 while
|
||||
refresh_stale had put a token in their environment."""
|
||||
|
||||
def test_each_module_naming_the_api_reads_the_token(self):
|
||||
scripts = Path(__file__).resolve().parent.parent / "scripts"
|
||||
silent = sorted(
|
||||
str(path.relative_to(scripts))
|
||||
for path in scripts.rglob("*.py")
|
||||
if "api.github.com" in (source := path.read_text(encoding="utf-8"))
|
||||
and "GITHUB_TOKEN" not in source
|
||||
and "github_headers(" not in source
|
||||
)
|
||||
self.assertEqual(silent, [])
|
||||
|
||||
if __name__ == "__main__":
|
||||
unittest.main()
|
||||
@@ -97,8 +97,123 @@ class ValidatedChoice(unittest.TestCase):
|
||||
for call in ast.walk(node)
|
||||
)
|
||||
}
|
||||
self.assertLessEqual({"generate_pack", "generate_manifest"}, callers)
|
||||
self.assertLessEqual(
|
||||
{"generate_pack", "generate_manifest", "_manifest_core_entries"}, callers
|
||||
)
|
||||
|
||||
def test_core_extras_are_judged_too(self):
|
||||
"""The baseline loop judged a platform's own files; the core-extras loop
|
||||
shipped whatever the name found. Both loops live in generate_pack."""
|
||||
tree = ast.parse((REPO_ROOT / "scripts" / "generate_pack.py").read_text(encoding="utf-8"))
|
||||
builder = next(
|
||||
node for node in ast.walk(tree)
|
||||
if isinstance(node, ast.FunctionDef) and node.name == "generate_pack"
|
||||
)
|
||||
calls = [
|
||||
call for call in ast.walk(builder)
|
||||
if isinstance(call, ast.Call) and getattr(call.func, "id", None) == "validated_choice"
|
||||
]
|
||||
self.assertGreaterEqual(len(calls), 2)
|
||||
|
||||
|
||||
class ManifestsServeWhatTheCoreAccepts(unittest.TestCase):
|
||||
"""RetroArch's GC/dsp_rom.bin was Dolphin's obsolete v0.3.1 free ROM while
|
||||
Nintendo's dump, which Dolphin's check accepts, sat in .variants/."""
|
||||
|
||||
def test_no_served_core_file_fails_its_check_beside_a_passing_variant(self):
|
||||
import json # noqa: PLC0415
|
||||
|
||||
from common import load_emulator_profiles, load_platform_config # noqa: PLC0415
|
||||
from generate_pack import _platform_cores # noqa: PLC0415
|
||||
from validation import check_file_validation # noqa: PLC0415
|
||||
|
||||
manifest_path = REPO_ROOT / "install" / "retroarch.json"
|
||||
if not (REPO_ROOT / "database.json").is_file() or not manifest_path.is_file():
|
||||
self.skipTest("database.json or the manifest is not built")
|
||||
db = json.loads((REPO_ROOT / "database.json").read_text(encoding="utf-8"))
|
||||
profiles = load_emulator_profiles(str(REPO_ROOT / "emulators"))
|
||||
config = load_platform_config("retroarch", str(REPO_ROOT / "platforms"))
|
||||
cores = {n: profiles[n] for n in _platform_cores(config, profiles)}
|
||||
index = _build_validation_index(cores)
|
||||
owners = destination_owners(cores)
|
||||
manifest = json.loads(manifest_path.read_text(encoding="utf-8"))
|
||||
wrong = []
|
||||
for entry in manifest["files"]:
|
||||
name = entry["dest"].rsplit("/", 1)[-1]
|
||||
path = entry.get("repo_path")
|
||||
if not entry.get("cores") or not path or name not in index:
|
||||
continue
|
||||
local = str(REPO_ROOT / path)
|
||||
if not Path(local).is_file() or not check_file_validation(local, name, index):
|
||||
continue
|
||||
chosen, _ = validated_choice(
|
||||
{"name": name}, local, db, index, str(REPO_ROOT / "bios"), None,
|
||||
entry["dest"], owners,
|
||||
)
|
||||
if chosen != local:
|
||||
wrong.append(entry["dest"])
|
||||
self.assertEqual(wrong, [])
|
||||
|
||||
|
||||
|
||||
class EachReaderJudgesWithItsOwnRules(unittest.TestCase):
|
||||
"""Merged by name, Azahar's 256-byte 3DS otp.bin rule judged Cemu's 1 KiB
|
||||
Wii U otp.bin, and the variant search gave Cemu the 3DS file."""
|
||||
|
||||
def test_rules_of_another_emulator_do_not_judge(self):
|
||||
from validation import check_file_validation # noqa: PLC0415
|
||||
|
||||
index = _build_validation_index({
|
||||
"azahar": {"files": [{"name": "otp.bin", "path": "sysdata/otp.bin",
|
||||
"size": 256, "validation": ["size"]}]},
|
||||
"cemu": {"files": [{"name": "otp.bin", "path": "Cemu/otp.bin",
|
||||
"size": 1024, "validation": ["size"]}]},
|
||||
})
|
||||
with tempfile.TemporaryDirectory(dir=REPO_ROOT / "tmp") as tmp:
|
||||
wiiu = Path(tmp) / "otp.bin"
|
||||
wiiu.write_bytes(b"w" * 1024)
|
||||
self.assertIsNone(check_file_validation(str(wiiu), "otp.bin", index, tmp, {"cemu"}))
|
||||
self.assertIsNotNone(check_file_validation(str(wiiu), "otp.bin", index, tmp, {"azahar"}))
|
||||
|
||||
def test_one_of_an_emulators_entries_is_enough(self):
|
||||
from validation import check_file_validation # noqa: PLC0415
|
||||
|
||||
index = _build_validation_index({"raze": {"files": [
|
||||
{"name": "SW.GRP", "size": 100, "validation": ["size"]},
|
||||
{"name": "SW.GRP", "size": 200, "validation": ["size"]},
|
||||
]}})
|
||||
with tempfile.TemporaryDirectory(dir=REPO_ROOT / "tmp") as tmp:
|
||||
grp = Path(tmp) / "SW.GRP"
|
||||
grp.write_bytes(b"s" * 200)
|
||||
self.assertIsNone(check_file_validation(str(grp), "SW.GRP", index, tmp, {"raze"}))
|
||||
|
||||
|
||||
class DolphinForksJudgeTheirOwnDspTable(unittest.TestCase):
|
||||
"""VerifyRoms (Source/Core/Core/DSP/DSPCore.cpp) accepts, without a prompt,
|
||||
Nintendo's pair and the newest free pair its table knows: v0.4 in
|
||||
Dolphin, PrimeHack, MMJR2 and Triforce, v0.3.1 in MMJR and Ishiiruka,
|
||||
whose table stops there. Adler-32 over the byte-swapped words."""
|
||||
|
||||
FREE_V04 = REPO_ROOT / "data" / "dolphin-sys" / "GC" / "dsp_rom.bin"
|
||||
FREE_V031 = REPO_ROOT / "bios" / "Nintendo" / "GameCube" / "Sys" / "GC" / "dsp_rom.bin"
|
||||
|
||||
def test_each_fork_accepts_its_own_free_rom(self):
|
||||
from common import load_emulator_profiles # noqa: PLC0415
|
||||
from validation import check_file_validation # noqa: PLC0415
|
||||
|
||||
if not self.FREE_V04.is_file() or not self.FREE_V031.is_file():
|
||||
self.skipTest("free DSP ROMs not present")
|
||||
profiles = load_emulator_profiles(str(REPO_ROOT / "emulators"))
|
||||
expect = {"dolphin": "v04", "primehack": "v04", "dolphin-mmjr2": "v04",
|
||||
"triforce": "v04", "dolphin-mmjr": "v031", "ishiiruka": "v031"}
|
||||
for name, accepted in expect.items():
|
||||
index = _build_validation_index({name: profiles[name]})
|
||||
with self.subTest(emulator=name):
|
||||
for label, path in (("v04", self.FREE_V04), ("v031", self.FREE_V031)):
|
||||
verdict = check_file_validation(
|
||||
str(path), "dsp_rom.bin", index, "bios", {name}
|
||||
)
|
||||
self.assertEqual(verdict is None, label == accepted, label)
|
||||
|
||||
if __name__ == "__main__":
|
||||
unittest.main()
|
||||
Reference in new issue
Block a user