7 Commits
31 changed files with 988 additions and 4982 deletions

No files matched your search

+4 -4
View File
@@ -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. 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 - **12 platforms** supported with platform-specific verification
- **506 emulators** profiled from source (RetroArch cores + standalone) - **506 emulators** profiled from source (RetroArch cores + standalone)
- **544 systems** handled by those emulators (NES, SNES, PlayStation, Saturn, Dreamcast, ...) - **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 | | ROCKNIX | 38/38 | 5,697/5,727 | MD5 hash |
| Recalbox | 351/351 | 2,731/2,739 | MD5 hash | | Recalbox | 351/351 | 2,731/2,739 | MD5 hash |
| RetroArch | 526/526 | 5,260/5,290 | file presence | | 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 | | RetroDECK | 2,008/2,008 | 5,400/5,450 | MD5 hash |
| RetroPie * | 526/526 | 9,181/9,323 | file presence | | 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/). 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. 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 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). 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*
+100
View File
@@ -58,6 +58,7 @@ files:
# ------------------------------------------------------- # -------------------------------------------------------
- name: ROM311 - name: ROM311
path: Archimedes/ROM311 path: Archimedes/ROM311
system: acorn-archimedes
description: "RISC OS v3.11" description: "RISC OS v3.11"
size: 2097152 size: 2097152
crc32: "54c0c963" crc32: "54c0c963"
@@ -78,6 +79,7 @@ files:
- name: os12.rom - name: os12.rom
path: BBCMicro/os12.rom path: BBCMicro/os12.rom
system: acorn-bbc-micro
description: "BBC MOS v1.2" description: "BBC MOS v1.2"
size: 16384 size: 16384
crc32: "3c14fc70" crc32: "3c14fc70"
@@ -95,6 +97,7 @@ files:
- name: dfs-2.26.rom - name: dfs-2.26.rom
path: BBCMicro/dfs-2.26.rom path: BBCMicro/dfs-2.26.rom
system: acorn-bbc-micro
description: "Acorn 1770 DFS 2.26 ROM" description: "Acorn 1770 DFS 2.26 ROM"
size: 16384 size: 16384
crc32: "5ae33e94" crc32: "5ae33e94"
@@ -104,6 +107,7 @@ files:
- name: adfs-1.30.rom - name: adfs-1.30.rom
path: BBCMicro/adfs-1.30.rom path: BBCMicro/adfs-1.30.rom
system: acorn-bbc-micro
description: "Acorn ADFS 1.30 ROM" description: "Acorn ADFS 1.30 ROM"
size: 16384 size: 16384
crc32: "d3855588" crc32: "d3855588"
@@ -113,6 +117,7 @@ files:
- name: ADT-1.40.rom - name: ADT-1.40.rom
path: BBCMicro/ADT-1.40.rom path: BBCMicro/ADT-1.40.rom
system: acorn-bbc-micro
description: "Advanced Disc Toolkit 1.40 ROM" description: "Advanced Disc Toolkit 1.40 ROM"
size: 16384 size: 16384
crc32: "8314fed0" crc32: "8314fed0"
@@ -122,6 +127,7 @@ files:
- name: TUBE110.rom - name: TUBE110.rom
path: BBCMicro/TUBE110.rom path: BBCMicro/TUBE110.rom
system: acorn-bbc-micro
description: "6502 Tube 1.10 Boot ROM" description: "6502 Tube 1.10 Boot ROM"
size: 2048 size: 2048
crc32: "9ec2dbd0" crc32: "9ec2dbd0"
@@ -131,6 +137,7 @@ files:
- name: Z80_122.rom - name: Z80_122.rom
path: BBCMicro/Z80_122.rom path: BBCMicro/Z80_122.rom
system: acorn-bbc-micro
description: "Z80 Tube 1.22 Boot ROM" description: "Z80 Tube 1.22 Boot ROM"
size: 4096 size: 4096
crc32: "b5851efc" crc32: "b5851efc"
@@ -151,6 +158,7 @@ files:
- name: os.rom - name: os.rom
path: Electron/os.rom path: Electron/os.rom
system: acorn-electron
description: "Electron MOS ROM v1.00" description: "Electron MOS ROM v1.00"
size: 16384 size: 16384
crc32: "bf63fb1f" crc32: "bf63fb1f"
@@ -163,6 +171,7 @@ files:
- name: ADFS-E00_1.rom - name: ADFS-E00_1.rom
path: Electron/ADFS-E00_1.rom path: Electron/ADFS-E00_1.rom
system: acorn-electron
description: "E00 ADFS ROM, first slot" description: "E00 ADFS ROM, first slot"
size: 16384 size: 16384
crc32: "51523993" crc32: "51523993"
@@ -172,6 +181,7 @@ files:
- name: ADFS-E00_2.rom - name: ADFS-E00_2.rom
path: Electron/ADFS-E00_2.rom path: Electron/ADFS-E00_2.rom
system: acorn-electron
description: "E00 ADFS ROM, second slot" description: "E00 ADFS ROM, second slot"
size: 16384 size: 16384
crc32: "8d17de0e" crc32: "8d17de0e"
@@ -181,6 +191,7 @@ files:
- name: adfs.rom - name: adfs.rom
path: Electron/adfs.rom path: Electron/adfs.rom
system: acorn-electron
description: "Acorn ADFS ROM" description: "Acorn ADFS ROM"
size: 16384 size: 16384
crc32: "3289bdc6" crc32: "3289bdc6"
@@ -190,6 +201,7 @@ files:
- name: DFS-1770-2.20.rom - name: DFS-1770-2.20.rom
path: Electron/DFS-1770-2.20.rom path: Electron/DFS-1770-2.20.rom
system: acorn-electron
description: "1770 DFS ROM" description: "1770 DFS ROM"
size: 16384 size: 16384
crc32: "f3dc9bc5" crc32: "f3dc9bc5"
@@ -208,6 +220,7 @@ files:
- name: AP6v133.rom - name: AP6v133.rom
path: Electron/AP6v133.rom path: Electron/AP6v133.rom
system: acorn-electron
description: "Advanced Plus 6 ROM" description: "Advanced Plus 6 ROM"
size: 7772 size: 7772
crc32: "e0013cfc" crc32: "e0013cfc"
@@ -220,6 +233,7 @@ files:
# ------------------------------------------------------- # -------------------------------------------------------
- name: Kickstart-v1.3-rev34.5-1987-Commodore-A500-A1000-A2000-CDTV.rom - 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 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" description: "A500/A1000/A2000/CDTV Kickstart 1.3 ROM"
size: 262144 size: 262144
crc32: "c4f0f55f" crc32: "c4f0f55f"
@@ -232,6 +246,7 @@ files:
# ------------------------------------------------------- # -------------------------------------------------------
- name: os464.rom - name: os464.rom
path: AmstradCPC/os464.rom path: AmstradCPC/os464.rom
system: amstrad-cpc
description: "CPC 464 firmware" description: "CPC 464 firmware"
size: 16384 size: 16384
crc32: "815752df" crc32: "815752df"
@@ -241,6 +256,7 @@ files:
- name: basic464.rom - name: basic464.rom
path: AmstradCPC/basic464.rom path: AmstradCPC/basic464.rom
system: amstrad-cpc
description: "CPC 464 BASIC ROM" description: "CPC 464 BASIC ROM"
size: 16384 size: 16384
crc32: "7d9a3bac" crc32: "7d9a3bac"
@@ -250,6 +266,7 @@ files:
- name: os664.rom - name: os664.rom
path: AmstradCPC/os664.rom path: AmstradCPC/os664.rom
system: amstrad-cpc
description: "CPC 664 firmware" description: "CPC 664 firmware"
size: 16384 size: 16384
crc32: "3f5a6dc4" crc32: "3f5a6dc4"
@@ -259,6 +276,7 @@ files:
- name: basic664.rom - name: basic664.rom
path: AmstradCPC/basic664.rom path: AmstradCPC/basic664.rom
system: amstrad-cpc
description: "CPC 664 BASIC ROM" description: "CPC 664 BASIC ROM"
size: 16384 size: 16384
crc32: "32fee492" crc32: "32fee492"
@@ -268,6 +286,7 @@ files:
- name: os6128.rom - name: os6128.rom
path: AmstradCPC/os6128.rom path: AmstradCPC/os6128.rom
system: amstrad-cpc
description: "CPC 6128 firmware" description: "CPC 6128 firmware"
size: 16384 size: 16384
crc32: "0219bb74" crc32: "0219bb74"
@@ -277,6 +296,7 @@ files:
- name: basic6128.rom - name: basic6128.rom
path: AmstradCPC/basic6128.rom path: AmstradCPC/basic6128.rom
system: amstrad-cpc
description: "CPC 6128 BASIC ROM" description: "CPC 6128 BASIC ROM"
size: 16384 size: 16384
crc32: "ca6af63d" crc32: "ca6af63d"
@@ -286,6 +306,7 @@ files:
- name: amsdos.rom - name: amsdos.rom
path: AmstradCPC/amsdos.rom path: AmstradCPC/amsdos.rom
system: amstrad-cpc
description: "Amstrad Disk Operating System" description: "Amstrad Disk Operating System"
size: 16384 size: 16384
crc32: "1fe22ecd" crc32: "1fe22ecd"
@@ -298,6 +319,7 @@ files:
# ------------------------------------------------------- # -------------------------------------------------------
- name: apple2o.rom - name: apple2o.rom
path: AppleII/apple2o.rom path: AppleII/apple2o.rom
system: apple-ii
description: "Original Apple II ROM" description: "Original Apple II ROM"
size: 12288 size: 12288
crc32: "ba210588" crc32: "ba210588"
@@ -307,6 +329,7 @@ files:
- name: apple2.rom - name: apple2.rom
path: AppleII/apple2.rom path: AppleII/apple2.rom
system: apple-ii
description: "Apple II+ ROM" description: "Apple II+ ROM"
size: 12288 size: 12288
crc32: "f66f9c26" crc32: "f66f9c26"
@@ -316,6 +339,7 @@ files:
- name: apple2eu.rom - name: apple2eu.rom
path: AppleII/apple2eu.rom path: AppleII/apple2eu.rom
system: apple-ii
description: "Apple IIe ROM" description: "Apple IIe ROM"
size: 32768 size: 32768
crc32: "e12be18d" crc32: "e12be18d"
@@ -325,6 +349,7 @@ files:
- name: apple2e.rom - name: apple2e.rom
path: AppleII/apple2e.rom path: AppleII/apple2e.rom
system: apple-ii
description: "Enhanced Apple IIe ROM" description: "Enhanced Apple IIe ROM"
size: 32768 size: 32768
crc32: "65989942" crc32: "65989942"
@@ -334,6 +359,7 @@ files:
- name: apple2-character.rom - name: apple2-character.rom
path: AppleII/apple2-character.rom path: AppleII/apple2-character.rom
system: apple-ii
description: "Apple II/II+ character ROM" description: "Apple II/II+ character ROM"
size: 2048 size: 2048
crc32: "64f415c6" crc32: "64f415c6"
@@ -343,6 +369,7 @@ files:
- name: apple2eu-character.rom - name: apple2eu-character.rom
path: AppleII/apple2eu-character.rom path: AppleII/apple2eu-character.rom
system: apple-ii
description: "Apple IIe character ROM" description: "Apple IIe character ROM"
size: 4096 size: 4096
crc32: "816a86f1" crc32: "816a86f1"
@@ -361,6 +388,7 @@ files:
- name: scsi.rom - name: scsi.rom
path: AppleII/scsi.rom path: AppleII/scsi.rom
system: apple-ii
description: "Apple II SCSI card ROM" description: "Apple II SCSI card ROM"
size: 16384 size: 16384
crc32: "5aff85d3" crc32: "5aff85d3"
@@ -373,6 +401,7 @@ files:
# ------------------------------------------------------- # -------------------------------------------------------
- name: apple2gs.rom - name: apple2gs.rom
path: AppleIIgs/apple2gs.rom path: AppleIIgs/apple2gs.rom
system: apple-iigs
description: "Apple IIgs ROM01" description: "Apple IIgs ROM01"
size: 131072 size: 131072
crc32: "42f124b0" crc32: "42f124b0"
@@ -382,6 +411,7 @@ files:
- name: apple2gs.rom2 - name: apple2gs.rom2
path: AppleIIgs/apple2gs.rom2 path: AppleIIgs/apple2gs.rom2
system: apple-iigs
description: "Apple IIgs ROM03" description: "Apple IIgs ROM03"
size: 262144 size: 262144
crc32: "de7ddf29" crc32: "de7ddf29"
@@ -399,6 +429,7 @@ files:
- name: "341s0632-2" - name: "341s0632-2"
path: "AppleIIgs/341s0632-2" path: "AppleIIgs/341s0632-2"
system: apple-iigs
description: "Apple IIgs ROM03 ADB microcontroller ROM" description: "Apple IIgs ROM03 ADB microcontroller ROM"
size: 4096 size: 4096
crc32: "e1c11fb0" crc32: "e1c11fb0"
@@ -410,6 +441,7 @@ files:
# ------------------------------------------------------- # -------------------------------------------------------
- name: tos100.img - name: tos100.img
path: AtariST/tos100.img path: AtariST/tos100.img
system: atari-st
description: "UK TOS 1.00 ROM" description: "UK TOS 1.00 ROM"
size: 196608 size: 196608
crc32: "1a586c64" crc32: "1a586c64"
@@ -421,6 +453,7 @@ files:
# ------------------------------------------------------- # -------------------------------------------------------
- name: coleco.rom - name: coleco.rom
path: ColecoVision/coleco.rom path: ColecoVision/coleco.rom
system: colecovision
description: "ColecoVision BIOS" description: "ColecoVision BIOS"
size: 8192 size: 8192
crc32: "3aa93ef3" crc32: "3aa93ef3"
@@ -455,6 +488,7 @@ files:
# ------------------------------------------------------- # -------------------------------------------------------
- name: boot-16.rom - name: boot-16.rom
path: DiskII/boot-16.rom path: DiskII/boot-16.rom
system: apple-ii
description: "Disk II 16-sector boot ROM" description: "Disk II 16-sector boot ROM"
size: 256 size: 256
crc32: "ce7144f6" crc32: "ce7144f6"
@@ -480,6 +514,7 @@ files:
- name: boot-13.rom - name: boot-13.rom
path: DiskII/boot-13.rom path: DiskII/boot-13.rom
system: apple-ii
description: "Disk II 13-sector boot ROM" description: "Disk II 13-sector boot ROM"
size: 256 size: 256
crc32: "d34eb2ff" crc32: "d34eb2ff"
@@ -501,6 +536,7 @@ files:
# ------------------------------------------------------- # -------------------------------------------------------
- name: exos10.bin - name: exos10.bin
path: Enterprise/exos10.bin path: Enterprise/exos10.bin
system: enterprise-64-128
description: "Enterprise EXOS ROM v1.0" description: "Enterprise EXOS ROM v1.0"
size: 32768 size: 32768
crc32: "30b26387" crc32: "30b26387"
@@ -511,6 +547,7 @@ files:
- name: exos20.bin - name: exos20.bin
path: Enterprise/exos20.bin path: Enterprise/exos20.bin
system: enterprise-64-128
description: "Enterprise EXOS ROM v2.0" description: "Enterprise EXOS ROM v2.0"
size: 32768 size: 32768
crc32: "d421795f" crc32: "d421795f"
@@ -521,6 +558,7 @@ files:
- name: exos21.bin - name: exos21.bin
path: Enterprise/exos21.bin path: Enterprise/exos21.bin
system: enterprise-64-128
description: "Enterprise EXOS ROM v2.1" description: "Enterprise EXOS ROM v2.1"
size: 32768 size: 32768
crc32: "982a3b44" crc32: "982a3b44"
@@ -531,6 +569,7 @@ files:
- name: exos23.bin - name: exos23.bin
path: Enterprise/exos23.bin path: Enterprise/exos23.bin
system: enterprise-64-128
description: "Enterprise EXOS ROM v2.3" description: "Enterprise EXOS ROM v2.3"
size: 65536 size: 65536
crc32: "24838410" crc32: "24838410"
@@ -541,6 +580,7 @@ files:
- name: basic10.bin - name: basic10.bin
path: Enterprise/basic10.bin path: Enterprise/basic10.bin
system: enterprise-64-128
description: "Enterprise BASIC ROM v1.0" description: "Enterprise BASIC ROM v1.0"
size: 16384 size: 16384
crc32: "d62e4fb7" crc32: "d62e4fb7"
@@ -550,6 +590,7 @@ files:
- name: "BASIC 1.0 - EPROM 1-2 (198x)(Enterprise).bin" - name: "BASIC 1.0 - EPROM 1-2 (198x)(Enterprise).bin"
path: "Enterprise/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" description: "Enterprise BASIC ROM v1.0, Part 1"
size: 8193 size: 8193
crc32: "37bf48e1" crc32: "37bf48e1"
@@ -559,6 +600,7 @@ files:
- name: "BASIC 1.0 - EPROM 2-2 (198x)(Enterprise).bin" - name: "BASIC 1.0 - EPROM 2-2 (198x)(Enterprise).bin"
path: "Enterprise/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" description: "Enterprise BASIC ROM v1.0, Part 2"
size: 8193 size: 8193
crc32: "c5298c79" crc32: "c5298c79"
@@ -568,6 +610,7 @@ files:
- name: basic11.bin - name: basic11.bin
path: Enterprise/basic11.bin path: Enterprise/basic11.bin
system: enterprise-64-128
description: "Enterprise BASIC ROM v1.1" description: "Enterprise BASIC ROM v1.1"
size: 16384 size: 16384
crc32: "683cf455" crc32: "683cf455"
@@ -577,6 +620,7 @@ files:
- name: "BASIC 1.1 - EPROM 1.1 (198x)(Enterprise).bin" - name: "BASIC 1.1 - EPROM 1.1 (198x)(Enterprise).bin"
path: "Enterprise/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" description: "Enterprise BASIC ROM v1.1, with trailing byte"
size: 16385 size: 16385
crc32: "c96b7602" crc32: "c96b7602"
@@ -586,6 +630,7 @@ files:
- name: basic21.bin - name: basic21.bin
path: Enterprise/basic21.bin path: Enterprise/basic21.bin
system: enterprise-64-128
description: "Enterprise BASIC ROM v2.1" description: "Enterprise BASIC ROM v2.1"
size: 16384 size: 16384
crc32: "55f96251" crc32: "55f96251"
@@ -598,6 +643,7 @@ files:
- name: epdos.bin - name: epdos.bin
path: Enterprise/epdos.bin path: Enterprise/epdos.bin
system: enterprise-64-128
description: "Enterprise EPDOS ROM" description: "Enterprise EPDOS ROM"
size: 32768 size: 32768
crc32: "201319eb" crc32: "201319eb"
@@ -608,6 +654,7 @@ files:
- name: exdos.bin - name: exdos.bin
path: Enterprise/exdos.bin path: Enterprise/exdos.bin
system: enterprise-64-128
description: "Enterprise EXDOS ROM" description: "Enterprise EXDOS ROM"
size: 16384 size: 16384
crc32: "e6daa0e9" crc32: "e6daa0e9"
@@ -621,6 +668,7 @@ files:
# ------------------------------------------------------- # -------------------------------------------------------
- name: mac128k.rom - name: mac128k.rom
path: Macintosh/mac128k.rom path: Macintosh/mac128k.rom
system: apple-macintosh
description: "Macintosh 128k ROM" description: "Macintosh 128k ROM"
size: 65536 size: 65536
crc32: "6d0c8a28" crc32: "6d0c8a28"
@@ -630,6 +678,7 @@ files:
- name: mac512k.rom - name: mac512k.rom
path: Macintosh/mac512k.rom path: Macintosh/mac512k.rom
system: apple-macintosh
description: "Macintosh 512k ROM" description: "Macintosh 512k ROM"
size: 65536 size: 65536
crc32: "cf759e0d" crc32: "cf759e0d"
@@ -639,6 +688,7 @@ files:
- name: macplus.rom - name: macplus.rom
path: Macintosh/macplus.rom path: Macintosh/macplus.rom
system: apple-macintosh
description: "Macintosh Plus ROM" description: "Macintosh Plus ROM"
size: 131072 size: 131072
crc32: "b2102e8e" crc32: "b2102e8e"
@@ -656,6 +706,7 @@ files:
# ------------------------------------------------------- # -------------------------------------------------------
- name: bios.sms - name: bios.sms
path: MasterSystem/bios.sms path: MasterSystem/bios.sms
system: sega-mastersystem
description: "European/US Master System BIOS" description: "European/US Master System BIOS"
region: [north-america, europe] region: [north-america, europe]
size: 8192 size: 8192
@@ -666,6 +717,7 @@ files:
- name: japanese-bios.sms - name: japanese-bios.sms
path: MasterSystem/japanese-bios.sms path: MasterSystem/japanese-bios.sms
system: sega-mastersystem
description: "Japanese Master System BIOS" description: "Japanese Master System BIOS"
region: [japan] region: [japan]
size: 8192 size: 8192
@@ -680,6 +732,7 @@ files:
- name: msx.rom - name: msx.rom
aliases: [MSX.ROM] aliases: [MSX.ROM]
path: MSX/MSX.ROM path: MSX/MSX.ROM
system: microsoft-msx
description: "Generic MSX BIOS" description: "Generic MSX BIOS"
size: 32768 size: 32768
crc32: "94ee12f3" crc32: "94ee12f3"
@@ -689,6 +742,7 @@ files:
- name: msx-japanese.rom - name: msx-japanese.rom
path: MSX/msx-japanese.rom path: MSX/msx-japanese.rom
system: microsoft-msx
description: "Japanese MSX BIOS" description: "Japanese MSX BIOS"
region: [japan] region: [japan]
size: 32768 size: 32768
@@ -699,6 +753,7 @@ files:
- name: msx-american.rom - name: msx-american.rom
path: MSX/msx-american.rom path: MSX/msx-american.rom
system: microsoft-msx
description: "American MSX BIOS" description: "American MSX BIOS"
region: [north-america] region: [north-america]
size: 32768 size: 32768
@@ -708,6 +763,7 @@ files:
- name: msx-european.rom - name: msx-european.rom
path: MSX/msx-european.rom path: MSX/msx-european.rom
system: microsoft-msx
description: "European MSX BIOS" description: "European MSX BIOS"
region: [europe] region: [europe]
size: 32768 size: 32768
@@ -727,6 +783,7 @@ files:
- name: msx2.rom - name: msx2.rom
aliases: [MSX2.ROM] aliases: [MSX2.ROM]
path: MSX/MSX2.ROM path: MSX/MSX2.ROM
system: microsoft-msx2
description: "Generic MSX2 BIOS" description: "Generic MSX2 BIOS"
size: 32768 size: 32768
crc32: "6cdaf3a5" crc32: "6cdaf3a5"
@@ -737,6 +794,7 @@ files:
- name: msx2ext.rom - name: msx2ext.rom
aliases: [MSX2EXT.ROM] aliases: [MSX2EXT.ROM]
path: MSX/MSX2EXT.ROM path: MSX/MSX2EXT.ROM
system: microsoft-msx2
description: "MSX2 extension ROM" description: "MSX2 extension ROM"
size: 16384 size: 16384
crc32: "66237ecf" crc32: "66237ecf"
@@ -758,6 +816,7 @@ files:
# ------------------------------------------------------- # -------------------------------------------------------
- name: basic10.rom - name: basic10.rom
path: Oric/basic10.rom path: Oric/basic10.rom
system: oric
description: "Oric BASIC 1.0" description: "Oric BASIC 1.0"
size: 16384 size: 16384
crc32: "f18710b4" crc32: "f18710b4"
@@ -767,6 +826,7 @@ files:
- name: basic11.rom - name: basic11.rom
path: Oric/basic11.rom path: Oric/basic11.rom
system: oric
description: "Oric BASIC 1.1" description: "Oric BASIC 1.1"
size: 16384 size: 16384
crc32: "c3a92bef" crc32: "c3a92bef"
@@ -776,6 +836,7 @@ files:
- name: pravetz.rom - name: pravetz.rom
path: Oric/pravetz.rom path: Oric/pravetz.rom
system: oric
description: "Pravetz BASIC" description: "Pravetz BASIC"
size: 16384 size: 16384
crc32: "58079502" crc32: "58079502"
@@ -785,6 +846,7 @@ files:
- name: colour.rom - name: colour.rom
path: Oric/colour.rom path: Oric/colour.rom
system: oric
description: "Oric colour ROM (128-byte version)" description: "Oric colour ROM (128-byte version)"
size: 128 size: 128
crc32: "d50fca65" crc32: "d50fca65"
@@ -794,6 +856,7 @@ files:
- name: ORIC.PAL-PROM-TBP24S10-1ab9b572.bin - name: ORIC.PAL-PROM-TBP24S10-1ab9b572.bin
path: Oric/ORIC.PAL-PROM-TBP24S10-1ab9b572.bin path: Oric/ORIC.PAL-PROM-TBP24S10-1ab9b572.bin
system: oric
description: "Oric colour ROM (256-byte version)" description: "Oric colour ROM (256-byte version)"
size: 256 size: 256
crc32: "1ab9b572" crc32: "1ab9b572"
@@ -803,6 +866,7 @@ files:
- name: PRAVETZ-8D.PAL-PROM-82S129-1576a69b.bin - name: PRAVETZ-8D.PAL-PROM-82S129-1576a69b.bin
path: Oric/PRAVETZ-8D.PAL-PROM-82S129-1576a69b.bin path: Oric/PRAVETZ-8D.PAL-PROM-82S129-1576a69b.bin
system: oric
description: "Pravetz 8D colour ROM" description: "Pravetz 8D colour ROM"
size: 256 size: 256
crc32: "1576a69b" crc32: "1576a69b"
@@ -812,6 +876,7 @@ files:
- name: bd500.rom - name: bd500.rom
path: Oric/bd500.rom path: Oric/bd500.rom
system: oric
description: "Oric Byte Drive 500 ROM" description: "Oric Byte Drive 500 ROM"
size: 8192 size: 8192
crc32: "61952e34" crc32: "61952e34"
@@ -821,6 +886,7 @@ files:
- name: jasmin.rom - name: jasmin.rom
path: Oric/jasmin.rom path: Oric/jasmin.rom
system: oric
description: "Oric Jasmin ROM" description: "Oric Jasmin ROM"
size: 2048 size: 2048
crc32: "37220e89" crc32: "37220e89"
@@ -830,6 +896,7 @@ files:
- name: microdisc.rom - name: microdisc.rom
path: Oric/microdisc.rom path: Oric/microdisc.rom
system: oric
description: "Oric Microdisc ROM" description: "Oric Microdisc ROM"
size: 8192 size: 8192
crc32: "a9664a9c" crc32: "a9664a9c"
@@ -839,6 +906,7 @@ files:
- name: 8dos.rom - name: 8dos.rom
path: Oric/8dos.rom path: Oric/8dos.rom
system: oric
description: "8DOS boot ROM" description: "8DOS boot ROM"
size: 512 size: 512
crc32: "49a74c06" crc32: "49a74c06"
@@ -851,6 +919,7 @@ files:
# ------------------------------------------------------- # -------------------------------------------------------
- name: GLABIOS_0.2.5_8T.ROM - name: GLABIOS_0.2.5_8T.ROM
path: PCCompatible/GLABIOS_0.2.5_8T.ROM path: PCCompatible/GLABIOS_0.2.5_8T.ROM
system: pc-compatible
description: "8088 GLaBIOS 0.2.5" description: "8088 GLaBIOS 0.2.5"
size: 8192 size: 8192
crc32: "9576944c" crc32: "9576944c"
@@ -860,6 +929,7 @@ files:
- name: GLaTICK_0.8.5_AT.ROM - name: GLaTICK_0.8.5_AT.ROM
path: PCCompatible/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" description: "AT GLaTICK 0.8.5 RTC option ROM"
size: 2048 size: 2048
crc32: "371ea3f1" crc32: "371ea3f1"
@@ -869,6 +939,7 @@ files:
- name: "Phoenix 80286 ROM BIOS Version 3.05.bin" - name: "Phoenix 80286 ROM BIOS Version 3.05.bin"
path: "PCCompatible/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" description: "Phoenix 80286 BIOS 3.05"
size: 32768 size: 32768
crc32: "8d0d318a" crc32: "8d0d318a"
@@ -878,6 +949,7 @@ files:
- name: at-bios.bin - name: at-bios.bin
path: PCCompatible/at-bios.bin path: PCCompatible/at-bios.bin
system: pc-compatible
description: "IBM PC AT BIOS v3" description: "IBM PC AT BIOS v3"
size: 65536 size: 65536
crc32: "674426be" crc32: "674426be"
@@ -887,6 +959,7 @@ files:
- name: BIOS_5170_15NOV85_U27_61X9266_27256.BIN - name: BIOS_5170_15NOV85_U27_61X9266_27256.BIN
path: PCCompatible/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" description: "IBM PC AT BIOS, Nov 1985, U27 chip"
size: 32768 size: 32768
crc32: "4995be7a" crc32: "4995be7a"
@@ -896,6 +969,7 @@ files:
- name: BIOS_5170_15NOV85_U47_61X9265_27256.BIN - name: BIOS_5170_15NOV85_U47_61X9265_27256.BIN
path: PCCompatible/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" description: "IBM PC AT BIOS, Nov 1985, U47 chip"
size: 32768 size: 32768
crc32: "c32713e4" crc32: "c32713e4"
@@ -905,6 +979,7 @@ files:
- name: CGA.F08 - name: CGA.F08
path: PCCompatible/CGA.F08 path: PCCompatible/CGA.F08
system: pc-compatible
description: "IBM CGA font" description: "IBM CGA font"
size: 2048 size: 2048
crc32: "a362ffe6" crc32: "a362ffe6"
@@ -914,6 +989,7 @@ files:
- name: EUMDA9.F14 - name: EUMDA9.F14
path: PCCompatible/EUMDA9.F14 path: PCCompatible/EUMDA9.F14
system: pc-compatible
description: "IBM MDA font" description: "IBM MDA font"
size: 3584 size: 3584
crc32: "7754882a" crc32: "7754882a"
@@ -941,6 +1017,7 @@ files:
- name: ibm-basic-1.10.rom - name: ibm-basic-1.10.rom
path: PCCompatible/ibm-basic-1.10.rom path: PCCompatible/ibm-basic-1.10.rom
system: pc-compatible
description: "IBM ROM BASIC 1.10" description: "IBM ROM BASIC 1.10"
size: 32768 size: 32768
crc32: "ebacb791" crc32: "ebacb791"
@@ -953,6 +1030,7 @@ files:
# ------------------------------------------------------- # -------------------------------------------------------
- name: basic.318006-01.bin - name: basic.318006-01.bin
path: Plus4/basic.318006-01.bin path: Plus4/basic.318006-01.bin
system: commodore-plus4
description: "C16+4 BASIC ROM" description: "C16+4 BASIC ROM"
size: 16384 size: 16384
crc32: "74eaae87" crc32: "74eaae87"
@@ -961,6 +1039,7 @@ files:
- name: kernal.318004-05.bin - name: kernal.318004-05.bin
path: Plus4/kernal.318004-05.bin path: Plus4/kernal.318004-05.bin
system: commodore-plus4
description: "C16+4 kernel, PAL-G revision 5" description: "C16+4 kernel, PAL-G revision 5"
size: 16384 size: 16384
crc32: "71c07bd4" crc32: "71c07bd4"
@@ -991,6 +1070,7 @@ files:
# ------------------------------------------------------- # -------------------------------------------------------
- name: mo5-v1.0.rom - name: mo5-v1.0.rom
path: Thomson/mo5-v1.0.rom path: Thomson/mo5-v1.0.rom
system: thomson-mo5
description: "Thomson MO5 ROM, version 1" description: "Thomson MO5 ROM, version 1"
size: 16384 size: 16384
crc32: "f62d2f3a" crc32: "f62d2f3a"
@@ -999,6 +1079,7 @@ files:
- name: mo5-v1.1.rom - name: mo5-v1.1.rom
path: Thomson/mo5-v1.1.rom path: Thomson/mo5-v1.1.rom
system: thomson-mo5
description: "Thomson MO5 ROM, version 1.1" description: "Thomson MO5 ROM, version 1.1"
size: 16384 size: 16384
crc32: "237c60bf" crc32: "237c60bf"
@@ -1007,6 +1088,7 @@ files:
- name: mo6-v1.rom - name: mo6-v1.rom
path: Thomson/mo6-v1.rom path: Thomson/mo6-v1.rom
system: thomson-mo6
description: "Thomson MO6 ROM, version 1" description: "Thomson MO6 ROM, version 1"
size: 65536 size: 65536
crc32: "45e859c6" crc32: "45e859c6"
@@ -1015,6 +1097,7 @@ files:
- name: mo6-v2.rom - name: mo6-v2.rom
path: Thomson/mo6-v2.rom path: Thomson/mo6-v2.rom
system: thomson-mo6
description: "Thomson MO6 ROM, version 2" description: "Thomson MO6 ROM, version 2"
size: 65536 size: 65536
crc32: "b4430a3b" crc32: "b4430a3b"
@@ -1023,6 +1106,7 @@ files:
- name: mo6-v3.rom - name: mo6-v3.rom
path: Thomson/mo6-v3.rom path: Thomson/mo6-v3.rom
system: thomson-mo6
description: "Thomson MO6 ROM, version 3" description: "Thomson MO6 ROM, version 3"
size: 65536 size: 65536
crc32: "7a012322" crc32: "7a012322"
@@ -1051,6 +1135,7 @@ files:
# ------------------------------------------------------- # -------------------------------------------------------
- name: basic.bin - name: basic.bin
path: Vic20/basic.bin path: Vic20/basic.bin
system: commodore-vic20
description: "VIC-20 BASIC ROM" description: "VIC-20 BASIC ROM"
size: 8192 size: 8192
crc32: "db4c43c1" crc32: "db4c43c1"
@@ -1059,6 +1144,7 @@ files:
- name: characters-english.bin - name: characters-english.bin
path: Vic20/characters-english.bin path: Vic20/characters-english.bin
system: commodore-vic20
description: "English-language VIC-20 character ROM" description: "English-language VIC-20 character ROM"
region: [north-america, europe] region: [north-america, europe]
size: 4096 size: 4096
@@ -1069,6 +1155,7 @@ files:
- name: kernel-pal.bin - name: kernel-pal.bin
path: Vic20/kernel-pal.bin path: Vic20/kernel-pal.bin
system: commodore-vic20
description: "English-language PAL VIC-20 kernel ROM" description: "English-language PAL VIC-20 kernel ROM"
region: [europe] region: [europe]
size: 8192 size: 8192
@@ -1079,6 +1166,7 @@ files:
- name: kernel-ntsc.bin - name: kernel-ntsc.bin
path: Vic20/kernel-ntsc.bin path: Vic20/kernel-ntsc.bin
system: commodore-vic20
description: "English-language NTSC VIC-20 kernel ROM" description: "English-language NTSC VIC-20 kernel ROM"
region: [north-america] region: [north-america]
size: 8192 size: 8192
@@ -1089,6 +1177,7 @@ files:
- name: characters-danish.bin - name: characters-danish.bin
path: Vic20/characters-danish.bin path: Vic20/characters-danish.bin
system: commodore-vic20
description: "Danish VIC-20 character ROM" description: "Danish VIC-20 character ROM"
region: [denmark] region: [denmark]
size: 4096 size: 4096
@@ -1099,6 +1188,7 @@ files:
- name: kernel-danish.bin - name: kernel-danish.bin
path: Vic20/kernel-danish.bin path: Vic20/kernel-danish.bin
system: commodore-vic20
description: "Danish VIC-20 kernel ROM" description: "Danish VIC-20 kernel ROM"
region: [denmark] region: [denmark]
size: 8192 size: 8192
@@ -1109,6 +1199,7 @@ files:
- name: characters-japanese.bin - name: characters-japanese.bin
path: Vic20/characters-japanese.bin path: Vic20/characters-japanese.bin
system: commodore-vic20
description: "Japanese VIC-20 character ROM" description: "Japanese VIC-20 character ROM"
region: [japan] region: [japan]
size: 4096 size: 4096
@@ -1119,6 +1210,7 @@ files:
- name: kernel-japanese.bin - name: kernel-japanese.bin
path: Vic20/kernel-japanese.bin path: Vic20/kernel-japanese.bin
system: commodore-vic20
description: "Japanese VIC-20 kernel ROM" description: "Japanese VIC-20 kernel ROM"
region: [japan] region: [japan]
size: 8192 size: 8192
@@ -1129,6 +1221,7 @@ files:
- name: characters-swedish.bin - name: characters-swedish.bin
path: Vic20/characters-swedish.bin path: Vic20/characters-swedish.bin
system: commodore-vic20
description: "Swedish VIC-20 character ROM" description: "Swedish VIC-20 character ROM"
region: [sweden] region: [sweden]
size: 4096 size: 4096
@@ -1139,6 +1232,7 @@ files:
- name: kernel-swedish.bin - name: kernel-swedish.bin
path: Vic20/kernel-swedish.bin path: Vic20/kernel-swedish.bin
system: commodore-vic20
description: "Swedish VIC-20 kernel ROM" description: "Swedish VIC-20 kernel ROM"
region: [sweden] region: [sweden]
size: 8192 size: 8192
@@ -1153,6 +1247,7 @@ files:
# ------------------------------------------------------- # -------------------------------------------------------
- name: 48.rom - name: 48.rom
path: ZXSpectrum/48.rom path: ZXSpectrum/48.rom
system: sinclair-zx-spectrum
description: "ZX Spectrum 48K ROM" description: "ZX Spectrum 48K ROM"
size: 16384 size: 16384
crc32: "ddee531f" crc32: "ddee531f"
@@ -1162,6 +1257,7 @@ files:
- name: 128.rom - name: 128.rom
path: ZXSpectrum/128.rom path: ZXSpectrum/128.rom
system: sinclair-zx-spectrum
description: "ZX Spectrum 128K ROM" description: "ZX Spectrum 128K ROM"
size: 32768 size: 32768
crc32: "2cbe8995" crc32: "2cbe8995"
@@ -1171,6 +1267,7 @@ files:
- name: plus2.rom - name: plus2.rom
path: ZXSpectrum/plus2.rom path: ZXSpectrum/plus2.rom
system: sinclair-zx-spectrum
description: "ZX Spectrum +2 ROM" description: "ZX Spectrum +2 ROM"
size: 32768 size: 32768
crc32: "e7a517dc" crc32: "e7a517dc"
@@ -1180,6 +1277,7 @@ files:
- name: plus3.rom - name: plus3.rom
path: ZXSpectrum/plus3.rom path: ZXSpectrum/plus3.rom
system: sinclair-zx-spectrum
description: "ZX Spectrum +2a/+3 ROM" description: "ZX Spectrum +2a/+3 ROM"
size: 65536 size: 65536
crc32: "96e3c17a" crc32: "96e3c17a"
@@ -1193,6 +1291,7 @@ files:
# ------------------------------------------------------- # -------------------------------------------------------
- name: zx80.rom - name: zx80.rom
path: ZX8081/zx80.rom path: ZX8081/zx80.rom
system: sinclair-zx80-81
description: "ZX80 BASIC ROM" description: "ZX80 BASIC ROM"
size: 4096 size: 4096
crc32: "4c7fc597" crc32: "4c7fc597"
@@ -1202,6 +1301,7 @@ files:
- name: zx81.rom - name: zx81.rom
path: ZX8081/zx81.rom path: ZX8081/zx81.rom
system: sinclair-zx80-81
description: "ZX81 BASIC ROM" description: "ZX81 BASIC ROM"
size: 8192 size: 8192
crc32: "4b1dd6eb" crc32: "4b1dd6eb"
+5 -5
View File
@@ -135,8 +135,8 @@ files:
required: false required: false
hle_fallback: true hle_fallback: true
size: 8192 size: 8192
validation: [size] validation: [size, adler32]
known_hash_adler32: "0x66f334fe" known_hash_adler32: ["0x66f334fe", "0x128ea7a2"]
adler32_byteswap: true adler32_byteswap: true
description: "DSP instruction ROM" 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." 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 required: false
hle_fallback: true hle_fallback: true
size: 4096 size: 4096
validation: [size] validation: [size, adler32]
known_hash_adler32: "0xf3b93527" known_hash_adler32: ["0xf3b93527", "0xa4a575f5"]
adler32_byteswap: true adler32_byteswap: true
description: "DSP coefficient ROM" 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." 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 - name: codehandler.bin
path: null path: null
+5 -5
View File
@@ -171,8 +171,8 @@ files:
required: false required: false
hle_fallback: true hle_fallback: true
size: 8192 size: 8192
validation: [size] validation: [size, adler32]
known_hash_adler32: "0x66f334fe" known_hash_adler32: ["0x66f334fe", "0xe789b5a5"]
adler32_byteswap: true adler32_byteswap: true
description: "DSP instruction ROM" 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." 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 required: false
hle_fallback: true hle_fallback: true
size: 4096 size: 4096
validation: [size] validation: [size, adler32]
known_hash_adler32: "0xf3b93527" known_hash_adler32: ["0xf3b93527", "0xa4a575f5"]
adler32_byteswap: true adler32_byteswap: true
description: "DSP coefficient ROM" 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." 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 - name: codehandler.bin
path: null path: null
+6 -6
View File
@@ -67,22 +67,22 @@ files:
size: 8192 size: 8192
required: false required: false
hle_fallback: true hle_fallback: true
validation: [size] validation: [size, adler32]
known_hash_adler32: "0x66f334fe" known_hash_adler32: ["0x66f334fe", "0xe789b5a5"]
adler32_byteswap: true adler32_byteswap: true
note: "DSP instruction ROM for LLE audio. Free replacement (v0.4) included" 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" - name: "dsp_coef.bin"
path: "GC/dsp_coef.bin" path: "GC/dsp_coef.bin"
size: 4096 size: 4096
required: false required: false
hle_fallback: true hle_fallback: true
validation: [size] validation: [size, adler32]
known_hash_adler32: "0xf3b93527" known_hash_adler32: ["0xf3b93527", "0xa4a575f5"]
adler32_byteswap: true adler32_byteswap: true
note: "DSP coefficient ROM for LLE audio and HLE polyphase resampling. Free replacement included" 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 -- # -- GameCube Fonts --
# Bundled free alternatives exist but have padding differences causing misplaced text. # Bundled free alternatives exist but have padding differences causing misplaced text.
+86 -13
View File
@@ -5,38 +5,51 @@ source: "https://github.com/libretro/dosbox-pure"
upstream: "https://codeberg.org/schelling/dosbox-pure" upstream: "https://codeberg.org/schelling/dosbox-pure"
logo: "https://raw.githubusercontent.com/schellingb/dosbox-pure/main/images/logo.png" logo: "https://raw.githubusercontent.com/schellingb/dosbox-pure/main/images/logo.png"
profiled_date: "2026-03-23" profiled_date: "2026-03-23"
source_commit: "a4a0bab7f8931433588f2fcad9045c85b277373d" source_commit: "cdaea10ce8cac231bc341ca05d4c5e4e5fe0fbd5"
core_version: "1.0-preview5" core_version: "1.0-preview7"
display_name: "DOS (DOSBox-Pure)" display_name: "DOS (DOSBox-Pure)"
cores: [dosbox_pure] cores: [dosbox_pure]
systems: [dos] systems: [dos]
verification: sha1 verification: sha1
notes: | 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): ROM scanning (both modes):
Recursive scan of system directory for *_CONTROL.ROM and *.SF2/*.SF3. Recursive scan of system directory for *_CONTROL.ROM and *.SF2/*.SF3.
ref: dosbox_pure_libretro.cpp:1399-1410 ref: dosbox_pure_libretro.cpp:1399-1410
MT-32 requires matched pair: *_CONTROL.ROM + *_PCM.ROM (PCM name derived MT-32 requires matched pair: *_CONTROL.ROM + *_PCM.ROM (PCM name derived
from CONTROL name by replacing CONTROL with PCM, preserving case). 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 = ZIP archives also supported — scanned for files by size (65536/131072 =
control, 524288/1048576 = PCM), not by name. control, 524288/1048576 = PCM), not by name.
ref: midi_mt32.h:160-166 ref: src/gui/midi_mt32.h:160-166
Files can also be on mounted C: drive (DOSBOX.SF2, MT32_CONTROL.ROM). Files can also be on mounted C: drive (DOSBOX.SF2, MT32_CONTROL.ROM,
ref: dosbox_pure_libretro.cpp:2803-2805 ROM1.BIN).
ref: dosbox_pure_libretro.cpp:2806-2813
Cache file DOSBoxPureMidiCache.txt written when scan >2s. 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. Bundled MUNT (header-only mt32emu.h) for MT-32 emulation.
SHA1+size validation at load: unrecognized ROMs rejected (Synth::open fails). 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). 12 full control ROMs + 2 PCM ROMs supported (no split ROMs in this MUNT).
TinySoundFont (tsf.h) for SF2/SF3 playback. TinySoundFont (tsf.h) for SF2/SF3 playback.
No firmware entries in .info file — all MIDI files optional. No firmware entries in .info file — all MIDI files optional.
DBP_STANDALONE build mode exists (same MIDI logic, different I/O layer). 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: files:
# -- MT-32 Control ROMs (64 KB) -- # -- MT-32 Control ROMs (64 KB) --
@@ -168,7 +181,7 @@ files:
note: > note: >
accepted by every MT-32 control ROM, v1.x and v2.x. Each control ROM 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 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" - name: "CM32L_PCM.ROM"
description: "CM-32L/CM-64/LAPC-I 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 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 256 and require this 1048576 byte image. The alias covers the name
derived from CM32LN_CONTROL.ROM. 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 -- # -- General MIDI SoundFont --
@@ -191,8 +204,68 @@ files:
description: "General MIDI SoundFont (any .sf2/.sf3 accepted)" description: "General MIDI SoundFont (any .sf2/.sf3 accepted)"
required: false required: false
hle_fallback: true 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: > note: >
Any .SF2 or .SF3 file in the system directory works. The core lists all 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 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. 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"
+6 -6
View File
@@ -64,22 +64,22 @@ files:
size: 8192 size: 8192
required: false required: false
hle_fallback: true hle_fallback: true
validation: [size] validation: [size, adler32]
known_hash_adler32: "0x66f334fe" known_hash_adler32: ["0x66f334fe", "0x128ea7a2"]
adler32_byteswap: true adler32_byteswap: true
note: "DSP instruction ROM for LLE audio. Free replacement included" 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" - name: "dsp_coef.bin"
path: "GC/dsp_coef.bin" path: "GC/dsp_coef.bin"
size: 4096 size: 4096
required: false required: false
hle_fallback: true hle_fallback: true
validation: [size] validation: [size, adler32]
known_hash_adler32: "0xf3b93527" known_hash_adler32: ["0xf3b93527", "0xa4a575f5"]
adler32_byteswap: true adler32_byteswap: true
note: "DSP coefficient ROM for LLE audio and HLE polyphase resampling. Free replacement included" 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 -- # -- GameCube Fonts --
# Bundled free alternatives exist but have padding differences causing misplaced text. # Bundled free alternatives exist but have padding differences causing misplaced text.
+6 -6
View File
@@ -68,22 +68,22 @@ files:
size: 8192 size: 8192
required: false required: false
hle_fallback: true hle_fallback: true
validation: [size] validation: [size, adler32]
known_hash_adler32: "0x66f334fe" known_hash_adler32: ["0x66f334fe", "0xe789b5a5"]
adler32_byteswap: true adler32_byteswap: true
note: "DSP instruction ROM for LLE audio. Free replacement (v0.4) included" 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" - name: "dsp_coef.bin"
path: "GC/dsp_coef.bin" path: "GC/dsp_coef.bin"
size: 4096 size: 4096
required: false required: false
hle_fallback: true hle_fallback: true
validation: [size] validation: [size, adler32]
known_hash_adler32: "0xf3b93527" known_hash_adler32: ["0xf3b93527", "0xa4a575f5"]
adler32_byteswap: true adler32_byteswap: true
note: "DSP coefficient ROM for LLE audio. Free replacement included" 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 -- # -- GameCube Fonts --
# Bundled free alternatives exist but have padding differences causing misplaced text. # Bundled free alternatives exist but have padding differences causing misplaced text.
+6 -6
View File
@@ -227,12 +227,12 @@ files:
path: "GC/dsp_rom.bin" path: "GC/dsp_rom.bin"
description: "DSP instruction ROM" description: "DSP instruction ROM"
size: 8192 size: 8192
validation: [size] validation: [size, adler32]
known_hash_adler32: "0x66f334fe" known_hash_adler32: ["0x66f334fe", "0xe789b5a5"]
adler32_byteswap: true adler32_byteswap: true
required: false required: false
hle_fallback: true 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: > note: >
LoadDSPRom rejects any file whose length differs from DSP_IROM_BYTE_SIZE and 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 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" path: "GC/dsp_coef.bin"
description: "DSP coefficient ROM" description: "DSP coefficient ROM"
size: 4096 size: 4096
validation: [size] validation: [size, adler32]
known_hash_adler32: "0xf3b93527" known_hash_adler32: ["0xf3b93527", "0xa4a575f5"]
adler32_byteswap: true adler32_byteswap: true
required: false required: false
hle_fallback: true 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: > note: >
Also read by the HLE AX ucode for polyphase resampling. Adler32 is taken over 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). the byte-swapped data (Source/Core/Core/HW/DSPLLE/DSPLLE.cpp:100-102).
+56 -1034
View File
File diff suppressed because it is too large. Load diff
+34 -771
View File
File diff suppressed because it is too large. Load diff
+6 -6
View File
@@ -1036,10 +1036,10 @@
}, },
{ {
"dest": "sysdata/otp.bin", "dest": "sysdata/otp.bin",
"sha1": "f0332b7252e9c01b30bf5d5a63ceb22dc47968aa", "sha1": "49489245b400f62c62faf1736b7f0a70714d3c49",
"sha256": "93c2e20cc377f2cb0fa9a2ee58c39be22e00baa94b890545e585e53b3eb4039f", "sha256": "e2f1810ceff3d1fd4f1c08ffc1f4d47aa8efca551edd24cd5686205c71a3b13b",
"size": 256, "size": 256,
"repo_path": "bios/Nintendo/3DS/Citra/sysdata/otp.bin", "repo_path": "bios/Nintendo/3DS/otp.bin",
"cores": [ "cores": [
"azahar" "azahar"
], ],
@@ -1270,10 +1270,10 @@
}, },
{ {
"dest": "GC/dsp_rom.bin", "dest": "GC/dsp_rom.bin",
"sha1": "f4f683a49d7eb4155566f793f2c1c27e90159992", "sha1": "3c6cc6e04fdd0b2a392d7a6ed769455444846be7",
"sha256": "7f33e6600722791ccee5fd15d4330af8d8f74165f7d1ded6738684c0294aaffe", "sha256": "49d987ee1eab29a157425b82d54516957a81e1bac247c8834e494642605c3e8c",
"size": 8192, "size": 8192,
"repo_path": "bios/Nintendo/GameCube/Sys/GC/dsp_rom.bin", "repo_path": "bios/Nintendo/GameCube/.variants/dsp_rom.bin.3c6cc6e0",
"cores": [ "cores": [
"dolphin" "dolphin"
], ],
+6 -6
View File
@@ -6110,10 +6110,10 @@
}, },
{ {
"dest": "sysdata/otp.bin", "dest": "sysdata/otp.bin",
"sha1": "f0332b7252e9c01b30bf5d5a63ceb22dc47968aa", "sha1": "49489245b400f62c62faf1736b7f0a70714d3c49",
"sha256": "93c2e20cc377f2cb0fa9a2ee58c39be22e00baa94b890545e585e53b3eb4039f", "sha256": "e2f1810ceff3d1fd4f1c08ffc1f4d47aa8efca551edd24cd5686205c71a3b13b",
"size": 256, "size": 256,
"repo_path": "bios/Nintendo/3DS/Citra/sysdata/otp.bin", "repo_path": "bios/Nintendo/3DS/otp.bin",
"cores": [ "cores": [
"azahar" "azahar"
] ]
@@ -61637,10 +61637,10 @@
}, },
{ {
"dest": "GC/dsp_rom.bin", "dest": "GC/dsp_rom.bin",
"sha1": "f4f683a49d7eb4155566f793f2c1c27e90159992", "sha1": "3c6cc6e04fdd0b2a392d7a6ed769455444846be7",
"sha256": "7f33e6600722791ccee5fd15d4330af8d8f74165f7d1ded6738684c0294aaffe", "sha256": "49d987ee1eab29a157425b82d54516957a81e1bac247c8834e494642605c3e8c",
"size": 8192, "size": 8192,
"repo_path": "bios/Nintendo/GameCube/Sys/GC/dsp_rom.bin", "repo_path": "bios/Nintendo/GameCube/.variants/dsp_rom.bin.3c6cc6e0",
"cores": [ "cores": [
"dolphin" "dolphin"
], ],
+3 -3
View File
@@ -9824,10 +9824,10 @@
}, },
{ {
"dest": "GC/dsp_rom.bin", "dest": "GC/dsp_rom.bin",
"sha1": "f4f683a49d7eb4155566f793f2c1c27e90159992", "sha1": "3c6cc6e04fdd0b2a392d7a6ed769455444846be7",
"sha256": "7f33e6600722791ccee5fd15d4330af8d8f74165f7d1ded6738684c0294aaffe", "sha256": "49d987ee1eab29a157425b82d54516957a81e1bac247c8834e494642605c3e8c",
"size": 8192, "size": 8192,
"repo_path": "bios/Nintendo/GameCube/Sys/GC/dsp_rom.bin", "repo_path": "bios/Nintendo/GameCube/.variants/dsp_rom.bin.3c6cc6e0",
"cores": [ "cores": [
"dolphin" "dolphin"
], ],
+6 -6
View File
@@ -6349,10 +6349,10 @@
}, },
{ {
"dest": "sysdata/otp.bin", "dest": "sysdata/otp.bin",
"sha1": "f0332b7252e9c01b30bf5d5a63ceb22dc47968aa", "sha1": "49489245b400f62c62faf1736b7f0a70714d3c49",
"sha256": "93c2e20cc377f2cb0fa9a2ee58c39be22e00baa94b890545e585e53b3eb4039f", "sha256": "e2f1810ceff3d1fd4f1c08ffc1f4d47aa8efca551edd24cd5686205c71a3b13b",
"size": 256, "size": 256,
"repo_path": "bios/Nintendo/3DS/Citra/sysdata/otp.bin", "repo_path": "bios/Nintendo/3DS/otp.bin",
"cores": [ "cores": [
"azahar" "azahar"
] ]
@@ -61876,10 +61876,10 @@
}, },
{ {
"dest": "GC/dsp_rom.bin", "dest": "GC/dsp_rom.bin",
"sha1": "f4f683a49d7eb4155566f793f2c1c27e90159992", "sha1": "3c6cc6e04fdd0b2a392d7a6ed769455444846be7",
"sha256": "7f33e6600722791ccee5fd15d4330af8d8f74165f7d1ded6738684c0294aaffe", "sha256": "49d987ee1eab29a157425b82d54516957a81e1bac247c8834e494642605c3e8c",
"size": 8192, "size": 8192,
"repo_path": "bios/Nintendo/GameCube/Sys/GC/dsp_rom.bin", "repo_path": "bios/Nintendo/GameCube/.variants/dsp_rom.bin.3c6cc6e0",
"cores": [ "cores": [
"dolphin" "dolphin"
], ],
+95 -976
View File
File diff suppressed because it is too large. Load diff
+60 -1128
View File
File diff suppressed because it is too large. Load diff
+6 -6
View File
@@ -6423,10 +6423,10 @@
}, },
{ {
"dest": "sysdata/otp.bin", "dest": "sysdata/otp.bin",
"sha1": "f0332b7252e9c01b30bf5d5a63ceb22dc47968aa", "sha1": "49489245b400f62c62faf1736b7f0a70714d3c49",
"sha256": "93c2e20cc377f2cb0fa9a2ee58c39be22e00baa94b890545e585e53b3eb4039f", "sha256": "e2f1810ceff3d1fd4f1c08ffc1f4d47aa8efca551edd24cd5686205c71a3b13b",
"size": 256, "size": 256,
"repo_path": "bios/Nintendo/3DS/Citra/sysdata/otp.bin", "repo_path": "bios/Nintendo/3DS/otp.bin",
"cores": [ "cores": [
"azahar" "azahar"
] ]
@@ -101392,10 +101392,10 @@
}, },
{ {
"dest": "GC/dsp_rom.bin", "dest": "GC/dsp_rom.bin",
"sha1": "f4f683a49d7eb4155566f793f2c1c27e90159992", "sha1": "3c6cc6e04fdd0b2a392d7a6ed769455444846be7",
"sha256": "7f33e6600722791ccee5fd15d4330af8d8f74165f7d1ded6738684c0294aaffe", "sha256": "49d987ee1eab29a157425b82d54516957a81e1bac247c8834e494642605c3e8c",
"size": 8192, "size": 8192,
"repo_path": "bios/Nintendo/GameCube/Sys/GC/dsp_rom.bin", "repo_path": "bios/Nintendo/GameCube/.variants/dsp_rom.bin.3c6cc6e0",
"cores": [ "cores": [
"dolphin" "dolphin"
], ],
+6 -6
View File
@@ -801,10 +801,10 @@
}, },
{ {
"dest": "sysdata/otp.bin", "dest": "sysdata/otp.bin",
"sha1": "f0332b7252e9c01b30bf5d5a63ceb22dc47968aa", "sha1": "49489245b400f62c62faf1736b7f0a70714d3c49",
"sha256": "93c2e20cc377f2cb0fa9a2ee58c39be22e00baa94b890545e585e53b3eb4039f", "sha256": "e2f1810ceff3d1fd4f1c08ffc1f4d47aa8efca551edd24cd5686205c71a3b13b",
"size": 256, "size": 256,
"repo_path": "bios/Nintendo/3DS/Citra/sysdata/otp.bin", "repo_path": "bios/Nintendo/3DS/otp.bin",
"cores": [ "cores": [
"azahar" "azahar"
] ]
@@ -2779,10 +2779,10 @@
}, },
{ {
"dest": "GC/dsp_rom.bin", "dest": "GC/dsp_rom.bin",
"sha1": "f4f683a49d7eb4155566f793f2c1c27e90159992", "sha1": "3c6cc6e04fdd0b2a392d7a6ed769455444846be7",
"sha256": "7f33e6600722791ccee5fd15d4330af8d8f74165f7d1ded6738684c0294aaffe", "sha256": "49d987ee1eab29a157425b82d54516957a81e1bac247c8834e494642605c3e8c",
"size": 8192, "size": 8192,
"repo_path": "bios/Nintendo/GameCube/Sys/GC/dsp_rom.bin", "repo_path": "bios/Nintendo/GameCube/.variants/dsp_rom.bin.3c6cc6e0",
"cores": [ "cores": [
"dolphin" "dolphin"
], ],
+112 -925
View File
File diff suppressed because it is too large. Load diff
+36 -7
View File
@@ -515,9 +515,24 @@
"pattern": "^[a-fA-F0-9]{8}$" "pattern": "^[a-fA-F0-9]{8}$"
}, },
"known_hash_adler32": { "known_hash_adler32": {
"type": [ "description": "Adler-32 values the code accepts; a list when several revisions pass.",
"string", "oneOf": [
"integer" {
"type": [
"string",
"integer"
]
},
{
"type": "array",
"items": {
"type": [
"string",
"integer"
]
},
"minItems": 1
}
] ]
}, },
"validation": { "validation": {
@@ -648,12 +663,26 @@
"if": { "if": {
"anyOf": [ "anyOf": [
{ {
"required": ["path"], "required": [
"properties": {"path": {"type": "string", "pattern": "/$"}} "path"
],
"properties": {
"path": {
"type": "string",
"pattern": "/$"
}
}
}, },
{ {
"required": ["standalone_path"], "required": [
"properties": {"standalone_path": {"type": "string", "pattern": "/$"}} "standalone_path"
],
"properties": {
"standalone_path": {
"type": "string",
"pattern": "/$"
}
}
} }
] ]
}, },
+10 -7
View File
@@ -88,13 +88,16 @@ class Pack:
def get_latest_release() -> dict: def get_latest_release() -> dict:
"""Fetch latest release info from GitHub API.""" """Fetch latest release info from GitHub API."""
url = f"{API}/repos/{REPO}/releases/latest" url = f"{API}/repos/{REPO}/releases/latest"
req = urllib.request.Request( headers = {
url, "User-Agent": "retrobios-downloader/1.0",
headers={ "Accept": "application/vnd.github.v3+json",
"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: try:
with urllib.request.urlopen(req, timeout=30) as resp: with urllib.request.urlopen(req, timeout=30) as resp:
+17 -2
View File
@@ -1068,6 +1068,16 @@ def generate_pack(
) )
if status in ("not_found", "external", "user_provided") or not local_path: if status in ("not_found", "external", "user_provided") or not local_path:
continue 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": if status == "hash_mismatch":
# The core's declared hash comes from its source, the local dump # The core's declared hash comes from its source, the local dump
# is what the collection holds. Shipping it keeps the emulator # is what the collection holds. Shipping it keeps the emulator
@@ -3100,6 +3110,8 @@ def _manifest_core_entries(
pack_only_sizes: list[int], pack_only_sizes: list[int],
selection: SelectionIndex, selection: SelectionIndex,
required_only: bool = False, required_only: bool = False,
validation_index: dict | None = None,
owners: dict | None = None,
) -> int: ) -> int:
"""Add the files a platform's cores need but its list does not name. """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 [], [source_emu] if source_emu else [],
) )
continue 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", "") 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, zip_contents, offline, region_drops, case_insensitive,
seen_destinations, seen_lower, seen_parents, manifest_files, seen_destinations, seen_lower, seen_parents, manifest_files,
omitted_by_destination, record_omission, pack_only_sizes, selection, 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 # 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_extras_prefix,
_detect_slug_structure, _detect_slug_structure,
_map_emulator_to_slug, _map_emulator_to_slug,
_emulator_systems_index,
_collect_emulator_extras, _collect_emulator_extras,
_extra_system_ids, _extra_system_ids,
platform_region_groups, platform_region_groups,
-15
View File
@@ -15,22 +15,7 @@ from common import runs_standalone
from common import sanitize_pack_path from common import sanitize_pack_path
from common import size_fits from common import size_fits
from validation import read_from_system_dir 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: def _detect_extras_prefix(config: dict, base_dest: str) -> str:
"""The prefix core-extra destinations take (may be empty). """The prefix core-extra destinations take (may be empty).
+8 -8
View File
@@ -20,7 +20,12 @@ import urllib.error
import urllib.request import urllib.request
try: 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: except ImportError:
# Allow running directly: python scripts/scraper/coreinfo_scraper.py # Allow running directly: python scripts/scraper/coreinfo_scraper.py
import os import os
@@ -30,6 +35,7 @@ except ImportError:
BaseScraper, BaseScraper,
BiosRequirement, BiosRequirement,
fetch_github_latest_version, fetch_github_latest_version,
github_headers,
) )
PLATFORM_NAME = "libretro_coreinfo" PLATFORM_NAME = "libretro_coreinfo"
@@ -209,13 +215,7 @@ class Scraper(BaseScraper):
# Use the tree API to get all files at once # Use the tree API to get all files at once
url = f"{GITHUB_API}/git/trees/master?recursive=1" url = f"{GITHUB_API}/git/trees/master?recursive=1"
try: try:
req = urllib.request.Request( req = urllib.request.Request(url, headers=github_headers())
url,
headers={
"User-Agent": "retrobios-scraper/1.0",
"Accept": "application/vnd.github.v3+json",
},
)
with urllib.request.urlopen(req, timeout=30) as resp: with urllib.request.urlopen(req, timeout=30) as resp:
data = json.loads(resp.read()) data = json.loads(resp.read())
+3 -1
View File
@@ -318,7 +318,9 @@ FBNEO_DATS_API = "https://api.github.com/repos/libretro/FBNeo/contents/dats"
def _api_json(url: str) -> object: 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: with urllib.request.urlopen(request, timeout=60) as response:
return json.load(response) return json.load(response)
+118 -6
View File
@@ -56,6 +56,84 @@ def _parse_validation(validation: list | dict | None) -> list[str]:
return [] 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]: def _build_validation_index(profiles: dict) -> dict[str, dict]:
"""Build per-filename validation rules from emulator profiles. """Build per-filename validation rules from emulator profiles.
@@ -98,7 +176,9 @@ def _build_validation_index(profiles: dict) -> dict[str, dict]:
"crypto_only": set(), "crypto_only": set(),
"emulators": set(), "emulators": set(),
"per_emulator": {}, "per_emulator": {},
"rules": [],
} }
index[fname]["rules"].append(_entry_rule(emu_name, f, checks))
index[fname]["emulators"].add(emu_name) index[fname]["emulators"].add(emu_name)
index[fname]["checks"].update(checks) index[fname]["checks"].update(checks)
# Track non-reproducible crypto 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 # Adler32 -stored as known_hash_adler32 field (not in validation: list
# for Dolphin, but support it in both forms for future profiles) # for Dolphin, but support it in both forms for future profiles)
adler_val = f.get("known_hash_adler32") or f.get("adler32") adler_val = f.get("known_hash_adler32") or f.get("adler32")
if adler_val: for value in adler_val if isinstance(adler_val, list) else [adler_val] if adler_val else []:
norm = adler_val.lower() norm = str(value).lower()
if norm.startswith("0x"): if norm.startswith("0x"):
norm = norm[2:] norm = norm[2:]
index[fname]["adler32"].add(norm) index[fname]["adler32"].add(norm)
@@ -233,12 +313,18 @@ def check_file_validation(
filename: str, filename: str,
validation_index: dict[str, dict], validation_index: dict[str, dict],
bios_dir: str = "bios", bios_dir: str = "bios",
emulators: set[str] | None = None,
) -> tuple[str, list[str]] | None: ) -> tuple[str, list[str]] | None:
"""Check emulator-level validation on a resolved file. """Check emulator-level validation on a resolved file.
Supports: size (exact/min/max), crc32, md5, sha1, adler32, Supports: size (exact/min/max), crc32, md5, sha1, adler32,
signature (RSA-2048 PKCS1v15 SHA256), crypto (AES-128-CBC + SHA256). 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 None if all checks pass or no validation applies.
Returns (reason, emulators) tuple on failure, where *emulators* Returns (reason, emulators) tuple on failure, where *emulators*
lists only those cores whose check actually failed. lists only those cores whose check actually failed.
@@ -246,6 +332,23 @@ def check_file_validation(
entry = validation_index.get(filename) entry = validation_index.get(filename)
if not entry: if not entry:
return None 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"] checks = entry["checks"]
pe = entry.get("per_emulator", {}) pe = entry.get("per_emulator", {})
@@ -366,6 +469,7 @@ def find_validated_variant(
validation_index: dict, validation_index: dict,
bios_dir: str = "bios", bios_dir: str = "bios",
platform_digest: str | None = None, platform_digest: str | None = None,
emulators: set[str] | None = None,
) -> str | None: ) -> str | None:
"""A held file the emulator's own checks accept, in place of current_path. """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) seen.add(real)
if accepted and str(entry.get(platform_digest, "")).lower() not in accepted: if accepted and str(entry.get(platform_digest, "")).lower() not in accepted:
continue 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 path
return None return None
@@ -575,18 +681,24 @@ def validated_choice(
return local_path, None return local_path, None
name = file_entry.get("name", "") name = file_entry.get("name", "")
rules = validation_index.get(name) rules = validation_index.get(name)
judges: set[str] | None = None
if rules and owners and destination: if rules and owners and destination:
owning = _owners_of(destination, name, owners) 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 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( 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: if not check:
return local_path, None return local_path, None
better = find_validated_variant( better = find_validated_variant(
file_entry, db, local_path, validation_index, bios_dir, file_entry, db, local_path, validation_index, bios_dir,
platform_digest=platform_digest, platform_digest=platform_digest, emulators=judges,
) )
if better: if better:
return better, None return better, None
+33 -16
View File
@@ -6151,26 +6151,43 @@ struct BurnDriver BurnDrvneogeo = {
self.assertIn("sony-playstation", readme) self.assertIn("sony-playstation", readme)
def test_extras_group_under_their_system_not_a_shared_bucket(self): def test_extras_group_under_their_system_not_a_shared_bucket(self):
"""find_undeclared_files reports the display name, the profiles are """A core extra competes in its system's group: the chain from the
keyed by slug; a key-only lookup put nearly every core extra in one gap report (system, systems) to platform_region_groups, not a
bucket and lost the per-system grouping both narrowing passes need.""" dictionary built by hand. Without it every extra stood alone and
from generate_pack import _emulator_systems_index --region compared nothing."""
import hashlib # noqa: PLC0415
index = _emulator_systems_index( from packextras import platform_region_groups # noqa: PLC0415
{
"beetle_psx": { files, by_name = {}, {}
"emulator": "Beetle PSX (Mednafen PSX)", for name in ("core_us.bin", "core_jp.bin"):
"systems": ["sony-playstation"], payload = name.encode()
}, path = os.path.join(self.bios_dir, name)
"beebem": {"emulator": "beebem", "systems": ["bbc-micro-b"]}, 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( 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): def test_slot_narrowed_pack_gets_its_own_name(self):
names = { names = {
+16 -1
View File
@@ -26,6 +26,7 @@ from common import ( # noqa: E402
load_data_dir_registry, load_data_dir_registry,
load_database, load_database,
load_emulator_profiles, load_emulator_profiles,
resolution_is_hash_exact,
resolve_local_file, 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). 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 = [] found = []
for profile, dest, status, local in claims: for profile, dest, status, local in claims:
if status != "name_exact" or local not in by_path: 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")] 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): def test_a_file_only_ever_found_by_name_is_not_judged(self):
claims = [ claims = [
("mame2003", "mame2003/cheat.dat", "name_exact", "bios/Arcade/cheat.dat"), ("mame2003", "mame2003/cheat.dat", "name_exact", "bios/Arcade/cheat.dat"),
+17
View File
@@ -285,5 +285,22 @@ class UnreadableReleaseStopsTheScrape(unittest.TestCase):
libretro_scraper.Scraper()._fetch_core_metadata() 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__": if __name__ == "__main__":
unittest.main() unittest.main()
+116 -1
View File
@@ -97,8 +97,123 @@ class ValidatedChoice(unittest.TestCase):
for call in ast.walk(node) 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__": if __name__ == "__main__":
unittest.main() unittest.main()