fix: replay system drops and keep file modes

This commit is contained in:
Abdessamad Derraz committed 2026-10-16 09:44:23 +02:00
1 parent 5fbb1286d0
commit 5cfaf97173
19 files changed
+31572 -525

No files matched your search

+4 -4
View File
@@ -87,12 +87,12 @@ Full list with per-file details: **[https://abdess.github.io/retrobios/](https:/
| Platform | On its BIOS list | Files its emulators load | Checked by |
|----------|-----------------:|-------------------------:|------------|
| Batocera | 353/353 | 12,297/12,727 | MD5 hash |
| BizHawk | 118/118 | 800/801 | SHA1 hash |
| EmuDeck | 168/168 | 430/432 | MD5 hash |
| BizHawk | 118/118 | 801/802 | SHA1 hash |
| EmuDeck | 168/168 | 431/433 | MD5 hash |
| Lakka | 526/526 | 5,260/5,290 | file presence |
| MiSTer FPGA | 81/81 | - | MD5 hash |
| ROCKNIX | 38/38 | 5,697/5,727 | MD5 hash |
| Recalbox | 351/351 | 2,731/2,739 | MD5 hash |
| Recalbox | 351/351 | 2,729/2,737 | MD5 hash |
| RetroArch | 526/526 | 5,260/5,290 | file presence |
| RetroBat | 348/348 | 11,887/12,317 | MD5 hash |
| RetroDECK | 2,008/2,008 | 5,400/5,450 | MD5 hash |
@@ -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-15T22:10:38Z*
*Auto-generated on 2026-10-16T05:35:03Z*
+1 -1
View File
@@ -8,7 +8,7 @@ param(
$ErrorActionPreference = "Stop"
$defaultInstallUrl = "https://raw.githubusercontent.com/Abdess/retrobios/main/install.py"
$defaultInstallSha256 = "0aa7b10a9c6f295366f5d22df012d7205af4ccf4cc9d9cdc9cd90872cc4d6bf3"
$defaultInstallSha256 = "bbc1b4665a37255deecf941765a1c13bb271da54ecf626bd218747165a126820"
$maximumInstallerBytes = 2MB
$installer = if ($PSScriptRoot) { Join-Path $PSScriptRoot "install.py" } else { $null }
$temporary = $null
+25 -5
View File
@@ -199,6 +199,9 @@ class _Interrupted(Exception):
# stops, and the next run asks the server for the rest: the release assets
# run to hundreds of megabytes. Smaller files simply start over.
RESUME_FROM_SIZE = 16 * 1024 * 1024
# Read once, before any download thread runs: reading the umask sets it.
_UMASK = os.umask(0)
os.umask(_UMASK)
def _enable_ansi() -> bool:
@@ -1106,7 +1109,9 @@ def _check_tags(entry: dict, field: str, where: str) -> None:
# What an alternative replaces on the entry it stands in for.
_COPY_FIELDS = ("sha1", "sha256", "size", "repo_path", "release_asset", "storage", "cores")
_COPY_FIELDS = (
"sha1", "sha256", "size", "repo_path", "release_asset", "storage", "cores", "executable",
)
def _check_download(entry: dict, where: str, dest: str) -> int:
@@ -1144,6 +1149,8 @@ def _check_download(entry: dict, where: str, dest: str) -> int:
not isinstance(cores, list) or not all(isinstance(core, str) for core in cores)
):
raise ValueError(f"invalid cores list for {dest}")
if not isinstance(entry.get("executable", False), bool):
raise ValueError(f"invalid executable flag for {dest}")
return size
@@ -1188,7 +1195,7 @@ def _validate_manifest(data: object, plat: str) -> dict:
largest_total += size
if largest_total > MAX_TOTAL_DOWNLOAD_SIZE:
raise ValueError("manifest total size exceeds safety limit")
for field in SELECTION_FIELDS:
for field in (*SELECTION_FIELDS, "declared_in"):
_check_tags(entry, field, dest)
declared_total_files = data.get("total_files")
@@ -1426,8 +1433,9 @@ def narrow_to_cores(
A file a core loads stays when that core is named. A file of the
platform's own list stays when one of its systems does: a system goes
when none of the cores `system_cores` gives it is named, and a system
it does not list stays whatever is named. A manifest without the two
maps keeps the platform's list whole and matches cores by name.
it does not list stays whatever is named. A dropped system's file gives
way to the first named core claiming its destination. A manifest without
the two maps keeps the platform's list whole and matches cores by name.
"""
cores = designated_cores(manifest, names)
reach = manifest.get("system_cores") or {}
@@ -1440,11 +1448,19 @@ def narrow_to_cores(
if copy is not None:
result.append(copy)
continue
systems = entry_systems(entry)
# The systems declaring the file, where they are fewer than the
# ones reading it.
systems = entry.get("declared_in") or entry_systems(entry)
if not systems or any(
s not in reach or cores.intersection(reach[s]) for s in systems
):
result.append(entry)
continue
# The system is dropped, which frees its destination for the
# first named core claiming it, as in a pack built for them.
copy = _for_cores(entry, cores)
if copy is not None:
result.append(copy)
return result
files = manifest.get("files", []) if files is None else files
@@ -1838,6 +1854,10 @@ def _download_one(
reason = "SHA-1 mismatch"
raise _Corrupt()
# The mode a plain open() gives, executable where the repository
# file is: the temporary file is private, and a BIOS folder
# written with sudo has to stay readable by the emulator's user.
os.chmod(tmp_path, (0o777 if f.get("executable") else 0o666) & ~_UMASK)
os.replace(tmp_path, dest)
return f["dest"], True, ""
+1 -1
View File
@@ -18,7 +18,7 @@ esac
TEMP_INSTALLER=""
TEMP_DIRECTORY=""
DEFAULT_INSTALL_URL="https://raw.githubusercontent.com/Abdess/retrobios/main/install.py"
DEFAULT_INSTALL_SHA256="0aa7b10a9c6f295366f5d22df012d7205af4ccf4cc9d9cdc9cd90872cc4d6bf3"
DEFAULT_INSTALL_SHA256="bbc1b4665a37255deecf941765a1c13bb271da54ecf626bd218747165a126820"
MAX_INSTALLER_BYTES=2097152
cleanup() {
+3139 -95
View File
File diff suppressed because it is too large. Load diff
+252 -10
View File
@@ -20,10 +20,10 @@
}
],
"standalone_copies": [],
"total_files": 948,
"total_size": 2585299183,
"pack_files": 950,
"pack_size": 2585299183,
"total_files": 949,
"total_size": 2585301231,
"pack_files": 951,
"pack_size": 2585301231,
"total_omitted": 0,
"omitted_files": [],
"core_names": {
@@ -650,6 +650,17 @@
"cores": null,
"systems": [
"3do"
],
"alternatives": [
{
"sha1": "34bf189111295f74d7b7dfc1f304d98b8d36325a",
"sha256": "41b5b8e7c44e55eaf5cfd4f2a58df42f4a1bbc776723368fb25bf118dd631b1b",
"size": 1048576,
"repo_path": "bios/3DO Company/3DO/panafz1.bin",
"cores": [
"opera"
]
}
]
},
{
@@ -672,6 +683,17 @@
"cores": null,
"systems": [
"3do"
],
"alternatives": [
{
"sha1": "ec7ec62d60ec0459a14ed56ebc66761ef3c80efc",
"sha256": "f356b28b1b35ec27c8697f70d9e0118c4f20609ac5586b9ee4f9241aea96336b",
"size": 1048576,
"repo_path": "bios/3DO Company/3DO/panafz1j.bin",
"cores": [
"opera"
]
}
]
},
{
@@ -683,6 +705,17 @@
"cores": null,
"systems": [
"3do"
],
"alternatives": [
{
"sha1": "3c912300775d1ad730dc35757e279c274c0acaad",
"sha256": "8d72334395cfc98e44c89804eabf036cf95a23645353e7fe8ab886445a3b6354",
"size": 1048576,
"repo_path": "bios/3DO Company/3DO/panafz10.bin",
"cores": [
"opera"
]
}
]
},
{
@@ -694,6 +727,17 @@
"cores": null,
"systems": [
"3do"
],
"alternatives": [
{
"sha1": "a900371f0cdcdc03f79557f11d406fd71251a5fd",
"sha256": "bf83957563970804fa90d0fee02e25c3befe054209d9df488c019715a80b455a",
"size": 1048576,
"repo_path": "bios/3DO Company/3DO/panafz10e-anvil.bin",
"cores": [
"opera"
]
}
]
},
{
@@ -716,6 +760,17 @@
"cores": null,
"systems": [
"3do"
],
"alternatives": [
{
"sha1": "c4a2e5336f77fb5f743de1eea2cda43675ee2de7",
"sha256": "4162ec1bc0f0f449c0457413e8ae8d1e8e351e67e0ccca20d0ac86813e7cfe9b",
"size": 1048576,
"repo_path": "bios/3DO Company/3DO/goldstar.bin",
"cores": [
"opera"
]
}
]
},
{
@@ -738,6 +793,17 @@
"cores": null,
"systems": [
"3do"
],
"alternatives": [
{
"sha1": "b01c53da256dde43ffec4ad3fc3adfa8d635e943",
"sha256": "c1e6bf926afd48d5ea408871a23ba6b4a9b07da411246185ab3d7bb5e435b039",
"size": 1048576,
"repo_path": "bios/3DO Company/3DO/sanyotry.bin",
"cores": [
"opera"
]
}
]
},
{
@@ -760,6 +826,17 @@
"cores": null,
"systems": [
"3do"
],
"alternatives": [
{
"sha1": "520d3d1b5897800af47f92efd2444a26b7a7dead",
"sha256": "72a88b5b47b76bd5604b30c102c948fa7e0ee90ccbc83aba496c45cf90b5a0e7",
"size": 524288,
"repo_path": "bios/3DO Company/3DO/3do_arcade_saot.bin",
"cores": [
"opera"
]
}
]
},
{
@@ -782,6 +859,17 @@
"cores": null,
"systems": [
"3do"
],
"alternatives": [
{
"sha1": "acd39a8fee1b9d2950d5ab447846c11fb31af63e",
"sha256": "303cd0812f2d2f3e703fe901c5d54e1e94c5c78f7e6c9321c2ca66fafa4f9bc6",
"size": 933636,
"repo_path": "bios/3DO Company/3DO/panafz1-kanji.bin",
"cores": [
"opera"
]
}
]
},
{
@@ -793,6 +881,17 @@
"cores": null,
"systems": [
"3do"
],
"alternatives": [
{
"sha1": "2e857b957803d0331fd229328df01f3ffab69eee",
"sha256": "4db281ad37c21ede8cbe343b349f4cd6c3ffc3c47ae2e0de8cedaf043faea97a",
"size": 1048576,
"repo_path": "bios/3DO Company/3DO/panafz10ja-anvil-kanji.bin",
"cores": [
"opera"
]
}
]
},
{
@@ -1200,6 +1299,17 @@
"cores": null,
"systems": [
"nintendo-3ds"
],
"alternatives": [
{
"sha1": "29556640b022cbfaf427874695838b43a5e8aff4",
"sha256": "0d866e062cf62275fbb291ba44af253e67fdc5bd76c7640b6c4a9dfe742510d9",
"size": 7357,
"repo_path": "bios/Nintendo/3DS/aes_keys.txt",
"cores": [
"trident"
]
}
]
},
{
@@ -1211,6 +1321,17 @@
"cores": null,
"systems": [
"nintendo-3ds"
],
"alternatives": [
{
"sha1": "9e2c006997761082be87cf316e57c4da5cddbc62",
"sha256": "ff485c60090185aff05354ece01f86b61f6020332bed0f9090c58d4678e5a180",
"size": 53264,
"repo_path": "bios/Nintendo/3DS/Citra/sysdata/seeddb.bin",
"cores": [
"trident"
]
}
]
},
{
@@ -1324,7 +1445,20 @@
"nintendo-ds"
],
"storage": "release",
"release_asset": "DSi_Nand_JPN.bin"
"release_asset": "DSi_Nand_JPN.bin",
"alternatives": [
{
"sha1": "c82d60626ac05b49ccec0cfb30001d4a3f31c5b9",
"sha256": "6b4c33a189794cd04a7b1359cbf3db86a24ca2c69e1cbefda545d0b34f4b5743",
"size": 251658304,
"repo_path": "bios/Nintendo/DS/DSi_Nand_JPN.bin",
"cores": [
"melonds"
],
"storage": "release",
"release_asset": "DSi_Nand_JPN.bin"
}
]
},
{
"dest": "DSi_Nand_EUR.bin",
@@ -1337,7 +1471,20 @@
"nintendo-ds"
],
"storage": "release",
"release_asset": "DSi_Nand_EUR.bin"
"release_asset": "DSi_Nand_EUR.bin",
"alternatives": [
{
"sha1": "bc4091b6cab4feba3812ac0f23e23d0353481ecf",
"sha256": "e577488f582921bdbfaa12a6255832cf646f5ad9f29214d78404e6005714e8bc",
"size": 251658304,
"repo_path": "bios/Nintendo/DS/DSi_Nand_EUR.bin",
"cores": [
"melonds"
],
"storage": "release",
"release_asset": "DSi_Nand_EUR.bin"
}
]
},
{
"dest": "DSi_Nand_USA.bin",
@@ -1350,7 +1497,20 @@
"nintendo-ds"
],
"storage": "release",
"release_asset": "DSi_Nand_USA.bin"
"release_asset": "DSi_Nand_USA.bin",
"alternatives": [
{
"sha1": "ef08ae02c5fbe1a22a208c36e25607f5a9d5ae98",
"sha256": "42c2c2e4029a05b25a5d61054b29e8192f93d8a33d535d16b3ef128d5dfc83f4",
"size": 251658304,
"repo_path": "bios/Nintendo/DS/DSi_Nand_USA.bin",
"cores": [
"melonds"
],
"storage": "release",
"release_asset": "DSi_Nand_USA.bin"
}
]
},
{
"dest": "DSi_Nand_AUS.bin",
@@ -1363,7 +1523,20 @@
"nintendo-ds"
],
"storage": "release",
"release_asset": "DSi_Nand_AUS.bin"
"release_asset": "DSi_Nand_AUS.bin",
"alternatives": [
{
"sha1": "7d006f8943171a4d50ae89bf2fca12b764d27e8b",
"sha256": "4149fc5552f8932f28b7999de506f2b2a6cf3093140b7bfcdcc88ade51d970d2",
"size": 251658304,
"repo_path": "bios/Nintendo/DS/DSi_Nand_AUS.bin",
"cores": [
"melonds"
],
"storage": "release",
"release_asset": "DSi_Nand_AUS.bin"
}
]
},
{
"dest": "DSi_Nand_CHN.bin",
@@ -1376,7 +1549,20 @@
"nintendo-ds"
],
"storage": "release",
"release_asset": "DSi_Nand_CHN.bin"
"release_asset": "DSi_Nand_CHN.bin",
"alternatives": [
{
"sha1": "4b3b3de0cb2c2aef80daa68394d5b804b8706d9f",
"sha256": "f5ab272f9c62a63d059934f146bf66c2abbfe5e864d852ab7708f97b53ad0fcb",
"size": 251658304,
"repo_path": "bios/Nintendo/DS/DSi_Nand_CHN.bin",
"cores": [
"melonds"
],
"storage": "release",
"release_asset": "DSi_Nand_CHN.bin"
}
]
},
{
"dest": "DSi_Nand_KOR.bin",
@@ -1389,7 +1575,20 @@
"nintendo-ds"
],
"storage": "release",
"release_asset": "DSi_Nand_KOR.bin"
"release_asset": "DSi_Nand_KOR.bin",
"alternatives": [
{
"sha1": "4b061953d8f870bcda006ce86ce136f112cc1793",
"sha256": "9d5ec8ff568b0cde27b9817d9f4901437806265aca59557e69905ed571c120a7",
"size": 251658304,
"repo_path": "bios/Nintendo/DS/DSi_Nand_KOR.bin",
"cores": [
"melonds"
],
"storage": "release",
"release_asset": "DSi_Nand_KOR.bin"
}
]
},
{
"dest": "GB_dmg.bin",
@@ -1730,6 +1929,17 @@
"cores": null,
"systems": [
"sega-32x"
],
"alternatives": [
{
"sha1": "dbebd76a448447cb6e524ac3cb0fd19fc065d944",
"sha256": "a2d6b6e1544467e27d404634de6e6b0a54ed4b3babb6b71739a260e1be04ebfc",
"size": 256,
"repo_path": "bios/Sega/32X/32X_G_BIOS.BIN",
"cores": [
"picodrive"
]
}
]
},
{
@@ -1741,6 +1951,17 @@
"cores": null,
"systems": [
"sega-32x"
],
"alternatives": [
{
"sha1": "1e5b0b2441a4979b6966d942b20cc76c413b8c5e",
"sha256": "4c6128229bd24dae5f11d3f569ca592665f141bef26cef937e2ce4d9b548cc3b",
"size": 2048,
"repo_path": "bios/Sega/32X/32X_M_BIOS.BIN",
"cores": [
"picodrive"
]
}
]
},
{
@@ -1752,6 +1973,17 @@
"cores": null,
"systems": [
"sega-32x"
],
"alternatives": [
{
"sha1": "4103668c1bbd66c5e24558e73d4f3f92061a109a",
"sha256": "7bde4245ce00c51a23a1ce73a881752e7b14dc12416e175352a3807338e04745",
"size": 1024,
"repo_path": "bios/Sega/32X/32X_S_BIOS.BIN",
"cores": [
"picodrive"
]
}
]
},
{
@@ -1963,6 +2195,16 @@
"texas-instruments-ti-83"
]
},
{
"dest": "5200.rom",
"sha1": "6ad7a1e8c9fad486fbec9498cb48bf5bc3adc530",
"sha256": "06b250f18983d058c0f156ce7ee88ae48b6eaf11e6f10f21dccf6ac7ffb6a6af",
"size": 2048,
"repo_path": "bios/Atari/5200/5200.rom",
"cores": [
"ares"
]
},
{
"dest": "colecovision.rom",
"sha1": "45bedc4cbdeac66c7df59e9e599195c778d86a92",
+278 -60
View File
@@ -250,10 +250,10 @@
}
}
],
"total_files": 618,
"total_size": 3472458179,
"pack_files": 620,
"pack_size": 3472458179,
"total_files": 620,
"total_size": 3482879822,
"pack_files": 622,
"pack_size": 3482879822,
"total_omitted": 0,
"omitted_files": [],
"core_names": {
@@ -584,6 +584,17 @@
"cores": null,
"systems": [
"coleco-colecovision"
],
"alternatives": [
{
"sha1": "45bedc4cbdeac66c7df59e9e599195c778d86a92",
"sha256": "990bf1956f10207d8781b619eb74f89b00d921c8d45c95c334c16c8cceca09ad",
"size": 8192,
"repo_path": "bios/Coleco/ColecoVision/BIOS.col",
"cores": [
"ares"
]
}
]
},
{
@@ -639,6 +650,17 @@
"cores": null,
"systems": [
"nintendo-ds"
],
"alternatives": [
{
"sha1": "24f67bdea115a2c847c8813a262502ee1607b7df",
"sha256": "ba65f690eb04ec92db67c0e299e21ad71de087d6d5de8a9cb17a62eaab563c17",
"size": 16384,
"repo_path": "bios/Nintendo/DS/NDS_Bios7.bin",
"cores": [
"melonds"
]
}
]
},
{
@@ -650,6 +672,17 @@
"cores": null,
"systems": [
"nintendo-ds"
],
"alternatives": [
{
"sha1": "bfaac75f101c135e32e2aaf541de6b1be4c8c62d",
"sha256": "1693983a7707ae394786fa526c0552457888a51d4e410d715ef07acd5a540555",
"size": 4096,
"repo_path": "bios/Nintendo/DS/NDS_Bios9.bin",
"cores": [
"melonds"
]
}
]
},
{
@@ -661,6 +694,17 @@
"cores": null,
"systems": [
"nintendo-ds"
],
"alternatives": [
{
"sha1": "cfe072921ee3fb93f688743f8beef89043c3e9ad",
"sha256": "57a1d6b43c1399d219ea18644240c4d4c6787c829f0a67ded216472867857cd0",
"size": 262144,
"repo_path": "bios/Nintendo/Nintendo DS/firmware.bin",
"cores": [
"melonds"
]
}
]
},
{
@@ -691,6 +735,17 @@
"cores": null,
"systems": [
"nintendo-nes"
],
"alternatives": [
{
"sha1": "af5af53f66982e749643fdf8b2acbb7d4d3ed229",
"sha256": "fdc1a76e654feea993fcb38366e05ee5f4eb641f86fe6bebaeefd412e112dd72",
"size": 8192,
"repo_path": "bios/Nintendo/Famicom Disk System/.variants/disksys.rom.af5af53f",
"cores": [
"ares"
]
}
]
},
{
@@ -735,6 +790,17 @@
"cores": null,
"systems": [
"sega-dreamcast"
],
"alternatives": [
{
"sha1": "8951d1bb219ab2ff8583033d2119c899cc81f18c",
"sha256": "88d6a666495ad14ab5988d8cb730533cfc94ec2cfd53a7eeda14642ab0d4abf9",
"size": 2097152,
"repo_path": "bios/Sega/Dreamcast/dc_bios.bin",
"cores": [
"flycast"
]
}
]
},
{
@@ -757,6 +823,17 @@
"cores": null,
"systems": [
"sega-dreamcast-arcade"
],
"alternatives": [
{
"sha1": "788aee0f30ee80ea54dcd705afe93944accafc31",
"sha256": "62a011c3a4dc5686ebced343987199bd7ccad1578ca8e2f2350b41204d87de65",
"size": 9651827,
"repo_path": "bios/Arcade/Arcade/naomi.zip",
"cores": [
"flycast"
]
}
]
},
{
@@ -768,6 +845,17 @@
"cores": null,
"systems": [
"sega-mega-cd"
],
"alternatives": [
{
"sha1": "7063192ae9f6b696c5b81bc8f0a9fe6f0c400e58",
"sha256": "fe608a2a07676a23ab5fd5eee2f53c9e2526d69a28aa16ccd85c0ec42e6933cb",
"size": 131072,
"repo_path": "bios/Sega/Mega CD/eu_mcd2_9303.bin",
"cores": [
"ares"
]
}
]
},
{
@@ -779,6 +867,17 @@
"cores": null,
"systems": [
"sega-mega-cd"
],
"alternatives": [
{
"sha1": "5a8c4b91d3034c1448aac4b5dc9a6484fce51636",
"sha256": "fb477cdbf94c84424c2feca4fe40656d85393fe7b7b401911b45ad2eb991258c",
"size": 131072,
"repo_path": "bios/Sega/Mega CD/SegaCDBIOS9303.bin",
"cores": [
"ares"
]
}
]
},
{
@@ -790,6 +889,17 @@
"cores": null,
"systems": [
"sega-mega-cd"
],
"alternatives": [
{
"sha1": "d203cfe22c03ae479dd8ca33840cf8d9776eb3ff",
"sha256": "7133fc2dd2fe5b7d0acd53a5f10f3d00b5d31270239ad20d74ef32393e24af88",
"size": 131072,
"repo_path": "bios/Sega/Mega CD/jp_mcd2_921222.bin",
"cores": [
"ares"
]
}
]
},
{
@@ -835,6 +945,17 @@
"systems": [
"snk-neogeo",
"snk-neogeo-cd"
],
"alternatives": [
{
"sha1": "447e23757e5be7ae688885a5ce8ea3da8c8bedc0",
"sha256": "9a8cf2b88488969d7000028b30474175067f753a649a1fe0c008efd8450d60a0",
"size": 1952551,
"repo_path": "bios/Arcade/MAME/neogeo.zip",
"cores": [
"mame"
]
}
]
},
{
@@ -858,6 +979,18 @@
"cores": null,
"systems": [
"sony-playstation"
],
"alternatives": [
{
"sha1": "b05def971d8ec59f346f2d9ac21fb742e3eb6917",
"sha256": "9c0421858e217805f4abe18698afea8d5aa36ff0727eb8484944e00eb5e7eadb",
"size": 524288,
"repo_path": "bios/Sony/PlayStation/scph5500.bin",
"cores": [
"ares",
"duckstation"
]
}
]
},
{
@@ -869,6 +1002,18 @@
"cores": null,
"systems": [
"sony-playstation"
],
"alternatives": [
{
"sha1": "0555c6fae8906f3f09baf5988f00e55f88e9f30b",
"sha256": "11052b6499e466bbf0a709b1f9cb6834a9418e66680387912451e971cf8a1fef",
"size": 524288,
"repo_path": "bios/Sony/PlayStation/scph5501.bin",
"cores": [
"ares",
"duckstation"
]
}
]
},
{
@@ -880,6 +1025,18 @@
"cores": null,
"systems": [
"sony-playstation"
],
"alternatives": [
{
"sha1": "f6bc2d1f5eb6593de7d089c425ac681d6fffd3f0",
"sha256": "1faaa18fa820a0225e488d9f086296b8e6c46df739666093987ff7d8fd352c09",
"size": 524288,
"repo_path": "bios/Sony/PlayStation/scph5502.bin",
"cores": [
"ares",
"duckstation"
]
}
]
},
{
@@ -946,6 +1103,17 @@
"cores": null,
"systems": [
"xbox"
],
"alternatives": [
{
"sha1": "5d270675b54eb8071b480e42d22a3015ac211cef",
"sha256": "e99e3a772bf5f5d262786aee895664eb96136196e37732fe66e14ae062f20335",
"size": 512,
"repo_path": "bios/Microsoft/Xbox/mcpx_1.0.bin",
"cores": [
"xemu"
]
}
]
},
{
@@ -959,6 +1127,16 @@
"xbox"
]
},
{
"dest": "5200.rom",
"sha1": "6ad7a1e8c9fad486fbec9498cb48bf5bc3adc530",
"sha256": "06b250f18983d058c0f156ce7ee88ae48b6eaf11e6f10f21dccf6ac7ffb6a6af",
"size": 2048,
"repo_path": "bios/Atari/5200/5200.rom",
"cores": [
"ares"
]
},
{
"dest": "gba_bios.bin",
"sha1": "300c20df6731a33952ded8c436f7f186d25d3492",
@@ -1507,7 +1685,8 @@
],
"systems": [
"nintendo-wii-u"
]
],
"executable": true
},
{
"dest": "Cemu/cafeLibs/snduser2.rpl",
@@ -1520,7 +1699,8 @@
],
"systems": [
"nintendo-wii-u"
]
],
"executable": true
},
{
"dest": "Cemu/cafeLibs/swkbd.rpl",
@@ -1533,7 +1713,8 @@
],
"systems": [
"nintendo-wii-u"
]
],
"executable": true
},
{
"dest": "Cemu/cafeLibs/erreula.rpl",
@@ -1546,7 +1727,8 @@
],
"systems": [
"nintendo-wii-u"
]
],
"executable": true
},
{
"dest": "switch/title.keys",
@@ -6473,7 +6655,8 @@
"repo_path": "bios/Sony/PlayStation 4/shadps4/sys_modules/libSceLibcInternal.sprx",
"cores": [
"shadps4"
]
],
"executable": true
},
{
"dest": "shadps4/sys_modules/libSceNgs2.sprx",
@@ -6483,7 +6666,8 @@
"repo_path": "bios/Sony/PlayStation 4/shadps4/sys_modules/libSceNgs2.sprx",
"cores": [
"shadps4"
]
],
"executable": true
},
{
"dest": "shadps4/sys_modules/libSceUlt.sprx",
@@ -6493,7 +6677,8 @@
"repo_path": "bios/Sony/PlayStation 4/shadps4/sys_modules/libSceUlt.sprx",
"cores": [
"shadps4"
]
],
"executable": true
},
{
"dest": "shadps4/sys_modules/libSceRtc.sprx",
@@ -6503,7 +6688,8 @@
"repo_path": "bios/Sony/PlayStation 4/shadps4/sys_modules/libSceRtc.sprx",
"cores": [
"shadps4"
]
],
"executable": true
},
{
"dest": "shadps4/sys_modules/libSceJpegDec.sprx",
@@ -6513,7 +6699,8 @@
"repo_path": "bios/Sony/PlayStation 4/shadps4/sys_modules/libSceJpegDec.sprx",
"cores": [
"shadps4"
]
],
"executable": true
},
{
"dest": "shadps4/sys_modules/libSceJpegEnc.sprx",
@@ -6523,7 +6710,8 @@
"repo_path": "bios/Sony/PlayStation 4/shadps4/sys_modules/libSceJpegEnc.sprx",
"cores": [
"shadps4"
]
],
"executable": true
},
{
"dest": "shadps4/sys_modules/libScePngEnc.sprx",
@@ -6533,7 +6721,8 @@
"repo_path": "bios/Sony/PlayStation 4/shadps4/sys_modules/libScePngEnc.sprx",
"cores": [
"shadps4"
]
],
"executable": true
},
{
"dest": "shadps4/sys_modules/libSceJson.sprx",
@@ -6543,7 +6732,8 @@
"repo_path": "bios/Sony/PlayStation 4/shadps4/sys_modules/libSceJson.sprx",
"cores": [
"shadps4"
]
],
"executable": true
},
{
"dest": "shadps4/sys_modules/libSceJson2.sprx",
@@ -6553,7 +6743,8 @@
"repo_path": "bios/Sony/PlayStation 4/shadps4/sys_modules/libSceJson2.sprx",
"cores": [
"shadps4"
]
],
"executable": true
},
{
"dest": "shadps4/sys_modules/libSceCesCs.sprx",
@@ -6563,7 +6754,8 @@
"repo_path": "bios/Sony/PlayStation 4/shadps4/sys_modules/libSceCesCs.sprx",
"cores": [
"shadps4"
]
],
"executable": true
},
{
"dest": "shadps4/sys_modules/libSceAt9Enc.sprx",
@@ -6573,7 +6765,8 @@
"repo_path": "bios/Other/shadps4/shadps4/sys_modules/libSceAt9Enc.sprx",
"cores": [
"shadps4"
]
],
"executable": true
},
{
"dest": "shadps4/sys_modules/libSceAudiodec.sprx",
@@ -6583,7 +6776,8 @@
"repo_path": "bios/Sony/PlayStation 4/shadps4/sys_modules/libSceAudiodec.sprx",
"cores": [
"shadps4"
]
],
"executable": true
},
{
"dest": "shadps4/sys_modules/libSceAudiodecCpu.sprx",
@@ -6593,7 +6787,8 @@
"repo_path": "bios/Other/shadps4/shadps4/sys_modules/libSceAudiodecCpu.sprx",
"cores": [
"shadps4"
]
],
"executable": true
},
{
"dest": "shadps4/sys_modules/libSceAudiodecCpuDdp.sprx",
@@ -6603,7 +6798,8 @@
"repo_path": "bios/Other/shadps4/shadps4/sys_modules/libSceAudiodecCpuDdp.sprx",
"cores": [
"shadps4"
]
],
"executable": true
},
{
"dest": "shadps4/sys_modules/libSceAudiodecCpuM4aac.sprx",
@@ -6613,7 +6809,8 @@
"repo_path": "bios/Other/shadps4/shadps4/sys_modules/libSceAudiodecCpuM4aac.sprx",
"cores": [
"shadps4"
]
],
"executable": true
},
{
"dest": "shadps4/sys_modules/libSceAudiodecCpuDtsHdLbr.sprx",
@@ -6623,7 +6820,8 @@
"repo_path": "bios/Other/shadps4/shadps4/sys_modules/libSceAudiodecCpuDtsHdLbr.sprx",
"cores": [
"shadps4"
]
],
"executable": true
},
{
"dest": "shadps4/sys_modules/libSceAudiodecCpuHevag.sprx",
@@ -6633,7 +6831,8 @@
"repo_path": "bios/Other/shadps4/shadps4/sys_modules/libSceAudiodecCpuHevag.sprx",
"cores": [
"shadps4"
]
],
"executable": true
},
{
"dest": "shadps4/sys_modules/libSceFont.sprx",
@@ -6643,7 +6842,8 @@
"repo_path": "bios/Sony/PlayStation 4/shadps4/sys_modules/libSceFont.sprx",
"cores": [
"shadps4"
]
],
"executable": true
},
{
"dest": "shadps4/sys_modules/libSceFontFt.sprx",
@@ -6653,7 +6853,8 @@
"repo_path": "bios/Sony/PlayStation 4/shadps4/sys_modules/libSceFontFt.sprx",
"cores": [
"shadps4"
]
],
"executable": true
},
{
"dest": "shadps4/sys_modules/libSceFreeTypeOt.sprx",
@@ -6663,7 +6864,8 @@
"repo_path": "bios/Sony/PlayStation 4/shadps4/sys_modules/libSceFreeTypeOt.sprx",
"cores": [
"shadps4"
]
],
"executable": true
},
{
"dest": "shadps4/sys_modules/libSceFreeTypeOl.sprx",
@@ -6673,7 +6875,8 @@
"repo_path": "bios/Other/shadps4/shadps4/sys_modules/libSceFreeTypeOl.sprx",
"cores": [
"shadps4"
]
],
"executable": true
},
{
"dest": "shadps4/sys_modules/libSceFreeTypeOptOl.sprx",
@@ -6683,7 +6886,8 @@
"repo_path": "bios/Other/shadps4/shadps4/sys_modules/libSceFreeTypeOptOl.sprx",
"cores": [
"shadps4"
]
],
"executable": true
},
{
"dest": "shadps4/sys_modules/libSceRudp.sprx",
@@ -6693,7 +6897,8 @@
"repo_path": "bios/Other/shadps4/shadps4/sys_modules/libSceRudp.sprx",
"cores": [
"shadps4"
]
],
"executable": true
},
{
"dest": "shadps4/sys_modules/libSceWkFontConfig.sprx",
@@ -6703,7 +6908,8 @@
"repo_path": "bios/Other/shadps4/shadps4/sys_modules/libSceWkFontConfig.sprx",
"cores": [
"shadps4"
]
],
"executable": true
},
{
"dest": "shadps4/sys_modules/libSceSystemGesture.sprx",
@@ -6713,7 +6919,8 @@
"repo_path": "bios/Other/shadps4/shadps4/sys_modules/libSceSystemGesture.sprx",
"cores": [
"shadps4"
]
],
"executable": true
},
{
"dest": "shadps4/sys_modules/libSceXml.sprx",
@@ -6723,7 +6930,8 @@
"repo_path": "bios/Other/shadps4/shadps4/sys_modules/libSceXml.sprx",
"cores": [
"shadps4"
]
],
"executable": true
},
{
"dest": "supermodel/Games.xml",
@@ -6947,6 +7155,29 @@
"Dolphin:file:GC/JAP/IPL.bin"
]
},
{
"dest": "naomi.zip",
"sha1": "a39d7d17e52c26435ed1745503c7d6a68b36be1d",
"sha256": "9b85d2183bc3739efa2ebf1440c73abb252c6ca8944efcff3a7204645f7e03d4",
"size": 10419595,
"repo_path": "bios/Arcade/MAME/naomi.zip",
"cores": [
"mame"
]
},
{
"dest": "ps2-0230a-20080220.bin",
"sha1": "f9229fe159d0353b9f0632f3fdc66819c9030458",
"sha256": "f609ed1ca62437519828cdd824b5ea79417fd756e71a4178443483e3781fedd2",
"size": 4194304,
"repo_path": "bios/Sony/PlayStation 2/ps2-0230a-20080220.bin",
"cores": [
"pcsx2"
],
"systems": [
"sony-playstation-2"
]
},
{
"dest": "eeprom.dat",
"sha1": "ffc6261e487efa8c7442069f71acfc4aa826993d",
@@ -8254,32 +8485,6 @@
"sony-playstation-2"
]
},
{
"dest": "ps2-0230a-20080220.bin",
"sha1": "f9229fe159d0353b9f0632f3fdc66819c9030458",
"sha256": "f609ed1ca62437519828cdd824b5ea79417fd756e71a4178443483e3781fedd2",
"size": 4194304,
"repo_path": "bios/Sony/PlayStation 2/ps2-0230a-20080220.bin",
"cores": [
"pcsx2"
],
"systems": [
"sony-playstation-2"
]
},
{
"dest": "ps2-0230a-20080220.nvm",
"sha1": "258ad0f26b0b269462bbd9acbb5506d5dfbcc3d5",
"sha256": "e017efa804f1f7d4d3da82b67d7370c5be062b4860f1cff4f898f93437d691a0",
"size": 1024,
"repo_path": "bios/Sony/PlayStation 2/ps2-0230a-20080220.nvm",
"cores": [
"pcsx2"
],
"systems": [
"sony-playstation-2"
]
},
{
"dest": "ps2-0230e-20080220.bin",
"sha1": "9915b5ba56798f4027ac1bd8d10abe0c1c9c326a",
@@ -8592,6 +8797,19 @@
"sony-playstation-2"
]
},
{
"dest": "ps2-0230a-20080220.nvm",
"sha1": "258ad0f26b0b269462bbd9acbb5506d5dfbcc3d5",
"sha256": "e017efa804f1f7d4d3da82b67d7370c5be062b4860f1cff4f898f93437d691a0",
"size": 1024,
"repo_path": "bios/Sony/PlayStation 2/ps2-0230a-20080220.nvm",
"cores": [
"pcsx2"
],
"systems": [
"sony-playstation-2"
]
},
{
"dest": "scph30004fr.nvm",
"sha1": "92ce9e739dcbfa0d6afb442620b71919d26bf283",
+5521 -18
View File
File diff suppressed because it is too large. Load diff
+3620 -64
View File
File diff suppressed because it is too large. Load diff
+5521 -18
View File
File diff suppressed because it is too large. Load diff
+2001 -87
View File
File diff suppressed because it is too large. Load diff
+4854 -48
View File
File diff suppressed because it is too large. Load diff
+5639 -51
View File
File diff suppressed because it is too large. Load diff
+537 -24
View File
@@ -17,10 +17,10 @@
}
],
"standalone_copies": [],
"total_files": 5803,
"total_size": 6570151065,
"pack_files": 5805,
"pack_size": 6570151065,
"total_files": 5805,
"total_size": 6570282649,
"pack_files": 5807,
"pack_size": 6570282649,
"total_omitted": 0,
"omitted_files": [],
"core_names": {
@@ -496,6 +496,20 @@
"cores": null,
"systems": [
"nintendo-ds"
],
"alternatives": [
{
"sha1": "cfe072921ee3fb93f688743f8beef89043c3e9ad",
"sha256": "57a1d6b43c1399d219ea18644240c4d4c6787c829f0a67ded216472867857cd0",
"size": 262144,
"repo_path": "bios/Nintendo/Nintendo DS/firmware.bin",
"cores": [
"desmume",
"melonds",
"melonds_ds",
"noods"
]
}
]
},
{
@@ -507,6 +521,20 @@
"cores": null,
"systems": [
"nintendo-ds"
],
"alternatives": [
{
"sha1": "24f67bdea115a2c847c8813a262502ee1607b7df",
"sha256": "ba65f690eb04ec92db67c0e299e21ad71de087d6d5de8a9cb17a62eaab563c17",
"size": 16384,
"repo_path": "bios/Nintendo/DS/NDS_Bios7.bin",
"cores": [
"desmume",
"melonds",
"melonds_ds",
"noods"
]
}
]
},
{
@@ -518,6 +546,20 @@
"cores": null,
"systems": [
"nintendo-ds"
],
"alternatives": [
{
"sha1": "bfaac75f101c135e32e2aaf541de6b1be4c8c62d",
"sha256": "1693983a7707ae394786fa526c0552457888a51d4e410d715ef07acd5a540555",
"size": 4096,
"repo_path": "bios/Nintendo/DS/NDS_Bios9.bin",
"cores": [
"desmume",
"melonds",
"melonds_ds",
"noods"
]
}
]
},
{
@@ -529,6 +571,18 @@
"cores": null,
"systems": [
"nintendo-ds"
],
"alternatives": [
{
"sha1": "c7c7570bfe51c3c7c5da3b01331b94e7e7cb4f53",
"sha256": "12a03016ba07cfd874fc002df49a2c6eb2414eb7cfa395c2043035ec5e9193e8",
"size": 65536,
"repo_path": "bios/Nintendo/DS/NDS_Bios7i.bin",
"cores": [
"melonds",
"melonds_ds"
]
}
]
},
{
@@ -540,6 +594,18 @@
"cores": null,
"systems": [
"nintendo-ds"
],
"alternatives": [
{
"sha1": "719b9eef33692406d7170ff526069615759c4dfc",
"sha256": "6e9f70b51dc4f26289b597f14e2513620c2af964374a95f4c5a62b5cad199afc",
"size": 65536,
"repo_path": "bios/Nintendo/DS/NDS_Bios9i.bin",
"cores": [
"melonds",
"melonds_ds"
]
}
]
},
{
@@ -551,6 +617,18 @@
"cores": null,
"systems": [
"nintendo-ds"
],
"alternatives": [
{
"sha1": "d2a5af338f09c5cbdd5d7628db5b9c075c69b616",
"sha256": "1d7c771de535e6e07182fc9820ac32e76c6f0b5bcefd256a861fdfab144761ec",
"size": 131072,
"repo_path": "bios/Nintendo/Nintendo DS/dsi_firmware.bin",
"cores": [
"melonds",
"melonds_ds"
]
}
]
},
{
@@ -564,7 +642,21 @@
"nintendo-ds"
],
"storage": "release",
"release_asset": "dsi_nand.bin.8b79a73c"
"release_asset": "dsi_nand.bin.8b79a73c",
"alternatives": [
{
"sha1": "b48f44194fe918aaaec5298861479512b581d661",
"sha256": "f57d9bf00529bec35d58404faff029a193fd2ccda0a83403ec4e6cc32626721b",
"size": 251658304,
"repo_path": "bios/Nintendo/DS/dsi_nand.bin",
"cores": [
"melonds",
"melonds_ds"
],
"storage": "release",
"release_asset": "dsi_nand.bin"
}
]
},
{
"dest": "GC/EUR/IPL.bin",
@@ -584,6 +676,18 @@
],
"region_system_groups": [
"nintendo-gamecube"
],
"alternatives": [
{
"sha1": "80b8744ff5e43585392f55546bd03a673d11ef5f",
"sha256": "85ffcbc834238eb24c87fce27ba7b438cc53a77db013a0a7c59c78e0af08cb84",
"size": 2097152,
"repo_path": "bios/Nintendo/GameCube/GC/EUR/IPL.bin",
"cores": [
"dolphin",
"ishiiruka"
]
}
]
},
{
@@ -604,6 +708,18 @@
],
"region_system_groups": [
"nintendo-gamecube"
],
"alternatives": [
{
"sha1": "a1837968288253ed541f2b11440b68f5a9b33875",
"sha256": "5b2f2617cc63f1861a1f4ae44bb135caf10e202b5b9b79271daaf60f8caaf37d",
"size": 2097152,
"repo_path": "bios/Nintendo/GameCube/GC/JAP/IPL.bin",
"cores": [
"dolphin",
"ishiiruka"
]
}
]
},
{
@@ -624,6 +740,18 @@
],
"region_system_groups": [
"nintendo-gamecube"
],
"alternatives": [
{
"sha1": "ef9194ab4804aa0aa8540d846caf291b28331165",
"sha256": "7c833f95839c226699108b93ab6acbe772788bfa3f05132b8ced5e78f5bc9a26",
"size": 2097152,
"repo_path": "bios/Nintendo/GameCube/GC/USA/IPL.bin",
"cores": [
"dolphin",
"ishiiruka"
]
}
]
},
{
@@ -635,6 +763,19 @@
"cores": null,
"systems": [
"nintendo-gb"
],
"alternatives": [
{
"sha1": "4ed31ec6b0b175bb109c0eb5fd3d193da823339f",
"sha256": "cf053eccb4ccafff9e67339d4e78e98dce7d1ed59be819d2a1ba2232c6fce1c7",
"size": 256,
"repo_path": "bios/Nintendo/Game Boy/GB_dmg.bin",
"cores": [
"gambatte",
"mgba",
"vbam"
]
}
]
},
{
@@ -646,6 +787,26 @@
"cores": null,
"systems": [
"nintendo-gba"
],
"alternatives": [
{
"sha1": "300c20df6731a33952ded8c436f7f186d25d3492",
"sha256": "fd2547724b505f487e6dcb29ec2ecff3af35a841a77ab2e85fd87350abd36570",
"size": 16384,
"repo_path": "bios/Nintendo/Game Boy Advance/GBA_bios.rom",
"cores": [
"beetle_gba",
"gpsp",
"mednafen_gba",
"mesence",
"mgba",
"mgba_splitscreen",
"noods",
"tempgba",
"vba_next",
"vbam"
]
}
]
},
{
@@ -657,6 +818,20 @@
"cores": null,
"systems": [
"nintendo-gbc"
],
"alternatives": [
{
"sha1": "1293d68bf9643bc4f36954c1e80e38f39864528d",
"sha256": "b4f2e416a35eef52cba161b159c7c8523a92594facb924b3ede0d722867c50c7",
"size": 2304,
"repo_path": "bios/Nintendo/Game Boy Color/GBC_cgb.bin",
"cores": [
"fixgb",
"gambatte",
"mgba",
"vbam"
]
}
]
},
{
@@ -668,6 +843,17 @@
"cores": null,
"systems": [
"sega-dreamcast"
],
"alternatives": [
{
"sha1": "8951d1bb219ab2ff8583033d2119c899cc81f18c",
"sha256": "88d6a666495ad14ab5988d8cb730533cfc94ec2cfd53a7eeda14642ab0d4abf9",
"size": 2097152,
"repo_path": "bios/Sega/Dreamcast/dc_bios.bin",
"cores": [
"flycast"
]
}
]
},
{
@@ -690,6 +876,17 @@
"cores": null,
"systems": [
"sega-dreamcast"
],
"alternatives": [
{
"sha1": "6d27d71aec4dfba98f66316ae74a1426d567698a",
"sha256": "d821817411834ea0e98ae48b1e2268b12e7d599630556fa5da1792c6e1a2c66f",
"size": 2097152,
"repo_path": "bios/Sega/Dreamcast/naomi_boot.bin",
"cores": [
"flycast"
]
}
]
},
{
@@ -701,6 +898,20 @@
"cores": null,
"systems": [
"sega-game-gear"
],
"alternatives": [
{
"sha1": "914aa165e3d879f060be77870d345b60cfeb4ede",
"sha256": "8c8a21335038285cfa03dc076100c1f0bfadf3e4ff70796f11f3dfaaab60eee2",
"size": 1024,
"repo_path": "bios/Sega/Game Gear/GG_majesco.gg",
"cores": [
"gearsystem",
"genesis_plus_gx",
"genesis_plus_gx_wide",
"mesence"
]
}
]
},
{
@@ -712,6 +923,20 @@
"cores": null,
"systems": [
"sega-master-system"
],
"alternatives": [
{
"sha1": "c315672807d8ddb8d91443729405c766dd95cae7",
"sha256": "477617917a12a30f9f43844909dc2de6e6a617430f5c9a36306c86414a670d50",
"size": 8192,
"repo_path": "bios/Other/zesarux/sms.rom",
"cores": [
"emux_sms",
"gearsystem",
"mesence",
"smsplus"
]
}
]
},
{
@@ -723,6 +948,19 @@
"cores": null,
"systems": [
"sega-mega-cd"
],
"alternatives": [
{
"sha1": "f891e0ea651e2232af0c5c4cb46a0cae2ee8f356",
"sha256": "16735df92fcc1d0fc6a1eced244867e95281c5006340926082b74e363e073dc4",
"size": 131072,
"repo_path": "bios/Sega/Mega CD/MCD_eu_100.bin",
"cores": [
"genesis_plus_gx",
"genesis_plus_gx_wide",
"picodrive"
]
}
]
},
{
@@ -734,6 +972,19 @@
"cores": null,
"systems": [
"sega-mega-cd"
],
"alternatives": [
{
"sha1": "f4f315adcef9b8feb0364c21ab7f0eaf5457f3ed",
"sha256": "807384678ef259494d943eddb6954dfc7069693d0dde0c424e2028488d88e81a",
"size": 131072,
"repo_path": "bios/Sega/Mega CD/bios_CD_U.bin",
"cores": [
"genesis_plus_gx",
"genesis_plus_gx_wide",
"picodrive"
]
}
]
},
{
@@ -745,6 +996,19 @@
"cores": null,
"systems": [
"sega-mega-cd"
],
"alternatives": [
{
"sha1": "4846f448160059a7da0215a5df12ca160f26dd69",
"sha256": "923eb9da740f98ab1572085e3d351e2c0982df0906b0b99efb68a9997c94cf8f",
"size": 131072,
"repo_path": "bios/Sega/Mega CD/MCD_jp_100p.bin",
"cores": [
"genesis_plus_gx",
"genesis_plus_gx_wide",
"picodrive"
]
}
]
},
{
@@ -756,6 +1020,21 @@
"cores": null,
"systems": [
"sega-saturn"
],
"alternatives": [
{
"sha1": "df94c5b4d47eb3cc404d88b33a8fda237eaf4720",
"sha256": "dcfef4b99605f872b6c3b6d05c045385cdea3d1b702906a0ed930df7bcb7deac",
"size": 524288,
"repo_path": "bios/Sega/Saturn/SAT_1.01-(J).bin",
"cores": [
"beetle_saturn",
"kronos",
"yabasanshiro",
"yabause",
"ymir"
]
}
]
},
{
@@ -767,6 +1046,20 @@
"cores": null,
"systems": [
"sega-saturn"
],
"alternatives": [
{
"sha1": "faa8ea183a6d7bbe5d4e03bb1332519800d3fbc3",
"sha256": "96e106f740ab448cf89f0dd49dfbac7fe5391cb6bd6e14ad5e3061c13330266f",
"size": 524288,
"repo_path": "bios/Sega/Saturn/SAT_1.00-(U+E).bin",
"cores": [
"beetle_saturn",
"kronos",
"yabasanshiro",
"yabause"
]
}
]
},
{
@@ -778,6 +1071,19 @@
"cores": null,
"systems": [
"sega-saturn"
],
"alternatives": [
{
"sha1": "a67cd4f550751f8b91de2b8b74528ab4e0c11c77",
"sha256": "1dd154a9fcee1816749502b5b2497bf4b1f2d973df38d0984905ee83b12d5e81",
"size": 2097152,
"repo_path": "bios/Sega/Saturn/SAT_KoF95.bin",
"cores": [
"beetle_saturn",
"kronos",
"ymir"
]
}
]
},
{
@@ -789,6 +1095,19 @@
"cores": null,
"systems": [
"sega-saturn"
],
"alternatives": [
{
"sha1": "56c1b93da6b660bf393fbf48ca47569000ef4047",
"sha256": "6e3b35af6e45d9005460cfe44e3907563bde7a4636926ebd316dc84913efdd1b",
"size": 2097152,
"repo_path": "bios/Sega/Saturn/SAT_Ultraman.bin",
"cores": [
"beetle_saturn",
"kronos",
"ymir"
]
}
]
},
{
@@ -800,6 +1119,18 @@
"cores": null,
"systems": [
"sega-saturn"
],
"alternatives": [
{
"sha1": "2b8cb4f87580683eb4d760e4ed210813d667f0a2",
"sha256": "ae4058627bb5db9be6d8d83c6be95a4aa981acc8a89042e517e73317886c8bc2",
"size": 524288,
"repo_path": "bios/Sega/Saturn/sega_100.bin",
"cores": [
"yabasanshiro",
"yabause"
]
}
]
},
{
@@ -811,6 +1142,19 @@
"cores": null,
"systems": [
"sony-playstation"
],
"alternatives": [
{
"sha1": "96880d1ca92a016ff054be5159bb06fe03cb4e14",
"sha256": "cbe758e1c8ece593c8e14ce1e8b3436428a01c608032a02613b3a4b442b4d712",
"size": 524288,
"repo_path": "bios/Sony/PlayStation/psxonpsp660.bin",
"cores": [
"beetle_psx",
"pcsx_rearmed",
"swanstation"
]
}
]
},
{
@@ -826,8 +1170,23 @@
"regions": [
"north-america"
],
"region_groups": [
"sony-playstation"
],
"region_system_groups": [
"sony-playstation"
],
"alternatives": [
{
"sha1": "dcffe16bd90a723499ad46c641424981338d8378",
"sha256": "aca9cbfa974b933646baad6556a867eca9b81ce65d8af343a7843f7775b9ffc8",
"size": 524288,
"repo_path": "bios/Sony/PlayStation/scph101.bin",
"cores": [
"pcsx_rearmed",
"rustation"
]
}
]
},
{
@@ -839,6 +1198,20 @@
"cores": null,
"systems": [
"sony-playstation"
],
"alternatives": [
{
"sha1": "10155d8d6e6e832d6ea66db9bc098321fb5e8ebf",
"sha256": "71af94d1e47a68c11e8fdb9f8368040601514a42a5a399cda48c7d3bff1e99d3",
"size": 524288,
"repo_path": "bios/Sony/PlayStation/scph1001.bin",
"cores": [
"duckstation",
"pcsx1",
"pcsx_rearmed",
"rustation"
]
}
]
},
{
@@ -850,6 +1223,21 @@
"cores": null,
"systems": [
"sony-playstation"
],
"alternatives": [
{
"sha1": "b05def971d8ec59f346f2d9ac21fb742e3eb6917",
"sha256": "9c0421858e217805f4abe18698afea8d5aa36ff0727eb8484944e00eb5e7eadb",
"size": 524288,
"repo_path": "bios/Sony/PlayStation/scph5500.bin",
"cores": [
"beetle_psx",
"duckstation",
"pcsx_rearmed",
"rustation",
"swanstation"
]
}
]
},
{
@@ -861,6 +1249,22 @@
"cores": null,
"systems": [
"sony-playstation"
],
"alternatives": [
{
"sha1": "0555c6fae8906f3f09baf5988f00e55f88e9f30b",
"sha256": "11052b6499e466bbf0a709b1f9cb6834a9418e66680387912451e971cf8a1fef",
"size": 524288,
"repo_path": "bios/Sony/PlayStation/scph5501.bin",
"cores": [
"beetle_psx",
"duckstation",
"pcsx1",
"pcsx_rearmed",
"rustation",
"swanstation"
]
}
]
},
{
@@ -872,6 +1276,21 @@
"cores": null,
"systems": [
"sony-playstation"
],
"alternatives": [
{
"sha1": "f6bc2d1f5eb6593de7d089c425ac681d6fffd3f0",
"sha256": "1faaa18fa820a0225e488d9f086296b8e6c46df739666093987ff7d8fd352c09",
"size": 524288,
"repo_path": "bios/Sony/PlayStation/scph5502.bin",
"cores": [
"beetle_psx",
"duckstation",
"pcsx_rearmed",
"rustation",
"swanstation"
]
}
]
},
{
@@ -883,6 +1302,20 @@
"cores": null,
"systems": [
"sony-playstation"
],
"alternatives": [
{
"sha1": "14df4f6c1e367ce097c11deae21566b4fe5647a9",
"sha256": "39dcc1a0717036c9b6ac52fefd1ee7a57d3808e8cfbc755879fa685a0a738278",
"size": 524288,
"repo_path": "bios/Sony/PlayStation/scph7001.bin",
"cores": [
"duckstation",
"pcsx1",
"pcsx_rearmed",
"rustation"
]
}
]
},
{
@@ -894,6 +1327,18 @@
"cores": null,
"systems": [
"sony-playstation-2"
],
"alternatives": [
{
"sha1": "f9229fe159d0353b9f0632f3fdc66819c9030458",
"sha256": "f609ed1ca62437519828cdd824b5ea79417fd756e71a4178443483e3781fedd2",
"size": 4194304,
"repo_path": "bios/Sony/PlayStation 2/ps2-0230a-20080220.bin",
"cores": [
"armsx2",
"yaps2"
]
}
]
},
{
@@ -3325,7 +3770,8 @@
"repo_path": "bios/Nintendo/Wii U/cafeLibs/snd_user.rpl",
"cores": [
"cemu"
]
],
"executable": true
},
{
"dest": "Cemu/cafeLibs/snduser2.rpl",
@@ -3335,7 +3781,8 @@
"repo_path": "bios/Nintendo/Wii U/cafeLibs/snduser2.rpl",
"cores": [
"cemu"
]
],
"executable": true
},
{
"dest": "Cemu/cafeLibs/swkbd.rpl",
@@ -3345,7 +3792,8 @@
"repo_path": "bios/Nintendo/Wii U/cafeLibs/swkbd.rpl",
"cores": [
"cemu"
]
],
"executable": true
},
{
"dest": "Cemu/cafeLibs/erreula.rpl",
@@ -3355,7 +3803,8 @@
"repo_path": "bios/Nintendo/Wii U/cafeLibs/erreula.rpl",
"cores": [
"cemu"
]
],
"executable": true
},
{
"dest": "STBIOS.bin",
@@ -3695,7 +4144,8 @@
"cores": [
"dosbox",
"dosbox_core"
]
],
"executable": true
},
{
"dest": "libbassmidi.so",
@@ -3706,7 +4156,8 @@
"cores": [
"dosbox",
"dosbox_core"
]
],
"executable": true
},
{
"dest": "bass.dll",
@@ -3739,7 +4190,8 @@
"cores": [
"dosbox",
"dosbox_core"
]
],
"executable": true
},
{
"dest": "libbassmidi.dylib",
@@ -3750,7 +4202,8 @@
"cores": [
"dosbox",
"dosbox_core"
]
],
"executable": true
},
{
"dest": "CM32LN_CONTROL.ROM",
@@ -17128,10 +17581,22 @@
"emux_gb",
"gearboy",
"irogb",
"sameboy"
"sameboy",
"mesen-s"
],
"systems": [
"nintendo-gb"
],
"alternatives": [
{
"sha1": "4ed31ec6b0b175bb109c0eb5fd3d193da823339f",
"sha256": "cf053eccb4ccafff9e67339d4e78e98dce7d1ed59be819d2a1ba2232c6fce1c7",
"size": 256,
"repo_path": "bios/Nintendo/Game Boy/GB_dmg.bin",
"cores": [
"mesence"
]
}
]
},
{
@@ -18498,11 +18963,23 @@
"cores": [
"gearboy",
"irogb",
"sameboy"
"sameboy",
"mesen-s"
],
"systems": [
"nintendo-gb",
"nintendo-gbc"
],
"alternatives": [
{
"sha1": "1293d68bf9643bc4f36954c1e80e38f39864528d",
"sha256": "b4f2e416a35eef52cba161b159c7c8523a92594facb924b3ede0d722867c50c7",
"size": 2304,
"repo_path": "bios/Nintendo/Game Boy Color/GBC_cgb.bin",
"cores": [
"mesence"
]
}
]
},
{
@@ -54450,7 +54927,8 @@
"repo_path": "bios/QEMU/openbios-ppc",
"cores": [
"qemu"
]
],
"executable": true
},
{
"dest": "qemu/slof.bin",
@@ -54500,7 +54978,8 @@
"repo_path": "bios/QEMU/u-boot.e500",
"cores": [
"qemu"
]
],
"executable": true
},
{
"dest": "qemu/u-boot-sam460-20100605.bin",
@@ -54530,7 +55009,8 @@
"repo_path": "bios/QEMU/openbios-sparc32",
"cores": [
"qemu"
]
],
"executable": true
},
{
"dest": "qemu/openbios-sparc64",
@@ -54540,7 +55020,8 @@
"repo_path": "bios/QEMU/openbios-sparc64",
"cores": [
"qemu"
]
],
"executable": true
},
{
"dest": "qemu/QEMU,tcx.bin",
@@ -54580,7 +55061,8 @@
"repo_path": "bios/QEMU/palcode-clipper",
"cores": [
"qemu"
]
],
"executable": true
},
{
"dest": "qemu/opensbi-riscv32-generic-fw_dynamic.bin",
@@ -54610,7 +55092,8 @@
"repo_path": "bios/QEMU/s390-ccw.img",
"cores": [
"qemu"
]
],
"executable": true
},
{
"dest": "qemu/s390-netboot.img",
@@ -54620,7 +55103,8 @@
"repo_path": "bios/QEMU/s390-netboot.img",
"cores": [
"qemu"
]
],
"executable": true
},
{
"dest": "qemu/hppa-firmware.img",
@@ -54630,7 +55114,8 @@
"repo_path": "bios/QEMU/hppa-firmware.img",
"cores": [
"qemu"
]
],
"executable": true
},
{
"dest": "qemu/hppa-firmware64.img",
@@ -54640,7 +55125,8 @@
"repo_path": "bios/QEMU/hppa-firmware64.img",
"cores": [
"qemu"
]
],
"executable": true
},
{
"dest": "qemu/mips_bios.bin",
@@ -59333,6 +59819,20 @@
"fbneo"
]
},
{
"dest": "mcpx_1.0.bin",
"sha1": "5d270675b54eb8071b480e42d22a3015ac211cef",
"sha256": "e99e3a772bf5f5d262786aee895664eb96136196e37732fe66e14ae062f20335",
"size": 512,
"repo_path": "bios/Microsoft/Xbox/mcpx_1.0.bin",
"cores": [
"directxbox",
"xemu"
],
"systems": [
"microsoft-xbox"
]
},
{
"dest": "GBA/gba_bios.bin",
"sha1": "300c20df6731a33952ded8c436f7f186d25d3492",
@@ -59359,6 +59859,19 @@
"sega-saturn"
]
},
{
"dest": "dc_flash.bin",
"sha1": "94d44d7f9529ec1642ba3771ed3c5f756d5bc872",
"sha256": "dd8b365521a9c08bb4c170da3592212580f7251f35a45d6083774d1c030bc3e3",
"size": 131072,
"repo_path": "bios/Sega/Dreamcast/dc_flash.bin",
"cores": [
"redream"
],
"systems": [
"sega-dreamcast"
]
},
{
"dest": "SkyEmu/gba_bios.bin",
"sha1": "300c20df6731a33952ded8c436f7f186d25d3492",
+1
View File
@@ -945,6 +945,7 @@
"atari-5200": [
"a5200",
"altirra",
"ares",
"atari800"
],
"atari-7800": [
+16
View File
@@ -445,9 +445,25 @@
},
"minItems": 1,
"uniqueItems": true
},
"executable": {
"type": "boolean"
}
}
}
},
"executable": {
"description": "The repository keeps the file executable; the installer gives it the execute bits the umask allows.",
"type": "boolean"
},
"declared_in": {
"description": "The platform systems declaring the file, when fewer than `systems`, which also names the systems whose cores read it there.",
"type": "array",
"items": {
"type": "string",
"minLength": 1
},
"uniqueItems": true
}
},
"oneOf": [
+106 -39
View File
@@ -3170,9 +3170,89 @@ def _manifest_entry(
if is_release_asset:
entry["storage"] = "release"
entry["release_asset"] = _release_asset_name(local_path, repo_root)
# The installer writes what it downloads with the umask's mode; a program
# (RetroDECK's pico8, vox) has to stay runnable. The git mode cannot say:
# hundreds of MAME archives carry an execute bit nothing reads.
if local_path and _is_program(local_path):
entry["executable"] = True
return entry, file_size
_PROGRAM_MAGIC = (
b"\x7fELF",
b"#!",
b"\xcf\xfa\xed\xfe",
b"\xce\xfa\xed\xfe",
b"\xca\xfe\xba\xbe",
)
def _is_program(path: str) -> bool:
"""An ELF or Mach-O binary, or a script with an interpreter line."""
with open(path, "rb") as handle:
head = handle.read(4)
return any(head.startswith(magic) for magic in _PROGRAM_MAGIC)
def _attach_claims(
entry: dict,
claims: list[dict],
db: dict,
bios_dir: str,
zip_contents,
offline,
required_only: bool,
validation_index: dict | None,
owners: dict | None,
dest: str,
manifest_dest: str,
repo_root: str,
) -> None:
"""Every other core that reads this destination, in the order the builder
meets them: a pack built without the earlier cores, or without the
platform system that declares the file, carries the first remaining
one's copy.
A claim joins the copy just before it when the bytes agree and starts an
alternative otherwise; it never joins an earlier copy, which would let it
win over a core the builder tries first. Only a core's first claim can
win: its later ones are reached only when that one is. A platform entry
names no core, so its first claim always starts an alternative.
"""
claimed = set(entry["cores"] or [])
for claim in claims:
claim_emu = claim.get("source_profile") or claim.get("source_emulator", "")
if not claim_emu or claim_emu in claimed:
continue
claimed.add(claim_emu)
if required_only and claim.get("required") is False:
continue
claim_path, claim_status = resolve_file(
claim, db, bios_dir, zip_contents,
dest_hint=claim.get("destination", ""), offline=offline,
)
if claim_status in ("not_found", "external", "user_provided") or not claim_path:
continue
claim_path, _ = validated_choice(
claim, claim_path, db, validation_index or {}, bios_dir, None, dest, owners,
)
copy, _size = _manifest_entry(
claim_path, manifest_dest, [claim_emu], db, repo_root, {}
)
if copy is None:
continue
alternatives = entry.setdefault("alternatives", [])
last = alternatives[-1] if alternatives else entry
if last["cores"] is not None and copy["sha1"] == last["sha1"]:
if claim_emu not in last["cores"]:
last["cores"].append(claim_emu)
continue
del copy["dest"]
alternatives.append(copy)
if not entry.get("alternatives"):
entry.pop("alternatives", None)
def _manifest_core_entries(
core_files: list,
config: dict,
@@ -3276,45 +3356,11 @@ def _manifest_core_entries(
pack_only_sizes.append(file_size)
continue
# Every other core that reads this destination, in the order the
# builder meets them: a pack built without the earlier cores carries
# the first remaining one's copy. A claim joins the copy just before
# it when the bytes agree, and starts an alternative otherwise; it
# never joins an earlier copy, which would let it win over a core
# the builder tries first. Only a core's first claim can win: its
# later ones are reached only when that one is.
claimed = set(entry["cores"])
for claim in fe.get("other_claims", []):
claim_emu = claim.get("source_profile") or claim.get("source_emulator", "")
if not claim_emu or claim_emu in claimed:
continue
claimed.add(claim_emu)
if required_only and claim.get("required") is False:
continue
claim_path, claim_status = resolve_file(
claim, db, bios_dir, zip_contents,
dest_hint=claim.get("destination", ""), offline=offline,
)
if claim_status in ("not_found", "external", "user_provided") or not claim_path:
continue
claim_path, _ = validated_choice(
claim, claim_path, db, validation_index or {}, bios_dir, None, dest, owners,
)
copy, _size = _manifest_entry(
claim_path, manifest_dest, [claim_emu], db, repo_root, {}
)
if copy is None:
continue
alternatives = entry.setdefault("alternatives", [])
last = alternatives[-1] if alternatives else entry
if copy["sha1"] == last["sha1"]:
if claim_emu not in last["cores"]:
last["cores"].append(claim_emu)
continue
del copy["dest"]
alternatives.append(copy)
if not entry.get("alternatives"):
entry.pop("alternatives", None)
_attach_claims(
entry, fe.get("other_claims", []), db, bios_dir, zip_contents,
offline, required_only, validation_index, owners, dest,
manifest_dest, repo_root,
)
manifest_files.append(entry)
omitted_by_destination.pop(full_dest, None)
@@ -3442,6 +3488,13 @@ def generate_manifest(
)
seen_destinations: set[str] = set()
# Destination -> (entry, full destination, manifest destination) of each
# platform file, for the core claims a target build would fall back on.
platform_entries: dict[str, tuple[dict, str, str]] = {}
# Full destination -> the platform systems declaring it. A file's
# `systems` also names the systems whose cores read it there; a pack built
# for a target keeps the file only while a declaring system stays.
declared_by: dict[str, set[str]] = {}
seen_lower: set[str] = set()
seen_parents: set[str] = set()
manifest_files: list[dict] = []
@@ -3514,6 +3567,7 @@ def generate_manifest(
if region_drops and dest in region_drops:
continue
full_dest = f"{base_dest}/{dest}" if base_dest else dest
declared_by.setdefault(full_dest, set()).add(sys_id)
preferred = preferred_entries.get(full_dest)
if preferred is not None and id(file_entry) != preferred:
@@ -3589,6 +3643,7 @@ def generate_manifest(
continue
manifest_files.append(entry)
platform_entries[dedup_key] = (entry, full_dest, dest)
omitted_by_destination.pop(full_dest, None)
total_size += file_size
seen_destinations.add(dedup_key)
@@ -3598,6 +3653,7 @@ def generate_manifest(
# Phase 2: core complement (emulator extras)
unplaceable: list[dict] = []
baseline_claims: dict[str, dict] = {}
if source != "platform":
core_files = _collect_emulator_extras(
config,
@@ -3609,6 +3665,7 @@ def generate_manifest(
target_cores=target_cores,
include_all=(source == "truth"),
unplaceable=unplaceable,
baseline_claims=baseline_claims,
)
else:
core_files = []
@@ -3620,6 +3677,16 @@ def generate_manifest(
omitted_by_destination, record_omission, pack_only_sizes, selection,
required_only, manifest_validation, manifest_owners,
)
for key, (entry, full_dest, dest) in platform_entries.items():
declared = declared_by.get(full_dest, set())
if declared and declared != set(entry.get("systems") or []):
entry["declared_in"] = sorted(declared)
claims = baseline_claims.get(key, {}).get("other_claims")
if claims:
_attach_claims(
entry, claims, db, bios_dir, zip_contents, offline, required_only,
manifest_validation, manifest_owners, dest, dest, repo_root,
)
# Phase 3: data directories. The installer does not fetch them, so they
# stay out of the file list; the pack carries them, so they count toward
+8
View File
@@ -477,9 +477,14 @@ def _collect_emulator_extras(
include_all: bool = False,
claimants: dict[tuple[str, str, str], str] | None = None,
unplaceable: list[dict] | None = None,
baseline_claims: dict[str, dict] | None = None,
) -> list[dict]:
"""Collect core requirement files from emulator profiles not in the platform pack.
``baseline_claims`` receives, for each destination in ``seen``, the core
claims made on it: a pack built for a target that drops the platform's
system frees the destination, and the first core claiming it fills it.
``claimants`` receives the destination of every report entry that
asked for one, the ones a sibling already took included: the region
report withdraws by that key, and an entry without one stayed listed
@@ -525,6 +530,9 @@ def _collect_emulator_extras(
seen_dests: set[str] = set(seen)
# Destination -> the extra that took it, to record later claimants on.
taken: dict[str, dict] = {}
if baseline_claims is not None:
for destination in seen:
taken[destination] = baseline_claims.setdefault(destination, {})
for u in undeclared:
if not u["in_repo"]:
continue
+48
View File
@@ -11,6 +11,7 @@ import contextlib
import hashlib
import http.server
import io
import json
import os
import subprocess
import sys
@@ -120,6 +121,53 @@ class LargeFilesResume(unittest.TestCase):
self.assertEqual(_RangeHandler.ranges, [""])
class InstalledFileModes(unittest.TestCase):
"""A file came out 0600, the mode of the temporary it was written to: run
with sudo for a root-owned BIOS folder, the emulator's own user could not
read it, and RetroDECK's pico8 and vox launchers were never executable."""
def _mode(self, entry: dict) -> int:
with _Server(), tempfile.TemporaryDirectory() as tmp:
dest, ok, _ = install._download_one(dict(entry), Path(tmp))
self.assertTrue(ok)
return (Path(tmp) / dest).stat().st_mode & 0o777
def test_the_umask_decides_as_for_any_new_file(self):
umask = os.umask(0o022)
try:
self.assertEqual(self._mode(ENTRY), 0o644)
self.assertEqual(self._mode({**ENTRY, "executable": True}), 0o755)
finally:
os.umask(umask)
class ProgramsAreMarked(unittest.TestCase):
"""The manifest says which files are programs, read from their header:
the git mode cannot, hundreds of MAME archives carrying an execute bit."""
def test_header_decides(self):
sys.path.insert(0, str(REPO_ROOT / "scripts"))
import generate_pack
with tempfile.TemporaryDirectory() as tmp:
for data, expected in ((b"\x7fELF\x02", True), (b"#!/bin/sh\n", True),
(b"PK\x03\x04", False), (b"", False)):
path = Path(tmp) / "f"
path.write_bytes(data)
with self.subTest(head=data):
self.assertEqual(generate_pack._is_program(str(path)), expected)
def test_retrodeck_launchers_are_executable(self):
manifest = json.loads((REPO_ROOT / "install" / "retrodeck.json").read_text())
launchers = [f for f in manifest["files"]
if f["dest"].endswith(("pico-8/pico8", "voxatron/vox"))]
if not launchers:
self.skipTest("no launcher in the RetroDECK manifest")
for entry in launchers:
with self.subTest(dest=entry["dest"]):
self.assertIs(entry.get("executable"), True)
class ManifestHashesMatchTheScan(unittest.TestCase):
"""A manifest entry's sha1 is checked against the database scan of the
same path: under load this host hashed a 252 MB DSi NAND to a sha1 no