Author SHA1 Message Date
Abdessamad Derraz 527526a8e2 fix: give each dolphin fork its own dsp rom table 2026-10-10 14:05:57 +02:00
Abdessamad Derraz f5a5d6f4bd fix: judge a core file by the cores that read it 2026-10-10 14:05:57 +02:00
Abdessamad Derraz 840f9ceaf6 fix: give clk roms the machine that requests them 2026-10-10 13:20:16 +02:00
Abdessamad Derraz 40b46d1d78 fix: re-profile dosbox_pure for its sc-55 driver 2026-10-10 12:56:01 +02:00
Abdessamad Derraz 6a39264fa6 fix: send the github token on every api call 2026-10-10 12:17:21 +02:00
Abdessamad Derraz fd8db894d8 fix: test extras grouping through the real chain 2026-10-10 12:16:11 +02:00
Abdessamad Derraz 15842d6402 fix: let a hash-proven owner guard its game data 2026-10-10 12:14:21 +02:00
Abdessamad Derraz c64e146a43 fix: refuse standalone copies install can't run 2026-10-10 12:13:18 +02:00
Abdessamad Derraz 61cba2d3c1 fix: hold the installer to python 3.8 for real 2026-10-10 12:12:32 +02:00
Abdessamad Derraz 8380f63f97 fix: write one romm entry per key 2026-10-10 12:11:16 +02:00
Abdessamad Derraz c38c790945 fix: never file a multi-system rom by guess 2026-10-10 12:10:32 +02:00
Abdessamad Derraz 88d7ca4814 fix: stop a retrodeck scrape on a failed fetch 2026-10-10 12:08:52 +02:00
Abdessamad Derraz 14b32b38ba fix: verify data-dir pack members by content 2026-10-10 12:08:13 +02:00
Abdessamad Derraz 3d0170264a fix: place slot claims where the pack puts extras 2026-10-10 12:07:00 +02:00
Abdessamad Derraz 2c2f284414 fix: file a slug-platform bios under its own system 2026-10-10 11:43:08 +02:00
Abdessamad Derraz 315549a5b0 fix: decide destination winners without data dirs 2026-10-10 11:20:33 +02:00
Abdessamad Derraz 26ea5336a7 fix: list a target's cores after its overrides 2026-10-10 11:17:53 +02:00
Abdessamad Derraz de795262d7 fix: count an alias as declared in the gap report 2026-10-10 11:16:59 +02:00
Abdessamad Derraz b00352754c fix: keep retropie's list idiom when extending 2026-10-10 11:16:21 +02:00
Abdessamad Derraz e26ee44229 fix: export only what the platform declares 2026-10-10 11:15:25 +02:00
Abdessamad Derraz b5f9095633 fix: write retrodeck additions beside homonyms 2026-10-10 10:57:57 +02:00
Abdessamad Derraz 0057a82fe1 fix: write recalbox additions at the core path 2026-10-10 10:56:46 +02:00
Abdessamad Derraz 1cedc9930b fix: let search order guard regional files 2026-10-10 10:56:09 +02:00
Abdessamad Derraz c2bdef4db4 fix: pair a bare truth name by name, not suffix 2026-10-10 10:04:35 +02:00
Abdessamad Derraz 556d4a45aa fix: carry an archive in the truth, not its roms 2026-10-10 10:04:35 +02:00
Abdessamad Derraz befb23b492 fix: tag only territory-switched ace-dl roms 2026-10-10 10:00:30 +02:00
Abdessamad Derraz 65d396e996 fix: drop territory tags from msx font roms 2026-10-10 09:58:05 +02:00
Abdessamad Derraz 2a049dc9c9 fix: let a shared path only keep a system 2026-10-10 09:49:56 +02:00
Abdessamad Derraz ffa6516e09 fix: let an alias settle only where the core reads 2026-10-10 09:47:50 +02:00
Abdessamad Derraz 836c56b3fa fix: pin the jaguar model-m boot rom by hash 2026-10-10 09:17:46 +02:00
Abdessamad Derraz bbce3902dd fix: keep a system an on-target core reads 2026-10-10 09:15:22 +02:00
Abdessamad Derraz f6da2cff3a fix: settle a core file only by its size or slot 2026-10-10 09:15:11 +02:00
Abdessamad Derraz be45eda62d fix: expect the renamed system pack in its test 2026-10-10 08:48:09 +02:00
Abdessamad Derraz c3f3d16999 chore: regenerate install manifests 2026-10-10 08:30:07 +02:00
Abdessamad Derraz d7cc757d22 fix: re-profile eka2l1 on its rewritten branch 2026-10-10 08:21:26 +02:00
Abdessamad Derraz e0dab891ee fix: let a system-less extra compete with nothing 2026-10-10 08:14:57 +02:00
Abdessamad Derraz 707c81d2cf fix: name a target by its canonical name 2026-10-10 08:09:00 +02:00
Abdessamad Derraz e6905f48e7 fix: name a system pack apart from an emulator one 2026-10-10 08:04:04 +02:00
Abdessamad Derraz 9002a4a4bb fix: lay a hash pack out as its emulator does 2026-10-10 07:59:18 +02:00
Abdessamad Derraz e8bdcb405d fix: refuse an unknown emulator for a hash pack 2026-10-10 07:54:56 +02:00
Abdessamad Derraz 1cd743242f fix: report a pin the tracked history lost 2026-10-10 07:53:06 +02:00
Abdessamad Derraz e8bac256e7 chore: re-pin advancemame on its rewritten master 2026-10-10 07:53:06 +02:00
Abdessamad Derraz 884c43c109 fix: a citation in an unmoved repo needs no move 2026-10-10 07:51:09 +02:00
Abdessamad Derraz a213898c6d fix: follow dosbox-pure to codeberg 2026-10-10 07:50:07 +02:00
Abdessamad Derraz 203e75c1f4 fix: let the live, owning repository judge a ref 2026-10-10 07:49:14 +02:00
Abdessamad Derraz 7e079e789e fix: point twice-shifted refs at their code 2026-10-10 07:46:12 +02:00
Abdessamad Derraz af7b3133a4 fix: resolve profile entries with their owner 2026-10-10 07:38:33 +02:00
Abdessamad Derraz 8a661932f2 chore: regenerate database, manifests and readme 2026-10-10 07:33:39 +02:00
Abdessamad Derraz 06ad1d10d3 fix: serve armsx2 the vulkan shader it reads 2026-10-10 07:32:21 +02:00
Abdessamad Derraz c38b8f980f fix: identify each zesarux rom by its bytes 2026-10-10 07:32:21 +02:00
Abdessamad Derraz 81a989c56c fix: give the azahar key slot its own key file 2026-10-10 07:32:21 +02:00
Abdessamad Derraz 1a182a1e33 fix: write each profile path with its file name 2026-10-10 07:16:03 +02:00
Abdessamad Derraz 31e2d4235a fix: say what the core refuses in emulator mode 2026-10-10 07:11:08 +02:00
Abdessamad Derraz 22cad6ee01 fix: a core copy does not pass a hash declaration 2026-10-10 07:04:22 +02:00
Abdessamad Derraz 748562e71d fix: count a conflicting declaration by its file 2026-10-10 07:02:38 +02:00
Abdessamad Derraz d2a61b4a89 refactor: name the new exceptions as errors 2026-10-10 05:29:38 +02:00
Abdessamad Derraz 4de21e1157 chore: deploy the site when manifest fields change 2026-10-10 05:29:38 +02:00
Abdessamad Derraz 20ba21c710 fix: keep the git probe out of the repository 2026-10-10 05:29:38 +02:00
Abdessamad Derraz 8c324706c5 chore: record systems and regions in the manifests 2026-10-10 04:56:18 +02:00
Abdessamad Derraz a493111820 fix: update the native source index under a lock 2026-10-10 04:48:30 +02:00
Abdessamad Derraz 77b9abfa49 fix: read a data directory tag before its download 2026-10-10 04:45:44 +02:00
Abdessamad Derraz a00f57ad37 fix: write scraped files whole or not at all 2026-10-10 04:45:10 +02:00
Abdessamad Derraz 170b7d93ae fix: record a release only from finished packs 2026-10-10 04:43:42 +02:00
Abdessamad Derraz 6c75f5ae15 fix: keep the cache when an archive yields nothing 2026-10-10 04:42:58 +02:00
Abdessamad Derraz 6fca4149f5 feat: offer the files no platform system owns 2026-10-10 04:42:11 +02:00
Abdessamad Derraz 788a6dd4df fix: read the upstream cache from one name 2026-10-10 04:41:39 +02:00
Abdessamad Derraz 537600730c chore: refresh mame refs at the 0.289 tag 2026-10-10 04:41:39 +02:00
Abdessamad Derraz a116743471 fix: scrape the mame release that labels the data 2026-10-10 04:40:27 +02:00
Abdessamad Derraz ece2c06aaf feat: choose systems, cores and regions to install 2026-10-10 04:31:57 +02:00
Abdessamad Derraz b0bd20f403 refactor: build every manifest entry in one place 2026-10-10 04:07:04 +02:00
Abdessamad Derraz bfa741a9c9 fix: accept the slug omission in the installer 2026-10-10 03:59:23 +02:00
Abdessamad Derraz 6a80f3ed08 fix: hand the terminal to a piped installer 2026-10-10 03:54:26 +02:00
Abdessamad Derraz 55eb953447 chore: record release v2026.10.10 2026-10-10 03:01:50 +02:00
Abdessamad Derraz 60ce4dff27 chore: refresh mame bios hashes to 0.289 2026-10-10 00:58:21 +02:00
Abdessamad Derraz f1d2b8adab fix: a plain build starts with no split paths 2026-10-09 23:51:58 +02:00
Abdessamad Derraz 8b76ea0310 refactor: name the two prologues of validate_pr 2026-10-09 23:37:40 +02:00
Abdessamad Derraz ac0c92e60a chore: regenerate manifests and readme 2026-10-09 23:18:37 +02:00
Abdessamad Derraz 6a2f9bf2e7 chore: read the three copy counts 2026-10-09 23:18:36 +02:00
Abdessamad Derraz d3e3c08b6c chore: name the slug omission in the schema 2026-10-09 23:18:36 +02:00
Abdessamad Derraz ed49b26c12 fix: a declared alias settles the entry 2026-10-09 23:18:36 +02:00
Abdessamad Derraz fab7d4eb2f chore: read the exit code of the region runs 2026-10-09 22:57:15 +02:00
Abdessamad Derraz 5c72a85ad6 chore: only a platform's profiles disarm its check 2026-10-09 22:57:15 +02:00
Abdessamad Derraz 3dd17ddead chore: pin every no-dedup directory 2026-10-09 22:57:15 +02:00
Abdessamad Derraz cc04ff78c9 fix: a step that could not run says so 2026-10-09 22:57:15 +02:00
Abdessamad Derraz 4a30cbf882 fix: count a refused standalone copy as an error 2026-10-09 22:57:15 +02:00
Abdessamad Derraz 1a862bc318 fix: retrobat defaults to its installer directory 2026-10-09 22:57:15 +02:00
Abdessamad Derraz c13d5c5368 fix: slots read the one gap scope rule 2026-10-09 22:57:15 +02:00
Abdessamad Derraz d295e51ad6 fix: list systems the way --system selects 2026-10-09 22:57:15 +02:00
Abdessamad Derraz 6207e81d9c refactor: read the grouping where it lives 2026-10-09 22:45:58 +02:00
Abdessamad Derraz 8fb65b8e97 fix: exporters keep what the maintainer wrote 2026-10-09 22:45:57 +02:00
Abdessamad Derraz 3baec1794b fix: match a loose dump by crc32 and size 2026-10-09 22:45:57 +02:00
Abdessamad Derraz 9cb152ef23 fix: file the psp bios where pcsx_rearmed does 2026-10-09 22:45:57 +02:00
Abdessamad Derraz 8a0c3b34ea fix: resolve the region audit like the pack 2026-10-09 22:45:57 +02:00
Abdessamad Derraz 45275811f0 fix: keep the quasi88 group to the extension roms 2026-10-09 22:45:57 +02:00
Abdessamad Derraz 82bdcfa1b1 fix: read the clone map beside the scanned tree 2026-10-09 22:45:57 +02:00
Abdessamad Derraz be2daab00c fix: judge the gap report on the flat declared set 2026-10-09 22:45:57 +02:00
Abdessamad Derraz 6e6ae77ccd fix: one selection and one name per system 2026-10-09 22:34:20 +02:00
Abdessamad Derraz b9cf7c7415 fix: report the extras a platform cannot place 2026-10-09 22:34:20 +02:00
Abdessamad Derraz f47088fe37 fix: write artifacts whole or not at all 2026-10-09 22:34:20 +02:00
Abdessamad Derraz 53bd42b2f4 feat: collect the pcsx2 forks' pinned resources 2026-10-09 22:20:00 +02:00
Abdessamad Derraz 5090208a64 fix: keep another emulator's tree out of resolution 2026-10-09 22:20:00 +02:00
Abdessamad Derraz 5ebb141dbf fix: score a losing twin against the shipped file 2026-10-09 22:20:00 +02:00
Abdessamad Derraz 8944486597 fix: a listed hash the other layer holds is agreement 2026-10-09 21:59:38 +02:00
Abdessamad Derraz 606d91ebab fix: prefer among the entries a reduced pack keeps 2026-10-09 21:59:38 +02:00
Abdessamad Derraz 3dc353dc73 fix: hold verify and pack to the same count both ways 2026-10-09 21:59:38 +02:00
Abdessamad Derraz 919f00a6ee fix: cite pcsx2 bundled resources at the pin 2026-10-09 17:56:02 +02:00
Abdessamad Derraz 5e0ec6f442 chore: hoist test imports to module level 2026-10-06 13:59:50 +02:00
Abdessamad Derraz d8ad89902b refactor: split helpers out of grown functions 2026-10-06 13:59:50 +02:00
Abdessamad Derraz ba7c185d8a refactor: share the gap scope rule 2026-10-06 13:59:50 +02:00
Abdessamad Derraz 12feecd3d5 chore: regenerate database, manifests and readme 2026-10-06 13:06:27 +02:00
Abdessamad Derraz 87a591a1ae fix: cite lrps2 bios loaders at the pin 2026-10-06 13:01:09 +02:00
Abdessamad Derraz 71aaf4bb04 fix: cite pokemini's bios reload at the pin 2026-10-06 13:00:09 +02:00
Abdessamad Derraz 0f6b948ca5 fix: cite the msx-emu fdc mapper at the pin 2026-10-06 13:00:00 +02:00
Abdessamad Derraz 6f9e2b3fc9 fix: cite the casloopy rom block at the pin 2026-10-06 12:59:43 +02:00
Abdessamad Derraz 4117589405 fix: a cited range past the file end is gone 2026-10-06 12:59:23 +02:00
Abdessamad Derraz 707a3e0447 fix: cite dolphin's NAND import where it is 2026-10-06 12:59:23 +02:00
Abdessamad Derraz 4dcc329e7e fix: pin kronos on the branch the buildbot builds 2026-10-06 12:56:44 +02:00
Abdessamad Derraz 1937f0c509 fix: name a file's readers by resolution 2026-10-06 12:55:41 +02:00
Abdessamad Derraz ed7ec8b6f8 fix: show unsourceable entries apart on the site 2026-10-06 12:53:10 +02:00
Abdessamad Derraz 580a082b0f fix: slot emulator entries where the pack puts them 2026-10-06 12:52:24 +02:00
Abdessamad Derraz c1b930a6fd fix: keep save and content files out of the truth 2026-10-06 12:48:58 +02:00
Abdessamad Derraz 29e2e13d65 fix: cross-reference the build a platform runs 2026-10-06 12:47:50 +02:00
Abdessamad Derraz ed7e83e99b fix: default each platform to the folder it reads 2026-10-06 12:46:35 +02:00
Abdessamad Derraz a7de9b9c9c fix: read extract folders from the registry 2026-10-06 12:44:32 +02:00
Abdessamad Derraz 908d75a86c fix: an untagged bios serves every region 2026-10-06 12:43:09 +02:00
Abdessamad Derraz 9304931845 fix: unmark files of standalone-only profiles 2026-10-06 12:39:34 +02:00
Abdessamad Derraz e39ac455cd fix: lock the pack directory while splitting 2026-10-06 12:34:31 +02:00
Abdessamad Derraz cfb038429d fix: hold dist/ for the whole pipeline run 2026-10-06 12:33:59 +02:00
Abdessamad Derraz e071233567 fix: refetch a large file the release replaced 2026-10-06 12:30:51 +02:00
Abdessamad Derraz 0dc0813bcd fix: check targeted packs the way --all builds 2026-10-06 12:29:40 +02:00
Abdessamad Derraz fc4451c59f docs: split parts are named, not renamed 2026-10-06 12:29:10 +02:00
Abdessamad Derraz 6fc879ce39 fix: name split parts directly, version their dir 2026-10-06 12:29:03 +02:00
Abdessamad Derraz 0c39fc479d fix: drop the --include-extras flag nothing read 2026-10-06 12:27:21 +02:00
Abdessamad Derraz ae333f80a6 fix: run every scraper contract class directly 2026-10-06 12:27:11 +02:00
Abdessamad Derraz c39588807f fix: refuse --include-archived without --all 2026-10-06 12:26:47 +02:00
Abdessamad Derraz db26a1276e fix: fail the fileless check on real errors 2026-10-06 12:25:18 +02:00
Abdessamad Derraz 1d00516d96 fix: read profile tree status from its own repo 2026-10-06 12:24:31 +02:00
Abdessamad Derraz 8bf8fdba9e fix: refuse a libretro scrape without core info 2026-10-06 12:23:48 +02:00
Abdessamad Derraz 1e61b749cf fix: refuse an emudeck scrape with no cores 2026-10-06 12:23:48 +02:00
Abdessamad Derraz 0eecb23724 fix: refuse batocera targets with unread boards 2026-10-06 12:22:51 +02:00
Abdessamad Derraz 548ea5935b fix: stop a scrape whose release tag is unread 2026-10-06 12:22:51 +02:00
Abdessamad Derraz cb5ce96103 fix: quote system.dat names as the original does 2026-10-06 12:16:23 +02:00
Abdessamad Derraz e787fcee8e fix: leave bizhawk's declared sha1 to bizhawk 2026-10-06 12:15:50 +02:00
Abdessamad Derraz 4727734c24 fix: refuse a one-md5 addition of several accepted 2026-10-06 12:15:49 +02:00
Abdessamad Derraz ecdfbdf64f fix: never pair files whose contents or dirs differ 2026-10-06 12:15:40 +02:00
Abdessamad Derraz e476758f73 feat: collect emucorex and dojo bundled resources 2026-10-06 12:13:27 +02:00
Abdessamad Derraz 06de56002d fix: prefer the owner's copy among equal path tails 2026-10-06 12:13:27 +02:00
Abdessamad Derraz b17d1f13ff fix: rank the owner's copy above shared tree names 2026-10-06 12:09:51 +02:00
Abdessamad Derraz bd669f6cee fix: look inside every zipped_file archive 2026-10-06 12:07:34 +02:00
Abdessamad Derraz 5b341dbe54 fix: report contradicted hashes in existence verify 2026-10-06 12:05:56 +02:00
Abdessamad Derraz 500535b7a6 fix: state no size for several accepted sizes 2026-10-06 12:04:24 +02:00
Abdessamad Derraz f3d01aeeeb refactor: split this round's fixes into small helpers 2026-10-06 11:16:06 +02:00
Abdessamad Derraz 70d6f431e3 fix: count variant choices made through validated_choice 2026-10-06 10:23:20 +02:00
Abdessamad Derraz 79cdbc24cf chore: regenerate database, manifests and readme 2026-10-06 09:59:51 +02:00
Abdessamad Derraz a24e17535f fix: count core archives among the core files 2026-10-06 09:54:33 +02:00
Abdessamad Derraz 55983f6b01 fix: pack undistributed core extras in a split part 2026-10-06 09:53:09 +02:00
Abdessamad Derraz c6681c0a63 fix: compute coverage from the profiles the site reads 2026-10-06 09:48:15 +02:00
Abdessamad Derraz 3730fa78c1 refactor: write one contributing text for both pages 2026-10-06 09:47:09 +02:00
Abdessamad Derraz 5c89ac6edc docs: name jsonschema where the build needs it 2026-10-06 09:46:10 +02:00
Abdessamad Derraz e9653069a2 fix: require the jsonschema format checkers 2026-10-06 09:45:25 +02:00
Abdessamad Derraz 892cff38bc fix: diff every declaration of a repeated destination 2026-10-06 09:43:58 +02:00
Abdessamad Derraz 7822de38fb fix: count site cores with the builder's resolution 2026-10-06 09:43:38 +02:00
Abdessamad Derraz a70ff264d2 fix: refuse an unknown mame or fbneo version 2026-10-06 09:42:33 +02:00
Abdessamad Derraz a848730a80 fix: count mister corrections only where it writes 2026-10-06 09:41:53 +02:00
Abdessamad Derraz aac09aa6ad fix: count bizhawk corrections only where it writes 2026-10-06 09:41:28 +02:00
Abdessamad Derraz d085fd895b fix: write emudeck corrections, count only what lands 2026-10-06 09:41:04 +02:00
Abdessamad Derraz e4616f7098 fix: never let a romm addition replace their entry 2026-10-06 09:40:09 +02:00
Abdessamad Derraz c9689ebad7 fix: keep platform hashes the truth does not contradict 2026-10-06 09:39:07 +02:00
Abdessamad Derraz a4009e3bbe fix: recale prose onto the code the pins carry 2026-10-06 09:38:27 +02:00
Abdessamad Derraz 4e3ae6a941 fix: tag regions only where the code picks by area 2026-10-06 09:37:44 +02:00
Abdessamad Derraz 3183ad982c fix: read gaps by normalized system, sha256, file names 2026-10-06 09:32:32 +02:00
Abdessamad Derraz 7a21b8d814 fix: keep refs for another version out of the pin check 2026-10-06 09:28:51 +02:00
Abdessamad Derraz 7224114a4b fix: realign stale prose before a pin moves 2026-10-06 09:27:33 +02:00
Abdessamad Derraz 2d000b8056 fix: leave mode-keyed pins to a hand edit 2026-10-06 09:25:23 +02:00
Abdessamad Derraz 5bf25d1964 fix: move a ref only on a hash found elsewhere 2026-10-06 09:24:49 +02:00
Abdessamad Derraz cdecb096a1 fix: refuse --refresh-data where nothing refreshes 2026-10-06 09:24:24 +02:00
Abdessamad Derraz 38ee085722 fix: hold the data dir lock in emulator packs 2026-10-06 09:20:42 +02:00
Abdessamad Derraz 0c53142585 fix: build system packs beside, not over, emulator packs 2026-10-06 09:19:18 +02:00
Abdessamad Derraz bb6669c362 fix: reduce emulator packs by region after required-only 2026-10-06 09:13:15 +02:00
Abdessamad Derraz 2e2fe2944c fix: read the data registry from --platforms-dir 2026-10-06 09:10:57 +02:00
Abdessamad Derraz d205d0bbc8 fix: keep display names out of pack file paths 2026-10-06 09:09:02 +02:00
Abdessamad Derraz 3b2a232a9d fix: install the variant the pack ships 2026-10-06 09:08:33 +02:00
Abdessamad Derraz 9419cd94c7 fix: restore release assets through a scratch file 2026-10-06 08:58:40 +02:00
Abdessamad Derraz 0dd6abab2c fix: refuse unread verify flags, read platforms dir 2026-10-06 08:58:21 +02:00
Abdessamad Derraz 74bc75fb7c fix: anchor the slot mode test on the override lookup 2026-10-06 08:53:58 +02:00
Abdessamad Derraz 177896a021 fix: count exclusions from the full pack only 2026-10-06 08:52:51 +02:00
Abdessamad Derraz 5a776fc06e fix: give np2kai scsi.rom a read ceiling, not a size 2026-10-06 08:52:26 +02:00
Abdessamad Derraz 947fd23421 fix: read numbered master keys in the switch test 2026-10-06 08:51:16 +02:00
Abdessamad Derraz 776e50f3c2 fix: file the older switch keys as variants 2026-10-06 08:50:38 +02:00
Abdessamad Derraz dc41a75615 fix: read the hle index scope from its comprehension 2026-10-06 07:37:41 +02:00
Abdessamad Derraz 354aa30bfb refactor: name unused mock arguments, flatten withs 2026-10-06 07:06:53 +02:00
Abdessamad Derraz 05ae30ce48 refactor: simplify pack label, hash merge, diff exit 2026-10-06 07:06:22 +02:00
Abdessamad Derraz c8a30de493 refactor: let the retropie core check take none 2026-10-06 07:05:05 +02:00
Abdessamad Derraz ebe4a1bbcc refactor: extract the alias scope helpers 2026-10-06 07:04:54 +02:00
Abdessamad Derraz 8d98e1c659 refactor: extract companion extras and the kept filter 2026-10-06 07:03:59 +02:00
Abdessamad Derraz 0eb824c69c refactor: extract emulator archive placement 2026-10-06 07:00:22 +02:00
Abdessamad Derraz 49a4b181bf refactor: one mismatch rule for builder and verifier 2026-10-06 06:57:01 +02:00
Abdessamad Derraz fb9426dfb7 refactor: extract verify listing and resolution steps 2026-10-06 06:50:59 +02:00
Abdessamad Derraz a711f8c456 refactor: move the truth steps out of pipeline main 2026-10-06 06:47:56 +02:00
Abdessamad Derraz 2c602596d1 refactor: pull mismatch and region steps from manifest 2026-10-06 06:45:45 +02:00
Abdessamad Derraz d3c4198eb9 refactor: extract retrodeck key matching helpers 2026-10-06 06:40:41 +02:00
Abdessamad Derraz 20dc2654f5 refactor: split truth merge into match, fold, create 2026-10-06 06:40:07 +02:00
Abdessamad Derraz b9086262b7 refactor: split the pin gate from bump_commit 2026-10-06 06:39:02 +02:00
Abdessamad Derraz 226a5df74a refactor: hoist test imports, rank pairs at module level 2026-10-06 06:38:35 +02:00
Abdessamad Derraz a5f3a5db25 fix: name only pinned claims as left unserved 2026-10-06 06:33:36 +02:00
Abdessamad Derraz 70bd093a59 fix: accept verified_members in pack manifests 2026-10-06 06:31:10 +02:00
Abdessamad Derraz b788078590 chore: regenerate database, manifests and readme 2026-10-06 05:46:44 +02:00
Abdessamad Derraz 6b57377111 fix: name each retropie package once per target 2026-10-06 05:33:18 +02:00
Abdessamad Derraz 2c0f37ff85 fix: give solarus and eka2l1 their own pad mappings 2026-10-06 05:26:54 +02:00
Abdessamad Derraz d3e02c8c5e fix: redeploy the site on any script it imports 2026-10-06 05:23:27 +02:00
Abdessamad Derraz 240a30f1d7 fix: read retropie targets the way retropie does 2026-10-06 05:22:34 +02:00
Abdessamad Derraz 29a285d37e fix: stop target scrapes on a failed request 2026-10-06 05:19:05 +02:00
Abdessamad Derraz 7f9e68dc4a fix: tell same-name files apart by path in truth 2026-10-06 05:18:07 +02:00
Abdessamad Derraz 8f4dd17507 fix: preserve release assets by registered path 2026-10-06 05:13:34 +02:00
Abdessamad Derraz 969026b88d fix: one game data list for notes and composition 2026-10-06 05:11:41 +02:00
Abdessamad Derraz 95b5a038f2 fix: give a targeted export the full truth model 2026-10-06 05:09:45 +02:00
Abdessamad Derraz c67fd96b0f fix: fail a truth diff that compared nothing 2026-10-06 05:09:11 +02:00
Abdessamad Derraz b307de5719 fix: skip schema tests when jsonschema is absent 2026-10-06 05:08:40 +02:00
Abdessamad Derraz 1e4ffa3db1 fix: point the retrobat guide at install.ps1 2026-10-06 05:06:15 +02:00
Abdessamad Derraz 3067865b02 fix: read hle fallbacks from the platform cores only 2026-10-06 05:06:04 +02:00
Abdessamad Derraz 62bae63bbf fix: fail a pack member the collection cannot name 2026-10-06 05:05:14 +02:00
Abdessamad Derraz 64516f2bdc fix: propose retropie names per core, never into or-lists 2026-10-06 05:01:10 +02:00
Abdessamad Derraz 0e7ed498e3 fix: keep recalbox notes its own 2026-10-06 05:00:36 +02:00
Abdessamad Derraz 9a8c60e12e fix: correct one retrodeck revision, not all of them 2026-10-06 05:00:24 +02:00
Abdessamad Derraz 683ba4ef62 fix: export one file's identity, never two mixed 2026-10-06 05:00:02 +02:00
Abdessamad Derraz 217fff8e06 chore: point seven profiles' refs at their values 2026-10-06 04:59:20 +02:00
Abdessamad Derraz ec41f28f3e chore: point five profiles' refs at their values 2026-10-06 04:59:20 +02:00
Abdessamad Derraz 456eefa656 chore: recale wqxemu and emucorex onto head 2026-10-06 04:59:20 +02:00
Abdessamad Derraz 7bc5e795f1 feat: profile visual-pinball hrtf, collect the sofa 2026-10-06 04:59:20 +02:00
Abdessamad Derraz df70a1458c chore: recale jazz2-native and linapple onto head 2026-10-06 04:59:20 +02:00
Abdessamad Derraz 883c812b70 fix: drop cpc firmware regions, a keyboard picks 2026-10-06 04:58:59 +02:00
Abdessamad Derraz 6bffa5d2d8 fix: drop saturn bios regions, the list is fixed 2026-10-06 04:58:59 +02:00
Abdessamad Derraz 21cb6dca39 fix: drop pce system card regions, an option picks 2026-10-06 04:58:59 +02:00
Abdessamad Derraz a1ce1d2fa0 fix: hold the data dir lock while packing it 2026-10-06 04:56:16 +02:00
Abdessamad Derraz c9f8f4b230 fix: choose regions among the files required-only keeps 2026-10-06 04:54:05 +02:00
Abdessamad Derraz ce135b788f fix: compare only the full pack to verify 2026-10-06 04:49:21 +02:00
Abdessamad Derraz e8884e4341 fix: finalize only the packs this run names 2026-10-06 04:48:32 +02:00
Abdessamad Derraz d130f43705 fix: keep large-file revisions and clean failed fetches 2026-10-06 04:47:10 +02:00
Abdessamad Derraz c37d7fc95a fix: apply required-only to emulator pack archives 2026-10-06 04:46:03 +02:00
Abdessamad Derraz c5566b7d06 fix: count undistributed split extras with the helper 2026-10-06 04:43:49 +02:00
Abdessamad Derraz 7498304e44 fix: give system packs their core extras 2026-10-06 04:42:35 +02:00
Abdessamad Derraz 7b62f7f702 fix: refuse every flag a quick mode does not read 2026-10-06 04:39:08 +02:00
Abdessamad Derraz a6e321c1d6 chore: recale geolith jg.c refs onto upstream head 2026-10-06 04:37:48 +02:00
Abdessamad Derraz 4a32ef2bb3 fix: judge each profile ref by its own repository 2026-10-06 04:37:48 +02:00
Abdessamad Derraz fe877ff79c fix: keep cross-named aliases inside their profile 2026-10-06 04:35:35 +02:00
Abdessamad Derraz 619c282477 fix: arbitrate slots on the strongest profile proof 2026-10-06 04:32:19 +02:00
Abdessamad Derraz 2cafeb1d33 fix: key the casefold index on its source dict 2026-10-06 04:30:11 +02:00
Abdessamad Derraz 1373964746 fix: pack windows platforms case-insensitively 2026-10-06 04:29:49 +02:00
Abdessamad Derraz b5feaccc2a fix: carry pcsx2 companions under the names it opens 2026-10-06 04:29:16 +02:00
Abdessamad Derraz ac4776b2d0 fix: withhold a file only on the frontend digest 2026-10-06 04:21:47 +02:00
Abdessamad Derraz dbc8d63318 fix: one agnostic substitute rule for pack and verify 2026-10-06 04:19:40 +02:00
Abdessamad Derraz b2e488e0a4 fix: carry identity in extras, refile rom b 2026-10-06 04:12:08 +02:00
Abdessamad Derraz 93f3560d19 refactor: split the all-variants flag refusals 2026-10-06 03:11:07 +02:00
Abdessamad Derraz ab75123320 refactor: move flag refusals out of the main functions 2026-10-06 03:08:35 +02:00
Abdessamad Derraz a2e5d73bf5 chore: regenerate database, manifests and readme 2026-10-06 02:47:55 +02:00
Abdessamad Derraz ae0d4cbd82 fix: read accepted revision lists in profile aliases 2026-10-06 02:06:01 +02:00
Abdessamad Derraz f004e9f400 test: check every registered platform pack 2026-10-06 01:54:11 +02:00
Abdessamad Derraz b14a35b788 test: keep validation index on platform cores 2026-10-06 01:49:24 +02:00
Abdessamad Derraz 33184102c9 test: pin exact sets in the shipped content ratchets 2026-10-06 01:49:09 +02:00
Abdessamad Derraz 820ed9cff0 test: fail, not skip, when slot conflicts vanish 2026-10-06 01:48:17 +02:00
Abdessamad Derraz 2a25274fcf fix: read platform hashes as verify does in PR checks 2026-10-06 01:47:48 +02:00
Abdessamad Derraz d6afb09663 refactor: one upstream name index for core lookups 2026-10-06 01:47:16 +02:00
Abdessamad Derraz 4bde2f0080 fix: lay out truth with the pack mode rule 2026-10-06 01:43:30 +02:00
Abdessamad Derraz 077351bab3 feat: list retrodeck standalone emulators 2026-10-06 01:43:30 +02:00
Abdessamad Derraz e0141fab15 fix: apply changed-only to every profile_sync output 2026-10-06 01:42:00 +02:00
Abdessamad Derraz d257ecc6ab fix: decrypt otp.bin with the standard library 2026-10-06 01:41:27 +02:00
Abdessamad Derraz fdc7fc8326 fix: default profile report containers to empty 2026-10-06 01:39:55 +02:00
Abdessamad Derraz 2a56fccc85 fix: refuse targets when their list cannot be read 2026-10-06 01:39:31 +02:00
Abdessamad Derraz 403c7ff910 fix: register yaps2 resources, check data dir refs 2026-10-06 01:38:39 +02:00
Abdessamad Derraz 6b0cb815aa fix: build the database without network calls 2026-10-06 01:37:40 +02:00
Abdessamad Derraz 41474596d0 fix: gate on slot crashes and empty consistency 2026-10-06 01:34:59 +02:00
Abdessamad Derraz ec9bbd3424 fix: fail the run when a platform pack errors 2026-10-06 01:34:30 +02:00
Abdessamad Derraz 5771f195b0 fix: send retropie users to the retropie pack 2026-10-06 01:33:58 +02:00
Abdessamad Derraz 236d8322b0 fix: point pack guides at the path each platform reads 2026-10-06 01:33:33 +02:00
Abdessamad Derraz 16be9476cb fix: dedup core extras on their real destination 2026-10-06 01:32:56 +02:00
Abdessamad Derraz cd2919400a fix: skip archive members by their yaml key 2026-10-06 01:32:33 +02:00
Abdessamad Derraz 6d818d4da0 fix: count romset members as held dumps 2026-10-06 01:32:09 +02:00
Abdessamad Derraz 25692f98fc fix: recale pcsx_rearmed bios refs, pal to oceania 2026-10-06 01:31:31 +02:00
Abdessamad Derraz 96f538c2f3 fix: serve pal psx bios to oceania too 2026-10-06 01:31:27 +02:00
Abdessamad Derraz e6fa6c76c9 fix: drop fmsx font regions, fonts are options 2026-10-06 01:31:27 +02:00
Abdessamad Derraz 58f49e421b fix: drop prosystem regions, pal is a signal 2026-10-06 01:31:27 +02:00
Abdessamad Derraz 9934109c84 fix: drop o2em regions, the bios is a model 2026-10-06 01:31:27 +02:00
Abdessamad Derraz aee3c09b57 fix: drop opera regions, the bios is an option 2026-10-06 01:31:27 +02:00
Abdessamad Derraz b59fede88d chore: regenerate database, manifests and readme 2026-10-06 01:22:56 +02:00
Abdessamad Derraz 95d10ee812 fix: count what each export format writes 2026-10-06 01:22:56 +02:00
Abdessamad Derraz bb789872b2 feat: collect the pc-88 font rom for quasi88 2026-10-06 01:22:56 +02:00
Abdessamad Derraz 7437df78b3 fix: attach profile aliases to a unique name only 2026-10-06 01:22:56 +02:00
Abdessamad Derraz 6d6cd7d668 fix: map pc-8801, dsi and cd-i system slugs 2026-10-06 01:22:56 +02:00
Abdessamad Derraz 7da259ec6a fix: refresh data dirs under a lock, by rename 2026-10-06 01:22:56 +02:00
Abdessamad Derraz 9e4b321886 feat: profile aps3e 2.43 on rpcs3 0.0.42 2026-10-06 00:26:36 +02:00
Abdessamad Derraz ce90dae4b9 feat: profile cap32 at c238550 with the 664 rom 2026-10-06 00:26:36 +02:00
Abdessamad Derraz d0a3563c3e fix: keep prose citations within reach and pinned 2026-10-06 00:26:36 +02:00
Abdessamad Derraz d18cd82d4b chore: recale gpsp refs onto their pin 2026-10-06 00:26:36 +02:00
Abdessamad Derraz 5c5e95218b chore: point desmume refs at the bios loads 2026-10-06 00:26:36 +02:00
Abdessamad Derraz f259634c38 fix: group variant slots across their systems 2026-10-06 00:26:36 +02:00
Abdessamad Derraz 1879c984f4 fix: decide slots on the region pass grouping 2026-10-06 00:26:36 +02:00
Abdessamad Derraz c4a080b0f4 fix: group regions by the target in pack integrity 2026-10-06 00:13:38 +02:00
Abdessamad Derraz 64f84e7ca6 fix: verify the pack the flags name, by exact name 2026-10-06 00:13:38 +02:00
Abdessamad Derraz 9be5a9bd0e chore: regenerate database, manifests and readme 2026-10-05 22:55:32 +02:00
Abdessamad Derraz 8b7e16caf6 feat: collect nethersx2-turnip assets from v0.7 2026-10-05 22:55:31 +02:00
Abdessamad Derraz 533dd7586f fix: scan free bios names only in the bios folder 2026-10-05 22:55:31 +02:00
Abdessamad Derraz 15e9f5486b feat: store pcsx2 achievement sound under its tail 2026-10-05 22:22:22 +02:00
Abdessamad Derraz 8e532db6aa fix: order same-named files by their owner's copy 2026-10-05 22:22:22 +02:00
Abdessamad Derraz f625039190 fix: no collision where one file passes every declaration 2026-10-05 22:12:23 +02:00
Abdessamad Derraz c61d35c41e fix: judge a slot on the declaration the pack ships 2026-10-05 22:10:48 +02:00
Abdessamad Derraz 30223faa00 fix: check every zipped member a platform declares 2026-10-05 22:05:10 +02:00
Abdessamad Derraz 8e41ddc297 fix: ship the archive every member declaration accepts 2026-10-05 22:05:10 +02:00
Abdessamad Derraz 138260c788 chore: regenerate install manifests 2026-10-05 22:00:13 +02:00
Abdessamad Derraz 29940abed6 fix: keep unsourceable entries out of the asset store 2026-10-05 22:00:13 +02:00
Abdessamad Derraz ed469ad8c9 chore: regenerate install manifests 2026-10-05 21:53:59 +02:00
Abdessamad Derraz b12a3280e6 fix: give the install manifest the arbitrated file 2026-10-05 21:53:59 +02:00
Abdessamad Derraz 3177a57103 fix: emulator region report reads the pack drop set 2026-10-05 21:43:32 +02:00
Abdessamad Derraz 012bf2fec2 fix: one rule for the variant an emulator accepts 2026-10-05 21:36:14 +02:00
Abdessamad Derraz 54016ad89b fix: keep profile identity on second-pass extras 2026-10-05 21:27:35 +02:00
Abdessamad Derraz eab1c03a52 fix: resolve held catacomb files, profile refs 2026-10-05 02:51:29 +02:00
Abdessamad Derraz e53eb8a43c chore: regenerate database, manifests and readme 2026-10-05 02:51:23 +02:00
Abdessamad Derraz 3f65defbf0 feat: collect ap6, shareddata, introset, a2 scsi 2026-10-05 02:51:23 +02:00
Abdessamad Derraz 15568b37aa feat: reprofile beetle_saturn, collect mpeg cards 2026-10-05 02:51:22 +02:00
Abdessamad Derraz a116192b3d feat: build engine data at pinned commits 2026-10-05 02:51:22 +02:00
Abdessamad Derraz 0d3a2b87ed fix: name homonymous release assets by path 2026-10-05 02:51:13 +02:00
Abdessamad Derraz 0d7939588e fix: one size predicate, size_options retired 2026-10-05 02:51:13 +02:00
180 changed files with 338412 additions and 9434 deletions

No files matched your search

+1
View File
@@ -22,6 +22,7 @@ on:
- "scripts/hashing.py"
- "scripts/largefiles.py"
- "scripts/list_platforms.py"
- "scripts/manifestselect.py"
- "scripts/nativemode.py"
- "scripts/packextras.py"
- "scripts/packpaths.py"
+31 -31
View File
@@ -32,7 +32,7 @@ The script auto-detects your platform, downloads only missing files, and verifie
## Download BIOS packs
One pack per platform, and it holds everything the platform runs: its own BIOS list plus every file its emulator cores load. Pick your platform, download the ZIP, extract to the BIOS path. The installer above does the same file by file, and `--target` narrows it to one machine; for a region or a bare minimum, build your own pack below.
One pack per platform, and it holds everything the platform runs: its own BIOS list plus every file its emulator cores load. Pick your platform, download the ZIP, extract to the BIOS path. The installer above does the same file by file. At a terminal it asks whether to install everything or to choose systems, cores and regions, and `--system`, `--core`, `--region` and `--target` make the same choice without questions; for a bare minimum, build your own pack below.
Files is how many the pack holds once extracted, the figure a file manager shows for the folder. It differs from one platform to the next because a pack carries only what that platform's emulators load. The size is what the files occupy once extracted; the ZIP itself downloads smaller.
A pack over 2 GB comes in several parts, and every part is needed. How to open them depends on their name:
@@ -44,18 +44,18 @@ Every release ships `SHA256SUMS.txt` and a detached signature of it, checkable a
| Platform | Files | Extracted size | Extract to | Download |
|----------|------:|---------------:|-----------|----------|
| Batocera | 1,839 | 4.0 GB | `/userdata/bios/` | [Download](../../releases/latest) |
| BizHawk | 542 | 2.2 GB | `Firmware/` | [Download](../../releases/latest) |
| EmuDeck | 624 | 3.2 GB | `~/Emulation/bios/` | [Download](../../releases/latest) |
| Lakka | 4,525 | 5.5 GB | `/storage/system/` | [Download](../../releases/latest) |
| MiSTer FPGA | 74 | 24 MB | `/media/fat/games/` | [Download](../../releases/latest) |
| ROCKNIX | 1,741 | 5.3 GB | `/storage/roms/bios/` | [Download](../../releases/latest) |
| Recalbox | 1,330 | 3.6 GB | `/recalbox/share/bios/` | [Download](../../releases/latest) |
| RetroArch | 4,525 | 5.5 GB | `system/` | [Download](../../releases/latest) |
| RetroBat | 1,466 | 4.4 GB | `bios/` | [Download](../../releases/latest) |
| RetroDECK | 3,519 | 6.2 GB | `~/retrodeck/` | [Download](../../releases/latest) |
| RetroPie * | 4,525 | 5.5 GB | `~/RetroPie/BIOS/` | [Download](../../releases/latest) |
| RomM | 617 | 1.3 GB | `library/bios/` | [Download](../../releases/latest) |
| Batocera | 12,810 | 7.5 GB | `/userdata/bios/` | [Download](../../releases/latest) |
| BizHawk | 950 | 2.4 GB | `Firmware/` | [Download](../../releases/latest) |
| EmuDeck | 620 | 3.2 GB | `~/Emulation/bios/` | [Download](../../releases/latest) |
| Lakka | 8,504 | 6.0 GB | `/storage/system/` | [Download](../../releases/latest) |
| MiSTer FPGA | 83 | 29 MB | `/media/fat/games/` | [Download](../../releases/latest) |
| ROCKNIX | 5,804 | 6.1 GB | `/storage/roms/bios/` | [Download](../../releases/latest) |
| Recalbox | 3,222 | 3.9 GB | `/recalbox/share/bios/` | [Download](../../releases/latest) |
| RetroArch | 8,504 | 6.0 GB | `system/` | [Download](../../releases/latest) |
| RetroBat | 12,399 | 7.9 GB | `bios/` | [Download](../../releases/latest) |
| RetroDECK | 7,793 | 8.0 GB | `~/retrodeck/` | [Download](../../releases/latest) |
| RetroPie * | 12,533 | 8.1 GB | `~/RetroPie/BIOS/` | [Download](../../releases/latest) |
| RomM | 1,087 | 1.5 GB | `library/bios/` | [Download](../../releases/latest) |
The RetroDECK pack already carries its own `bios/` folder, so it extracts into `~/retrodeck/` rather than into the BIOS folder.
@@ -68,17 +68,17 @@ These are the files an emulator loads from disk instead of carrying inside itsel
Each file is checked the way your platform checks it. Most compare a checksum, the fingerprint of a file's contents, which catches a corrupt or unexpected copy. RetroArch, Lakka and RetroPie only look for the filename, because that is all their code does: the Coverage table says which applies to you. Independently of that, the collection records five fingerprints per file, and wherever an emulator's code states an expected size or hash, that value is read from its source and rechecked here.
- **392 files** the platforms' emulators load are still to be found, and 51 more cannot be sourced at all (per-user keys, user-filled slots, dumps nobody has made); both are named in the [gap analysis](https://abdess.github.io/retrobios/gaps/)
- **393 files** the platforms' emulators load are still to be found, and 51 more cannot be sourced at all (per-user keys, user-filled slots, dumps nobody has made); both are named in the [gap analysis](https://abdess.github.io/retrobios/gaps/)
- **12 platforms** supported with platform-specific verification
- **506 emulators** profiled from source (RetroArch cores + standalone)
- **546 systems** handled by those emulators (NES, SNES, PlayStation, Saturn, Dreamcast, ...)
- **18,997 files in the collection**, each with its SHA1, MD5, SHA256, CRC32 and Adler-32 fingerprints: 5,261 system files, 2,808 arcade ROM sets, 10,928 game and engine data files. That is every platform and emulator together, so no pack holds them all: each carries what its own emulators load, counted in the download table
- **562 of 5,261 system files** matched to dump-preservation catalogs (No-Intro, Redump, TOSEC); arcade sets and engine data fall outside what those catalogs index
- **16677 MB** total collection size
- **544 systems** handled by those emulators (NES, SNES, PlayStation, Saturn, Dreamcast, ...)
- **19,005 files in the collection**, each with its SHA1, MD5, SHA256, CRC32 and Adler-32 fingerprints: 5,269 system files, 2,808 arcade ROM sets, 10,928 game and engine data files. That is every platform and emulator together, so no pack holds them all: each carries what its own emulators load, counted in the download table
- **562 of 5,269 system files** matched to dump-preservation catalogs (No-Intro, Redump, TOSEC); arcade sets and engine data fall outside what those catalogs index
- **16687 MB** total collection size
## Supported systems
NES, SNES, Nintendo 64, GameCube, Wii, Game Boy, Game Boy Advance, Nintendo DS, Nintendo 3DS, Switch, PlayStation, PlayStation 2, PlayStation 3, PSP, PS Vita, Mega Drive, Saturn, Dreamcast, Game Gear, Master System, Neo Geo, Atari 2600, Atari 7800, Atari Lynx, Atari ST, MSX, PC Engine, TurboGrafx-16, ColecoVision, Intellivision, Commodore 64, Amiga, ZX Spectrum, Arcade (MAME), and 512+ more.
NES, SNES, Nintendo 64, GameCube, Wii, Game Boy, Game Boy Advance, Nintendo DS, Nintendo 3DS, Switch, PlayStation, PlayStation 2, PlayStation 3, PSP, PS Vita, Mega Drive, Saturn, Dreamcast, Game Gear, Master System, Neo Geo, Atari 2600, Atari 7800, Atari Lynx, Atari ST, MSX, PC Engine, TurboGrafx-16, ColecoVision, Intellivision, Commodore 64, Amiga, ZX Spectrum, Arcade (MAME), and 510+ more.
Full list with per-file details: **[https://abdess.github.io/retrobios/](https://abdess.github.io/retrobios/)**
@@ -86,18 +86,18 @@ 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,306/12,737 | MD5 hash |
| BizHawk | 118/118 | 806/807 | SHA1 hash |
| EmuDeck | 168/168 | 431/433 | MD5 hash |
| Lakka | 527/527 | 5,264/5,294 | file presence |
| Batocera | 353/353 | 12,295/12,726 | MD5 hash |
| BizHawk | 118/118 | 800/801 | SHA1 hash |
| EmuDeck | 168/168 | 430/432 | MD5 hash |
| Lakka | 526/526 | 5,260/5,290 | file presence |
| MiSTer FPGA | 81/81 | - | MD5 hash |
| ROCKNIX | 38/38 | 5,698/5,728 | MD5 hash |
| Recalbox | 351/351 | 2,730/2,738 | MD5 hash |
| RetroArch | 527/527 | 5,264/5,294 | file presence |
| RetroBat | 348/348 | 11,889/12,319 | MD5 hash |
| RetroDECK | 2,008/2,008 | 5,407/5,457 | MD5 hash |
| RetroPie * | 527/527 | 9,183/9,325 | file presence |
| RomM | 381/381 | 751/757 | MD5 hash |
| ROCKNIX | 38/38 | 5,697/5,727 | MD5 hash |
| Recalbox | 351/351 | 2,731/2,739 | MD5 hash |
| RetroArch | 526/526 | 5,260/5,290 | file presence |
| RetroBat | 348/348 | 11,885/12,316 | MD5 hash |
| RetroDECK | 2,008/2,008 | 5,400/5,450 | MD5 hash |
| RetroPie * | 526/526 | 9,181/9,323 | file presence |
| RomM | 381/381 | 753/760 | MD5 hash |
Each fraction is what the pack has over what is needed, counting required and optional files alike since both ship. The first column is the BIOS list the platform publishes. The second counts files its emulators load that this list never mentions, found by reading their source code, and it is routinely several times larger. A short fraction means files are still missing, and they are named in the [gap analysis](https://abdess.github.io/retrobios/gaps/).
That second number is a floor, not a ceiling: an emulator that accepts any file handed to it names none in its code, so nothing there can be counted.
@@ -180,4 +180,4 @@ The scripts and tooling are released under the [MIT License](LICENSE).
The BIOS and firmware files are not covered by that license: they are third-party system software, preserved and provided for personal backup, archival, and interoperability with emulation software. [NOTICE](NOTICE) sets out their status and how to ask for a file to be removed.
The reasoning, and where it is weakest, is in the [FAQ](https://abdess.github.io/retrobios/wiki/faq/#is-this-legal).
*Auto-generated on 2026-10-06T11:05:39Z*
*Auto-generated on 2026-10-10T10:40:24Z*
File diff suppressed because it is too large. Load diff
File diff suppressed because it is too large. Load diff
Binary file not shown.
+150
View File
@@ -0,0 +1,150 @@
# Default keys file bundled with Azahar.
# DISCLAIMER: The keys present in this document are used exclusively for interoperability
# with the user's legally obtained software, as well as to perform cryptographic operations
# on other 3DS-related data of non creative nature (data structures, numbers, etc).
:AES
# Generator constant
generatorConstant=1ff9e9aac5fe0408024591dc5d52768a
# OTP
otpKey=06457901d485a367ac4f2ad01c53cf74
otpIV=ba4f599b0ae1122c80e13f6865c4fa49
# Movable
movableKeyY=a717802dea9776137ba16cd389141cf0
movableCmacY=6e1e6bcb9ee098dd67ae771ad73b2cc9
# KeyX
slot0x18KeyX=82e9c9bebfb8bdb875ecc0a07d474374
slot0x19KeyX=f5367fce73142e66ed13917914b7f2ef
slot0x1AKeyX=eaba984c9cb766d4a3a7e974e2e713a3
slot0x1BKeyX=45ad04953992c7c893724a9a7bce6182
slot0x1CKeyX=c3830f8156e3543b723f0bc046741e8f
slot0x1DKeyX=d6b38bc759417596d619d6029d13e0d8
slot0x1EKeyX=bb623a97ddd793d757c4104b8d9fb969
slot0x1FKeyX=4c28ec6effa3c23646078bba350c7995
slot0x25KeyX=cee7d8ab30c00dae850ef5e382ac5af3
slot0x2CKeyX=b98e95ceca3e4d171f76a94de934c053
slot0x2DKeyX=b98e95ceca3e4d171f76a94de934c053
slot0x2EKeyX=b98e95ceca3e4d171f76a94de934c053
slot0x2FKeyX=b98e95ceca3e4d171f76a94de934c053
slot0x30KeyX=c66e23128f289133f04cdb877a3749f2
slot0x31KeyX=c66e23128f289133f04cdb877a3749f2
slot0x32KeyX=c66e23128f289133f04cdb877a3749f2
slot0x33KeyX=c66e23128f289133f04cdb877a3749f2
slot0x34KeyX=6fbb01f872caf9c01834eec04065ee53
slot0x35KeyX=6fbb01f872caf9c01834eec04065ee53
slot0x36KeyX=6fbb01f872caf9c01834eec04065ee53
slot0x37KeyX=6fbb01f872caf9c01834eec04065ee53
slot0x38KeyX=b529221cddb5db5a1bf26eff2041e875
slot0x39KeyX=b529221cddb5db5a1bf26eff2041e875
slot0x3AKeyX=b529221cddb5db5a1bf26eff2041e875
slot0x3BKeyX=b529221cddb5db5a1bf26eff2041e875
slot0x3CKeyX=c35d6d15680b1ad4e912a341836121b3
slot0x3DKeyX=617085719b7cfb316df4df2e8362c6e2
slot0x3EKeyX=24baf628d06889bf282d0aa35dc55650
slot0x3FKeyX=a31233280bb4daa7761393f78c424952
# KeyY
slot0x04KeyY=ff3388ecd21705bb339e967986dc4907
slot0x05KeyY=54ef035f30260e0e9b5e004fc985dc22
slot0x06KeyY=24b05aaaac0b099252030c02d1040317
slot0x07KeyY=e9acc5abd4ad3f0660c83c8934882f3f
slot0x08KeyY=4803050106d482dcd75f85c5aadff9b3
slot0x09KeyY=af6346efdddfa9806e3c6b6855b78930
slot0x0AKeyY=0a870a2c4b2fc3172e5f0335d8c5085d
slot0x0BKeyY=fda0152fcd6ddb3133b887ba727c0ada
slot0x24KeyY=74ca074884f4228deb2a1ca72d287762
slot0x2EKeyY=7462553f9e5a7904b8647cca736da1f5
slot0x2FKeyY=c369baa21e188a88a9aa94e5506a9f16
slot0x31KeyY=7462553f9e5a7904b8647cca736da1f5
# DLP/NFC KeyY (slot 0x39)
dlpKeyY=7462553f9e5a7904b8647cca736da1f5
nfcKeyY=ed7858a8bba7eed7fc970c5979bc0af2
# Ticket Common KeyY (slot 0x3D)
common0=d07b337f9ca4385932a2e25723232eb9
common1=0c767230f0998f1c46828202faacbe4c
common2=c475cb3ab8c788bb575e12a10907b8a4
common3=e486eee3d0c09c902f6686d4c06f649f
common4=ed31ba9c04b067506c4497a35b7804fc
common5=5e66998ab4e8931606850fd7a16dd755
# KeyN
slot0x0CKeyN=e7c9ff9d4f5b6f4dc5e2f50e856f0ab2
slot0x0DKeyN=e7c9ff9d4f5b6f4dc5e2f50e856f0ab2
slot0x0EKeyN=e7c9ff9d4f5b6f4dc5e2f50e856f0ab2
slot0x0FKeyN=e7c9ff9d4f5b6f4dc5e2f50e856f0ab2
slot0x10KeyN=285713db53051c089bdfb3b6aa638fda
slot0x11KeyN=285713db53051c089bdfb3b6aa638fda
slot0x12KeyN=285713db53051c089bdfb3b6aa638fda
slot0x13KeyN=285713db53051c089bdfb3b6aa638fda
slot0x14KeyN=2af3bbd32cd59c06fd4abe58651987ad
slot0x15KeyN=be2836751c734ba8da18e1887f888bd6
slot0x16KeyN=e3a18eb1c1dc8a3d27c3967e6e362de3
slot0x17KeyN=d0294cfb7be0b4fb7324d986fd3993bb
slot0x20KeyN=7c92f6272551c4614db0b345edd2e869
slot0x21KeyN=7c92f6272551c4614db0b345edd2e869
slot0x22KeyN=7c92f6272551c4614db0b345edd2e869
slot0x23KeyN=7c92f6272551c4614db0b345edd2e869
slot0x26KeyN=bbe8b4e09d0937816b234d8eb3cd3ca2
slot0x27KeyN=bbe8b4e09d0937816b234d8eb3cd3ca2
slot0x28KeyN=bbe8b4e09d0937816b234d8eb3cd3ca2
slot0x29KeyN=5218127e133ce3b85bb8c018ce76b7e2
slot0x2AKeyN=4a4264cf32e84170666f29ac88ef3f7e
slot0x2BKeyN=51af6c4c8b13da3228bd29b371cf84e1
slot0x2DKeyN=3ed6f5cf2cc37c54655000b7c8b52e0d
slot0x32KeyN=b87e64018b190ffe048a8124c6454196
slot0x36KeyN=28c0d59b736657bcdf50ff174979958a
slot0x38KeyN=6e78a3be9bddda09bfd569483f24fce0
# NFC Secrets
nfcSecret0Phrase=756e666978656420696e666f7300
nfcSecret0Seed=db4b9e3f45278f397eff9b4fb993
nfcSecret0HmacKey=1d164b375b72a55728b91d64b6a3c205
nfcSecret1Phrase=6c6f636b65642073656372657400
nfcSecret1Seed=fdc8a07694b89e4c47d37de8ce5c74c1
nfcSecret1HmacKey=7f752d2873a20017fef85c0575904b6d
nfcIv=4fd39a6e79fceaad99904db8ee38e9db
:RSA
# Slots
slot0x00X=c034829a11c7116a08633e89a78ca0919779da8cc967077afc60e1786247e5068b9a76588a15f0304b3887b5147c259f7a2e6e480aceb0be35f0c5885ea2d8838fd6aafe45ac58fc08d4d0569d3cd3b09f9c6985fcd5c7152ebc54a885d6b11129b503611510bbfa0b07552d5800ecf636ef90d101cd475a3f4274e0c1e828b2bb516c8cd80f95f5db6a239083435509c0190e5d218b19c3bebc2a3aa73cebf53e7e4998d9be01a440f3f1c0f3157ba6f65a7be9e059d4d26f9de997141979df2ceaa175d91db2079051978f805d6f97741b6db4e96e3305611392b4b7ca76f0b45387c40d5879cde6b1509062216cb9ac21f3510ccd6df4da8f581ff86d2f31
slot0x00M=c12e4877ff0fedb98afa6dbe5d7ac86489a4e0901dba22d2e7ba945c830126ca71976f284a5e57e386b4778fbb78e3f1750ecd8b6ed3984f3cd363f801dd9ed5271ea859f49ff4da02d88445efba774b3a46279167cb905300d0903ecb71772b78cfe918921e2bef699f87d9cbef273fbc0e320d177e925021e869bb827f227f17da206ae9ce5de262566c4fab0be86866f7218fd48c248c0d8cbdeb3adbc423a6cd1b572f82c0172d23e32b1b4f0c30b04c20749126851dba39b31a2918c23f91034969e601c0a1099742e8fd31cfe4a02cd9e6bd7b646c52465567c7463b2a9e7e9fa53a0e260d4daee68091ee7adfa1c1491538276161e1c10293f4592a33
# Ticket wrap
ticketWrapExp=010001
ticketWrapMod=d24cb2e48feaf004d4bb08f8f3defcbb0c934a146b15366c9ddc1eb1649b9feb964b569c2283954d3d2b8a1ab21dc1159c2e6cb4cdd4c0bb96dbad4f02d31f45573892af855273aca20c459b9bd3126425c05d766bfd2fad87986c08416aea8d4266cd9d4ffc3f20f7b5672b686793141edde1b11689aca2f6469c9b0ea4577150235185ed4e7e4f2f9036c165a20c73e160c644a47303d2ed9bb0ba2fc90989bd87eb4563d8f7a61d889a7807b155e7f2107d048d828fcba23090839341385614fde4fabe84f2f0532da34750f32ab11fbe084c0083edbf0b50e96a49dd9d1e293e2249ee954db8afd139461ead4f11a2d06836446473140ed3867e4e5ead3b
# Secure info
secureInfoExp=010001
secureInfoMod=b1791a6d1eadd429ba89a1cd433630174bc68730c5e70560197b50d8c4546710a6e8a101bc2ceb0376f005c70ce0b6d6dffd26df33468bdbb2391e7ec01aa1a5a091e807da378676ba390a25429d5961e161d40485a74bb20186beb11a3572c1c2ea28ab7a1015325c9e712b7df965eae6c6fb8baed76c2a94a6c5ece40eaf987e06f20f884fd20635a476e9f70aba5c5b1461520054044593e468270435355aad5809d1193f5a0728d6db6b551f77945dc3be6fae5bcc0863e476dfa29b36ea853403e616eaa905e07f3a3e7e7077cf166a61d17e4d354c744485d4f67b0eee32f1c2d5790248e9621a33baa39b02b02294057ff6b43888e301e55a237c9c0b
# Local friend code seed
lfcsExp=010001
lfcsMod=a3759a3546cfa7fe30ec55a1b64e08e9449d0c72fcd191fd610a288975bce6a9b21556e9c7670255adfc3cee5edb78259a4b221b71e7e9515b2a6793b21868ce5e5e12ffd86806af318d56f9549902346a17e7837496a05aaf6efde6bed686aafd7a65a8ebe11c983a15c17ab540c23d9b7cfdd463c5e6deb77824c629473335b2e937e054ee9fa53dd793ca3eae4db60f5a11e70cdfba03b21e2b31b65906db5f940bf76e74cad4ab55d940058f10fe06050c81bb422190ba4f5c5382e1e10fbc949f60695d1303aae2e0c108424c200b9baa552d55276e24e5d60457588ff75f0cec819f6d2d28f31055f83b7662d4e4a69369b5da6b4023af07eb9cbfa9c9
:ECC
# Root public
rootPublicXY=004e3bb74d5d959e68ce900434fe9e4a3f094a33771fa7c0e4b023264d98014ca1fc799d3fa52171d5f9bd5b1777ec0fef7a38d1669bbf830325843a
# Padding......
+154
View File
@@ -0,0 +1,154 @@
# Default keys file bundled with Azahar.
# DISCLAIMER: The keys present in this document are used exclusively for interoperability
# with the user's legally obtained software, as well as to perform cryptographic operations
# on other 3DS-related data of non creative nature (data structures, numbers, etc).
:AES
# Generator constant
generatorConstant=1ff9e9aac5fe0408024591dc5d52768a
# OTP
otpKey=06457901d485a367ac4f2ad01c53cf74
otpIV=ba4f599b0ae1122c80e13f6865c4fa49
# Movable
movableKeyY=a717802dea9776137ba16cd389141cf0
movableCmacY=6e1e6bcb9ee098dd67ae771ad73b2cc9
# KeyX
slot0x18KeyX=82e9c9bebfb8bdb875ecc0a07d474374
slot0x19KeyX=f5367fce73142e66ed13917914b7f2ef
slot0x1AKeyX=eaba984c9cb766d4a3a7e974e2e713a3
slot0x1BKeyX=45ad04953992c7c893724a9a7bce6182
slot0x1CKeyX=c3830f8156e3543b723f0bc046741e8f
slot0x1DKeyX=d6b38bc759417596d619d6029d13e0d8
slot0x1EKeyX=bb623a97ddd793d757c4104b8d9fb969
slot0x1FKeyX=4c28ec6effa3c23646078bba350c7995
slot0x25KeyX=cee7d8ab30c00dae850ef5e382ac5af3
slot0x2CKeyX=b98e95ceca3e4d171f76a94de934c053
slot0x2DKeyX=b98e95ceca3e4d171f76a94de934c053
slot0x2EKeyX=b98e95ceca3e4d171f76a94de934c053
slot0x2FKeyX=b98e95ceca3e4d171f76a94de934c053
slot0x30KeyX=c66e23128f289133f04cdb877a3749f2
slot0x31KeyX=c66e23128f289133f04cdb877a3749f2
slot0x32KeyX=c66e23128f289133f04cdb877a3749f2
slot0x33KeyX=c66e23128f289133f04cdb877a3749f2
slot0x34KeyX=6fbb01f872caf9c01834eec04065ee53
slot0x35KeyX=6fbb01f872caf9c01834eec04065ee53
slot0x36KeyX=6fbb01f872caf9c01834eec04065ee53
slot0x37KeyX=6fbb01f872caf9c01834eec04065ee53
slot0x38KeyX=b529221cddb5db5a1bf26eff2041e875
slot0x39KeyX=b529221cddb5db5a1bf26eff2041e875
slot0x3AKeyX=b529221cddb5db5a1bf26eff2041e875
slot0x3BKeyX=b529221cddb5db5a1bf26eff2041e875
slot0x3CKeyX=c35d6d15680b1ad4e912a341836121b3
slot0x3DKeyX=617085719b7cfb316df4df2e8362c6e2
slot0x3EKeyX=24baf628d06889bf282d0aa35dc55650
slot0x3FKeyX=a31233280bb4daa7761393f78c424952
# KeyY
slot0x04KeyY=ff3388ecd21705bb339e967986dc4907
slot0x05KeyY=54ef035f30260e0e9b5e004fc985dc22
slot0x06KeyY=24b05aaaac0b099252030c02d1040317
slot0x07KeyY=e9acc5abd4ad3f0660c83c8934882f3f
slot0x08KeyY=4803050106d482dcd75f85c5aadff9b3
slot0x09KeyY=af6346efdddfa9806e3c6b6855b78930
slot0x0AKeyY=0a870a2c4b2fc3172e5f0335d8c5085d
slot0x0BKeyY=fda0152fcd6ddb3133b887ba727c0ada
slot0x24KeyY=74ca074884f4228deb2a1ca72d287762
slot0x2EKeyY=7462553f9e5a7904b8647cca736da1f5
slot0x2FKeyY=c369baa21e188a88a9aa94e5506a9f16
slot0x31KeyY=7462553f9e5a7904b8647cca736da1f5
# DLP/NFC KeyY (slot 0x39)
dlpKeyY=7462553f9e5a7904b8647cca736da1f5
nfcKeyY=ed7858a8bba7eed7fc970c5979bc0af2
# Ticket Common KeyY (slot 0x3D)
common0=d07b337f9ca4385932a2e25723232eb9
common1=0c767230f0998f1c46828202faacbe4c
common2=c475cb3ab8c788bb575e12a10907b8a4
common3=e486eee3d0c09c902f6686d4c06f649f
common4=ed31ba9c04b067506c4497a35b7804fc
common5=5e66998ab4e8931606850fd7a16dd755
# KeyN
slot0x0CKeyN=e7c9ff9d4f5b6f4dc5e2f50e856f0ab2
slot0x0DKeyN=e7c9ff9d4f5b6f4dc5e2f50e856f0ab2
slot0x0EKeyN=e7c9ff9d4f5b6f4dc5e2f50e856f0ab2
slot0x0FKeyN=e7c9ff9d4f5b6f4dc5e2f50e856f0ab2
slot0x10KeyN=285713db53051c089bdfb3b6aa638fda
slot0x11KeyN=285713db53051c089bdfb3b6aa638fda
slot0x12KeyN=285713db53051c089bdfb3b6aa638fda
slot0x13KeyN=285713db53051c089bdfb3b6aa638fda
slot0x14KeyN=2af3bbd32cd59c06fd4abe58651987ad
slot0x15KeyN=be2836751c734ba8da18e1887f888bd6
slot0x16KeyN=e3a18eb1c1dc8a3d27c3967e6e362de3
slot0x17KeyN=d0294cfb7be0b4fb7324d986fd3993bb
slot0x20KeyN=7c92f6272551c4614db0b345edd2e869
slot0x21KeyN=7c92f6272551c4614db0b345edd2e869
slot0x22KeyN=7c92f6272551c4614db0b345edd2e869
slot0x23KeyN=7c92f6272551c4614db0b345edd2e869
slot0x26KeyN=bbe8b4e09d0937816b234d8eb3cd3ca2
slot0x27KeyN=bbe8b4e09d0937816b234d8eb3cd3ca2
slot0x28KeyN=bbe8b4e09d0937816b234d8eb3cd3ca2
slot0x29KeyN=5218127e133ce3b85bb8c018ce76b7e2
slot0x2AKeyN=4a4264cf32e84170666f29ac88ef3f7e
slot0x2BKeyN=51af6c4c8b13da3228bd29b371cf84e1
slot0x2DKeyN=3ed6f5cf2cc37c54655000b7c8b52e0d
slot0x32KeyN=b87e64018b190ffe048a8124c6454196
slot0x36KeyN=28c0d59b736657bcdf50ff174979958a
slot0x38KeyN=6e78a3be9bddda09bfd569483f24fce0
# NFC Secrets
nfcSecret0Phrase=756e666978656420696e666f7300
nfcSecret0Seed=db4b9e3f45278f397eff9b4fb993
nfcSecret0HmacKey=1d164b375b72a55728b91d64b6a3c205
nfcSecret1Phrase=6c6f636b65642073656372657400
nfcSecret1Seed=fdc8a07694b89e4c47d37de8ce5c74c1
nfcSecret1HmacKey=7f752d2873a20017fef85c0575904b6d
nfcIv=4fd39a6e79fceaad99904db8ee38e9db
# DLP Checksum
dlpChecksumModIv=fe449ac13ae3b4095011d18944107833
:RSA
# Slots
slot0x00X=c034829a11c7116a08633e89a78ca0919779da8cc967077afc60e1786247e5068b9a76588a15f0304b3887b5147c259f7a2e6e480aceb0be35f0c5885ea2d8838fd6aafe45ac58fc08d4d0569d3cd3b09f9c6985fcd5c7152ebc54a885d6b11129b503611510bbfa0b07552d5800ecf636ef90d101cd475a3f4274e0c1e828b2bb516c8cd80f95f5db6a239083435509c0190e5d218b19c3bebc2a3aa73cebf53e7e4998d9be01a440f3f1c0f3157ba6f65a7be9e059d4d26f9de997141979df2ceaa175d91db2079051978f805d6f97741b6db4e96e3305611392b4b7ca76f0b45387c40d5879cde6b1509062216cb9ac21f3510ccd6df4da8f581ff86d2f31
slot0x00M=c12e4877ff0fedb98afa6dbe5d7ac86489a4e0901dba22d2e7ba945c830126ca71976f284a5e57e386b4778fbb78e3f1750ecd8b6ed3984f3cd363f801dd9ed5271ea859f49ff4da02d88445efba774b3a46279167cb905300d0903ecb71772b78cfe918921e2bef699f87d9cbef273fbc0e320d177e925021e869bb827f227f17da206ae9ce5de262566c4fab0be86866f7218fd48c248c0d8cbdeb3adbc423a6cd1b572f82c0172d23e32b1b4f0c30b04c20749126851dba39b31a2918c23f91034969e601c0a1099742e8fd31cfe4a02cd9e6bd7b646c52465567c7463b2a9e7e9fa53a0e260d4daee68091ee7adfa1c1491538276161e1c10293f4592a33
# Ticket wrap
ticketWrapExp=010001
ticketWrapMod=d24cb2e48feaf004d4bb08f8f3defcbb0c934a146b15366c9ddc1eb1649b9feb964b569c2283954d3d2b8a1ab21dc1159c2e6cb4cdd4c0bb96dbad4f02d31f45573892af855273aca20c459b9bd3126425c05d766bfd2fad87986c08416aea8d4266cd9d4ffc3f20f7b5672b686793141edde1b11689aca2f6469c9b0ea4577150235185ed4e7e4f2f9036c165a20c73e160c644a47303d2ed9bb0ba2fc90989bd87eb4563d8f7a61d889a7807b155e7f2107d048d828fcba23090839341385614fde4fabe84f2f0532da34750f32ab11fbe084c0083edbf0b50e96a49dd9d1e293e2249ee954db8afd139461ead4f11a2d06836446473140ed3867e4e5ead3b
# Secure info
secureInfoExp=010001
secureInfoMod=b1791a6d1eadd429ba89a1cd433630174bc68730c5e70560197b50d8c4546710a6e8a101bc2ceb0376f005c70ce0b6d6dffd26df33468bdbb2391e7ec01aa1a5a091e807da378676ba390a25429d5961e161d40485a74bb20186beb11a3572c1c2ea28ab7a1015325c9e712b7df965eae6c6fb8baed76c2a94a6c5ece40eaf987e06f20f884fd20635a476e9f70aba5c5b1461520054044593e468270435355aad5809d1193f5a0728d6db6b551f77945dc3be6fae5bcc0863e476dfa29b36ea853403e616eaa905e07f3a3e7e7077cf166a61d17e4d354c744485d4f67b0eee32f1c2d5790248e9621a33baa39b02b02294057ff6b43888e301e55a237c9c0b
# Local friend code seed
lfcsExp=010001
lfcsMod=a3759a3546cfa7fe30ec55a1b64e08e9449d0c72fcd191fd610a288975bce6a9b21556e9c7670255adfc3cee5edb78259a4b221b71e7e9515b2a6793b21868ce5e5e12ffd86806af318d56f9549902346a17e7837496a05aaf6efde6bed686aafd7a65a8ebe11c983a15c17ab540c23d9b7cfdd463c5e6deb77824c629473335b2e937e054ee9fa53dd793ca3eae4db60f5a11e70cdfba03b21e2b31b65906db5f940bf76e74cad4ab55d940058f10fe06050c81bb422190ba4f5c5382e1e10fbc949f60695d1303aae2e0c108424c200b9baa552d55276e24e5d60457588ff75f0cec819f6d2d28f31055f83b7662d4e4a69369b5da6b4023af07eb9cbfa9c9
:ECC
# Root public
rootPublicXY=004e3bb74d5d959e68ce900434fe9e4a3f094a33771fa7c0e4b023264d98014ca1fc799d3fa52171d5f9bd5b1777ec0fef7a38d1669bbf830325843a
# Padding...................
File renamed without changes.
Binary file not shown.
File diff suppressed because it is too large. Load diff
File diff suppressed because it is too large. Load diff
+245 -57
View File
@@ -1,8 +1,9 @@
{
"schema_version": 1,
"generated_at": "2026-10-06T10:11:17Z",
"total_files": 18997,
"total_size": 17487414657,
"generated_at": "2026-10-10T05:24:26Z",
"total_files": 19005,
"total_size": 17497729510,
"bios_dir": "bios",
"files": {
"738c7f5fd0c8b57ee2e87ae7a97bf8e21a821d07": {
"path": "bios/3D Realms/Duke Nukem 3D/DUKE.RTS",
@@ -131659,6 +131660,16 @@
"crc32": "6b7152b1",
"adler32": "d84f79e3"
},
"71fc274cbe27f382afb0324024ebdc6f59aa666d": {
"path": "bios/Other/aethersx2/resources/GameIndex.yaml",
"name": "GameIndex.yaml",
"size": 984983,
"sha1": "71fc274cbe27f382afb0324024ebdc6f59aa666d",
"md5": "3758db793dae7bc206fbbd799c3cbb05",
"sha256": "e7c70faf16ce180e6a17c040dc2bb326c6fcca63e7fb3f83f992d65fbe480443",
"crc32": "5acc416a",
"adler32": "986d242e"
},
"8acfbc4a51909de382e33a221a82f0b8efc04794": {
"path": "bios/Other/altirra/.variants/810-archiver.rom.8080d51e",
"name": "810-archiver.rom",
@@ -132709,16 +132720,6 @@
"crc32": "a5b357e6",
"adler32": "44a50462"
},
"dceb4536fba7fb89452864fc512a4d071a19eae0": {
"path": "bios/Other/armsx2/RedumpDatabase.yaml",
"name": "RedumpDatabase.yaml",
"size": 1906463,
"sha1": "dceb4536fba7fb89452864fc512a4d071a19eae0",
"md5": "dbf48fe7b36fab316a1682961178ffd7",
"sha256": "755962450efd5effd2f3fe2f9a60c73d6cb3f9b4acea964abf5bb25a86ee25bc",
"crc32": "0496a60f",
"adler32": "c76311d2"
},
"00d62fbdc8d5dec4c659005e116d0ba2ee63b547": {
"path": "bios/Other/armsx2/Roboto-Regular.ttf",
"name": "Roboto-Regular.ttf",
@@ -132959,6 +132960,16 @@
"crc32": "6e8b2b47",
"adler32": "f5bc538e"
},
"72bfdf91fa11a86e2810a7c167cdcf11e20418a8": {
"path": "bios/Other/armsx2/pcsx2/resources/GameIndex.yaml",
"name": "GameIndex.yaml",
"size": 2690355,
"sha1": "72bfdf91fa11a86e2810a7c167cdcf11e20418a8",
"md5": "ec65dbfe7379cfac816b4d02259c0ca5",
"sha256": "61c77b789ccde856096f024e4a3eef6891e15ca59c127e0dd13e762a7d338a7e",
"crc32": "1a8e4cf7",
"adler32": "479c1f04"
},
"456e74b0805d1931a7786d3d04673a3b02dd4dd3": {
"path": "bios/Other/armsx2/pcsx2/resources/fonts/NotoSansArabic-Regular.ttf",
"name": "NotoSansArabic-Regular.ttf",
@@ -133029,6 +133040,16 @@
"crc32": "05eb51ca",
"adler32": "cd7061bf"
},
"f7d0f1606c87019f00109ebdf0f260299f0a72da": {
"path": "bios/Other/armsx2/pcsx2/resources/patches.zip",
"name": "patches.zip",
"size": 2007224,
"sha1": "f7d0f1606c87019f00109ebdf0f260299f0a72da",
"md5": "809868f006eebec4e4615dd8bc397ef7",
"sha256": "8d95f1fba3acc83195bbac2d3e042b5f34c3c399856d9865e681d173f4cee609",
"crc32": "5120eae7",
"adler32": "68c47b84"
},
"8618516b26a0bc319ed174b66fd2d990eb5b74a3": {
"path": "bios/Other/armsx2/pcsx2/resources/shaders/common/ffx_a_fsr1.h",
"name": "ffx_a_fsr1.h",
@@ -133339,6 +133360,26 @@
"crc32": "1e65e2e2",
"adler32": "765cc424"
},
"5fab786695311433602028cd89898689c5df0898": {
"path": "bios/Other/azahar/sysdata/keys.txt",
"name": "keys.txt",
"size": 7344,
"sha1": "5fab786695311433602028cd89898689c5df0898",
"md5": "cb52d323b13129a2f0bc3e3e911e567f",
"sha256": "dee8cbca96b74e81d19b0292f8c6255f0e2b23d8551f82cacd086c2eead35ea4",
"crc32": "352ceb91",
"adler32": "5d463cad"
},
"5288772be438b86978a801e6dcb14228ad3a20af": {
"path": "bios/Other/azaharplus/sysdata/keys.txt",
"name": "keys.txt",
"size": 7424,
"sha1": "5288772be438b86978a801e6dcb14228ad3a20af",
"md5": "4812e96097b7fc1bdd7b40366208b7a7",
"sha256": "ea8b3d7c752d85f2326b9bfa01615414ab34ba052f87481b0ff4003fd887e50a",
"crc32": "d5b60ff6",
"adler32": "13b65227"
},
"efd505f459448c5741a8ca249089f068b72cb751": {
"path": "bios/Other/beebem/AUNMap",
"name": "AUNMap",
@@ -135676,6 +135717,16 @@
"crc32": "e8038ec9",
"adler32": "933aaa5d"
},
"dceb4536fba7fb89452864fc512a4d071a19eae0": {
"path": "bios/Other/emucorex/resources/RedumpDatabase.yaml",
"name": "RedumpDatabase.yaml",
"size": 1906463,
"sha1": "dceb4536fba7fb89452864fc512a4d071a19eae0",
"md5": "dbf48fe7b36fab316a1682961178ffd7",
"sha256": "755962450efd5effd2f3fe2f9a60c73d6cb3f9b4acea964abf5bb25a86ee25bc",
"crc32": "0496a60f",
"adler32": "c76311d2"
},
"a3d939af27fe0929e61b8e20d49ef58316c0a66c": {
"path": "bios/Other/emucorex/resources/patches.zip",
"name": "patches.zip",
@@ -156183,7 +156234,7 @@
"adler32": "b5608705"
},
"6e5c9416a1cc89fe4012627f496f71ff2bb07b81": {
"path": "bios/Other/zesarux/ace.rom",
"path": "bios/Other/zesarux/alternate_roms/ace.rom",
"name": "ace.rom",
"size": 8192,
"sha1": "6e5c9416a1cc89fe4012627f496f71ff2bb07b81",
@@ -157023,6 +157074,16 @@
"crc32": "340a3285",
"adler32": "bc8e2965"
},
"0a74bd34538a03d0e1d214b425d95c14ad10c8c4": {
"path": "bios/Other/zesarux/trdos.rom",
"name": "trdos.rom",
"size": 16384,
"sha1": "0a74bd34538a03d0e1d214b425d95c14ad10c8c4",
"md5": "0c42e3b9ab8dd91ea096f1d0c07c55e5",
"sha256": "9ee624153f6ff198267fa57dd7568933a36e2003fbe9dd17799b6d21652a37bb",
"crc32": "c43d717f",
"adler32": "1d25c092"
},
"cdb90bd05b073ec7a5f875444e29ab0f6bcee9ac": {
"path": "bios/Other/zesarux/unodos3.rom",
"name": "unodos3.rom",
@@ -192831,6 +192892,16 @@
"crc32": "0b805686",
"adler32": "5b7b9c1d"
},
"5e2d50a3376dc6a0750505bec68626d39a5bd4c1": {
"path": "bios/Sony/PlayStation 2/resources/.variants/GameIndex.yaml.fc3c1420",
"name": "GameIndex.yaml",
"size": 2683897,
"sha1": "5e2d50a3376dc6a0750505bec68626d39a5bd4c1",
"md5": "fc3c14208a929c386445635b19baa3f2",
"sha256": "6531239315d759d0588985b31576696d2672c1a0e192633ea2d4f3d011bfdb37",
"crc32": "a7541e89",
"adler32": "078dc6f1"
},
"40ecf6138c99a0aba775ef93240b295025a45500": {
"path": "bios/Sony/PlayStation 2/resources/GameIndex.yaml",
"name": "GameIndex.yaml",
@@ -192841,6 +192912,16 @@
"crc32": "a3e573a0",
"adler32": "e808396a"
},
"bf2c73d668cd671df8adfe2ec3c7074e8ba9176a": {
"path": "bios/Sony/PlayStation 2/resources/RedumpDatabase.yaml",
"name": "RedumpDatabase.yaml",
"size": 1917242,
"sha1": "bf2c73d668cd671df8adfe2ec3c7074e8ba9176a",
"md5": "0525ad1f1381152f20bfb05775cf39cd",
"sha256": "302b57fdd1f9472ef590789e4b347381cc8442a04a765c7eae3d3f2e4b06394c",
"crc32": "28709e73",
"adler32": "ffcd6c8e"
},
"c54f04b63ac6f04e0a0944ef260b5497e4494dbd": {
"path": "bios/Sony/PlayStation 2/resources/sounds/achievements/message.wav",
"name": "message.wav",
@@ -208066,6 +208147,7 @@
"dfdd9924295f491d54f30569874287f8": "0c15d6753cf0ae2a1737b6e857e8e82ee135a697",
"9a293eaaebca601f671070ad56cb81b6": "56306e7234bcffd14b4f977d42d237c4ad9c12d5",
"b494140c6250b2faa8a801e0efef08d5": "042ce2001fb438a0a34e0c5d0001a9d95d5516df",
"3758db793dae7bc206fbbd799c3cbb05": "71fc274cbe27f382afb0324024ebdc6f59aa666d",
"8080d51e2d787aa3fa181e4ddbd455ed": "8acfbc4a51909de382e33a221a82f0b8efc04794",
"5bac80439b16ee31feb5b45489a1a5da": "ad28302b3bdd8aef667969fceb073f0845942017",
"888b281fa986de2eaccb0f9c8b591395": "7fad1628fd7da3b7a4bad6a7040f9fb4ed945d3a",
@@ -208171,7 +208253,6 @@
"dcde75e5d5c62a03f7bf35312f5116a9": "0f37f2795ca071eb712d5243247675f140897c50",
"65e1739196c3163ec5e77f49eea118ae": "bd9262879f8a72ec610a9554b503d747194a0f49",
"4981d3d22bda9c3d0791c13cb612e95d": "343f90558952049a0232faf6cf136fc2b8d4be84",
"dbf48fe7b36fab316a1682961178ffd7": "dceb4536fba7fb89452864fc512a4d071a19eae0",
"86da78cb59576328483a11c6ef74bc2b": "00d62fbdc8d5dec4c659005e116d0ba2ee63b547",
"8ad82b1dc550319993a7d6c932b2656d": "9056e59b69c6f1160fdfb92a0773f17f6307f3ad",
"a7470da305b78df13804a1e62c7bb41e": "660c7fe74de23ee604bea47673f84710bd34f075",
@@ -208196,6 +208277,7 @@
"083257a65f869a927d8f5a4534f46106": "36cc8f46014a321b7602e52c062ab23d7c256ccc",
"95f294d24b5e97ceab96282f1284190f": "8dba66121f3bbc4b2bdf67722ef4c2b6b6b23ee6",
"6f47c5daf33a759df3395db8ebe62ed1": "7b0bb79d38c573648de218645c6fb16449e156e0",
"ec65dbfe7379cfac816b4d02259c0ca5": "72bfdf91fa11a86e2810a7c167cdcf11e20418a8",
"75527903c6a793772b02807c5343f4c8": "456e74b0805d1931a7786d3d04673a3b02dd4dd3",
"46dbe14f577b56ade221acf89631fd7b": "69253a2722f999ba4205f2e679d0b75e3b17109f",
"5199b3892ba596a6bf8d0f930729157f": "9dc5783345f258d0c66c17028d39652daa234473",
@@ -208203,6 +208285,7 @@
"e910afbd441c5247227fb4a731d65799": "83d3c03dc1fc16f2a5b8bbf929d4cc21a078282c",
"19498325f22381f551df06ce1b4cad4f": "01299427e4d789295c614752c8398261f006479b",
"ad18e8fc265252917dd3698e268977d7": "59815234d228a7f390364c6d6380cc518ea63db1",
"809868f006eebec4e4615dd8bc397ef7": "f7d0f1606c87019f00109ebdf0f260299f0a72da",
"d91939cc76fb66f536476320987d0dc0": "8618516b26a0bc319ed174b66fd2d990eb5b74a3",
"7547b120ce49d79d50addee5ea6fe38b": "fb33e36d016aedea36478eb4bb15b35ca1b7bb0c",
"2c928cbd0410a7e7edae6b2808a1f566": "b478ce9d1343b8dd201c045f010bd1b64ba158ae",
@@ -208234,6 +208317,8 @@
"1d361b7dc10f35866f2e9e713acaf0ee": "f8200a0f4bd284670f0f0191fa9340684e94f66d",
"d5a884f20ade826001ea9fd93be86345": "da328a0a3074ec86fee2d6741bfc2e5a1f68d063",
"3a1f6bebe84204bc6fe507cdb2f80ee6": "99fc2a4d8107c36ee3075c9cff24872d2a98e37a",
"cb52d323b13129a2f0bc3e3e911e567f": "5fab786695311433602028cd89898689c5df0898",
"4812e96097b7fc1bdd7b40366208b7a7": "5288772be438b86978a801e6dcb14228ad3a20af",
"d2e4b22f9433cf16a3dcb320dc2cf1a2": "efd505f459448c5741a8ca249089f068b72cb751",
"cd6ba85e22adec70b6d863de4c053db7": "05980c296e1a7800c4aa21d6bed16323b6d859d5",
"751f615ccbefa312915d1be8aa5617f5": "ba33eaf1a23cfef6fc1b88aa516ca2b3693e69d9",
@@ -208467,6 +208552,7 @@
"f4ae6809bd8c31573370e8da72514012": "e18b9aabbda0cc178436855ef8d04bce96533049",
"bf5e583b038933c5f7bc4f0a6f70617c": "c549a2088bc9b678c8c79fa987ac5f4e6ff4772c",
"602ea57b1d141e81b2a96f20a4b8098c": "2d9878fdd70979ecf6dd0da7652efd3797c26039",
"dbf48fe7b36fab316a1682961178ffd7": "dceb4536fba7fb89452864fc512a4d071a19eae0",
"ed4d4e8f81d9707dbf4931a786b6b56d": "a3d939af27fe0929e61b8e20d49ef58316c0a66c",
"efa6392d3dd6e66abf94542159889e4c": "81c56a54bde692fb15fca4efe6db508b7d09bf6e",
"b56eb507fac5ac64a7079514c02b8ca7": "cb0d4276f9947762af0841a8af75efa6cbe9109c",
@@ -210583,6 +210669,7 @@
"3e77d3685c3e5ba755ab3d34c820b488": "c627527551e441a000184565a72df8ff37fce891",
"9deb72f8785888a80d97d9ed60300c7e": "82bf848bac698d1ffd9ca809c4293f004152645a",
"133ec2129ebf57555662d899d55fe374": "b7ec72fa0a55243a53c55d649e0555acea25d0c1",
"0c42e3b9ab8dd91ea096f1d0c07c55e5": "0a74bd34538a03d0e1d214b425d95c14ad10c8c4",
"6132dc41594d166a86a9067622b8cb90": "cdb90bd05b073ec7a5f875444e29ab0f6bcee9ac",
"d9cdd73ad75df44489b01550af6e4cbd": "1570048704f11dc239060ee4f63190d199c94987",
"a406f2d22ee445b2ddd061e0f5bea549": "2551026b7d63a2627f79701e26688a7d715dc96a",
@@ -213919,7 +214006,9 @@
"2e70ad008d4ec8549aada8002fdf42fb": "caa18ed04854a91e68f2d61a782560edd6373bbf",
"b53d51edc7fc086685e31b811dc32aad": "34a81db03ab617fbfdd7f9b861692dd2ecd57b82",
"5dea62f70439682a6cee16ba3823d11e": "6eddec30056cde7c664a0cf508dcad29353a12bb",
"fc3c14208a929c386445635b19baa3f2": "5e2d50a3376dc6a0750505bec68626d39a5bd4c1",
"de6da198a7359d1200c3eeb6df9c7eda": "40ecf6138c99a0aba775ef93240b295025a45500",
"0525ad1f1381152f20bfb05775cf39cd": "bf2c73d668cd671df8adfe2ec3c7074e8ba9176a",
"d66b0bccd743bd11eaca55bcaec925da": "c54f04b63ac6f04e0a0944ef260b5497e4494dbd",
"44552702b05697a14ccbe2ca22ee7139": "47d2ec4b342649e4c391043ab915d4435f9d180d",
"362e2dac5e4de13591c67fb5eceeb94a": "92ce9e739dcbfa0d6afb442620b71919d26bf283",
@@ -246683,7 +246772,9 @@
"4d88ddd169da56de721e4aa9e213a421f7221b4b"
],
"keys.txt": [
"9edc52be45201ec99f6e4ceb5dc6abfc633c4eae"
"9edc52be45201ec99f6e4ceb5dc6abfc633c4eae",
"5fab786695311433602028cd89898689c5df0898",
"5288772be438b86978a801e6dcb14228ad3a20af"
],
"CafeCn.ttf": [
"23abcb52bc8bd580e9f58556d220f541dccafd15",
@@ -247296,6 +247387,20 @@
"b624812e3aa0ef2f75847f47907296e1f370cecd",
"ca84ef31b6d48c6ab9530b743da373790a4f723b"
],
"GameIndex.yaml": [
"71fc274cbe27f382afb0324024ebdc6f59aa666d",
"72bfdf91fa11a86e2810a7c167cdcf11e20418a8",
"2d9878fdd70979ecf6dd0da7652efd3797c26039",
"997fdfb1c1873c1a43972b2984ac0da61fd47b14",
"fca26d4f7c1fe0abf6534b470da2ee5ad461eba5",
"58fb1f8ea6cf2d526904349640453e682fe388a1",
"7efb2ed721cf0c0f0677324e09be311a8337e793",
"57369df9ca82a460e596cea7835c5a0797dee668",
"b22389650f6c0a1e276b48213fed8a9c1c6476ce",
"6eddec30056cde7c664a0cf508dcad29353a12bb",
"5e2d50a3376dc6a0750505bec68626d39a5bd4c1",
"40ecf6138c99a0aba775ef93240b295025a45500"
],
"810-archiver.rom": [
"8acfbc4a51909de382e33a221a82f0b8efc04794",
"1eb8a3ee2366c605f7e47f8025a9e714ee9cf129"
@@ -247611,9 +247716,6 @@
"NotoColorEmoji-Regular.ttf": [
"343f90558952049a0232faf6cf136fc2b8d4be84"
],
"RedumpDatabase.yaml": [
"dceb4536fba7fb89452864fc512a4d071a19eae0"
],
"Roboto-Regular.ttf": [
"00d62fbdc8d5dec4c659005e116d0ba2ee63b547",
"d0860202be85147f3ce96d71aa88541d939a1aea"
@@ -247712,6 +247814,12 @@
"NotoSansTC-Regular.ttf": [
"59815234d228a7f390364c6d6380cc518ea63db1"
],
"patches.zip": [
"f7d0f1606c87019f00109ebdf0f260299f0a72da",
"a3d939af27fe0929e61b8e20d49ef58316c0a66c",
"2562e542d66db945ccf158d7a221c2a28e3b6be4",
"541a74165496fb7ef35ce6ec03f711ebbe263e11"
],
"ffx_a_fsr1.h": [
"8618516b26a0bc319ed174b66fd2d990eb5b74a3"
],
@@ -248488,21 +248596,9 @@
"games.db": [
"0e2ee74d1f9ebc3a6faf9dbaebbacc2ff053f4df"
],
"GameIndex.yaml": [
"2d9878fdd70979ecf6dd0da7652efd3797c26039",
"997fdfb1c1873c1a43972b2984ac0da61fd47b14",
"fca26d4f7c1fe0abf6534b470da2ee5ad461eba5",
"58fb1f8ea6cf2d526904349640453e682fe388a1",
"7efb2ed721cf0c0f0677324e09be311a8337e793",
"57369df9ca82a460e596cea7835c5a0797dee668",
"b22389650f6c0a1e276b48213fed8a9c1c6476ce",
"6eddec30056cde7c664a0cf508dcad29353a12bb",
"40ecf6138c99a0aba775ef93240b295025a45500"
],
"patches.zip": [
"a3d939af27fe0929e61b8e20d49ef58316c0a66c",
"2562e542d66db945ccf158d7a221c2a28e3b6be4",
"541a74165496fb7ef35ce6ec03f711ebbe263e11"
"RedumpDatabase.yaml": [
"dceb4536fba7fb89452864fc512a4d071a19eae0",
"bf2c73d668cd671df8adfe2ec3c7074e8ba9176a"
],
"libopenglplugin.so": [
"407f0fde89ac1a628fed0329072dfae1f8d304b1",
@@ -254416,6 +254512,13 @@
"transtape3-vC.rom": [
"b7ec72fa0a55243a53c55d649e0555acea25d0c1"
],
"trdos.rom": [
"0a74bd34538a03d0e1d214b425d95c14ad10c8c4",
"0de79c33e378c601e238ee37c219f8aa8442787a",
"56b8959de51919e55f1f691def6d7c6dc402bcd0",
"cd046dd7e71d8605a9323e9889d222817d77400f",
"21695e3f2a8f796386ce66eea8a246b0ac44810c"
],
"unodos3.rom": [
"cdb90bd05b073ec7a5f875444e29ab0f6bcee9ac"
],
@@ -262674,12 +262777,6 @@
"0a747cc0b827a94b4fd74cfd818ca792437a38f7",
"22e50c6ba4157a3f6a821bd9937cd26e292775c6"
],
"trdos.rom": [
"0de79c33e378c601e238ee37c219f8aa8442787a",
"56b8959de51919e55f1f691def6d7c6dc402bcd0",
"cd046dd7e71d8605a9323e9889d222817d77400f",
"21695e3f2a8f796386ce66eea8a246b0ac44810c"
],
"128-spanish-0.rom": [
"968937b1c750f0ef6205f01c6db4148da4cca4e3"
],
@@ -264084,7 +264181,8 @@
"45bedc4cbdeac66c7df59e9e599195c778d86a92"
],
"coleco.rom": [
"45bedc4cbdeac66c7df59e9e599195c778d86a92"
"45bedc4cbdeac66c7df59e9e599195c778d86a92",
"99ba9be24ada3e86e5c17aeecb7a2d68c5edfe59"
],
"colecovision.rom": [
"45bedc4cbdeac66c7df59e9e599195c778d86a92"
@@ -283870,6 +283968,7 @@
"feeddf41": "0c15d6753cf0ae2a1737b6e857e8e82ee135a697",
"2b3e5a61": "56306e7234bcffd14b4f977d42d237c4ad9c12d5",
"6b7152b1": "042ce2001fb438a0a34e0c5d0001a9d95d5516df",
"5acc416a": "71fc274cbe27f382afb0324024ebdc6f59aa666d",
"bd90e77d": "8acfbc4a51909de382e33a221a82f0b8efc04794",
"196eed02": "ad28302b3bdd8aef667969fceb073f0845942017",
"55dfc9ac": "7fad1628fd7da3b7a4bad6a7040f9fb4ed945d3a",
@@ -283975,7 +284074,6 @@
"84ad7d58": "0f37f2795ca071eb712d5243247675f140897c50",
"1094a89e": "bd9262879f8a72ec610a9554b503d747194a0f49",
"a5b357e6": "343f90558952049a0232faf6cf136fc2b8d4be84",
"0496a60f": "dceb4536fba7fb89452864fc512a4d071a19eae0",
"f49fbea6": "00d62fbdc8d5dec4c659005e116d0ba2ee63b547",
"27922b13": "9056e59b69c6f1160fdfb92a0773f17f6307f3ad",
"84d6cb99": "660c7fe74de23ee604bea47673f84710bd34f075",
@@ -284000,6 +284098,7 @@
"8216948a": "36cc8f46014a321b7602e52c062ab23d7c256ccc",
"2c7a1b2a": "8dba66121f3bbc4b2bdf67722ef4c2b6b6b23ee6",
"6e8b2b47": "7b0bb79d38c573648de218645c6fb16449e156e0",
"1a8e4cf7": "72bfdf91fa11a86e2810a7c167cdcf11e20418a8",
"92685e68": "456e74b0805d1931a7786d3d04673a3b02dd4dd3",
"b02dadf9": "69253a2722f999ba4205f2e679d0b75e3b17109f",
"96886a26": "9dc5783345f258d0c66c17028d39652daa234473",
@@ -284007,6 +284106,7 @@
"0fcd7543": "83d3c03dc1fc16f2a5b8bbf929d4cc21a078282c",
"07694737": "01299427e4d789295c614752c8398261f006479b",
"05eb51ca": "59815234d228a7f390364c6d6380cc518ea63db1",
"5120eae7": "f7d0f1606c87019f00109ebdf0f260299f0a72da",
"3a8aeca2": "8618516b26a0bc319ed174b66fd2d990eb5b74a3",
"6743e2ad": "fb33e36d016aedea36478eb4bb15b35ca1b7bb0c",
"ce9e57e4": "b478ce9d1343b8dd201c045f010bd1b64ba158ae",
@@ -284038,6 +284138,8 @@
"7d7e5f43": "f8200a0f4bd284670f0f0191fa9340684e94f66d",
"d1a532a3": "da328a0a3074ec86fee2d6741bfc2e5a1f68d063",
"1e65e2e2": "99fc2a4d8107c36ee3075c9cff24872d2a98e37a",
"352ceb91": "5fab786695311433602028cd89898689c5df0898",
"d5b60ff6": "5288772be438b86978a801e6dcb14228ad3a20af",
"71ddc671": "efd505f459448c5741a8ca249089f068b72cb751",
"56b44837": "05980c296e1a7800c4aa21d6bed16323b6d859d5",
"ed80462a": "ba33eaf1a23cfef6fc1b88aa516ca2b3693e69d9",
@@ -284271,6 +284373,7 @@
"e1232465": "e18b9aabbda0cc178436855ef8d04bce96533049",
"ca72899c": "c549a2088bc9b678c8c79fa987ac5f4e6ff4772c",
"e8038ec9": "2d9878fdd70979ecf6dd0da7652efd3797c26039",
"0496a60f": "dceb4536fba7fb89452864fc512a4d071a19eae0",
"8820b708": "a3d939af27fe0929e61b8e20d49ef58316c0a66c",
"ea1fd68a": "81c56a54bde692fb15fca4efe6db508b7d09bf6e",
"13eed5a5": "cb0d4276f9947762af0841a8af75efa6cbe9109c",
@@ -286387,6 +286490,7 @@
"dc68673c": "c627527551e441a000184565a72df8ff37fce891",
"0aed1b3f": "82bf848bac698d1ffd9ca809c4293f004152645a",
"340a3285": "b7ec72fa0a55243a53c55d649e0555acea25d0c1",
"c43d717f": "0a74bd34538a03d0e1d214b425d95c14ad10c8c4",
"4cdff071": "cdb90bd05b073ec7a5f875444e29ab0f6bcee9ac",
"cb7b98f7": "1570048704f11dc239060ee4f63190d199c94987",
"4c7e9e47": "2551026b7d63a2627f79701e26688a7d715dc96a",
@@ -289723,7 +289827,9 @@
"41391dd3": "caa18ed04854a91e68f2d61a782560edd6373bbf",
"25f6212a": "34a81db03ab617fbfdd7f9b861692dd2ecd57b82",
"0b805686": "6eddec30056cde7c664a0cf508dcad29353a12bb",
"a7541e89": "5e2d50a3376dc6a0750505bec68626d39a5bd4c1",
"a3e573a0": "40ecf6138c99a0aba775ef93240b295025a45500",
"28709e73": "bf2c73d668cd671df8adfe2ec3c7074e8ba9176a",
"d766f908": "c54f04b63ac6f04e0a0944ef260b5497e4494dbd",
"2c3bcd32": "47d2ec4b342649e4c391043ab915d4435f9d180d",
"0509cea5": "92ce9e739dcbfa0d6afb442620b71919d26bf283",
@@ -302869,6 +302975,7 @@
"68757d34c21e28cce68c38ec1cc0de37b9fb046eed0716036ba4f1d0df3bcc5e": "0c15d6753cf0ae2a1737b6e857e8e82ee135a697",
"2a5448dd69dcd13c48c7b256e51907aa43bdc2ce2dde618a039c0b7cc009a57d": "56306e7234bcffd14b4f977d42d237c4ad9c12d5",
"9e7fb1335e56027f150b7ff9b7b6cddd9c0844af19be6dbc17347e1882022038": "042ce2001fb438a0a34e0c5d0001a9d95d5516df",
"e7c70faf16ce180e6a17c040dc2bb326c6fcca63e7fb3f83f992d65fbe480443": "71fc274cbe27f382afb0324024ebdc6f59aa666d",
"b861b939d32cb2c1e672cb9c50668394f1d83d723fd5f331727a19c36001f5ad": "8acfbc4a51909de382e33a221a82f0b8efc04794",
"5160ac22a55d6c82ee2304046b2b6eac13d153c0d0b1164bd693e93acc053623": "ad28302b3bdd8aef667969fceb073f0845942017",
"acb8f9c481ffe762021f980c0cee42bd1a512ccd210686e6e0ac7d6e34f5a374": "7fad1628fd7da3b7a4bad6a7040f9fb4ed945d3a",
@@ -302974,7 +303081,6 @@
"dedbaf271c3257db2a02493a53616d1da78302c678575c9b0f4d254cdb1e4293": "0f37f2795ca071eb712d5243247675f140897c50",
"c217cc125856b0ee9776208b8e0bf5f1a4f04561ff2fa644f690518f87f55942": "bd9262879f8a72ec610a9554b503d747194a0f49",
"1ca0775b9dc92d8d959cd06dd773e2d4dacc97301ad81e6b5aa02cd5e7233a27": "343f90558952049a0232faf6cf136fc2b8d4be84",
"755962450efd5effd2f3fe2f9a60c73d6cb3f9b4acea964abf5bb25a86ee25bc": "dceb4536fba7fb89452864fc512a4d071a19eae0",
"797e35f7f5d6020a5c6ea13b42ecd668bcfb3bbc4baa0e74773527e5b6cb3174": "00d62fbdc8d5dec4c659005e116d0ba2ee63b547",
"4d901b560f20f455b3c82c6616b17b72360956747cb35c3808aa370052fe8e32": "9056e59b69c6f1160fdfb92a0773f17f6307f3ad",
"c4541eefde3f31e4216559ada91f52d1b7ec95b849f7e9afc7a05613a56c8bf2": "660c7fe74de23ee604bea47673f84710bd34f075",
@@ -302999,6 +303105,7 @@
"022c8b05d8f3e7e6046077a2d6ad2d3da1e7fa0e69c8321f3c556b9963be2477": "36cc8f46014a321b7602e52c062ab23d7c256ccc",
"c749cd9513bd345b9f12ff46eac0ffbf4e54c0b0884921df97ca8297396e3fea": "8dba66121f3bbc4b2bdf67722ef4c2b6b6b23ee6",
"ab829598e15b771112130cbafbd982736400690c11e3d7c81e3fc8c582c24f47": "7b0bb79d38c573648de218645c6fb16449e156e0",
"61c77b789ccde856096f024e4a3eef6891e15ca59c127e0dd13e762a7d338a7e": "72bfdf91fa11a86e2810a7c167cdcf11e20418a8",
"90f50de40af560ad55f2fcf460af8205f842b534b057bd8b8bcf7d3e10d3223a": "456e74b0805d1931a7786d3d04673a3b02dd4dd3",
"11fa517464dbd568e855e449650a9004d1072c4a54ac1845aaafc462c0652b64": "69253a2722f999ba4205f2e679d0b75e3b17109f",
"1edcc5695148a632b8a5516ba41a86edf01f06289c5c2e84a1afafe833eb25da": "9dc5783345f258d0c66c17028d39652daa234473",
@@ -303006,6 +303113,7 @@
"9db318b65ee9c575a43e7efd273dbdd1afef26e467eea3e1073a50e1a6595f6d": "83d3c03dc1fc16f2a5b8bbf929d4cc21a078282c",
"ae82f4e2a55e1316a55bcc1d05e9555ce08d8bda07e893b486896b626fd852ff": "01299427e4d789295c614752c8398261f006479b",
"6b137e2eb57a2d1e4cf391c886ab1b783a0e5ddb5c75254748bde00c15cb8ff5": "59815234d228a7f390364c6d6380cc518ea63db1",
"8d95f1fba3acc83195bbac2d3e042b5f34c3c399856d9865e681d173f4cee609": "f7d0f1606c87019f00109ebdf0f260299f0a72da",
"f60e2722fcd13989523b9164d776ab382b3692791767f3bf8bb19967f763f3fb": "8618516b26a0bc319ed174b66fd2d990eb5b74a3",
"93c3922362ea7fc99cbcc698ca30c98de4f8c246d1fbb0b09e015ddef38ce3a5": "fb33e36d016aedea36478eb4bb15b35ca1b7bb0c",
"3d5b9cef750ea8bedceef43c4c52215e8280abb81b5b8fa002007bb3f97f0506": "b478ce9d1343b8dd201c045f010bd1b64ba158ae",
@@ -303037,6 +303145,8 @@
"e4cbe52fae4f8bd59c0b616907fcf06cd10c8ce8f681cac8664af6f323795679": "f8200a0f4bd284670f0f0191fa9340684e94f66d",
"d9b8d3b5e4ae0a6ed336e769301546735ff34f29c14be6e1232da6b7096c0988": "da328a0a3074ec86fee2d6741bfc2e5a1f68d063",
"f7261790bd5aaaef104ffa7173182a3847de9e21ef444033555c3caed83bff10": "99fc2a4d8107c36ee3075c9cff24872d2a98e37a",
"dee8cbca96b74e81d19b0292f8c6255f0e2b23d8551f82cacd086c2eead35ea4": "5fab786695311433602028cd89898689c5df0898",
"ea8b3d7c752d85f2326b9bfa01615414ab34ba052f87481b0ff4003fd887e50a": "5288772be438b86978a801e6dcb14228ad3a20af",
"7edd55c0dc5e520987a92a4b41f3f8baed9167d68697afd25f28c733244cb275": "efd505f459448c5741a8ca249089f068b72cb751",
"e67d1afdd4ed545a6c544cbdf50d3d32dbffdd94d97f3b822d2fa08a5e6b0aed": "05980c296e1a7800c4aa21d6bed16323b6d859d5",
"103fd16b0dab2c3267e8689ee01497fa9568935be87b253dbf22cd8c8417e57f": "ba33eaf1a23cfef6fc1b88aa516ca2b3693e69d9",
@@ -303270,6 +303380,7 @@
"306b53ecfb182a504dd8a7446093c316387d2fd8dc350d0792ed1753fe0996cd": "e18b9aabbda0cc178436855ef8d04bce96533049",
"cdefaf8efd47045f6820928eba84db5bed7557539328952b5f828315485e02ee": "c549a2088bc9b678c8c79fa987ac5f4e6ff4772c",
"d5558a0e0aa033482b098cc8a6449e78137f5069beabf421ab60d9eccbb62d8f": "2d9878fdd70979ecf6dd0da7652efd3797c26039",
"755962450efd5effd2f3fe2f9a60c73d6cb3f9b4acea964abf5bb25a86ee25bc": "dceb4536fba7fb89452864fc512a4d071a19eae0",
"aa14a46908c1114e0c0f1c06accbfa7efc83c1768fb501699e043cbdb1af797f": "a3d939af27fe0929e61b8e20d49ef58316c0a66c",
"817eb2a258e44bb730b94ab77b00cac2480c2e27449078949e2897bad3cb3bc3": "81c56a54bde692fb15fca4efe6db508b7d09bf6e",
"53e5ddc6825ecde7b502acb5fae3a173ba6696ec5b8bb7445f378f7b0ad1beb8": "cb0d4276f9947762af0841a8af75efa6cbe9109c",
@@ -305386,6 +305497,7 @@
"5b84f59e701dc9ace29be5a3f93d00680d37f883623d871dd43e82ec5da10026": "c627527551e441a000184565a72df8ff37fce891",
"53af928797a17cde8bd0f551f0d2bc522c5a82117470ad9493c25d3a103de995": "82bf848bac698d1ffd9ca809c4293f004152645a",
"e3efe8d378a77aa09abe08fb2b4083941737bef21ba947d7c634b378c25e7768": "b7ec72fa0a55243a53c55d649e0555acea25d0c1",
"9ee624153f6ff198267fa57dd7568933a36e2003fbe9dd17799b6d21652a37bb": "0a74bd34538a03d0e1d214b425d95c14ad10c8c4",
"a802e4f07234bae69a985496bb2ee1a5669a7f5a6f9a351eee59aad37004eb5b": "cdb90bd05b073ec7a5f875444e29ab0f6bcee9ac",
"409844660a4fb101f0846e058d30c2b6457fb0616b69e4428dec23111a1982a4": "1570048704f11dc239060ee4f63190d199c94987",
"3acae3f2e61c9ed92ff8669af242cc5dd1d1b7d5edbc31dd8847e019a74f8fe8": "2551026b7d63a2627f79701e26688a7d715dc96a",
@@ -308722,7 +308834,9 @@
"6b61e27861c288a99ee9b4878862ed824173a037ebaca2bef0581017a85241e1": "caa18ed04854a91e68f2d61a782560edd6373bbf",
"e8eed9831c39fc298be087ba11d620673134bc683b97ccc909c555d29cc1b207": "34a81db03ab617fbfdd7f9b861692dd2ecd57b82",
"3e14a0d3db871704a9652a5d90d4ba62be2bceefbca6bb46da65275b09d4f78e": "6eddec30056cde7c664a0cf508dcad29353a12bb",
"6531239315d759d0588985b31576696d2672c1a0e192633ea2d4f3d011bfdb37": "5e2d50a3376dc6a0750505bec68626d39a5bd4c1",
"483face8f50f5e96d89528059522be3766b44f5e07e854bae1fa92ff0111d0a7": "40ecf6138c99a0aba775ef93240b295025a45500",
"302b57fdd1f9472ef590789e4b347381cc8442a04a765c7eae3d3f2e4b06394c": "bf2c73d668cd671df8adfe2ec3c7074e8ba9176a",
"dfd8035387a463722ad07af3c91934e0a685f2afa57e31d305f0602656d1edb1": "c54f04b63ac6f04e0a0944ef260b5497e4494dbd",
"41de2047af8382988bfd568035ff26eec5f1cabc3efe773680546aa00a82857d": "47d2ec4b342649e4c391043ab915d4435f9d180d",
"fc1b5e12e426b229fc4f114a4b8cbe6a5441f7e0ce6654abce382e677f1c051d": "92ce9e739dcbfa0d6afb442620b71919d26bf283",
@@ -469525,6 +469639,18 @@
"aethersx2/game_controller_db.txt": [
"042ce2001fb438a0a34e0c5d0001a9d95d5516df"
],
"Other/aethersx2/resources/GameIndex.yaml": [
"71fc274cbe27f382afb0324024ebdc6f59aa666d"
],
"aethersx2/resources/GameIndex.yaml": [
"71fc274cbe27f382afb0324024ebdc6f59aa666d"
],
"resources/GameIndex.yaml": [
"71fc274cbe27f382afb0324024ebdc6f59aa666d",
"72bfdf91fa11a86e2810a7c167cdcf11e20418a8",
"2d9878fdd70979ecf6dd0da7652efd3797c26039",
"40ecf6138c99a0aba775ef93240b295025a45500"
],
"Other/altirra/.variants/810-archiver.rom.8080d51e": [
"8acfbc4a51909de382e33a221a82f0b8efc04794"
],
@@ -470176,12 +470302,6 @@
"armsx2/NotoColorEmoji-Regular.ttf": [
"343f90558952049a0232faf6cf136fc2b8d4be84"
],
"Other/armsx2/RedumpDatabase.yaml": [
"dceb4536fba7fb89452864fc512a4d071a19eae0"
],
"armsx2/RedumpDatabase.yaml": [
"dceb4536fba7fb89452864fc512a4d071a19eae0"
],
"Other/armsx2/Roboto-Regular.ttf": [
"00d62fbdc8d5dec4c659005e116d0ba2ee63b547"
],
@@ -470329,6 +470449,15 @@
"armsx2/no-save.png": [
"7b0bb79d38c573648de218645c6fb16449e156e0"
],
"Other/armsx2/pcsx2/resources/GameIndex.yaml": [
"72bfdf91fa11a86e2810a7c167cdcf11e20418a8"
],
"armsx2/pcsx2/resources/GameIndex.yaml": [
"72bfdf91fa11a86e2810a7c167cdcf11e20418a8"
],
"pcsx2/resources/GameIndex.yaml": [
"72bfdf91fa11a86e2810a7c167cdcf11e20418a8"
],
"Other/armsx2/pcsx2/resources/fonts/NotoSansArabic-Regular.ttf": [
"456e74b0805d1931a7786d3d04673a3b02dd4dd3"
],
@@ -470443,6 +470572,19 @@
"fonts/NotoSansTC-Regular.ttf": [
"59815234d228a7f390364c6d6380cc518ea63db1"
],
"Other/armsx2/pcsx2/resources/patches.zip": [
"f7d0f1606c87019f00109ebdf0f260299f0a72da"
],
"armsx2/pcsx2/resources/patches.zip": [
"f7d0f1606c87019f00109ebdf0f260299f0a72da"
],
"pcsx2/resources/patches.zip": [
"f7d0f1606c87019f00109ebdf0f260299f0a72da"
],
"resources/patches.zip": [
"f7d0f1606c87019f00109ebdf0f260299f0a72da",
"a3d939af27fe0929e61b8e20d49ef58316c0a66c"
],
"Other/armsx2/pcsx2/resources/shaders/common/ffx_a_fsr1.h": [
"8618516b26a0bc319ed174b66fd2d990eb5b74a3"
],
@@ -470912,6 +471054,22 @@
"ax360e/Account": [
"99fc2a4d8107c36ee3075c9cff24872d2a98e37a"
],
"Other/azahar/sysdata/keys.txt": [
"5fab786695311433602028cd89898689c5df0898"
],
"azahar/sysdata/keys.txt": [
"5fab786695311433602028cd89898689c5df0898"
],
"sysdata/keys.txt": [
"5fab786695311433602028cd89898689c5df0898",
"5288772be438b86978a801e6dcb14228ad3a20af"
],
"Other/azaharplus/sysdata/keys.txt": [
"5288772be438b86978a801e6dcb14228ad3a20af"
],
"azaharplus/sysdata/keys.txt": [
"5288772be438b86978a801e6dcb14228ad3a20af"
],
"Other/beebem/AUNMap": [
"efd505f459448c5741a8ca249089f068b72cb751"
],
@@ -473021,9 +473179,15 @@
"emucorex/resources/GameIndex.yaml": [
"2d9878fdd70979ecf6dd0da7652efd3797c26039"
],
"resources/GameIndex.yaml": [
"2d9878fdd70979ecf6dd0da7652efd3797c26039",
"40ecf6138c99a0aba775ef93240b295025a45500"
"Other/emucorex/resources/RedumpDatabase.yaml": [
"dceb4536fba7fb89452864fc512a4d071a19eae0"
],
"emucorex/resources/RedumpDatabase.yaml": [
"dceb4536fba7fb89452864fc512a4d071a19eae0"
],
"resources/RedumpDatabase.yaml": [
"dceb4536fba7fb89452864fc512a4d071a19eae0",
"bf2c73d668cd671df8adfe2ec3c7074e8ba9176a"
],
"Other/emucorex/resources/patches.zip": [
"a3d939af27fe0929e61b8e20d49ef58316c0a66c"
@@ -473031,9 +473195,6 @@
"emucorex/resources/patches.zip": [
"a3d939af27fe0929e61b8e20d49ef58316c0a66c"
],
"resources/patches.zip": [
"a3d939af27fe0929e61b8e20d49ef58316c0a66c"
],
"Other/emucorex/resources/shaders/common/fxaa.fx": [
"81c56a54bde692fb15fca4efe6db508b7d09bf6e"
],
@@ -495819,10 +495980,13 @@
"zesarux/Z88UK400.rom": [
"23c63ceced72d0a9031cba08d2ebc72ca336921d"
],
"Other/zesarux/ace.rom": [
"Other/zesarux/alternate_roms/ace.rom": [
"6e5c9416a1cc89fe4012627f496f71ff2bb07b81"
],
"zesarux/ace.rom": [
"zesarux/alternate_roms/ace.rom": [
"6e5c9416a1cc89fe4012627f496f71ff2bb07b81"
],
"alternate_roms/ace.rom": [
"6e5c9416a1cc89fe4012627f496f71ff2bb07b81"
],
"Other/zesarux/aszmice07.rom": [
@@ -496245,6 +496409,12 @@
"zesarux/transtape3-vC.rom": [
"b7ec72fa0a55243a53c55d649e0555acea25d0c1"
],
"Other/zesarux/trdos.rom": [
"0a74bd34538a03d0e1d214b425d95c14ad10c8c4"
],
"zesarux/trdos.rom": [
"0a74bd34538a03d0e1d214b425d95c14ad10c8c4"
],
"Other/zesarux/unodos3.rom": [
"cdb90bd05b073ec7a5f875444e29ab0f6bcee9ac"
],
@@ -544377,12 +544547,30 @@
".variants/GameIndex.yaml": [
"6eddec30056cde7c664a0cf508dcad29353a12bb"
],
"Sony/PlayStation 2/resources/.variants/GameIndex.yaml.fc3c1420": [
"5e2d50a3376dc6a0750505bec68626d39a5bd4c1"
],
"PlayStation 2/resources/.variants/GameIndex.yaml.fc3c1420": [
"5e2d50a3376dc6a0750505bec68626d39a5bd4c1"
],
"resources/.variants/GameIndex.yaml.fc3c1420": [
"5e2d50a3376dc6a0750505bec68626d39a5bd4c1"
],
".variants/GameIndex.yaml.fc3c1420": [
"5e2d50a3376dc6a0750505bec68626d39a5bd4c1"
],
"Sony/PlayStation 2/resources/GameIndex.yaml": [
"40ecf6138c99a0aba775ef93240b295025a45500"
],
"PlayStation 2/resources/GameIndex.yaml": [
"40ecf6138c99a0aba775ef93240b295025a45500"
],
"Sony/PlayStation 2/resources/RedumpDatabase.yaml": [
"bf2c73d668cd671df8adfe2ec3c7074e8ba9176a"
],
"PlayStation 2/resources/RedumpDatabase.yaml": [
"bf2c73d668cd671df8adfe2ec3c7074e8ba9176a"
],
"Sony/PlayStation 2/resources/sounds/achievements/message.wav": [
"c54f04b63ac6f04e0a0944ef260b5497e4494dbd"
],
-10
View File
@@ -88,7 +88,6 @@ files:
- name: OS6128_UK.rom
path: "private/firmware/OS6128_UK.rom"
system: amstrad-cpc
region: [uk]
required: true
min_size: 32768
validation: [size]
@@ -138,7 +137,6 @@ files:
- name: OS464_UK.rom
path: "private/firmware/OS464_UK.rom"
system: amstrad-cpc
region: [uk]
required: false
min_size: 32768
validation: [size]
@@ -150,7 +148,6 @@ files:
- name: OS464_FR.rom
path: "private/firmware/OS464_FR.rom"
system: amstrad-cpc
region: [france]
required: false
min_size: 32768
validation: [size]
@@ -164,7 +161,6 @@ files:
- name: OS664_UK.rom
path: "private/firmware/OS664_UK.rom"
system: amstrad-cpc
region: [uk]
required: false
min_size: 32768
validation: [size]
@@ -176,7 +172,6 @@ files:
- name: XMEM_FW_3_15_UK.rom
path: "private/firmware/XMEM_FW_3_15_UK.rom"
system: amstrad-cpc
region: [uk]
required: false
min_size: 32768
validation: [size]
@@ -188,7 +183,6 @@ files:
- name: XMEM_FW_3_15_FR.rom
path: "private/firmware/XMEM_FW_3_15_FR.rom"
system: amstrad-cpc
region: [france]
required: false
min_size: 32768
validation: [size]
@@ -224,7 +218,6 @@ files:
- name: Amstrad_f4.cpr
path: "private/firmware/Amstrad_f4.cpr"
system: amstrad-cpc
region: [france]
required: false
size: 131156
md5: e7159fd674022ba05f9b347ae3cdafc6
@@ -235,7 +228,6 @@ files:
- name: Amstrad_s4.cpr
path: "private/firmware/Amstrad_s4.cpr"
system: amstrad-cpc
region: [spain]
required: false
size: 131156
md5: 6eeed3fdd4abc98a2a932da810410128
@@ -257,7 +249,6 @@ files:
- name: hackit400uk.rom
path: "private/hacker/hackit400uk.rom"
system: amstrad-cpc
region: [uk]
required: false
size: 16384
md5: 9a293eaaebca601f671070ad56cb81b6
@@ -269,7 +260,6 @@ files:
- name: hacker481fr.rom
path: "private/hacker/hacker481fr.rom"
system: amstrad-cpc
region: [france]
required: false
size: 16384
md5: dfdd9924295f491d54f30569874287f8
+1 -1
View File
@@ -4,7 +4,7 @@ core_classification: enhanced_fork
source: "https://github.com/amadvance/advancemame"
upstream: "https://www.mamedev.org"
profiled_date: "2026-08-08"
source_commit: "0f6a7677ad42b4dfdfa36b046f74bef5238d5837"
source_commit: "21f8f6f79d8a9abe9f23b1a070841963774cf65d"
core_version: "5.0"
mame_version: "0.106"
display_name: "Arcade (AdvanceMAME)"
+3
View File
@@ -148,6 +148,9 @@ files:
path: resources/GameIndex.yaml
required: false
bundled: true
sha1:
- 997fdfb1c1873c1a43972b2984ac0da61fd47b14
- 71fc274cbe27f382afb0324024ebdc6f59aa666d
description: "Game database"
note: "Read from the resources folder, keyed by serial, and carrying the per-game fixes, patches and settings overrides. Parsed into gamedb.cache in the cache folder and reparsed whenever the modification time moves."
source_ref: "aethersx2/pcsx2/GameDatabase.cpp:35-36, aethersx2/pcsx2/GameDatabase.cpp:348-352, aethersx2/pcsx2/GameDatabase.cpp:523-535"
+1 -1
View File
@@ -61,7 +61,7 @@ notes: |
Firmware path resolution: settings.paths.firmware (user override) or
{userData}/ares/Firmware/ (default). Per-system firmware assigned in
Settings > Firmware dialog or via scan-by-hash.
ref: desktop-ui/settings/settings.hpp:89-101, desktop-ui/desktop-ui.cpp:68-75
ref: desktop-ui/settings/settings.hpp:87-99, desktop-ui/desktop-ui.cpp:68-75
Systems with fully embedded firmware (no user files needed):
Game Boy (boot.rom), Game Boy Color (boot.rom), Mega Drive (TMSS),
+9
View File
@@ -272,6 +272,8 @@ files:
standalone_path: resources/GameIndex.yaml
required: false
bundled: true
sha1: 72bfdf91fa11a86e2810a7c167cdcf11e20418a8
size: 2690355
description: "Game database"
note: >-
Read from the resources folder, keyed by serial, carrying the per-game
@@ -297,6 +299,8 @@ files:
standalone_path: resources/RedumpDatabase.yaml
required: false
bundled: true
sha1: bf2c73d668cd671df8adfe2ec3c7074e8ba9176a
size: 1917242
description: "Disc track hash database"
note: >-
Loaded on the first hash lookup and used to tell the user whether a dump
@@ -308,6 +312,8 @@ files:
standalone_path: resources/patches.zip
required: false
bundled: true
sha1: f7d0f1606c87019f00109ebdf0f260299f0a72da
size: 2007224
description: "Game patch archive"
note: >-
Per-game pnach entries matched on serial and disc CRC. The patches and
@@ -500,6 +506,7 @@ files:
- name: cas.glsl
path: pcsx2/resources/shaders/vulkan/cas.glsl
standalone_path: resources/shaders/vulkan/cas.glsl
sha1: "005cecf1a5e20b05407d55d0aad22cf81ad66c31"
required: false
bundled: true
description: "Vulkan contrast adaptive sharpening shader"
@@ -787,6 +794,8 @@ files:
standalone_path: resources/sounds/achievements/unlock.wav
required: false
bundled: true
sha1: da328a0a3074ec86fee2d6741bfc2e5a1f68d063
size: 202702
description: "Achievement unlock sound"
source_ref: "pcsx2/Achievements.cpp:69, pcsx2/Achievements.cpp:1278-1284, pcsx2/Achievements.cpp:1581"
+4 -2
View File
@@ -38,8 +38,10 @@ files:
system: nintendo-3ds
required: false
hle_fallback: true
note: "embedded encrypted fallback if missing"
source_ref: "src/core/hw/aes/key.cpp:283, src/common/common_paths.h:83"
sha1: "5fab786695311433602028cd89898689c5df0898"
md5: "cb52d323b13129a2f0bc3e3e911e567f"
note: "embedded encrypted fallback if missing: default_keys_enc, AES-CBC with a zero key and IV; the hashes are those of the decrypted text without its PKCS#7 block"
source_ref: "src/core/hw/aes/key.cpp:283-300, src/common/common_paths.h:83, src/core/hw/default_keys.h:4-5"
- name: shared_font.bin
path: sysdata/shared_font.bin
+4 -2
View File
@@ -56,8 +56,10 @@ files:
system: nintendo-3ds
required: false
hle_fallback: true
note: "AES key slots, common keys and NFC secrets; embedded encrypted blob used if missing"
source_ref: "src/core/hw/aes/key.cpp:225-364, src/core/hw/aes/key.cpp:473-613"
sha1: "5288772be438b86978a801e6dcb14228ad3a20af"
md5: "4812e96097b7fc1bdd7b40366208b7a7"
note: "AES key slots, common keys and NFC secrets; embedded encrypted blob used if missing: default_keys_enc, AES-CBC with a zero key and IV, the hashes are those of the decrypted text"
source_ref: "src/core/hw/aes/key.cpp:225-364, src/core/hw/aes/key.cpp:473-613, src/core/hw/default_keys.h:11"
- name: aes_keys.txt
path: sysdata/aes_keys.txt
+1 -1
View File
@@ -14,7 +14,7 @@ notes: |
Libretro port of Mednafen's Virtual Boy emulation module.
No external BIOS or firmware files. The Virtual Boy has no boot
ROM; the V810 CPU executes directly from the game ROM mapped at
0x07000000. Load() in libretro.cpp:1833 takes only ROM data.
0x07000000. Load() in libretro.cpp:1810 takes only ROM data.
Upstream Mednafen supports an optional vb.pal palette file
(Documentation/vb.html); the libretro port handles palette via
core options instead.
-3
View File
@@ -406,7 +406,6 @@ files:
- name: KANJI.rom
path: "Machines/Shared Roms/KANJI.rom"
region: [japan]
size: 262144
required: false
note: "Kanji font ROM (256 KB). Used by MSX2+, turboR, and Japanese MSX2 machines."
@@ -414,7 +413,6 @@ files:
- name: MSXKANJI.rom
path: "Machines/Shared Roms/MSXKANJI.rom"
region: [japan]
size: 32768
required: false
note: "MSX-Kanji driver ROM. Used by MSX2+, turboR, and Japanese MSX2 for kanji display."
@@ -456,7 +454,6 @@ files:
- name: HANGUL.rom
path: "Machines/Shared Roms/HANGUL.rom"
region: [south-korea]
size: 131072
required: false
note: "Korean Hangul font ROM (128 KB)."
+5 -5
View File
@@ -36,7 +36,7 @@ files:
mode: standalone
size: 256
note: "Original Nintendo DMG boot ROM"
source_ref: "src/gb.rs:1516, src/data.rs:14"
source_ref: "src/gb.rs:1416, src/data.rs:14"
- name: sgb_boot.bin
system: nintendo-gb
@@ -45,7 +45,7 @@ files:
mode: standalone
size: 256
note: "Super Game Boy boot ROM"
source_ref: "src/gb.rs:1517, src/data.rs:29"
source_ref: "src/gb.rs:1417, src/data.rs:29"
- name: dmg_bootix.bin
system: nintendo-gb
@@ -54,7 +54,7 @@ files:
mode: standalone
size: 256
note: "Open-source DMG boot ROM from Bootix (default DMG)"
source_ref: "src/gb.rs:1518, src/data.rs:44"
source_ref: "src/gb.rs:1418, src/data.rs:44"
- name: mgb_bootix.bin
system: nintendo-gb
@@ -63,7 +63,7 @@ files:
mode: standalone
size: 256
note: "Open-source MGB (Pocket) boot ROM from Bootix"
source_ref: "src/gb.rs:1519, src/data.rs:59"
source_ref: "src/gb.rs:1419, src/data.rs:59"
- name: cgb_boot.bin
system: nintendo-gbc
@@ -81,4 +81,4 @@ files:
mode: standalone
size: 2304
note: "Custom open-source CGB boot ROM (default CGB)"
source_ref: "src/gb.rs:1484, src/data.rs:177"
source_ref: "src/gb.rs:1421, src/data.rs:177"
+4 -4
View File
@@ -24,25 +24,25 @@ mode: standalone
files:
- name: "prod.keys"
required: true
path: "switch/"
path: "switch/prod.keys"
note: "Production keys for NCA decryption (master, key area, header, titlekek)"
source_ref: "src/core/crypto/key_manager.cpp:655-656"
- name: "title.keys"
required: false
path: "switch/"
path: "switch/title.keys"
note: "Per-title encryption keys (rights_id to titlekey mappings)"
source_ref: "src/core/crypto/key_manager.cpp:659-660"
- name: "console.keys"
required: false
path: "switch/"
path: "switch/console.keys"
note: "Console-specific keys (BIS, SD seed)"
source_ref: "src/core/crypto/key_manager.cpp:661-662"
- name: "key_retail.bin"
required: false
path: "switch/"
path: "switch/key_retail.bin"
size: 160
note: "Amiibo decryption keys (two InternalKey structs, 0x50 bytes each)"
source_ref: "src/core/hle/service/nfc/common/amiibo_crypto.cpp:274-292"
+100
View File
@@ -58,6 +58,7 @@ files:
# -------------------------------------------------------
- name: ROM311
path: Archimedes/ROM311
system: acorn-archimedes
description: "RISC OS v3.11"
size: 2097152
crc32: "54c0c963"
@@ -78,6 +79,7 @@ files:
- name: os12.rom
path: BBCMicro/os12.rom
system: acorn-bbc-micro
description: "BBC MOS v1.2"
size: 16384
crc32: "3c14fc70"
@@ -95,6 +97,7 @@ files:
- name: dfs-2.26.rom
path: BBCMicro/dfs-2.26.rom
system: acorn-bbc-micro
description: "Acorn 1770 DFS 2.26 ROM"
size: 16384
crc32: "5ae33e94"
@@ -104,6 +107,7 @@ files:
- name: adfs-1.30.rom
path: BBCMicro/adfs-1.30.rom
system: acorn-bbc-micro
description: "Acorn ADFS 1.30 ROM"
size: 16384
crc32: "d3855588"
@@ -113,6 +117,7 @@ files:
- name: ADT-1.40.rom
path: BBCMicro/ADT-1.40.rom
system: acorn-bbc-micro
description: "Advanced Disc Toolkit 1.40 ROM"
size: 16384
crc32: "8314fed0"
@@ -122,6 +127,7 @@ files:
- name: TUBE110.rom
path: BBCMicro/TUBE110.rom
system: acorn-bbc-micro
description: "6502 Tube 1.10 Boot ROM"
size: 2048
crc32: "9ec2dbd0"
@@ -131,6 +137,7 @@ files:
- name: Z80_122.rom
path: BBCMicro/Z80_122.rom
system: acorn-bbc-micro
description: "Z80 Tube 1.22 Boot ROM"
size: 4096
crc32: "b5851efc"
@@ -151,6 +158,7 @@ files:
- name: os.rom
path: Electron/os.rom
system: acorn-electron
description: "Electron MOS ROM v1.00"
size: 16384
crc32: "bf63fb1f"
@@ -163,6 +171,7 @@ files:
- name: ADFS-E00_1.rom
path: Electron/ADFS-E00_1.rom
system: acorn-electron
description: "E00 ADFS ROM, first slot"
size: 16384
crc32: "51523993"
@@ -172,6 +181,7 @@ files:
- name: ADFS-E00_2.rom
path: Electron/ADFS-E00_2.rom
system: acorn-electron
description: "E00 ADFS ROM, second slot"
size: 16384
crc32: "8d17de0e"
@@ -181,6 +191,7 @@ files:
- name: adfs.rom
path: Electron/adfs.rom
system: acorn-electron
description: "Acorn ADFS ROM"
size: 16384
crc32: "3289bdc6"
@@ -190,6 +201,7 @@ files:
- name: DFS-1770-2.20.rom
path: Electron/DFS-1770-2.20.rom
system: acorn-electron
description: "1770 DFS ROM"
size: 16384
crc32: "f3dc9bc5"
@@ -208,6 +220,7 @@ files:
- name: AP6v133.rom
path: Electron/AP6v133.rom
system: acorn-electron
description: "Advanced Plus 6 ROM"
size: 7772
crc32: "e0013cfc"
@@ -220,6 +233,7 @@ files:
# -------------------------------------------------------
- name: Kickstart-v1.3-rev34.5-1987-Commodore-A500-A1000-A2000-CDTV.rom
path: Amiga/Kickstart-v1.3-rev34.5-1987-Commodore-A500-A1000-A2000-CDTV.rom
system: amiga
description: "A500/A1000/A2000/CDTV Kickstart 1.3 ROM"
size: 262144
crc32: "c4f0f55f"
@@ -232,6 +246,7 @@ files:
# -------------------------------------------------------
- name: os464.rom
path: AmstradCPC/os464.rom
system: amstrad-cpc
description: "CPC 464 firmware"
size: 16384
crc32: "815752df"
@@ -241,6 +256,7 @@ files:
- name: basic464.rom
path: AmstradCPC/basic464.rom
system: amstrad-cpc
description: "CPC 464 BASIC ROM"
size: 16384
crc32: "7d9a3bac"
@@ -250,6 +266,7 @@ files:
- name: os664.rom
path: AmstradCPC/os664.rom
system: amstrad-cpc
description: "CPC 664 firmware"
size: 16384
crc32: "3f5a6dc4"
@@ -259,6 +276,7 @@ files:
- name: basic664.rom
path: AmstradCPC/basic664.rom
system: amstrad-cpc
description: "CPC 664 BASIC ROM"
size: 16384
crc32: "32fee492"
@@ -268,6 +286,7 @@ files:
- name: os6128.rom
path: AmstradCPC/os6128.rom
system: amstrad-cpc
description: "CPC 6128 firmware"
size: 16384
crc32: "0219bb74"
@@ -277,6 +296,7 @@ files:
- name: basic6128.rom
path: AmstradCPC/basic6128.rom
system: amstrad-cpc
description: "CPC 6128 BASIC ROM"
size: 16384
crc32: "ca6af63d"
@@ -286,6 +306,7 @@ files:
- name: amsdos.rom
path: AmstradCPC/amsdos.rom
system: amstrad-cpc
description: "Amstrad Disk Operating System"
size: 16384
crc32: "1fe22ecd"
@@ -298,6 +319,7 @@ files:
# -------------------------------------------------------
- name: apple2o.rom
path: AppleII/apple2o.rom
system: apple-ii
description: "Original Apple II ROM"
size: 12288
crc32: "ba210588"
@@ -307,6 +329,7 @@ files:
- name: apple2.rom
path: AppleII/apple2.rom
system: apple-ii
description: "Apple II+ ROM"
size: 12288
crc32: "f66f9c26"
@@ -316,6 +339,7 @@ files:
- name: apple2eu.rom
path: AppleII/apple2eu.rom
system: apple-ii
description: "Apple IIe ROM"
size: 32768
crc32: "e12be18d"
@@ -325,6 +349,7 @@ files:
- name: apple2e.rom
path: AppleII/apple2e.rom
system: apple-ii
description: "Enhanced Apple IIe ROM"
size: 32768
crc32: "65989942"
@@ -334,6 +359,7 @@ files:
- name: apple2-character.rom
path: AppleII/apple2-character.rom
system: apple-ii
description: "Apple II/II+ character ROM"
size: 2048
crc32: "64f415c6"
@@ -343,6 +369,7 @@ files:
- name: apple2eu-character.rom
path: AppleII/apple2eu-character.rom
system: apple-ii
description: "Apple IIe character ROM"
size: 4096
crc32: "816a86f1"
@@ -361,6 +388,7 @@ files:
- name: scsi.rom
path: AppleII/scsi.rom
system: apple-ii
description: "Apple II SCSI card ROM"
size: 16384
crc32: "5aff85d3"
@@ -373,6 +401,7 @@ files:
# -------------------------------------------------------
- name: apple2gs.rom
path: AppleIIgs/apple2gs.rom
system: apple-iigs
description: "Apple IIgs ROM01"
size: 131072
crc32: "42f124b0"
@@ -382,6 +411,7 @@ files:
- name: apple2gs.rom2
path: AppleIIgs/apple2gs.rom2
system: apple-iigs
description: "Apple IIgs ROM03"
size: 262144
crc32: "de7ddf29"
@@ -399,6 +429,7 @@ files:
- name: "341s0632-2"
path: "AppleIIgs/341s0632-2"
system: apple-iigs
description: "Apple IIgs ROM03 ADB microcontroller ROM"
size: 4096
crc32: "e1c11fb0"
@@ -410,6 +441,7 @@ files:
# -------------------------------------------------------
- name: tos100.img
path: AtariST/tos100.img
system: atari-st
description: "UK TOS 1.00 ROM"
size: 196608
crc32: "1a586c64"
@@ -421,6 +453,7 @@ files:
# -------------------------------------------------------
- name: coleco.rom
path: ColecoVision/coleco.rom
system: colecovision
description: "ColecoVision BIOS"
size: 8192
crc32: "3aa93ef3"
@@ -455,6 +488,7 @@ files:
# -------------------------------------------------------
- name: boot-16.rom
path: DiskII/boot-16.rom
system: apple-ii
description: "Disk II 16-sector boot ROM"
size: 256
crc32: "ce7144f6"
@@ -480,6 +514,7 @@ files:
- name: boot-13.rom
path: DiskII/boot-13.rom
system: apple-ii
description: "Disk II 13-sector boot ROM"
size: 256
crc32: "d34eb2ff"
@@ -501,6 +536,7 @@ files:
# -------------------------------------------------------
- name: exos10.bin
path: Enterprise/exos10.bin
system: enterprise-64-128
description: "Enterprise EXOS ROM v1.0"
size: 32768
crc32: "30b26387"
@@ -511,6 +547,7 @@ files:
- name: exos20.bin
path: Enterprise/exos20.bin
system: enterprise-64-128
description: "Enterprise EXOS ROM v2.0"
size: 32768
crc32: "d421795f"
@@ -521,6 +558,7 @@ files:
- name: exos21.bin
path: Enterprise/exos21.bin
system: enterprise-64-128
description: "Enterprise EXOS ROM v2.1"
size: 32768
crc32: "982a3b44"
@@ -531,6 +569,7 @@ files:
- name: exos23.bin
path: Enterprise/exos23.bin
system: enterprise-64-128
description: "Enterprise EXOS ROM v2.3"
size: 65536
crc32: "24838410"
@@ -541,6 +580,7 @@ files:
- name: basic10.bin
path: Enterprise/basic10.bin
system: enterprise-64-128
description: "Enterprise BASIC ROM v1.0"
size: 16384
crc32: "d62e4fb7"
@@ -550,6 +590,7 @@ files:
- name: "BASIC 1.0 - EPROM 1-2 (198x)(Enterprise).bin"
path: "Enterprise/BASIC 1.0 - EPROM 1-2 (198x)(Enterprise).bin"
system: enterprise-64-128
description: "Enterprise BASIC ROM v1.0, Part 1"
size: 8193
crc32: "37bf48e1"
@@ -559,6 +600,7 @@ files:
- name: "BASIC 1.0 - EPROM 2-2 (198x)(Enterprise).bin"
path: "Enterprise/BASIC 1.0 - EPROM 2-2 (198x)(Enterprise).bin"
system: enterprise-64-128
description: "Enterprise BASIC ROM v1.0, Part 2"
size: 8193
crc32: "c5298c79"
@@ -568,6 +610,7 @@ files:
- name: basic11.bin
path: Enterprise/basic11.bin
system: enterprise-64-128
description: "Enterprise BASIC ROM v1.1"
size: 16384
crc32: "683cf455"
@@ -577,6 +620,7 @@ files:
- name: "BASIC 1.1 - EPROM 1.1 (198x)(Enterprise).bin"
path: "Enterprise/BASIC 1.1 - EPROM 1.1 (198x)(Enterprise).bin"
system: enterprise-64-128
description: "Enterprise BASIC ROM v1.1, with trailing byte"
size: 16385
crc32: "c96b7602"
@@ -586,6 +630,7 @@ files:
- name: basic21.bin
path: Enterprise/basic21.bin
system: enterprise-64-128
description: "Enterprise BASIC ROM v2.1"
size: 16384
crc32: "55f96251"
@@ -598,6 +643,7 @@ files:
- name: epdos.bin
path: Enterprise/epdos.bin
system: enterprise-64-128
description: "Enterprise EPDOS ROM"
size: 32768
crc32: "201319eb"
@@ -608,6 +654,7 @@ files:
- name: exdos.bin
path: Enterprise/exdos.bin
system: enterprise-64-128
description: "Enterprise EXDOS ROM"
size: 16384
crc32: "e6daa0e9"
@@ -621,6 +668,7 @@ files:
# -------------------------------------------------------
- name: mac128k.rom
path: Macintosh/mac128k.rom
system: apple-macintosh
description: "Macintosh 128k ROM"
size: 65536
crc32: "6d0c8a28"
@@ -630,6 +678,7 @@ files:
- name: mac512k.rom
path: Macintosh/mac512k.rom
system: apple-macintosh
description: "Macintosh 512k ROM"
size: 65536
crc32: "cf759e0d"
@@ -639,6 +688,7 @@ files:
- name: macplus.rom
path: Macintosh/macplus.rom
system: apple-macintosh
description: "Macintosh Plus ROM"
size: 131072
crc32: "b2102e8e"
@@ -656,6 +706,7 @@ files:
# -------------------------------------------------------
- name: bios.sms
path: MasterSystem/bios.sms
system: sega-mastersystem
description: "European/US Master System BIOS"
region: [north-america, europe]
size: 8192
@@ -666,6 +717,7 @@ files:
- name: japanese-bios.sms
path: MasterSystem/japanese-bios.sms
system: sega-mastersystem
description: "Japanese Master System BIOS"
region: [japan]
size: 8192
@@ -680,6 +732,7 @@ files:
- name: msx.rom
aliases: [MSX.ROM]
path: MSX/MSX.ROM
system: microsoft-msx
description: "Generic MSX BIOS"
size: 32768
crc32: "94ee12f3"
@@ -689,6 +742,7 @@ files:
- name: msx-japanese.rom
path: MSX/msx-japanese.rom
system: microsoft-msx
description: "Japanese MSX BIOS"
region: [japan]
size: 32768
@@ -699,6 +753,7 @@ files:
- name: msx-american.rom
path: MSX/msx-american.rom
system: microsoft-msx
description: "American MSX BIOS"
region: [north-america]
size: 32768
@@ -708,6 +763,7 @@ files:
- name: msx-european.rom
path: MSX/msx-european.rom
system: microsoft-msx
description: "European MSX BIOS"
region: [europe]
size: 32768
@@ -727,6 +783,7 @@ files:
- name: msx2.rom
aliases: [MSX2.ROM]
path: MSX/MSX2.ROM
system: microsoft-msx2
description: "Generic MSX2 BIOS"
size: 32768
crc32: "6cdaf3a5"
@@ -737,6 +794,7 @@ files:
- name: msx2ext.rom
aliases: [MSX2EXT.ROM]
path: MSX/MSX2EXT.ROM
system: microsoft-msx2
description: "MSX2 extension ROM"
size: 16384
crc32: "66237ecf"
@@ -758,6 +816,7 @@ files:
# -------------------------------------------------------
- name: basic10.rom
path: Oric/basic10.rom
system: oric
description: "Oric BASIC 1.0"
size: 16384
crc32: "f18710b4"
@@ -767,6 +826,7 @@ files:
- name: basic11.rom
path: Oric/basic11.rom
system: oric
description: "Oric BASIC 1.1"
size: 16384
crc32: "c3a92bef"
@@ -776,6 +836,7 @@ files:
- name: pravetz.rom
path: Oric/pravetz.rom
system: oric
description: "Pravetz BASIC"
size: 16384
crc32: "58079502"
@@ -785,6 +846,7 @@ files:
- name: colour.rom
path: Oric/colour.rom
system: oric
description: "Oric colour ROM (128-byte version)"
size: 128
crc32: "d50fca65"
@@ -794,6 +856,7 @@ files:
- name: ORIC.PAL-PROM-TBP24S10-1ab9b572.bin
path: Oric/ORIC.PAL-PROM-TBP24S10-1ab9b572.bin
system: oric
description: "Oric colour ROM (256-byte version)"
size: 256
crc32: "1ab9b572"
@@ -803,6 +866,7 @@ files:
- name: PRAVETZ-8D.PAL-PROM-82S129-1576a69b.bin
path: Oric/PRAVETZ-8D.PAL-PROM-82S129-1576a69b.bin
system: oric
description: "Pravetz 8D colour ROM"
size: 256
crc32: "1576a69b"
@@ -812,6 +876,7 @@ files:
- name: bd500.rom
path: Oric/bd500.rom
system: oric
description: "Oric Byte Drive 500 ROM"
size: 8192
crc32: "61952e34"
@@ -821,6 +886,7 @@ files:
- name: jasmin.rom
path: Oric/jasmin.rom
system: oric
description: "Oric Jasmin ROM"
size: 2048
crc32: "37220e89"
@@ -830,6 +896,7 @@ files:
- name: microdisc.rom
path: Oric/microdisc.rom
system: oric
description: "Oric Microdisc ROM"
size: 8192
crc32: "a9664a9c"
@@ -839,6 +906,7 @@ files:
- name: 8dos.rom
path: Oric/8dos.rom
system: oric
description: "8DOS boot ROM"
size: 512
crc32: "49a74c06"
@@ -851,6 +919,7 @@ files:
# -------------------------------------------------------
- name: GLABIOS_0.2.5_8T.ROM
path: PCCompatible/GLABIOS_0.2.5_8T.ROM
system: pc-compatible
description: "8088 GLaBIOS 0.2.5"
size: 8192
crc32: "9576944c"
@@ -860,6 +929,7 @@ files:
- name: GLaTICK_0.8.5_AT.ROM
path: PCCompatible/GLaTICK_0.8.5_AT.ROM
system: pc-compatible
description: "AT GLaTICK 0.8.5 RTC option ROM"
size: 2048
crc32: "371ea3f1"
@@ -869,6 +939,7 @@ files:
- name: "Phoenix 80286 ROM BIOS Version 3.05.bin"
path: "PCCompatible/Phoenix 80286 ROM BIOS Version 3.05.bin"
system: pc-compatible
description: "Phoenix 80286 BIOS 3.05"
size: 32768
crc32: "8d0d318a"
@@ -878,6 +949,7 @@ files:
- name: at-bios.bin
path: PCCompatible/at-bios.bin
system: pc-compatible
description: "IBM PC AT BIOS v3"
size: 65536
crc32: "674426be"
@@ -887,6 +959,7 @@ files:
- name: BIOS_5170_15NOV85_U27_61X9266_27256.BIN
path: PCCompatible/BIOS_5170_15NOV85_U27_61X9266_27256.BIN
system: pc-compatible
description: "IBM PC AT BIOS, Nov 1985, U27 chip"
size: 32768
crc32: "4995be7a"
@@ -896,6 +969,7 @@ files:
- name: BIOS_5170_15NOV85_U47_61X9265_27256.BIN
path: PCCompatible/BIOS_5170_15NOV85_U47_61X9265_27256.BIN
system: pc-compatible
description: "IBM PC AT BIOS, Nov 1985, U47 chip"
size: 32768
crc32: "c32713e4"
@@ -905,6 +979,7 @@ files:
- name: CGA.F08
path: PCCompatible/CGA.F08
system: pc-compatible
description: "IBM CGA font"
size: 2048
crc32: "a362ffe6"
@@ -914,6 +989,7 @@ files:
- name: EUMDA9.F14
path: PCCompatible/EUMDA9.F14
system: pc-compatible
description: "IBM MDA font"
size: 3584
crc32: "7754882a"
@@ -941,6 +1017,7 @@ files:
- name: ibm-basic-1.10.rom
path: PCCompatible/ibm-basic-1.10.rom
system: pc-compatible
description: "IBM ROM BASIC 1.10"
size: 32768
crc32: "ebacb791"
@@ -953,6 +1030,7 @@ files:
# -------------------------------------------------------
- name: basic.318006-01.bin
path: Plus4/basic.318006-01.bin
system: commodore-plus4
description: "C16+4 BASIC ROM"
size: 16384
crc32: "74eaae87"
@@ -961,6 +1039,7 @@ files:
- name: kernal.318004-05.bin
path: Plus4/kernal.318004-05.bin
system: commodore-plus4
description: "C16+4 kernel, PAL-G revision 5"
size: 16384
crc32: "71c07bd4"
@@ -991,6 +1070,7 @@ files:
# -------------------------------------------------------
- name: mo5-v1.0.rom
path: Thomson/mo5-v1.0.rom
system: thomson-mo5
description: "Thomson MO5 ROM, version 1"
size: 16384
crc32: "f62d2f3a"
@@ -999,6 +1079,7 @@ files:
- name: mo5-v1.1.rom
path: Thomson/mo5-v1.1.rom
system: thomson-mo5
description: "Thomson MO5 ROM, version 1.1"
size: 16384
crc32: "237c60bf"
@@ -1007,6 +1088,7 @@ files:
- name: mo6-v1.rom
path: Thomson/mo6-v1.rom
system: thomson-mo6
description: "Thomson MO6 ROM, version 1"
size: 65536
crc32: "45e859c6"
@@ -1015,6 +1097,7 @@ files:
- name: mo6-v2.rom
path: Thomson/mo6-v2.rom
system: thomson-mo6
description: "Thomson MO6 ROM, version 2"
size: 65536
crc32: "b4430a3b"
@@ -1023,6 +1106,7 @@ files:
- name: mo6-v3.rom
path: Thomson/mo6-v3.rom
system: thomson-mo6
description: "Thomson MO6 ROM, version 3"
size: 65536
crc32: "7a012322"
@@ -1051,6 +1135,7 @@ files:
# -------------------------------------------------------
- name: basic.bin
path: Vic20/basic.bin
system: commodore-vic20
description: "VIC-20 BASIC ROM"
size: 8192
crc32: "db4c43c1"
@@ -1059,6 +1144,7 @@ files:
- name: characters-english.bin
path: Vic20/characters-english.bin
system: commodore-vic20
description: "English-language VIC-20 character ROM"
region: [north-america, europe]
size: 4096
@@ -1069,6 +1155,7 @@ files:
- name: kernel-pal.bin
path: Vic20/kernel-pal.bin
system: commodore-vic20
description: "English-language PAL VIC-20 kernel ROM"
region: [europe]
size: 8192
@@ -1079,6 +1166,7 @@ files:
- name: kernel-ntsc.bin
path: Vic20/kernel-ntsc.bin
system: commodore-vic20
description: "English-language NTSC VIC-20 kernel ROM"
region: [north-america]
size: 8192
@@ -1089,6 +1177,7 @@ files:
- name: characters-danish.bin
path: Vic20/characters-danish.bin
system: commodore-vic20
description: "Danish VIC-20 character ROM"
region: [denmark]
size: 4096
@@ -1099,6 +1188,7 @@ files:
- name: kernel-danish.bin
path: Vic20/kernel-danish.bin
system: commodore-vic20
description: "Danish VIC-20 kernel ROM"
region: [denmark]
size: 8192
@@ -1109,6 +1199,7 @@ files:
- name: characters-japanese.bin
path: Vic20/characters-japanese.bin
system: commodore-vic20
description: "Japanese VIC-20 character ROM"
region: [japan]
size: 4096
@@ -1119,6 +1210,7 @@ files:
- name: kernel-japanese.bin
path: Vic20/kernel-japanese.bin
system: commodore-vic20
description: "Japanese VIC-20 kernel ROM"
region: [japan]
size: 8192
@@ -1129,6 +1221,7 @@ files:
- name: characters-swedish.bin
path: Vic20/characters-swedish.bin
system: commodore-vic20
description: "Swedish VIC-20 character ROM"
region: [sweden]
size: 4096
@@ -1139,6 +1232,7 @@ files:
- name: kernel-swedish.bin
path: Vic20/kernel-swedish.bin
system: commodore-vic20
description: "Swedish VIC-20 kernel ROM"
region: [sweden]
size: 8192
@@ -1153,6 +1247,7 @@ files:
# -------------------------------------------------------
- name: 48.rom
path: ZXSpectrum/48.rom
system: sinclair-zx-spectrum
description: "ZX Spectrum 48K ROM"
size: 16384
crc32: "ddee531f"
@@ -1162,6 +1257,7 @@ files:
- name: 128.rom
path: ZXSpectrum/128.rom
system: sinclair-zx-spectrum
description: "ZX Spectrum 128K ROM"
size: 32768
crc32: "2cbe8995"
@@ -1171,6 +1267,7 @@ files:
- name: plus2.rom
path: ZXSpectrum/plus2.rom
system: sinclair-zx-spectrum
description: "ZX Spectrum +2 ROM"
size: 32768
crc32: "e7a517dc"
@@ -1180,6 +1277,7 @@ files:
- name: plus3.rom
path: ZXSpectrum/plus3.rom
system: sinclair-zx-spectrum
description: "ZX Spectrum +2a/+3 ROM"
size: 65536
crc32: "96e3c17a"
@@ -1193,6 +1291,7 @@ files:
# -------------------------------------------------------
- name: zx80.rom
path: ZX8081/zx80.rom
system: sinclair-zx80-81
description: "ZX80 BASIC ROM"
size: 4096
crc32: "4c7fc597"
@@ -1202,6 +1301,7 @@ files:
- name: zx81.rom
path: ZX8081/zx81.rom
system: sinclair-zx80-81
description: "ZX81 BASIC ROM"
size: 8192
crc32: "4b1dd6eb"
+5 -5
View File
@@ -135,8 +135,8 @@ files:
required: false
hle_fallback: true
size: 8192
validation: [size]
known_hash_adler32: "0x66f334fe"
validation: [size, adler32]
known_hash_adler32: ["0x66f334fe", "0x128ea7a2"]
adler32_byteswap: true
description: "DSP instruction ROM"
note: "DSP LLE only, and LLE aborts when the file is absent or not 8192 bytes. The adler32 is taken over the byte-swapped image and the value here is the Nintendo pair; five replacement pairs are also accepted."
@@ -147,12 +147,12 @@ files:
required: false
hle_fallback: true
size: 4096
validation: [size]
known_hash_adler32: "0xf3b93527"
validation: [size, adler32]
known_hash_adler32: ["0xf3b93527", "0xa4a575f5"]
adler32_byteswap: true
description: "DSP coefficient ROM"
note: "Read by DSP LLE alongside the instruction ROM, and by the AX ucode under HLE for polyphase resampling, which drops any file that is not 0x1000 bytes and plays on without it."
source_ref: "Source/Core/Common/CommonPaths.h:109, Source/Core/Core/HW/DSPLLE/DSPLLE.cpp:120-152, Source/Core/Core/HW/DSPHLE/UCodes/AX.cpp:45-70, Source/Core/Core/DSP/DSPCore.h:49"
source_ref: "Source/Core/Common/CommonPaths.h:109, Source/Core/Core/HW/DSPLLE/DSPLLE.cpp:120-152, Source/Core/Core/HW/DSPHLE/UCodes/AX.cpp:45-70, Source/Core/Core/DSP/DSPCore.h:49, Source/Core/Core/DSP/DSPCore.cpp:38-105"
- name: codehandler.bin
path: null
+5 -5
View File
@@ -171,8 +171,8 @@ files:
required: false
hle_fallback: true
size: 8192
validation: [size]
known_hash_adler32: "0x66f334fe"
validation: [size, adler32]
known_hash_adler32: ["0x66f334fe", "0xe789b5a5"]
adler32_byteswap: true
description: "DSP instruction ROM"
note: "DSP LLE only, and a file that is absent or not 8192 bytes fails initialisation, which aborts the emulation thread. The adler32 is taken over the byte-swapped image and the value here is the Nintendo pair; six replacement pairs are also accepted."
@@ -183,12 +183,12 @@ files:
required: false
hle_fallback: true
size: 4096
validation: [size]
known_hash_adler32: "0xf3b93527"
validation: [size, adler32]
known_hash_adler32: ["0xf3b93527", "0xa4a575f5"]
adler32_byteswap: true
description: "DSP coefficient ROM"
note: "Read by DSP LLE alongside the instruction ROM, and by the AX ucode under HLE for polyphase resampling, which drops any file that is not 0x1000 bytes and plays on without it."
source_ref: "Source/Core/Common/CommonPaths.h:121, Source/Core/Core/HW/DSPLLE/DSPLLE.cpp:87-120, Source/Core/Core/HW/DSPHLE/UCodes/AX.cpp:42-69, Source/Core/Core/DSP/DSPCore.h:58"
source_ref: "Source/Core/Common/CommonPaths.h:121, Source/Core/Core/HW/DSPLLE/DSPLLE.cpp:87-120, Source/Core/Core/HW/DSPHLE/UCodes/AX.cpp:42-69, Source/Core/Core/DSP/DSPCore.h:58, Source/Core/Core/DSP/DSPCore.cpp:28-102"
- name: codehandler.bin
path: null
+6 -6
View File
@@ -67,22 +67,22 @@ files:
size: 8192
required: false
hle_fallback: true
validation: [size]
known_hash_adler32: "0x66f334fe"
validation: [size, adler32]
known_hash_adler32: ["0x66f334fe", "0xe789b5a5"]
adler32_byteswap: true
note: "DSP instruction ROM for LLE audio. Free replacement (v0.4) included"
source_ref: "Source/Core/Common/CommonPaths.h:136, Source/Core/Core/HW/DSPLLE/DSPLLE.cpp:84-117"
source_ref: "Source/Core/Common/CommonPaths.h:136, Source/Core/Core/HW/DSPLLE/DSPLLE.cpp:84-117, Source/Core/Core/DSP/DSPCore.cpp:28-102"
- name: "dsp_coef.bin"
path: "GC/dsp_coef.bin"
size: 4096
required: false
hle_fallback: true
validation: [size]
known_hash_adler32: "0xf3b93527"
validation: [size, adler32]
known_hash_adler32: ["0xf3b93527", "0xa4a575f5"]
adler32_byteswap: true
note: "DSP coefficient ROM for LLE audio and HLE polyphase resampling. Free replacement included"
source_ref: "Source/Core/Common/CommonPaths.h:137, Source/Core/Core/DSP/DSPCore.cpp:32-33, Source/Core/Core/HW/DSPHLE/UCodes/AX.cpp:55-62"
source_ref: "Source/Core/Common/CommonPaths.h:137, Source/Core/Core/DSP/DSPCore.cpp:32-33, Source/Core/Core/HW/DSPHLE/UCodes/AX.cpp:55-62, Source/Core/Core/DSP/DSPCore.cpp:28-102"
# -- GameCube Fonts --
# Bundled free alternatives exist but have padding differences causing misplaced text.
+2 -2
View File
@@ -1,8 +1,8 @@
emulator: DOSBox Pure Unleashed
type: standalone
core_classification: official_port
source: "https://github.com/schellingb/dosbox-pure-unleashed"
upstream: "https://github.com/schellingb/dosbox-pure"
source: "https://codeberg.org/schelling/dosbox-pure-unleashed"
upstream: "https://codeberg.org/schelling/dosbox-pure"
source_commit: "4a11412248ca4c862751a7d9e6818023795031e9"
upstream_commit: "7f6e8fb7385fa446d1444d671063268520bf9b54"
logo: "https://raw.githubusercontent.com/schellingb/dosbox-pure-unleashed/main/images/logo.png"
+1 -1
View File
@@ -16,7 +16,7 @@ notes: |
ref: src/gui/midi_mt32.cpp:35,51-66
MUNT identifies ROMs by SHA1+size (libretro/deps/munt/mt32emu/src/ROMInfo.cpp:171-180).
FluidSynth reads .sf2/.sf3/.dls/.gig from system/soundfonts/.
ref: libretro/src/libretro.cpp:1112-1123
ref: libretro/src/libretro.cpp:1099-1110
BASSMIDI reads .sf2/.sfz from system/soundfonts/, requires BASS +
BASSMIDI shared libs in system dir (dlopen'd at runtime).
ref: libretro/src/midi_bassmidi.cpp:232-254
+87 -14
View File
@@ -2,41 +2,54 @@ emulator: DOSBox Pure
type: standalone + libretro
core_classification: enhanced_fork
source: "https://github.com/libretro/dosbox-pure"
upstream: "https://github.com/schellingb/dosbox-pure"
upstream: "https://codeberg.org/schelling/dosbox-pure"
logo: "https://raw.githubusercontent.com/schellingb/dosbox-pure/main/images/logo.png"
profiled_date: "2026-03-23"
source_commit: "a4a0bab7f8931433588f2fcad9045c85b277373d"
core_version: "1.0-preview5"
source_commit: "cdaea10ce8cac231bc341ca05d4c5e4e5fe0fbd5"
core_version: "1.0-preview7"
display_name: "DOS (DOSBox-Pure)"
cores: [dosbox_pure]
systems: [dos]
verification: sha1
notes: |
No BIOS required. MT-32 and SoundFont support is optional for MIDI music.
No BIOS required. MT-32, Sound Canvas and SoundFont support is optional for
MIDI music.
ROM scanning (both modes):
Recursive scan of system directory for *_CONTROL.ROM and *.SF2/*.SF3.
ref: dosbox_pure_libretro.cpp:1399-1410
MT-32 requires matched pair: *_CONTROL.ROM + *_PCM.ROM (PCM name derived
from CONTROL name by replacing CONTROL with PCM, preserving case).
ref: midi_mt32.h:189-199
ref: src/gui/midi_mt32.h:189-199
ZIP archives also supported — scanned for files by size (65536/131072 =
control, 524288/1048576 = PCM), not by name.
ref: midi_mt32.h:160-166
Files can also be on mounted C: drive (DOSBOX.SF2, MT32_CONTROL.ROM).
ref: dosbox_pure_libretro.cpp:2803-2805
ref: src/gui/midi_mt32.h:160-166
Files can also be on mounted C: drive (DOSBOX.SF2, MT32_CONTROL.ROM,
ROM1.BIN).
ref: dosbox_pure_libretro.cpp:2806-2813
Cache file DOSBoxPureMidiCache.txt written when scan >2s.
ref: dosbox_pure_libretro.cpp:1425-1445
ref: dosbox_pure_libretro.cpp:1449-1464
Sound Canvas: the scan also lists every file whose name ends in ROM1.BIN,
WAVEROM1.BIN excepted, as "Sound Canvas SC-55". Selected, the Nuked-SC55
driver opens it at exactly 32768 bytes, then ROM2, ROM2_ST, ROM_SM,
WAVEROM1, WAVEROM2 and WAVEROM3 beside it, spelled with the capitalization
and extension of ROM1.BIN. Each file fills the slot its size names. Byte 67
of ROM1 selects the model, SC-55mkII/SC-55st, SC-55/SC-155, CM-300/SCC-1,
JV-880 or SCB-55, and the sizes the other ROMs must have. The driver does
not open without ROM1 and ROM2.
ref: dosbox_pure_libretro.cpp:1405, src/gui/midi_sc55.h:38-47,
src/gui/midi_sc55.h:71-95, src/gui/midi_sc55.h:97-134
Bundled MUNT (header-only mt32emu.h) for MT-32 emulation.
SHA1+size validation at load: unrecognized ROMs rejected (Synth::open fails).
ref: mt32emu.h:2982-2988,3016-3019,5183-5187
ref: src/gui/mt32emu.h:2982-2988,3016-3019,5183-5187
12 full control ROMs + 2 PCM ROMs supported (no split ROMs in this MUNT).
TinySoundFont (tsf.h) for SF2/SF3 playback.
No firmware entries in .info file — all MIDI files optional.
DBP_STANDALONE build mode exists (same MIDI logic, different I/O layer).
ref: dosbox_pure_libretro.cpp:81,1590,2302
ref: dosbox_pure_libretro.cpp:81,1588,2302
files:
# -- MT-32 Control ROMs (64 KB) --
@@ -168,7 +181,7 @@ files:
note: >
accepted by every MT-32 control ROM, v1.x and v2.x. Each control ROM
fixes the PCM size it accepts through its pcmCount: 128 requires this
524288 byte image. ref: mt32emu.h:2586-2598,3167,3025
524288 byte image. ref: src/gui/mt32emu.h:2586-2598,3167,3025
- name: "CM32L_PCM.ROM"
description: "CM-32L/CM-64/LAPC-I PCM ROM"
@@ -183,7 +196,7 @@ files:
accepted by the CM-32L and CM-32LN control ROMs, which carry pcmCount
256 and require this 1048576 byte image. The alias covers the name
derived from CM32LN_CONTROL.ROM.
ref: mt32emu.h:2586-2598,3167,3025, midi_mt32.h:194-195
ref: src/gui/mt32emu.h:2586-2598,3167,3025, src/gui/midi_mt32.h:194-195
# -- General MIDI SoundFont --
@@ -191,8 +204,68 @@ files:
description: "General MIDI SoundFont (any .sf2/.sf3 accepted)"
required: false
hle_fallback: true
source_ref: "dosbox_pure_libretro.cpp:1410 (scan classifies .SF* as a SoundFont), dosbox_pure_libretro.cpp:2492-2495 (path taken from the system directory), dosbox_pure_libretro.cpp:2803-2805 (auto-detected on the mounted C: drive)"
source_ref: "dosbox_pure_libretro.cpp:1405 (scan classifies .SF* as a SoundFont), dosbox_pure_libretro.cpp:2495-2499 (path taken from the system directory), dosbox_pure_libretro.cpp:2806-2813 (auto-detected on the mounted C: drive)"
note: >
Any .SF2 or .SF3 file in the system directory works. The core lists all
found SoundFonts in the MIDI config dropdown. DOSBOX.SF2 is the conventional
name and is also auto-detected when placed inside game content on C: drive.
# -- Roland SC-55 family ROMs (Nuked-SC55 driver) --
- name: "ROM1.BIN"
path: "SC-55/ROM1.BIN"
aliases: ["rom1.bin"]
description: "SC-55 family program ROM 1"
required: false
size: 32768
validation: [size]
source_ref: "dosbox_pure_libretro.cpp:1405, src/gui/midi_sc55.h:71-75, src/gui/midi_sc55.h:97-101"
note: >-
Any name ending in ROM1.BIN anywhere under the system directory is
listed; byte 67 selects the emulated model.
- name: "ROM2.BIN"
path: "SC-55/ROM2.BIN"
aliases: ["rom2.bin", "ROM2_ST.BIN", "rom2_st.bin"]
description: "SC-55 family program ROM 2"
required: false
size: [262144, 524288]
validation: [size]
source_ref: "src/gui/midi_sc55.h:41, src/gui/midi_sc55.h:78-93, src/gui/midi_sc55.h:95"
note: "The driver does not open without ROM1 and ROM2. ROM2_ST fills the same slot when ROM2 did not."
- name: "ROM_SM.BIN"
path: "SC-55/ROM_SM.BIN"
aliases: ["rom_sm.bin"]
description: "SC-55mkII/SC-55st sub-MCU ROM"
required: false
size: 4096
validation: [size]
source_ref: "src/gui/midi_sc55.h:42, src/gui/midi_sc55.h:78-93, src/gui/midi_sc55.h:113-116"
- name: "WAVEROM1.BIN"
path: "SC-55/WAVEROM1.BIN"
aliases: ["waverom1.bin"]
description: "SC-55 family wave ROM 1"
required: false
size: [1048576, 2097152]
validation: [size]
source_ref: "src/gui/midi_sc55.h:43-45, src/gui/midi_sc55.h:78-93, src/gui/midi_sc55.h:111-134"
- name: "WAVEROM2.BIN"
path: "SC-55/WAVEROM2.BIN"
aliases: ["waverom2.bin"]
description: "SC-55 family wave ROM 2"
required: false
size: [1048576, 2097152]
validation: [size]
source_ref: "src/gui/midi_sc55.h:43-45, src/gui/midi_sc55.h:78-93, src/gui/midi_sc55.h:111-134"
- name: "WAVEROM3.BIN"
path: "SC-55/WAVEROM3.BIN"
aliases: ["waverom3.bin"]
description: "SC-55/SC-155/CM-300 wave ROM 3"
required: false
size: 1048576
validation: [size]
source_ref: "src/gui/midi_sc55.h:43-45, src/gui/midi_sc55.h:78-93, src/gui/midi_sc55.h:117-125"
+1 -1
View File
@@ -30,7 +30,7 @@ notes: |
only by the two settings screens, which fall back to the real filename when it
is null.
ref: src/core/bios.h:41-43 (field declarations)
ref: src/duckstation-qt/biossettingswidget.cpp:149, src/core/fullscreenui_settings.cpp:3301
ref: src/duckstation-qt/biossettingswidget.cpp:149, src/core/fullscreenui_settings.cpp:3281
Lower priority = preferred. PS2 deprioritized (>= 100) for dynamic fast boot.
Late PAL deprioritized (>= 150) due to additional regional checks.
OpenBIOS detected by signature at offset 0x78, not by hash.
+1 -1
View File
@@ -24,7 +24,7 @@ notes: |
"embedded" when that fails. The system directory is still passed to SelectGame,
but for the game data search, not for the engine package.
ref: src/libretro/ecwolf_pk3_data.c, src/wl_iwad.cpp:664-672,
src/libretro/libretro.cpp:1028-1030
src/libretro/libretro.cpp:1009-1011
Standalone: ecwolf.pk3 searched in progdir (binary directory).
ref: src/libretro/wl_main.cpp:1247 (progdir passed to SelectGame)
+5 -5
View File
@@ -27,31 +27,31 @@ mode: standalone
files:
- name: "prod.keys"
required: true
path: "switch/"
path: "switch/prod.keys"
note: "Production keys for NCA decryption (master, key area, header, titlekek)"
source_ref: "src/core/crypto/key_manager.cpp:574-575, 853"
- name: "dev.keys"
required: false
path: "switch/"
path: "switch/dev.keys"
note: "Development-unit keys, read instead of prod.keys when use_dev_keys is set"
source_ref: "src/core/crypto/key_manager.cpp:570-571, 852"
- name: "title.keys"
required: false
path: "switch/"
path: "switch/title.keys"
note: "Per-title encryption keys (rights_id to titlekey mappings)"
source_ref: "src/core/crypto/key_manager.cpp:577-578, 850"
- name: "console.keys"
required: false
path: "switch/"
path: "switch/console.keys"
note: "Console-specific keys (BIS, SD seed)"
source_ref: "src/core/crypto/key_manager.cpp:579-580"
- name: "key_retail.bin"
required: false
path: "switch/"
path: "switch/key_retail.bin"
size: 160
note: "Amiibo decryption keys (two InternalKey structs, 0x50 bytes each)"
source_ref: "src/core/hle/service/nfc/common/amiibo_crypto.cpp:281-302"
+23 -23
View File
@@ -8,9 +8,9 @@ upstream: "https://github.com/EKA2L1/EKA2L1"
profiled_date: "2026-09-17"
source_commit:
standalone: "1fcfadbff7f8b81d8c17bc82d04b0c94d16803bf"
libretro: "97ac3df6767f819c95405e4c86e7007d2e8ae61d"
libretro: "1c49c1bcde3853273cd520a5360bff756f872e06"
upstream_commit:
libretro: "47b4ad76a6dd7d3656f52be86dfd5b9ff9a50c70"
libretro: "11f5b6cd141c0884a130ee45743f1f5e17bb1783"
core_version: "0.0.9"
display_name: "Nokia - Symbian / N-Gage (EKA2L1)"
cores:
@@ -27,13 +27,13 @@ notes: |
N-Gage 2.0 libraries and the game libraries from S60v1 to Symbian Belle. One
tree builds the Qt desktop frontend, the Android and iOS applications, and a
libretro core; the core lives on the libretro branch of the WizzardSK fork,
merged from upstream at 47b4ad76. The tip of that branch, 7a40bb0d, merges
upstream 0b7d9d67 and does not build the core: content.cpp still calls
install_firmware and install_rom_with_optional_rpkg without the
isolate_drives argument they take from that merge on. The libretro pin is the
last revision of the branch that builds.
rebased on the upstream revision named in its upstream.version, 11f5b6cd.
content.cpp passes isolate_drives false to install_firmware and
install_rom_with_optional_rpkg, so drives C, D and E are shared between
devices.
ref: README.md:20, README.md:29-32, src/emu/CMakeLists.txt:61-62,
CMakeLists.txt:18, .gitlab-ci.yml:14-22, src/emu/libretro/src/content.cpp:96-100,
CMakeLists.txt:18, .gitlab-ci.yml:17-25, src/emu/libretro/CMakeLists.txt:40-46,
src/emu/libretro/src/content.cpp:178-184,
src/emu/system/src/installation/rpkg.cpp:208-210,
src/emu/system/src/installation/firmware.cpp:290-293
@@ -54,12 +54,12 @@ notes: |
sw.txt or langsw.txt under z:\resource\versions, sw.txt or langsw.txt under
z:\system\versions, or z:\system\install\sonyericssonp90xplatform.sis. That
is the N-Gage case: its files are unpacked to drives/z/, the firmware code is
read from them and the image is copied to SYM.ROM. The libretro pin tests
z:\system\versions\sw.txt alone. Any other image needs the RPKG made by the
Dumber tool beside it, which supplies the ROFS. A .vpl variant packing list
names the .fpsx flash images of a factory firmware, from which the core image,
the ROFS and the drive contents are extracted. The names of the dump files
are free; SYM.ROM is the name the installers give the resident copy.
read from them and the image is copied to SYM.ROM. Any other image needs
the RPKG made by the Dumber tool beside it, which supplies the ROFS. A .vpl
variant packing list names the .fpsx flash images of a factory firmware,
from which the core image, the ROFS and the drive contents are extracted.
The names of the dump files are free; SYM.ROM is the name the installers
give the resident copy.
ref: src/emu/system/src/installation/rpkg.cpp:44-68,
src/emu/system/src/software.cpp:396-408,
src/emu/system/src/installation/rpkg.cpp:132-199,
@@ -97,11 +97,11 @@ notes: |
<system>/eka2l1/libretro-content.txt against the UID it registered, or a
.eka2l1 text shortcut naming the UID of an application already installed.
supports_no_game is false. is_experimental is true in the .info.
ref: src/emu/libretro/src/main.cpp:51-53, src/emu/libretro/src/state.cpp:12-17,
src/emu/libretro/src/main.cpp:82-100, src/emu/libretro/src/content.cpp:44-111,
src/emu/libretro/src/main.cpp:161-169, src/emu/libretro/src/main.cpp:68-69,
src/emu/libretro/src/main.cpp:116-117, src/emu/libretro/src/content.cpp:119,
src/emu/libretro/src/content.cpp:244-249
ref: src/emu/libretro/src/main.cpp:55-57, src/emu/libretro/src/state.cpp:12-17,
src/emu/libretro/src/main.cpp:92-110, src/emu/libretro/src/content.cpp:129-195,
src/emu/libretro/src/main.cpp:173-181, src/emu/libretro/src/main.cpp:72-73,
src/emu/libretro/src/main.cpp:126-127, src/emu/libretro/src/content.cpp:203,
src/emu/libretro/src/content.cpp:350-355
At this revision the libretro build stages none of the shipped resource
folders and never calls set_runtime_resource_root, so the GL shaders, the
@@ -110,8 +110,8 @@ notes: |
and creates no audio or controller driver, so the patch libraries, the Lua
scripts, the MIDI banks and the controller database are not read there.
Those entries carry mode standalone.
ref: src/emu/libretro/CMakeLists.txt:8-45, src/emu/libretro/src/thread.cpp:19-38,
src/emu/libretro/src/thread.cpp:41-60, src/emu/libretro/src/thread.cpp:83-89,
ref: src/emu/libretro/CMakeLists.txt:8-72, src/emu/libretro/src/thread.cpp:20-61,
src/emu/libretro/src/thread.cpp:87-93,
src/emu/common/src/path.cpp:427-450, src/emu/system/src/epoc.cpp:1389-1410
Shipped runtime files are read at their own name below the working
@@ -156,7 +156,7 @@ notes: |
src/emu/config/src/panic_blacklist.cpp:27-35, src/emu/config/src/app_settings.cpp:82-114,
src/emu/utils/src/panic.cpp:32-38, src/emu/scripting/src/manager.cpp:196-202,
src/emu/scripting/src/manager.cpp:230-256, src/emu/services/src/fbs/fbs.cpp:443,
src/emu/services/src/fbs/impls/font.cpp:1185-1208, .gitlab-ci.yml:19,
src/emu/services/src/fbs/impls/font.cpp:1185-1208, .gitlab-ci.yml:22,
src/emu/qt/CMakeLists.txt:264-278, src/emu/qt/CMakeLists.txt:289-290,
src/emu/qt/CMakeLists.txt:376-377, cmake/Symbian.cmake:20-31
@@ -182,7 +182,7 @@ files:
dump, an EKA2 image with its RPKG, or a VPL with its .fpsx images.
source_ref:
standalone: "src/emu/system/src/epoc.cpp:1486-1494, src/emu/system/src/epoc.cpp:824-848, src/emu/system/include/system/consts.h:23-25, src/emu/system/src/installation/rpkg.cpp:44-68, src/emu/system/src/installation/rpkg.cpp:196-199, src/emu/qt/src/device_install_dialog.cpp:162-172"
libretro: "src/emu/libretro/src/main.cpp:82-100, src/emu/libretro/src/content.cpp:44-111, src/emu/libretro/src/main.cpp:161-169, src/emu/system/src/installation/rpkg.cpp:202-248"
libretro: "src/emu/libretro/src/main.cpp:92-110, src/emu/libretro/src/content.cpp:129-195, src/emu/libretro/src/main.cpp:173-181, src/emu/system/src/installation/rpkg.cpp:208-255"
- name: audiooutputrouting.dll.map
standalone_path: patch/audiooutputrouting.dll.map
+8
View File
@@ -289,6 +289,8 @@ files:
system: sony-playstation-2
required: false
bundled: true
sha1: 2d9878fdd70979ecf6dd0da7652efd3797c26039
size: 2697551
category: game_data
description: "per-title compatibility and fix database"
note: >-
@@ -303,6 +305,8 @@ files:
system: sony-playstation-2
required: false
bundled: true
sha1: dceb4536fba7fb89452864fc512a4d071a19eae0
size: 1906463
category: game_data
description: "disc hash database"
note: >-
@@ -315,6 +319,8 @@ files:
system: sony-playstation-2
required: false
bundled: true
sha1: a3d939af27fe0929e61b8e20d49ef58316c0a66c
size: 2091144
category: game_data
description: "built-in game patch archive"
note: >-
@@ -554,6 +560,8 @@ files:
- name: unlock.wav
path: resources/sounds/achievements/unlock.wav
sha1: da328a0a3074ec86fee2d6741bfc2e5a1f68d063
size: 202702
system: sony-playstation-2
required: false
description: "achievement unlock sound"
+2 -2
View File
@@ -21,7 +21,7 @@ systems:
- coleco-colecovision
- sinclair-spectrum
- msx
- nes-fds
- nintendo-fds
- super-kaneko-nova
- deco-cassette
- namco-na1
@@ -1061,7 +1061,7 @@ files:
# -------------------------------------------------------
- name: "fdsbios.nes"
archive: fdsbios.zip
system: nes-fds
system: nintendo-fds
required: true
size: 8192 # 0x2000
crc32: "5e607dcf"
+3 -3
View File
@@ -16,7 +16,7 @@ notes: |
contributed by Joe Zbiciak (jzIntv), mask ROM embedded in source
(src/ivoice.c:337-510, 4097-byte static array). No external ivoice ROM.
BIOS loading in retro_init() (src/libretro.c:1184-1192). Paths joined
BIOS loading in retro_init() (src/libretro.c:1175-1183). Paths joined
directly to system directory, no subdirectory.
loadExec() reads exec.bin as big-endian 16-bit words into 0x1000-0x1FFF.
@@ -35,11 +35,11 @@ files:
required: true
size: 8192
note: "Executive ROM. Big-endian 16-bit words loaded at 0x1000-0x1FFF."
source_ref: "src/intv.c:55-142, src/libretro.c:1187"
source_ref: "src/intv.c:51-96, src/libretro.c:1178"
- name: "grom.bin"
system: intellivision
required: true
size: 2048
note: "Graphics ROM. Raw bytes loaded at 0x3000-0x37FF."
source_ref: "src/intv.c:144-190, src/libretro.c:1191"
source_ref: "src/intv.c:98-144, src/libretro.c:1182"
+4 -4
View File
@@ -34,17 +34,17 @@ files:
- name: "bios.sms"
system: sega-mastersystem
required: false
source_ref: "platforms/libretro/libretro.cpp:777, platforms/libretro/libretro.cpp:780 (load_bootroms)"
source_ref: "platforms/libretro/libretro.cpp:736, platforms/libretro/libretro.cpp:731-743 (load_bootroms)"
- name: "bios.gg"
system: sega-gamegear
required: false
source_ref: "platforms/libretro/libretro.cpp:1067, platforms/libretro/libretro.cpp:780 (load_bootroms)"
source_ref: "platforms/libretro/libretro.cpp:737, platforms/libretro/libretro.cpp:731-743 (load_bootroms)"
platform_details:
mastersystem:
bios_filename: "bios.sms"
source_ref: "src/Memory.cpp:227-232"
source_ref: "src/Memory.cpp:267-272"
note: |
Boot ROM loaded via LoadBootromSMS() -> LoadBootroom(path, false).
Raw binary read, stored in m_pBootromSMS. Bank count computed as
@@ -52,7 +52,7 @@ platform_details:
gamegear:
bios_filename: "bios.gg"
source_ref: "src/Memory.cpp:234-239"
source_ref: "src/Memory.cpp:274-279"
note: |
Boot ROM loaded via LoadBootromGG() -> LoadBootroom(path, true).
Raw binary read, stored in m_pBootromGG. Same bank computation.
+6 -6
View File
@@ -64,22 +64,22 @@ files:
size: 8192
required: false
hle_fallback: true
validation: [size]
known_hash_adler32: "0x66f334fe"
validation: [size, adler32]
known_hash_adler32: ["0x66f334fe", "0x128ea7a2"]
adler32_byteswap: true
note: "DSP instruction ROM for LLE audio. Free replacement included"
source_ref: "Source/Core/Common/CommonPaths.h:112, Source/Core/Core/HW/DSPLLE/DSPLLE.cpp:142-150, Source/Core/Core/DSP/DSPCore.cpp:48,67"
source_ref: "Source/Core/Common/CommonPaths.h:112, Source/Core/Core/HW/DSPLLE/DSPLLE.cpp:142-150, Source/Core/Core/DSP/DSPCore.cpp:48,67, Source/Core/Core/DSP/DSPCore.cpp:38-105"
- name: "dsp_coef.bin"
path: "GC/dsp_coef.bin"
size: 4096
required: false
hle_fallback: true
validation: [size]
known_hash_adler32: "0xf3b93527"
validation: [size, adler32]
known_hash_adler32: ["0xf3b93527", "0xa4a575f5"]
adler32_byteswap: true
note: "DSP coefficient ROM for LLE audio and HLE polyphase resampling. Free replacement included"
source_ref: "Source/Core/Common/CommonPaths.h:113, Source/Core/Core/HW/DSPLLE/DSPLLE.cpp:143-153, Source/Core/Core/HW/DSPHLE/UCodes/AX.cpp:43-72, Source/Core/Core/DSP/DSPCore.cpp:48,68"
source_ref: "Source/Core/Common/CommonPaths.h:113, Source/Core/Core/HW/DSPLLE/DSPLLE.cpp:143-153, Source/Core/Core/HW/DSPHLE/UCodes/AX.cpp:43-72, Source/Core/Core/DSP/DSPCore.cpp:48,68, Source/Core/Core/DSP/DSPCore.cpp:38-105"
# -- GameCube Fonts --
# Bundled free alternatives exist but have padding differences causing misplaced text.
+2 -2
View File
@@ -187,7 +187,7 @@ files:
- name: "<CaCertificateId>.der"
required: false
path: system/ssl/
path: "system/ssl/<CaCertificateId>.der"
unsourceable: "replacement certificate the user picks for one certificate authority, with no canonical artefact behind the name"
description: "Override for one built-in root certificate"
note: >-
@@ -199,7 +199,7 @@ files:
- name: "<driver>.zip"
required: false
path: drivers/
path: "drivers/<driver>.zip"
unsourceable: "third-party Vulkan driver built for one GPU family, not an emulator artefact"
description: "Replacement Vulkan driver for the Android build"
note: >-
+5 -5
View File
@@ -30,7 +30,7 @@ notes: |
files:
- name: "<bios>.bin"
path: "pcsx2/bios/"
path: "pcsx2/bios/<bios>.bin"
required: true
description: "PS2 BIOS binary"
min_size: 4194304
@@ -43,7 +43,7 @@ files:
pcsx2_bios. Falls back to first valid BIOS found if configured BIOS is missing.
- name: "<bios>.rom1"
path: "pcsx2/bios/"
path: "pcsx2/bios/<bios>.rom1"
required: false
max_size: 4194304
description: "DVD player ROM"
@@ -53,7 +53,7 @@ files:
(extension replaced). Silently skipped if not found.
- name: "<bios>.rom2"
path: "pcsx2/bios/"
path: "pcsx2/bios/<bios>.rom2"
required: false
max_size: 524288
description: "Chinese ROM extension"
@@ -63,7 +63,7 @@ files:
Only present on Chinese region consoles.
- name: "<bios>.nvm"
path: "pcsx2/bios/"
path: "pcsx2/bios/<bios>.nvm"
required: false
hle_fallback: true
size: 1024
@@ -75,7 +75,7 @@ files:
Auto-created with region-appropriate defaults if missing or invalid.
- name: "<bios>.mec"
path: "pcsx2/bios/"
path: "pcsx2/bios/<bios>.mec"
required: false
hle_fallback: true
size: 4
+1 -1
View File
@@ -17,7 +17,7 @@ notes: |
standalone upstream.
retro_load_game() calls lutro_load(info->path) to load the game
directory or archive (libretro.c:267). The core exposes
directory or archive (libretro.c:241). The core exposes
love.filesystem.getAppdataDirectory to games as the system_dir
(filesystem.c:296) but does not load any files from it itself.
No BIOS, firmware, or system files required.
+1112 -1009
View File
File diff suppressed because it is too large. Load diff
+410 -401
View File
File diff suppressed because it is too large. Load diff
+1 -1
View File
@@ -215,4 +215,4 @@ files:
note: >
Keyboard remapping configuration (text file). User-created file
for custom keyboard layout. The core uses built-in defaults if absent.
source_ref: "keystat.c:43,113-148"
source_ref: "keystat.c:46,116-151"
+6 -6
View File
@@ -20,7 +20,7 @@ notes: |
Doukutsu.exe there (nxengine/libretro/libretro.cpp:289-294). When launched with a .exe
content file, it uses the parent directory of that file (nxengine/libretro/libretro.cpp:272).
At startup (main.cpp:75-90), the core opens Doukutsu.exe and extracts:
At startup (nxengine/main.cpp:75-90), the core opens Doukutsu.exe and extracts:
ORG music (extractorg.c), PXT sound effects (extractpxt.c), stage tile
attributes (extractstages.c), 18 credit BMPs + pixel.bmp (endpic/),
and the wavetable (nxengine/extract-auto/cachefiles.c:464-485). All kept in memory.
@@ -28,7 +28,7 @@ notes: |
The data/ directory (399 files from the freeware release) is loaded into
an in-memory cache at init (nxengine/extract-auto/cachefiles.c:38-439, 497-540). All subsequent
file access goes through this cache. The core verifies data/ by checking
for data/npc.tbl (main.cpp:47-58).
for data/npc.tbl (nxengine/main.cpp:47-58).
The font is compiled-in (bitmap_font.h). The upstream standalone version
uses font.ttf via SDL_ttf.
@@ -45,7 +45,7 @@ files:
size: 1478656
md5: "38695d3d69d7a0ada8178072dad4c58b"
sha1: "bb2d0441e073da9c584f23c2ad8c7ab8aac293bf"
source_ref: "main.cpp:77-78 (opened for extraction), nxengine/libretro/libretro.cpp:290 (existence check)"
source_ref: "nxengine/main.cpp:77-78 (opened for extraction), nxengine/libretro/libretro.cpp:278 (existence check)"
note: "Placed in system/nxengine/. The core extracts ORG music, PXT sounds, stage tile attributes, BMP graphics, and wavetable from this binary at each launch."
- name: "data/"
@@ -64,7 +64,7 @@ files:
system: cave-story
description: "NPC attribute table (entity behavior flags, HP, damage, display rect offsets)"
required: true
source_ref: "main.cpp:50 (existence check for data/ directory), ai/ai.cpp:56-59 (loaded for NPC properties)"
source_ref: "nxengine/main.cpp:47-53 (existence check for data/ directory), nxengine/ai/ai.cpp:56-59 (loaded for NPC properties)"
note: "Located in system/nxengine/data/. Used to validate data directory presence and to load NPC behavior attributes."
- name: "data/sprites.sif"
@@ -84,5 +84,5 @@ files:
description: "Tile attribute lookup table (maps tile codes to collision/behavior attributes)"
required: false
hle_fallback: true
source_ref: "map.cpp:290-303 (loaded at init, hardcoded default if missing)"
note: "Not part of the freeware distribution. Generated by the standalone NXEngine extraction tool. The libretro core has hardcoded defaults in map.cpp:30."
source_ref: "nxengine/map.cpp:290-303 (loaded at init, hardcoded default if missing)"
note: "Not part of the freeware distribution. Generated by the standalone NXEngine extraction tool. The libretro core has hardcoded defaults in nxengine/map.cpp:30."
+1 -1
View File
@@ -16,7 +16,7 @@ files:
required: false
description: "64DD IPL ROM"
note: "Only loaded when a 64DD disk image (.ndd) is present via subsystem API. Core fails to load disk games without it."
source_ref: "libretro/libretro.c:1021"
source_ref: "libretro/libretro.c:848"
notes:
hle_available: true
+5 -5
View File
@@ -83,7 +83,7 @@ notes: |
files:
- name: "<bios>.bin"
path: "pcsx2/bios/"
path: "pcsx2/bios/<bios>.bin"
description: "PS2 BIOS image"
min_size: 4194304
max_size: 8388608
@@ -96,7 +96,7 @@ files:
auto selection accept any size that passes the romdir check.
- name: "<bios>.rom1"
path: "pcsx2/bios/"
path: "pcsx2/bios/<bios>.rom1"
description: "DVD player ROM"
max_size: 4194304
required: false
@@ -106,7 +106,7 @@ files:
skipped with a console line when absent.
- name: "<bios>.rom2"
path: "pcsx2/bios/"
path: "pcsx2/bios/<bios>.rom2"
description: "Chinese ROM extension"
max_size: 4194304
required: false
@@ -115,7 +115,7 @@ files:
Same lookup as rom1. Present on Chinese region consoles only.
- name: "<bios>.nvm"
path: "pcsx2/bios/"
path: "pcsx2/bios/<bios>.nvm"
description: "Console NVRAM (region parameters, language, iLink ID, OSD settings)"
size: 1024
required: false
@@ -127,7 +127,7 @@ files:
on save.
- name: "<bios>.mec"
path: "pcsx2/bios/"
path: "pcsx2/bios/<bios>.mec"
description: "Mechacon version, one u32"
size: 4
required: false
+4
View File
@@ -69,6 +69,8 @@ files:
path: resources/GameIndex.yaml
required: false
bundled: true
sha1: 5e2d50a3376dc6a0750505bec68626d39a5bd4c1
size: 2683897
category: game_data
description: "per-title compatibility and fix database"
source_ref: "pcsx2/GameDatabase.cpp:39, pcsx2/GameDatabase.cpp:1026-1035"
@@ -78,6 +80,8 @@ files:
path: resources/RedumpDatabase.yaml
required: false
bundled: true
sha1: bf2c73d668cd671df8adfe2ec3c7074e8ba9176a
size: 1917242
category: game_data
description: "disc hash database"
source_ref: "pcsx2/GameDatabase.cpp:1133, pcsx2/GameDatabase.cpp:1188-1197"
+4 -4
View File
@@ -59,14 +59,14 @@ files:
# -- Fallback BIOS filenames (searched in order after scph550x) --
- name: "psxonpsp660.bin"
description: "PSP embedded PS1 BIOS (region detected at runtime)"
region: [world]
description: "PSP embedded PS1 BIOS, filed as the Japanese BIOS"
region: [japan]
size: 524288
required: false
hle_fallback: true
validation: [size]
source_ref: "frontend/libretro.c:3864-3867 (listed_bios[3])"
note: "Region detected from content at runtime. Must be 512 KB in libretro context."
source_ref: "frontend/libretro.c:3864-3867 (listed_bios[3]), frontend/libretro.c:3654-3669 (try_use_bios region guess)"
note: "The core reads the region out of the image: bytes 0x7ff51 are ' J' in this dump, so it takes the JP slot (' E' takes EU, anything else US), one image per slot, first found kept. The disc licence picks the slot at boot (Config.Bios[Config.PsxRegion]); a US or EU disc only reaches this file when its own slot is empty. Must be 512 KB."
- name: "scph101.bin"
description: "SCPH-101 (v4.4 03-24-00 A) - PSone US"
+5 -5
View File
@@ -12,7 +12,7 @@ systems:
- sega-megadrive
- sega-genesis
- sega-megacd
- sega-segacd
- sega-megacd
- sega-32x
- sega-mastersystem
- sega-gamegear
@@ -63,7 +63,7 @@ files:
# Mega CD / Sega CD - US region
# -------------------------------------------------------
- name: "us_scd2_9306.bin"
system: sega-segacd
system: sega-megacd
variant_group: "mega-cd-bios"
region: [north-america]
priority: 1
@@ -73,7 +73,7 @@ files:
source_ref: "platform/libretro/libretro.c:1273"
- name: "SegaCDBIOS9303.bin"
system: sega-segacd
system: sega-megacd
variant_group: "mega-cd-bios"
region: [north-america]
priority: 2
@@ -83,7 +83,7 @@ files:
source_ref: "platform/libretro/libretro.c:1273"
- name: "us_scd1_9210.bin"
system: sega-segacd
system: sega-megacd
variant_group: "mega-cd-bios"
region: [north-america]
priority: 3
@@ -93,7 +93,7 @@ files:
source_ref: "platform/libretro/libretro.c:1273"
- name: "bios_CD_U.bin"
system: sega-segacd
system: sega-megacd
variant_group: "mega-cd-bios"
region: [north-america]
priority: 4
+1 -1
View File
@@ -51,5 +51,5 @@ files:
md5: "72ae1b47820fcc93cc0df9c428d0face"
sha1: "5f4aed208301449c2e9514edfd325fe9dead76fa"
crc32: "a5751b99"
source_ref: "src/d_main.c:1438-1476 (PACKAGE .wad load), libretro/libretro.c:4254-4330 (I_FindFile search), src/config.h:39 (PACKAGE=prboom)"
source_ref: "src/d_main.c:1449-1465 (PACKAGE .wad load), libretro/libretro.c:4171-4252 (I_FindFile search), src/config.h:39 (PACKAGE=prboom)"
note: "Searched in system/prboom/ then system/. Falls back to internal defaults if missing, but menus and HUD may render incorrectly without it."
+6 -6
View File
@@ -68,22 +68,22 @@ files:
size: 8192
required: false
hle_fallback: true
validation: [size]
known_hash_adler32: "0x66f334fe"
validation: [size, adler32]
known_hash_adler32: ["0x66f334fe", "0xe789b5a5"]
adler32_byteswap: true
note: "DSP instruction ROM for LLE audio. Free replacement (v0.4) included"
source_ref: "Source/Core/Common/CommonPaths.h:135, Source/Core/Core/HW/DSPLLE/DSPLLE.cpp:87-117"
source_ref: "Source/Core/Common/CommonPaths.h:135, Source/Core/Core/HW/DSPLLE/DSPLLE.cpp:87-117, Source/Core/Core/DSP/DSPCore.cpp:28-102"
- name: "dsp_coef.bin"
path: "GC/dsp_coef.bin"
size: 4096
required: false
hle_fallback: true
validation: [size]
known_hash_adler32: "0xf3b93527"
validation: [size, adler32]
known_hash_adler32: ["0xf3b93527", "0xa4a575f5"]
adler32_byteswap: true
note: "DSP coefficient ROM for LLE audio. Free replacement included"
source_ref: "Source/Core/Common/CommonPaths.h:138, Source/Core/Core/DSP/DSPCore.cpp:32-38"
source_ref: "Source/Core/Common/CommonPaths.h:138, Source/Core/Core/DSP/DSPCore.cpp:32-38, Source/Core/Core/DSP/DSPCore.cpp:28-102"
# -- GameCube Fonts --
# Bundled free alternatives exist but have padding differences causing misplaced text.
+5 -5
View File
@@ -56,7 +56,7 @@ notes: |
capsimg.so/capsimg.dll is an optional shared library for IPF floppy image
support (SPS/CAPS format). Not a BIOS file, loaded dynamically at runtime.
Source: libretro/libretro-core.h:140-245, libretro/libretro-core.c:5612-5752,
Source: libretro/libretro-core.h:140-245, libretro/libretro-core.c:5609-5777,
libretro/libretro-core.c:6044-6093
files:
@@ -243,20 +243,20 @@ files:
system: commodore-amiga
required: false
note: "Amiga Forever ROM decryption key. Copied to saves/WHDLoad/Devs/Kickstarts/ for WHDLoad."
source_ref: "libretro/libretro-core.c:5969-5980"
source_ref: "libretro/libretro-core.c:5963-5978"
- name: "WHDLoad.key"
system: commodore-amiga
required: false
unsourceable: "per-user signed registration key, never distributed generically, WHDLoad free since v18.2"
note: "WHDLoad license key. Copied to saves/WHDLoad/L/ for registered WHDLoad use."
source_ref: "libretro/libretro-core.c:5985-5998"
source_ref: "libretro/libretro-core.c:5979-5994"
- name: "WHDLoad.prefs"
system: commodore-amiga
required: false
note: "WHDLoad preferences. Copied to saves/WHDLoad/S/ when present."
source_ref: "libretro/libretro-core.c:6000-6023"
source_ref: "libretro/libretro-core.c:5995-6018"
model_kickstart_map:
A500: {kickstart: "kick34005.A500", ext: null}
@@ -290,4 +290,4 @@ platform_details:
amiga_forever: "amiga-os-{version}.rom"
tosec: "Kickstart v{version} rev {rev} ({year})(Commodore)({model}).rom"
scan_prefixes: ["kick", "amiga-os", "KS ROM"]
source_ref: "libretro/libretro-core.c:2651-2678"
source_ref: "libretro/libretro-core.c:2650-2677"
+6 -6
View File
@@ -60,8 +60,8 @@ notes: |
capsimg.so/capsimg.dll is an optional shared library for IPF floppy image
support (SPS/CAPS format). Not a BIOS file, loaded dynamically at runtime.
Source: libretro/libretro-core.h:140-245, libretro/libretro-core.c:5384-5550,
libretro/libretro-core.c:5636-5795
Source: libretro/libretro-core.h:140-245, libretro/libretro-core.c:5533-5701,
libretro/libretro-core.c:5788-5879
files:
# -------------------------------------------------------
@@ -247,20 +247,20 @@ files:
system: commodore-amiga
required: false
note: "Amiga Forever ROM decryption key. Copied to saves/WHDLoad/Devs/Kickstarts/ for WHDLoad."
source_ref: "libretro/libretro-core.c:5735-5746"
source_ref: "libretro/libretro-core.c:5887-5902"
- name: "WHDLoad.key"
system: commodore-amiga
required: false
unsourceable: "per-user signed registration key, never distributed generically, WHDLoad free since v18.2"
note: "WHDLoad license key. Copied to saves/WHDLoad/L/ for registered WHDLoad use."
source_ref: "libretro/libretro-core.c:5751-5764"
source_ref: "libretro/libretro-core.c:5903-5918"
- name: "WHDLoad.prefs"
system: commodore-amiga
required: false
note: "WHDLoad preferences. Copied to saves/WHDLoad/S/ when present."
source_ref: "libretro/libretro-core.c:5768-5791"
source_ref: "libretro/libretro-core.c:5919-5942"
model_kickstart_map:
A500: {kickstart: "kick34005.A500", ext: null}
@@ -294,4 +294,4 @@ platform_details:
amiga_forever: "amiga-os-{version}.rom"
tosec: "Kickstart v{version} rev {rev} ({year})(Commodore)({model}).rom"
scan_prefixes: ["kick", "amiga-os", "KS ROM"]
source_ref: "libretro/libretro-core.c:2577-2616"
source_ref: "libretro/libretro-core.c:2629-2656"
+3 -3
View File
@@ -20,19 +20,19 @@ mode: standalone
files:
- name: "prod.keys"
required: true
path: "switch/"
path: "switch/prod.keys"
note: "Switch production keys for NCA decryption"
source_ref: "src/Ryujinx.HLE/FileSystem/VirtualFileSystem.cs:239"
- name: "title.keys"
required: false
path: "switch/"
path: "switch/title.keys"
note: "Per-title decryption keys, needed for specific game content"
source_ref: "src/Ryujinx.HLE/FileSystem/VirtualFileSystem.cs:240"
- name: "console.keys"
required: false
path: "switch/"
path: "switch/console.keys"
note: "Console-specific keys for encrypted content"
source_ref: "src/Ryujinx.HLE/FileSystem/VirtualFileSystem.cs:241"
+26 -26
View File
@@ -48,20 +48,20 @@ files:
- name: "libSceLibcInternal.sprx"
required: false
hle_fallback: true
path: "shadps4/sys_modules/"
path: "shadps4/sys_modules/libSceLibcInternal.sprx"
description: "PS4 C standard library"
source_ref: "src/core/linker.cpp:80-91"
- name: "libSceNgs2.sprx"
required: false
hle_fallback: true
path: "shadps4/sys_modules/"
path: "shadps4/sys_modules/libSceNgs2.sprx"
description: "PS4 next-generation audio system"
source_ref: "src/core/libraries/sysmodule/sysmodule_internal.cpp:217"
- name: "libSceUlt.sprx"
required: false
path: "shadps4/sys_modules/"
path: "shadps4/sys_modules/libSceUlt.sprx"
description: "PS4 user-level threading library"
note: "No HLE implementation; the module is stubbed when absent."
source_ref: "src/core/libraries/sysmodule/sysmodule_internal.cpp:218"
@@ -69,13 +69,13 @@ files:
- name: "libSceRtc.sprx"
required: false
hle_fallback: true
path: "shadps4/sys_modules/"
path: "shadps4/sys_modules/libSceRtc.sprx"
description: "PS4 real-time clock library"
source_ref: "src/core/libraries/sysmodule/sysmodule_internal.cpp:221"
- name: "libSceJpegDec.sprx"
required: false
path: "shadps4/sys_modules/"
path: "shadps4/sys_modules/libSceJpegDec.sprx"
description: "PS4 JPEG decoder"
note: "No HLE implementation; the module is stubbed when absent."
source_ref: "src/core/libraries/sysmodule/sysmodule_internal.cpp:222"
@@ -83,83 +83,83 @@ files:
- name: "libSceJpegEnc.sprx"
required: false
hle_fallback: true
path: "shadps4/sys_modules/"
path: "shadps4/sys_modules/libSceJpegEnc.sprx"
description: "PS4 JPEG encoder"
source_ref: "src/core/libraries/sysmodule/sysmodule_internal.cpp:223"
- name: "libScePngEnc.sprx"
required: false
hle_fallback: true
path: "shadps4/sys_modules/"
path: "shadps4/sys_modules/libScePngEnc.sprx"
description: "PS4 PNG encoder"
source_ref: "src/core/libraries/sysmodule/sysmodule_internal.cpp:225"
- name: "libSceJson.sprx"
required: false
path: "shadps4/sys_modules/"
path: "shadps4/sys_modules/libSceJson.sprx"
description: "PS4 JSON parser"
note: "No HLE implementation; the module is stubbed when absent."
source_ref: "src/core/libraries/sysmodule/sysmodule_internal.cpp:226"
- name: "libSceJson2.sprx"
required: false
path: "shadps4/sys_modules/"
path: "shadps4/sys_modules/libSceJson2.sprx"
description: "PS4 JSON v2 parser"
note: "No HLE implementation; the module is stubbed when absent."
source_ref: "src/core/libraries/sysmodule/sysmodule_internal.cpp:227"
- name: "libSceCesCs.sprx"
required: false
path: "shadps4/sys_modules/"
path: "shadps4/sys_modules/libSceCesCs.sprx"
description: "PS4 character encoding conversion"
note: "No HLE implementation; the module is stubbed when absent."
source_ref: "src/core/libraries/sysmodule/sysmodule_internal.cpp:228"
- name: "libSceAt9Enc.sprx"
required: false
path: "shadps4/sys_modules/"
path: "shadps4/sys_modules/libSceAt9Enc.sprx"
description: "PS4 ATRAC9 encoder"
note: "No HLE implementation; the module is stubbed when absent."
source_ref: "src/core/libraries/sysmodule/sysmodule_internal.cpp:229"
- name: "libSceAudiodec.sprx"
required: false
path: "shadps4/sys_modules/"
path: "shadps4/sys_modules/libSceAudiodec.sprx"
description: "PS4 audio decoder"
note: "No HLE implementation; the module is stubbed when absent."
source_ref: "src/core/libraries/sysmodule/sysmodule_internal.cpp:230"
- name: "libSceAudiodecCpu.sprx"
required: false
path: "shadps4/sys_modules/"
path: "shadps4/sys_modules/libSceAudiodecCpu.sprx"
description: "PS4 CPU audio decoder"
note: "No HLE implementation; the module is stubbed when absent."
source_ref: "src/core/libraries/sysmodule/sysmodule_internal.cpp:231"
- name: "libSceAudiodecCpuDdp.sprx"
required: false
path: "shadps4/sys_modules/"
path: "shadps4/sys_modules/libSceAudiodecCpuDdp.sprx"
description: "PS4 CPU Dolby Digital Plus decoder"
note: "No HLE implementation; the module is stubbed when absent."
source_ref: "src/core/libraries/sysmodule/sysmodule_internal.cpp:232"
- name: "libSceAudiodecCpuM4aac.sprx"
required: false
path: "shadps4/sys_modules/"
path: "shadps4/sys_modules/libSceAudiodecCpuM4aac.sprx"
description: "PS4 CPU AAC decoder"
note: "No HLE implementation; the module is stubbed when absent."
source_ref: "src/core/libraries/sysmodule/sysmodule_internal.cpp:233"
- name: "libSceAudiodecCpuDtsHdLbr.sprx"
required: false
path: "shadps4/sys_modules/"
path: "shadps4/sys_modules/libSceAudiodecCpuDtsHdLbr.sprx"
description: "PS4 CPU DTS-HD LBR decoder"
note: "No HLE implementation; the module is stubbed when absent."
source_ref: "src/core/libraries/sysmodule/sysmodule_internal.cpp:234"
- name: "libSceAudiodecCpuHevag.sprx"
required: false
path: "shadps4/sys_modules/"
path: "shadps4/sys_modules/libSceAudiodecCpuHevag.sprx"
description: "PS4 CPU HEVAG decoder"
note: "No HLE implementation; the module is stubbed when absent."
source_ref: "src/core/libraries/sysmodule/sysmodule_internal.cpp:235"
@@ -167,34 +167,34 @@ files:
- name: "libSceFont.sprx"
required: false
hle_fallback: true
path: "shadps4/sys_modules/"
path: "shadps4/sys_modules/libSceFont.sprx"
description: "PS4 font rendering library"
source_ref: "src/core/libraries/sysmodule/sysmodule_internal.cpp:236"
- name: "libSceFontFt.sprx"
required: false
hle_fallback: true
path: "shadps4/sys_modules/"
path: "shadps4/sys_modules/libSceFontFt.sprx"
description: "PS4 FreeType font library"
source_ref: "src/core/libraries/sysmodule/sysmodule_internal.cpp:237"
- name: "libSceFreeTypeOt.sprx"
required: false
path: "shadps4/sys_modules/"
path: "shadps4/sys_modules/libSceFreeTypeOt.sprx"
description: "PS4 FreeType OpenType library"
note: "No HLE implementation; the module is stubbed when absent."
source_ref: "src/core/libraries/sysmodule/sysmodule_internal.cpp:238"
- name: "libSceFreeTypeOl.sprx"
required: false
path: "shadps4/sys_modules/"
path: "shadps4/sys_modules/libSceFreeTypeOl.sprx"
description: "PS4 FreeType outline library"
note: "No HLE implementation; the module is stubbed when absent."
source_ref: "src/core/libraries/sysmodule/sysmodule_internal.cpp:239"
- name: "libSceFreeTypeOptOl.sprx"
required: false
path: "shadps4/sys_modules/"
path: "shadps4/sys_modules/libSceFreeTypeOptOl.sprx"
description: "PS4 FreeType optimised outline library"
note: "No HLE implementation; the module is stubbed when absent."
source_ref: "src/core/libraries/sysmodule/sysmodule_internal.cpp:240"
@@ -202,13 +202,13 @@ files:
- name: "libSceRudp.sprx"
required: false
hle_fallback: true
path: "shadps4/sys_modules/"
path: "shadps4/sys_modules/libSceRudp.sprx"
description: "PS4 reliable UDP library"
source_ref: "src/core/libraries/sysmodule/sysmodule_internal.cpp:243"
- name: "libSceWkFontConfig.sprx"
required: false
path: "shadps4/sys_modules/"
path: "shadps4/sys_modules/libSceWkFontConfig.sprx"
description: "PS4 WebKit font configuration"
note: "No HLE implementation; the module is stubbed when absent."
source_ref: "src/core/libraries/sysmodule/sysmodule_internal.cpp:244"
@@ -216,13 +216,13 @@ files:
- name: "libSceSystemGesture.sprx"
required: false
hle_fallback: true
path: "shadps4/sys_modules/"
path: "shadps4/sys_modules/libSceSystemGesture.sprx"
description: "PS4 system gesture recognition"
source_ref: "src/core/libraries/sysmodule/sysmodule_internal.cpp:249"
- name: "libSceXml.sprx"
required: false
path: "shadps4/sys_modules/"
path: "shadps4/sys_modules/libSceXml.sprx"
description: "PS4 XML parser"
note: "No HLE implementation; the module is stubbed when absent."
source_ref: "src/core/libraries/sysmodule/sysmodule_internal.cpp:250"
+4 -4
View File
@@ -25,25 +25,25 @@ mode: standalone
files:
- name: "prod.keys"
required: true
path: "switch/"
path: "switch/prod.keys"
note: "Production keys for NCA decryption (master, key area, header, titlekek)"
source_ref: "src/core/crypto/key_manager.cpp:654"
- name: "title.keys"
required: false
path: "switch/"
path: "switch/title.keys"
note: "Per-title encryption keys (rights_id to titlekey mappings)"
source_ref: "src/core/crypto/key_manager.cpp:657"
- name: "console.keys"
required: false
path: "switch/"
path: "switch/console.keys"
note: "Console-specific keys (BIS, SD seed)"
source_ref: "src/core/crypto/key_manager.cpp:658"
- name: "key_retail.bin"
required: false
path: "switch/"
path: "switch/key_retail.bin"
size: 160
note: "Amiibo decryption keys (two InternalKey structs, 0x50 bytes each)"
source_ref: "src/core/hle/service/nfc/common/amiibo_crypto.cpp:273-294"
+6 -6
View File
@@ -227,12 +227,12 @@ files:
path: "GC/dsp_rom.bin"
description: "DSP instruction ROM"
size: 8192
validation: [size]
known_hash_adler32: "0x66f334fe"
validation: [size, adler32]
known_hash_adler32: ["0x66f334fe", "0xe789b5a5"]
adler32_byteswap: true
required: false
hle_fallback: true
source_ref: "Source/Core/Common/CommonPaths.h:145, Source/Core/Core/HW/DSPLLE/DSPLLE.cpp:87-105,109-118, Source/Core/Core/DSP/DSPCore.h:44, Source/Core/Core/DSP/DSPCore.cpp:36-38"
source_ref: "Source/Core/Common/CommonPaths.h:145, Source/Core/Core/HW/DSPLLE/DSPLLE.cpp:87-105,109-118, Source/Core/Core/DSP/DSPCore.h:44, Source/Core/Core/DSP/DSPCore.cpp:36-38, Source/Core/Core/DSP/DSPCore.cpp:28-102"
note: >
LoadDSPRom rejects any file whose length differs from DSP_IROM_BYTE_SIZE and
swaps every 16 bit word before storing it, so the Adler32 in the source is
@@ -245,12 +245,12 @@ files:
path: "GC/dsp_coef.bin"
description: "DSP coefficient ROM"
size: 4096
validation: [size]
known_hash_adler32: "0xf3b93527"
validation: [size, adler32]
known_hash_adler32: ["0xf3b93527", "0xa4a575f5"]
adler32_byteswap: true
required: false
hle_fallback: true
source_ref: "Source/Core/Common/CommonPaths.h:146, Source/Core/Core/HW/DSPLLE/DSPLLE.cpp:87-105,110-119, Source/Core/Core/DSP/DSPCore.h:58, Source/Core/Core/HW/DSPHLE/UCodes/AX.cpp:61-62"
source_ref: "Source/Core/Common/CommonPaths.h:146, Source/Core/Core/HW/DSPLLE/DSPLLE.cpp:87-105,110-119, Source/Core/Core/DSP/DSPCore.h:58, Source/Core/Core/HW/DSPHLE/UCodes/AX.cpp:61-62, Source/Core/Core/DSP/DSPCore.cpp:28-102"
note: >
Also read by the HLE AX ucode for polyphase resampling. Adler32 is taken over
the byte-swapped data (Source/Core/Core/HW/DSPLLE/DSPLLE.cpp:100-102).
+5 -5
View File
@@ -74,7 +74,7 @@ notes: |
Source: retrodep/embedded/*.c (embedded ROM tables),
vice/src/*/rom.h (ROM name defines), vice/src/drive/driverom.h (drive ROMs),
retrodep/ui.c:274-315 (JiffyDOS loading), retrodep/ui.c:258-271 (SCPU kernal),
libretro/libretro-core.c:2807-2872 (core options for JiffyDOS/SCPU)
libretro/libretro-core.c:2806-2871 (core options for JiffyDOS/SCPU)
files:
# -------------------------------------------------------
@@ -1082,7 +1082,7 @@ files:
hle_fallback: true
embedded: false
note: "SuperCPU DOS v1.40 external kernal. Optional, selected via core option. Goes in system/vice/SCPU64/."
source_ref: "retrodep/ui.c:266, libretro/libretro-core.c:2832"
source_ref: "retrodep/ui.c:266, libretro/libretro-core.c:2830"
- name: "vice/SCPU64/scpu-dos-2.04.bin"
system: commodore-c64
@@ -1090,7 +1090,7 @@ files:
hle_fallback: true
embedded: false
note: "SuperCPU DOS v2.04 external kernal. Optional, selected via core option. Goes in system/vice/SCPU64/."
source_ref: "retrodep/ui.c:263, libretro/libretro-core.c:2834"
source_ref: "retrodep/ui.c:263, libretro/libretro-core.c:2831"
# -------------------------------------------------------
# Drive ROMs (shared across all cores with True Drive Emulation)
@@ -1274,7 +1274,7 @@ files:
hle_fallback: true
embedded: false
note: "JiffyDOS C64 kernal replacement. Optional, proprietary. Requires True Drive Emulation + 1541/1571/1581 drive."
source_ref: "retrodep/ui.c:302, libretro/libretro-core.c:2862"
source_ref: "retrodep/ui.c:302, libretro/libretro-core.c:2859"
- name: "vice/JiffyDOS_SX-64.bin"
system: commodore-c64
@@ -1290,7 +1290,7 @@ files:
hle_fallback: true
embedded: false
note: "JiffyDOS C128 kernal replacement. Optional, proprietary. C128 core only."
source_ref: "retrodep/ui.c:309, libretro/libretro-core.c:2864"
source_ref: "retrodep/ui.c:309, libretro/libretro-core.c:2861"
- name: "vice/JiffyDOS_1541-II.bin"
system: commodore-c64
+4 -3
View File
@@ -112,10 +112,11 @@ files:
required: false
size: 131072
validation: [size]
aliases:
- boot.rom
sha1: "af643900fea84234e08b616a6d27f03f0a61db96"
md5: "6e844759720226e58d55ecaf33608a13"
crc32: "ae25bdf5"
description: "Model-M cart boot ROM, read when the BIOS type is Model M"
source_ref: "libretro.c:5358-5380"
source_ref: "libretro.c:5358-5380, src/bios/jagbios_m.c:9"
note: >-
Read from the system directory only, as jagboot_m.rom, and only when
biosType is BT_M_SERIES. A short read falls back to the embedded
+4 -4
View File
@@ -26,25 +26,25 @@ mode: standalone
files:
- name: "prod.keys"
required: true
path: "switch/"
path: "switch/prod.keys"
note: "Production keys for NCA decryption (master, key area, header, titlekek)"
source_ref: "src/core/crypto/key_manager.cpp:655-656"
- name: "title.keys"
required: false
path: "switch/"
path: "switch/title.keys"
note: "Per-title encryption keys (rights_id to titlekey mappings)"
source_ref: "src/core/crypto/key_manager.cpp:659-660"
- name: "console.keys"
required: false
path: "switch/"
path: "switch/console.keys"
note: "Console-specific keys (BIS, SD seed)"
source_ref: "src/core/crypto/key_manager.cpp:661-662"
- name: "key_retail.bin"
required: false
path: "switch/"
path: "switch/key_retail.bin"
size: 160
note: "Amiibo decryption keys (two InternalKey structs, 0x50 bytes each)"
source_ref: "src/core/hle/service/nfc/common/amiibo_crypto.cpp:273-294"
+109
View File
@@ -90,6 +90,7 @@ files:
# ============================================================
- name: "48.rom"
sha1: "5ea7c2b824672e914525d1d5c419d71b84a426a2"
size: 16384
validation: [size]
required: true
@@ -100,6 +101,7 @@ files:
note: "48K BASIC. Also loaded four times over as the TBBlue fast-boot image (src/cpu.c:3653-3662)."
- name: "48es.rom"
sha1: "9e535e2e24231ccb65e33d107f6d0ceb23e99477"
size: 16384
validation: [size]
required: true
@@ -109,6 +111,7 @@ files:
note: "Spanish 48K+ ROM, selected for MACHINE_ID_SPECTRUM_48_PLUS_SPA."
- name: "inves.rom"
sha1: "d020440638aff4d39467128413ef795677be9c23"
size: 16384
validation: [size]
required: true
@@ -118,6 +121,7 @@ files:
note: "Investronica Inves Spectrum+. Loaded at memoria_spectrum[65536] (src/cpu.c:3551-3557)."
- name: "128.rom"
sha1: "16375d42ea109b47edded7a16028de7fdb3013a1"
size: 32768
validation: [size]
required: true
@@ -126,6 +130,7 @@ files:
source_ref: "src/cpu.c:3312-3314, src/utils.c:4100"
- name: "128s.rom"
sha1: "57c0b6681224378ce1d279fde13d644478423783"
size: 32768
validation: [size]
required: true
@@ -134,6 +139,7 @@ files:
source_ref: "src/cpu.c:3316-3318, src/utils.c:4100"
- name: "p2.rom"
sha1: "8cafb292af58617907b9e6b9093d3588a75849b8"
size: 32768
validation: [size]
required: true
@@ -143,6 +149,7 @@ files:
note: "ZX Spectrum +2."
- name: "p2f.rom"
sha1: "8a5be00921afd4e2c74059c217b31b9fb51c3d41"
size: 32768
validation: [size]
required: true
@@ -151,6 +158,7 @@ files:
source_ref: "src/cpu.c:3327-3329, src/utils.c:4100"
- name: "p2s.rom"
sha1: "baca5d798b3e786078feded19486d9fc29dbd4b7"
size: 32768
validation: [size]
required: true
@@ -159,6 +167,7 @@ files:
source_ref: "src/cpu.c:3331-3333, src/utils.c:4100"
- name: "p2a40.rom"
sha1: "929bf1a5e5687ebd8d7245f9b513a596c0ec21a4"
size: 65536
validation: [size]
required: true
@@ -168,6 +177,7 @@ files:
note: "+2A/+3 ROM v4.0."
- name: "p2a41.rom"
sha1: "500c0945760abeefcbd08bc22c0d07b14b336cf0"
size: 65536
validation: [size]
required: true
@@ -177,6 +187,7 @@ files:
note: "+2A/+3 ROM v4.1."
- name: "p2as.rom"
sha1: "a4b311135ccbe010318dcb872dae2c8f078c7447"
size: 65536
validation: [size]
required: true
@@ -185,6 +196,7 @@ files:
source_ref: "src/cpu.c:3347-3350, src/utils.c:4102"
- name: "pentagon.rom"
sha1: "a584272f21dc82c14b7d4f1ed440e23a976e71f0"
size: 32768
validation: [size]
required: true
@@ -193,6 +205,7 @@ files:
source_ref: "src/cpu.c:3381-3383, src/utils.c:4100 (MACHINE_IS_SPECTRUM_128_P2 covers Pentagon, src/cpu.h:545)"
- name: "se.rom"
sha1: "14321f2092b8af21b52b35c1518d9a753d6618d4"
size: 32768
validation: [size]
required: true
@@ -202,6 +215,7 @@ files:
note: "Chloe 140SE/280SE, SE Basic IV."
- name: "chrome.rom"
sha1: "fb305656769765224c58ca02445d4bf041891d18"
size: 65536
validation: [size]
required: true
@@ -210,6 +224,7 @@ files:
source_ref: "src/cpu.c:3406-3408, src/utils.c:4112"
- name: "prism.rom"
sha1: "6e03d87f868c40d5662ef6906931c77ba1b8b2c2"
size: 327680
validation: [size]
required: true
@@ -219,6 +234,7 @@ files:
note: "20 pages of 16K. Page map documented at src/cpu.c:3622-3638."
- name: "prism_failsafe.rom"
sha1: "d020440638aff4d39467128413ef795677be9c23"
size: 16384
validation: [size]
required: true
@@ -228,6 +244,7 @@ files:
note: "Loaded straight after prism.rom by prism_load_failsafe_rom(). The only ROM whose absence is fatal: the loader calls cpu_panic both when the file is missing and when the read is not 16384 bytes."
- name: "zxuno_bootloader.rom"
sha1: "0afcb798128e6587e7ea0787714568f7b68be012"
size: 8126
required: true
bundled: true
@@ -236,6 +253,7 @@ files:
size_note: "Read caps at 8192 bytes and only errors when fewer than 1 byte is read, so no exact size check. get_rom_size returns 214 for ZX-Uno (src/utils.c:4104) but that value is unused on this path."
- name: "zxevo_tsconf.rom"
sha1: "2551026b7d63a2627f79701e26688a7d715dc96a"
size: 524288
validation: [size]
required: true
@@ -244,6 +262,7 @@ files:
source_ref: "src/cpu.c:3410-3412, src/utils.c:4114"
- name: "zxevo_baseconf.rom"
sha1: "1570048704f11dc239060ee4f63190d199c94987"
size: 524288
validation: [size]
required: true
@@ -257,6 +276,7 @@ files:
# ============================================================
- name: "tbblue_loader.rom"
sha1: "8b2e927d0523bc27bffcc34c39527ab0d2362e0c"
size: 8192
validation: [size]
required: true
@@ -266,6 +286,7 @@ files:
note: "FPGA loader, mirrored to 16K at src/cpu.c:3665. Bypassed when --tbblue-fast-boot-mode selects 48.rom instead."
- name: "tbblue.mmc"
sha1: "e838e1d63dc9c1e518a79195c9512042dffb765f"
size: 67108864
required: false
bundled: true
@@ -279,6 +300,7 @@ files:
# ============================================================
- name: "tk90x.rom"
sha1: "9a943a008be13194fb006bddffa7d22d2277813f"
size: 16384
validation: [size]
required: true
@@ -287,6 +309,7 @@ files:
source_ref: "src/cpu.c:3294-3296, src/utils.c:4098"
- name: "tk90xs.rom"
sha1: "a9421b9e3a17689b7392da1f72dc71dd46e09ab1"
size: 16384
validation: [size]
required: true
@@ -295,6 +318,7 @@ files:
source_ref: "src/cpu.c:3298-3300, src/utils.c:4098"
- name: "tk95.rom"
sha1: "94edc401d43b0e9a9cdc1d35de4b6462dc414ab3"
size: 16384
validation: [size]
required: true
@@ -303,6 +327,7 @@ files:
source_ref: "src/cpu.c:3302-3304, src/utils.c:4098"
- name: "tk95es.rom"
sha1: "54f3445374d1758a3133232672e8783cb4fc7a32"
size: 16384
validation: [size]
required: true
@@ -315,6 +340,7 @@ files:
# ============================================================
- name: "tc2048.rom"
sha1: "febb2d495b6eda7cdcb4074935d6e9d9f328972d"
size: 16384
validation: [size]
required: true
@@ -323,6 +349,7 @@ files:
source_ref: "src/cpu.c:3418-3420, src/utils.c:4098 (TC2048 falls under MACHINE_IS_SPECTRUM_16_48, src/cpu.h:543)"
- name: "ts2068.rom"
sha1: "34cd8113bf75b65a4da6eea355f9d46ad635f7e4"
size: 24576
validation: [size]
required: true
@@ -332,6 +359,7 @@ files:
note: "Read as two blocks: 16384 into the main ROM table, then 8192 into the EX ROM table. Serves TS2068 and TC2068."
- name: "ts1500.rom"
sha1: "3eb437359221b4406d236085ec66fa02278e7495"
size: 8192
validation: [size]
required: true
@@ -344,6 +372,7 @@ files:
# ============================================================
- name: "zx80.rom"
sha1: "b6769a3197c77009e0933e038c15b43cf4c98c7a"
size: [4096, 8192]
validation: [size]
required: true
@@ -353,6 +382,7 @@ files:
note: "Serves ZX80, TK80 and TK82. An 8192-byte file is accepted as-is so the ZX81 ROM can run on a ZX80 (src/cpu.c:3758)."
- name: "zx81.rom"
sha1: "7b143ee964e9ada89d1f9e88f0bd48d919184cfc"
size: 8192
validation: [size]
required: true
@@ -362,6 +392,7 @@ files:
note: "Serves ZX81, Timex TS1000, TK82C, TK83 and the Czerweny CZ 1000/1500 models."
- name: "tk85.rom"
sha1: "7b961a1733fc047eb682150a32e17bca10a018d2"
size: 10240
validation: [size]
required: true
@@ -371,6 +402,7 @@ files:
note: "The TK85 test precedes the generic ZX81 test in get_rom_size, so 10240 wins over 8192."
- name: "zxpand_zx81.rom"
sha1: "3bdbf55720cf9623431a4d4017fa8f165aac4a66"
size: 8192
validation: [size]
required: false
@@ -380,6 +412,7 @@ files:
note: "ZXpand interface firmware. A short read disables ZXpand emulation."
- name: "zxpand_zx80.rom"
sha1: "8968261beab240e8a06e8cfe9e070987d860064b"
size: 8192
validation: [size]
required: false
@@ -388,6 +421,7 @@ files:
source_ref: "src/storage/zxpand.c:72, src/storage/zxpand.c:240, src/storage/zxpand.c:246-254"
- name: "ace.rom"
sha1: "597ba8a15a292688333c84dc9fd35172abe5e7e6"
size: 8192
validation: [size]
required: true
@@ -400,6 +434,7 @@ files:
# ============================================================
- name: "ql_js.rom"
sha1: "6e1e3cae275d0cd58977258c0b13480c8e910138"
size: 49152
min_size: 16384
validation: [size]
@@ -410,6 +445,7 @@ files:
size_note: "Reads up to 131072 bytes and errors only below 16384, so the check is a minimum rather than an exact size."
- name: "ql_jm.rom"
sha1: "6a8468dcdb27dc1b194febba8c957c4ef4313538"
size: 49152
required: false
bundled: true
@@ -418,6 +454,7 @@ files:
note: "JM release. Reachable through --romfile; the switch selects ql_js.rom."
- name: "tkii220.rom"
sha1: "f364472a81352479290e388e9a5afb57a0de8249"
size: 16384
required: false
bundled: true
@@ -426,6 +463,7 @@ files:
note: "QJUMP Toolkit II 2.20, the ROM ql.c names as the example for --ql-rom-c000-file. ql_load_extra_roms() runs after the system ROM and reads 16K into memoria_ql at 0xC000 from the path the option gives; the read count is not checked."
- name: "qsound_V1.94.rom"
sha1: "622a81dce98524148f067780c17eddbaf46e27f6"
aliases: ["Qsound_V1.94.rom"]
size: 8192
required: false
@@ -435,6 +473,7 @@ files:
note: "QL Qsound firmware, read into memoria_ql at 0xC0000 once --ql-qsound-enabled is set; the read count is not checked and --ql-qsound-rom points the loader at another file. QSOUND_ROM_FILE is spelled qsound_V1.94.rom while the shipped file is Qsound_V1.94.rom, so the default only resolves on a case-insensitive filesystem."
- name: "Z88OZ47.rom"
sha1: "35e528e81d8f4e5860adf4160a3da0926525c8fa"
size: 524288
required: true
bundled: true
@@ -443,6 +482,7 @@ files:
size_note: "Reads up to 512K and errors only when nothing is read; z88_internal_rom_size is derived from the byte count, so any size is accepted."
- name: "mk14.rom"
sha1: "802dc637ce5391a2a6627f76f919b12a869b56ef"
size: 512
validation: [size]
required: true
@@ -455,6 +495,7 @@ files:
# ============================================================
- name: "cpc464.rom"
sha1: "56d39c463da60968d93e58b4ba0e675829412a20"
size: 32768
validation: [size]
required: true
@@ -464,6 +505,7 @@ files:
note: "Serves CPC 464 and CPC 4128."
- name: "cpc664.rom"
sha1: "4a38f7f5bf7fd0a95cf882433c69e67251a46868"
size: 49152
validation: [size]
required: true
@@ -472,6 +514,7 @@ files:
source_ref: "src/cpu.c:3476-3478, src/utils.c:4142"
- name: "cpc6128.rom"
sha1: "29dd0487dc5a96cd00966d074de8700ddd4ee18b"
size: 49152
validation: [size]
required: true
@@ -480,6 +523,7 @@ files:
source_ref: "src/cpu.c:3480-3482, src/utils.c:4142"
- name: "pcw_boot.rom"
sha1: "245a173cfc7976a4cae8d255f3d1422aeaf5f09a"
size: 275
validation: [size]
required: true
@@ -489,6 +533,7 @@ files:
note: "Boot block the PCW pulls into RAM rather than a mapped ROM (src/cpu.c:3849). Serves PCW 8256 and 8512."
- name: "pcw_8x_boot1.dsk"
sha1: "3be724b3bfa01d03931463b8501ffb5c3f3621b7"
size: 194864
required: false
bundled: true
@@ -497,6 +542,7 @@ files:
note: "LocoScript boot disc, inserted by pcw_boot_locoscript()."
- name: "pcw_8x_boot2.dsk"
sha1: "4c13bba076897076322b375e34f87306640cf0d6"
size: 194864
required: false
bundled: true
@@ -509,6 +555,7 @@ files:
# ============================================================
- name: "samcoupe.rom"
sha1: "c86601633fb61a8c517f7657aad9af4e6870f2ee"
size: 32768
validation: [size]
required: true
@@ -517,6 +564,7 @@ files:
source_ref: "src/cpu.c:3484-3487, src/utils.c:4144"
- name: "atomlite.rom"
sha1: "b2303b7200f5a17b54b841af9f0604db7bbdd1ab"
size: 32768
validation: [size]
required: false
@@ -526,6 +574,7 @@ files:
note: "Replaces samcoupe.rom when Atom Lite emulation is on."
- name: "samram.rom"
sha1: "acac00b8b342d19ce9bb35a8744a9c0060d5eedd"
size: 32768
validation: [size]
required: false
@@ -535,6 +584,7 @@ files:
note: "SamRam interface firmware, opened from a path the user selects."
- name: "samram_eng.rom"
sha1: "5344ee16523862fa66e9397d1f8cfa2b2cbaf341"
size: 32768
validation: [size]
required: false
@@ -548,6 +598,7 @@ files:
# ============================================================
- name: "coleco.rom"
sha1: "99ba9be24ada3e86e5c17aeecb7a2d68c5edfe59"
size: 8192
validation: [size]
required: true
@@ -556,6 +607,7 @@ files:
source_ref: "src/cpu.c:3385-3387, src/utils.c:4120"
- name: "sg1000.rom"
sha1: "fdea3168fda81e5f25f7dee3a7231192a492836e"
size: 155
required: true
bundled: true
@@ -564,6 +616,7 @@ files:
size_note: "Nothing is read from this file. The SG-1000 branch is empty and the source comment states the file only has to exist for the open to succeed."
- name: "sms.rom"
sha1: "c315672807d8ddb8d91443729405c766dd95cae7"
size: 8192
validation: [size]
required: true
@@ -572,6 +625,7 @@ files:
source_ref: "src/cpu.c:3393-3395, src/utils.c:4124"
- name: "msx.rom"
sha1: "e998f0c441f4f1800ef44e42cd1659150206cf79"
size: 32768
validation: [size]
required: true
@@ -580,6 +634,7 @@ files:
source_ref: "src/cpu.c:3397-3399, src/utils.c:4126"
- name: "svi.rom"
sha1: "7d8daf52f78371ca2c9443e04827c8e1f98c8f2c"
size: 32768
validation: [size]
required: true
@@ -593,6 +648,7 @@ files:
# ============================================================
- name: "esxmmc085.rom"
sha1: "aa4c31dc9b08d80d0107b580d5a9216d23214776"
size: 8192
validation: [size]
required: false
@@ -602,6 +658,7 @@ files:
note: "divMMC esxdos firmware, the default when --divmmc-rom is unset. Needed by --enable-esxdos-handler, which the ES-DE zxnext command line sets."
- name: "esxide085.rom"
sha1: "178bae9e9209c43282e12c09884562e4ddf07e68"
size: 8192
validation: [size]
required: false
@@ -611,6 +668,7 @@ files:
note: "divIDE esxdos firmware, the default when --divide-rom is unset."
- name: "unodos3.rom"
sha1: "cdb90bd05b073ec7a5f875444e29ab0f6bcee9ac"
size: 8192
validation: [size]
required: false
@@ -620,6 +678,7 @@ files:
note: "divMMC firmware substituted for esxmmc085.rom on Chloe machines."
- name: "trdos.rom"
sha1: "0a74bd34538a03d0e1d214b425d95c14ad10c8c4"
size: 16384
validation: [size]
required: false
@@ -629,6 +688,7 @@ files:
note: "Beta Disk / TR-DOS firmware."
- name: "if1-v1.rom"
sha1: "4ffd9ed9c00cdc6f92ce69fdd8b618ef1203f48e"
size: [8192, 16384]
validation: [size]
required: false
@@ -638,6 +698,7 @@ files:
note: "Interface 1 firmware version 1, selected when if1_rom_version is 1. The load accepts 8192 or 16384 bytes and disables Interface 1 emulation otherwise."
- name: "if1-v2.rom"
sha1: "5cfb6bca4177c45fefd571734576b55e3a127c08"
size: [8192, 16384]
validation: [size]
required: false
@@ -647,6 +708,7 @@ files:
note: "Interface 1 firmware version 2, the default branch of if1_return_rom_name()."
- name: "hilow_datadrive.rom"
sha1: "fd3f165860c2564847805cfa7a7f769a627a687c"
size: 8192
validation: [size]
required: false
@@ -656,6 +718,7 @@ files:
note: "HiLow Data Drive firmware."
- name: "zxmmcplus.flash"
sha1: "9f0697c261c37e92bf2e488e3db223443c341b9d"
size: 1048576
validation: [size]
required: false
@@ -666,6 +729,7 @@ files:
size_note: "The image holds ROM and RAM together, so the check is ZXMMCPLUS_FLASHROM_SIZE + ZXMMCPLUS_RAM_SIZE, not the 512K ROM constant alone."
- name: "zxuno.flash"
sha1: "bb6740f15b5ed8d1d60f7f61f0737f769215ca57"
size: 4194304
validation: [size]
required: false
@@ -679,6 +743,7 @@ files:
# ============================================================
- name: "mf1.rom"
sha1: "ba28754a3cc31a4ca579829ed4310c313409cf5d"
size: 8192
validation: [size]
required: false
@@ -688,6 +753,7 @@ files:
note: "Multiface One. The file selector rejects anything that is not exactly 8 KB."
- name: "mf128.rom"
sha1: "f03f4ecbcf4a654f4775d16bda0d4cc47f884379"
size: 8192
validation: [size]
required: false
@@ -697,6 +763,7 @@ files:
note: "Multiface 128."
- name: "mf3.rom"
sha1: "5d74d2e2e5a537639da92ff120f8a6d86f474495"
size: 8192
validation: [size]
required: false
@@ -706,6 +773,7 @@ files:
note: "Multiface 3."
- name: "specmate.rom"
sha1: "c8f128610eeb5142d4d80f28e5dd07b7a5ab6b84"
size: 8192
validation: [size]
required: false
@@ -714,6 +782,7 @@ files:
source_ref: "src/copy_interfaces/specmate.h:27, src/copy_interfaces/specmate.h:29, src/copy_interfaces/specmate.c:189-205"
- name: "phoenix3.rom"
sha1: "d4f01500e0383a1cf34683fb30d96230c14c7da3"
size: 16384
validation: [size]
required: false
@@ -722,6 +791,7 @@ files:
source_ref: "src/copy_interfaces/phoenix.h:27, src/copy_interfaces/phoenix.h:29, src/copy_interfaces/phoenix.c:142"
- name: "defcon.rom"
sha1: "4c7d702e295a3383326606b805eab74affc501ba"
size: 16384
validation: [size]
required: false
@@ -730,6 +800,7 @@ files:
source_ref: "src/copy_interfaces/defcon.h:27, src/copy_interfaces/defcon.h:29, src/copy_interfaces/defcon.c:139"
- name: "dinamid3.rom"
sha1: "9ee4ca7abee12ba6fb34aede2185f6aa3cb2800b"
size: 2048
validation: [size]
required: false
@@ -738,6 +809,7 @@ files:
source_ref: "src/copy_interfaces/dinamid3.h:27, src/copy_interfaces/dinamid3.h:29, src/copy_interfaces/dinamid3.c:142"
- name: "interface007.rom"
sha1: "81af60ecd412854069227487417eb80b6c89934d"
size: 2048
validation: [size]
required: false
@@ -746,6 +818,7 @@ files:
source_ref: "src/copy_interfaces/interface007.h:27, src/copy_interfaces/interface007.h:29, src/copy_interfaces/interface007.c:143"
- name: "ramjet2.rom"
sha1: "a3852ee24ab57e0e1d800c9d99cd244f7363449b"
size: 16384
validation: [size]
required: false
@@ -754,6 +827,7 @@ files:
source_ref: "src/copy_interfaces/ramjet.h:27, src/copy_interfaces/ramjet.h:28-30, src/copy_interfaces/ramjet.c:165"
- name: "ramjet3.rom"
sha1: "362589adb01ebbf006a162e76062921c03ceb26e"
size: 16384
validation: [size]
required: false
@@ -762,6 +836,7 @@ files:
source_ref: "src/copy_interfaces/ramjet.h:28, src/copy_interfaces/ramjet.c:165"
- name: "transtape2.rom"
sha1: "45d3e32d58b1c405b75ee72d80153dd0305bbd9d"
size: 16384
validation: [size]
required: false
@@ -771,6 +846,7 @@ files:
note: "Selected when transtape_version is 2."
- name: "transtape3-vC.rom"
sha1: "b7ec72fa0a55243a53c55d649e0555acea25d0c1"
size: 16384
validation: [size]
required: false
@@ -780,6 +856,7 @@ files:
note: "Default for Transtape version 3."
- name: "transtape3-vA.rom"
sha1: "c627527551e441a000184565a72df8ff37fce891"
size: 16384
validation: [size]
required: false
@@ -789,6 +866,7 @@ files:
note: "Revision A, reached through the user-set transtape_rom_filename and loaded by the same size-checked path as the defaults."
- name: "transtape3-vB.rom"
sha1: "82bf848bac698d1ffd9ca809c4293f004152645a"
size: 16384
validation: [size]
required: false
@@ -798,6 +876,7 @@ files:
note: "Revision B, reached through the user-set transtape_rom_filename."
- name: "hilow_barbanegra.rom"
sha1: "3b3862943758ad35f340537b742ca25a8286267a"
size: 8192
validation: [size]
required: false
@@ -806,6 +885,7 @@ files:
source_ref: "src/copy_interfaces/hilow_barbanegra.h:27, src/copy_interfaces/hilow_barbanegra.h:30, src/copy_interfaces/hilow_barbanegra.c:282"
- name: "mhpokeador.rom"
sha1: "557f91755ede646a89e1146904a6d713f38d6b05"
size: 1024
validation: [size]
required: false
@@ -814,6 +894,7 @@ files:
source_ref: "src/copy_interfaces/mhpokeador.h:27, src/copy_interfaces/mhpokeador.h:39, src/copy_interfaces/mhpokeador.c:264"
- name: "mhpokeador-transfer.rom"
sha1: "4099c5d8f65a25bc0053e5730b7c40a29bcfb614"
size: 1024
validation: [size]
required: false
@@ -822,6 +903,7 @@ files:
source_ref: "src/copy_interfaces/mhpokeador.h:28, src/copy_interfaces/mhpokeador.c:264"
- name: "mhpokeador-salvapan.rom"
sha1: "4e438541ec2da0c3b9cf2cbf0cc3f5bc6cfb295e"
size: 1024
validation: [size]
required: false
@@ -830,6 +912,7 @@ files:
source_ref: "src/copy_interfaces/mhpokeador.h:29, src/copy_interfaces/mhpokeador.c:264"
- name: "mantransfev3.bin"
sha1: "e134a38468ed84d53df164d97fa24990aa557da3"
size: 200
required: false
bundled: true
@@ -842,6 +925,7 @@ files:
# ============================================================
- name: "gs105a.rom"
sha1: "1ba78923dc7d803e7995c165992e14e4608c2153"
size: 32768
validation: [size]
required: false
@@ -851,6 +935,7 @@ files:
note: "General Sound firmware v1.05a. GS_ROM_SIZE is in KB and the read is GS_ROM_SIZE*1024."
- name: "gs104.rom"
sha1: "c865121306eb3a7d811d82fbcc653b4dc1d6fa3d"
size: 32768
required: false
bundled: true
@@ -864,6 +949,7 @@ files:
# ============================================================
- name: "80-lec.rom"
sha1: "bb7a77d66e95d2e28ebb610e543c065e0d428619"
size: 16384
required: false
bundled: true
@@ -871,6 +957,7 @@ files:
source_ref: "src/start.c:4876-4880, src/cpu.c:3520-3523"
- name: "tk90x_v1br.rom"
sha1: "eab2eab803d8ec717b55a915de3bcb931b410a2f"
size: 16384
required: false
bundled: true
@@ -878,6 +965,7 @@ files:
source_ref: "src/ALTERNATEROMS:97, src/start.c:4876-4880, src/cpu.c:3520-3523"
- name: "tk90x_v2es.rom"
sha1: "a9af9c4d38882e2bd85086fc0c2d8d9afe90afad"
size: 16384
required: false
bundled: true
@@ -886,6 +974,7 @@ files:
note: "Corrected TK90X ROM."
- name: "tk95es_modif.rom"
sha1: "1dd39ee98e236389467e91a86cf5d8ed52583ba5"
size: 16384
required: false
bundled: true
@@ -894,6 +983,7 @@ files:
note: "TK95 Spanish ROM with message and symbol fixes by Rodolfo Edison Guerra."
- name: "Z88OZ431.rom"
sha1: "82e12674ba91eb85d4904c3948e4167aea6fd1b7"
size: 524288
required: false
bundled: true
@@ -901,6 +991,7 @@ files:
source_ref: "src/ALTERNATEROMS:83-92, src/start.c:4876-4880"
- name: "Z88OZ441.rom"
sha1: "778d188c201bd9eb6bf795e0cc8344a87600cd45"
size: 524288
required: false
bundled: true
@@ -908,6 +999,7 @@ files:
source_ref: "src/ALTERNATEROMS:83-92, src/start.c:4876-4880"
- name: "Z88OZ45.rom"
sha1: "aecf46de3563c6c6443e9780d633d7b7507e79ef"
size: 524288
required: false
bundled: true
@@ -915,6 +1007,7 @@ files:
source_ref: "src/ALTERNATEROMS:83-92, src/start.c:4876-4880"
- name: "Z88OZ46.rom"
sha1: "9e0e29baa3720abcbb8006cda8f19ea365faf20e"
size: 524288
required: false
bundled: true
@@ -922,6 +1015,7 @@ files:
source_ref: "src/ALTERNATEROMS:83-92, src/start.c:4876-4880"
- name: "Z88UK220.rom"
sha1: "5d89e8d98d2cc0acb8cd42dbfca601b7bd09c51e"
size: 131072
required: false
bundled: true
@@ -929,6 +1023,7 @@ files:
source_ref: "src/ALTERNATEROMS:83-92, src/start.c:4876-4880"
- name: "Z88UK300.rom"
sha1: "ceb688025b79454cf229cae4dbd0449df2747f79"
size: 131072
required: false
bundled: true
@@ -936,6 +1031,7 @@ files:
source_ref: "src/ALTERNATEROMS:83-92, src/start.c:4876-4880"
- name: "Z88UK400.rom"
sha1: "23c63ceced72d0a9031cba08d2ebc72ca336921d"
size: 131072
required: false
bundled: true
@@ -944,6 +1040,7 @@ files:
- name: "aszmice07.rom"
path: "alternate_roms/aszmice07.rom"
sha1: "7a37a248572689c8ac226c082b7026972d399b1c"
size: 8192
required: false
bundled: true
@@ -953,6 +1050,7 @@ files:
- name: "sp-rom.rom"
path: "alternate_roms/sp-rom.rom"
sha1: "ef4b575b5b5cc18a3e6c71c241c65aa18957e2d5"
size: 4096
required: false
bundled: true
@@ -962,6 +1060,7 @@ files:
- name: "ace.rom"
path: "alternate_roms/ace.rom"
sha1: "6e5c9416a1cc89fe4012627f496f71ff2bb07b81"
size: 8192
required: false
bundled: true
@@ -972,6 +1071,7 @@ files:
- name: "opense.rom"
path: "alternate_roms/opense.rom"
sha1: "24a339c5c163a687a8fed50f93714c6450e2562d"
size: 16384
required: false
bundled: true
@@ -981,6 +1081,7 @@ files:
- name: "sebasic4_rom1.rom"
path: "alternate_roms/sebasic4_rom1.rom"
sha1: "d7092d6d55ee8280057399362b5798d1f65d8eeb"
size: 16384
required: false
bundled: true
@@ -990,6 +1091,7 @@ files:
- name: "derby_p_32K.rom"
path: "alternate_roms/derby_p_32K.rom"
sha1: "f9c337782f9a4781548528841babd5bd13f2b745"
size: 32768
required: false
bundled: true
@@ -999,6 +1101,7 @@ files:
- name: "derby_pp_64K.rom"
path: "alternate_roms/derby_pp_64K.rom"
sha1: "7eaaf1ff19f74d5449033bacce9834d7b13022a9"
size: 65536
required: false
bundled: true
@@ -1008,6 +1111,7 @@ files:
- name: "plus2c.rom"
path: "alternate_roms/plus2c.rom"
sha1: "98effb0e2dc4ecf6e9f70be9828a688341396c0c"
size: 32768
required: false
bundled: true
@@ -1017,6 +1121,7 @@ files:
- name: "plus2b.rom"
path: "alternate_roms/plus2b.rom"
sha1: "420d8f1cd7bd75a79803eaa49e191d90cfd24f38"
size: 65536
required: false
bundled: true
@@ -1026,6 +1131,7 @@ files:
- name: "plus3e_mmcen3eE.rom"
path: "alternate_roms/plus3e_mmcen3eE.rom"
sha1: "a579f9c3571669294dad37b04dcb889a9c147d94"
size: 65536
required: false
bundled: true
@@ -1035,6 +1141,7 @@ files:
- name: "plus3e_mmces3eE.rom"
path: "alternate_roms/plus3e_mmces3eE.rom"
sha1: "44e98a3dfc966f7c8725c252487a44a2c0b450d6"
size: 65536
required: false
bundled: true
@@ -1044,6 +1151,7 @@ files:
- name: "plus3e_sm8en3eE.rom"
path: "alternate_roms/plus3e_sm8en3eE.rom"
sha1: "89b6227798a88a6ad0e3b9e58db979694912ee04"
size: 65536
required: false
bundled: true
@@ -1053,6 +1161,7 @@ files:
- name: "plus3e_sm8es3eE.rom"
path: "alternate_roms/plus3e_sm8es3eE.rom"
sha1: "a5b62b647ccaec4af9989b8fd7857d5f6426ae5d"
size: 65536
required: false
bundled: true
+1 -1
View File
@@ -8,7 +8,7 @@ param(
$ErrorActionPreference = "Stop"
$defaultInstallUrl = "https://raw.githubusercontent.com/Abdess/retrobios/main/install.py"
$defaultInstallSha256 = "60e18da18b5a9a43b18d37020b676ad47babd6d12c5314e8fcc1370e4864c4e5"
$defaultInstallSha256 = "d5f352fbe34cfd8ae40c0980c3986158ec1d9dd1babfe2bbc0918ffc0fa0bdf0"
$maximumInstallerBytes = 2MB
$installer = if ($PSScriptRoot) { Join-Path $PSScriptRoot "install.py" } else { $null }
$temporary = $null
+548 -18
View File
@@ -10,6 +10,7 @@ Usage:
python install.py --platform retroarch --dest ~/custom/bios
python install.py --check
python install.py --list-platforms
python install.py --platform retroarch --system sony-playstation --region us
"""
from __future__ import annotations
@@ -81,9 +82,59 @@ MAX_TARGETS_BYTES = 4 * 1024 * 1024
MAX_MANIFEST_FILES = 100_000
MAX_DOWNLOAD_SIZE = 1024 * 1024 * 1024
MAX_TOTAL_DOWNLOAD_SIZE = 64 * 1024 * 1024 * 1024
# Why a manifest leaves a file out, as the installer words it. The manifest
# schema and the generator are held to this list by the tests.
OMISSION_REASONS = {
"hash_mismatch": "hash mismatch",
"not_found": "not found",
"external": "external",
"user_provided": "user provided",
"no_platform_slug": "no platform folder",
}
_SHA1_RE = re.compile(r"^[0-9a-fA-F]{40}$")
_SHA256_RE = re.compile(r"^[0-9a-fA-F]{64}$")
# The region vocabulary of scripts/region.py, which this file cannot import.
# A test holds the two copies equal.
WORLD_REGION = "world"
REGION_TREE: dict[str, frozenset] = {
"north-america": frozenset({"canada"}),
"latin-america": frozenset({"brazil", "mexico", "argentina"}),
"europe": frozenset({
"uk", "france", "germany", "italy", "spain", "netherlands", "portugal",
"greece", "poland", "russia", "sweden", "norway", "denmark", "finland",
}),
"asia": frozenset({
"japan", "south-korea", "china", "taiwan", "hong-kong", "singapore",
"india", "asia-ntsc", "asia-pal",
}),
"oceania": frozenset({"australia", "new-zealand"}),
}
REGION_ALIASES: dict[str, str] = {
"jp": "japan",
"ntsc-j": "japan",
"us": "north-america",
"usa": "north-america",
"na": "north-america",
"ntsc-u": "north-america",
"eu": "europe",
"pal": "europe",
"kr": "south-korea",
"korea": "south-korea",
"auto": WORLD_REGION,
"gb": "uk",
}
_REGION_PARENT = {
member: parent for parent, members in REGION_TREE.items() for member in members
}
REGIONS = frozenset({WORLD_REGION} | set(REGION_TREE) | set(_REGION_PARENT))
MAX_SELECTION_TAGS = 1000
SELECTION_FIELDS = ("systems", "regions", "region_groups", "region_system_groups")
# The files cores load for systems the platform does not list (game engines,
# computers): no system of the platform owns them, and choosing systems
# leaves them out unless this name is chosen too.
OTHER_SYSTEMS = "other"
# Platforms with a manifest in install/. Manifest URLs are case sensitive,
# so user input is normalized against this list before any fetch.
AVAILABLE_PLATFORMS = (
@@ -120,7 +171,8 @@ def _os_default_dests(os_type: str) -> dict[str, Path]:
appdata = Path(os.environ.get("APPDATA", str(home / "AppData" / "Roaming")))
return {
"retroarch": appdata / "RetroArch" / "system",
"retrobat": profile / "RetroBat" / "bios",
# RetroBat's installer defaults to C:\RetroBat (installer.iss).
"retrobat": Path("C:/RetroBat/bios"),
"bizhawk": profile / "BizHawk" / "Firmware",
}
if os_type == "darwin":
@@ -803,6 +855,19 @@ def _destination_path(root: Path, value: object) -> Path:
return root.resolve() / Path(*relative.parts)
def _check_tags(entry: dict, field: str, where: str) -> None:
"""A selection field is absent or a short list of short strings."""
value = entry.get(field)
if value is None:
return
if (
not isinstance(value, list)
or len(value) > MAX_SELECTION_TAGS
or not all(isinstance(tag, str) and 0 < len(tag) <= 256 for tag in value)
):
raise ValueError(f"invalid {field} for {where}")
def _validate_manifest(data: object, plat: str) -> dict:
"""Validate the untrusted install-manifest boundary using stdlib only."""
if not isinstance(data, dict):
@@ -861,6 +926,8 @@ def _validate_manifest(data: object, plat: str) -> dict:
not isinstance(cores, list) or not all(isinstance(core, str) for core in cores)
):
raise ValueError(f"invalid cores list for {dest}")
for field in SELECTION_FIELDS:
_check_tags(entry, field, dest)
declared_total_files = data.get("total_files")
if declared_total_files is not None and declared_total_files != len(files):
@@ -873,9 +940,6 @@ def _validate_manifest(data: object, plat: str) -> dict:
if not isinstance(omitted, list) or len(omitted) > MAX_MANIFEST_FILES:
raise ValueError("invalid omitted_files list")
seen_omitted: set[str] = set()
allowed_omission_reasons = {
"hash_mismatch", "not_found", "external", "user_provided"
}
for index, entry in enumerate(omitted):
if not isinstance(entry, dict):
raise ValueError(f"omitted_files[{index}] must be an object")
@@ -893,7 +957,7 @@ def _validate_manifest(data: object, plat: str) -> dict:
raise ValueError(f"invalid omitted system for {dest}")
if not isinstance(entry.get("required"), bool):
raise ValueError(f"invalid omitted required flag for {dest}")
if entry.get("reason") not in allowed_omission_reasons:
if entry.get("reason") not in OMISSION_REASONS:
raise ValueError(f"invalid omission reason for {dest}")
cores = entry.get("cores")
if cores is not None and (
@@ -901,6 +965,8 @@ def _validate_manifest(data: object, plat: str) -> dict:
or not all(isinstance(core, str) for core in cores)
):
raise ValueError(f"invalid omitted cores list for {dest}")
for field in SELECTION_FIELDS:
_check_tags(entry, field, dest)
declared_total_omitted = data.get("total_omitted")
if (
declared_total_omitted is not None
@@ -914,6 +980,24 @@ def _validate_manifest(data: object, plat: str) -> dict:
for index, entry in enumerate(copies):
if not isinstance(entry, dict):
raise ValueError(f"standalone_copies[{index}] must be an object")
# The shape do_standalone_copies reads, checked here: a note with a
# list for detect, a copy naming neither file nor pattern, or a list
# for emulator passed and crashed the copy step after the download.
where = f"standalone_copies[{index}]"
if "note" in entry:
detect = entry.get("detect", {})
if not isinstance(entry["note"], str) or not isinstance(detect, dict):
raise ValueError(f"invalid note entry at {where}")
for values in detect.values():
if not isinstance(values, list) or not all(
isinstance(value, str) for value in values
):
raise ValueError(f"invalid note entry at {where}")
continue
if "file" not in entry and "pattern" not in entry:
raise ValueError(f"{where} names neither a file nor a pattern")
if not isinstance(entry.get("emulator", ""), str):
raise ValueError(f"invalid emulator at {where}")
if "file" in entry:
_safe_relative_path(
entry["file"], f"standalone_copies[{index}].file"
@@ -1017,6 +1101,228 @@ def _filter_by_target(
return result
def canonical_region(raw: str) -> str:
"""One region name or alias, spelled the way manifests spell it."""
key = raw.strip().lower()
key = REGION_ALIASES.get(key, key)
if key not in REGIONS:
raise ValueError(f"unknown region: {raw.strip()}")
return key
def _region_comparable(a: str, b: str) -> bool:
return a == b or _REGION_PARENT.get(a) == b or _REGION_PARENT.get(b) == a
def _region_rank(file_regions: set[str], requested: list[str]) -> int:
for index, wanted in enumerate(requested):
if any(_region_comparable(wanted, region) for region in file_regions):
return index
return len(requested)
def region_drops(
entries: list[dict], requested: list[str], systems: list[str] | None = None
) -> set[str]:
"""Destinations a region priority list withdraws.
The pack builder's rule (region.resolve_region_drops), replayed over the
groups the manifest records. Per group, the best-ranked regional file
stays; a world file beats unmatched regional ones the code does not search
before it (`priority`, lower first); when nothing matches and no world
file exists, every regional file stays, so a group is never emptied. A file with no region never competes and always stays.
A core extra competes whatever systems are chosen; a platform's own
declaration competes only when its system is kept, as in the pack.
"""
if not requested:
return set()
kept_systems = set(systems) if systems else None
groups: dict[str, list[tuple[set, str, object]]] = {}
for entry in entries:
regions = entry.get("regions")
if not regions:
continue
joined = list(entry.get("region_groups") or [])
joined += [
group for group in entry.get("region_system_groups") or []
if kept_systems is None or group in kept_systems
]
priority = entry.get("priority")
if not isinstance(priority, int) or isinstance(priority, bool):
priority = None
for group in joined:
groups.setdefault(group, []).append((set(regions), entry["dest"], priority))
keep: set[str] = set()
drop: set[str] = set()
for members in groups.values():
world = {dest for regions, dest, _p in members if WORLD_REGION in regions}
ranks = {dest: priority for _regions, dest, priority in members}
regional = [
(_region_rank(regions, requested), dest)
for regions, dest, _p in members
if WORLD_REGION not in regions
]
keep |= world
if not regional:
continue
matched = [(rank, dest) for rank, dest in regional if rank < len(requested)]
if matched:
best = min(rank for rank, _dest in matched)
keep |= {dest for rank, dest in matched if rank == best}
drop |= {dest for _rank, dest in regional}
elif world:
world_ranks = [ranks[dest] for dest in world]
best_world = min(world_ranks) if None not in world_ranks else None
for _rank, dest in regional:
ours = ranks[dest]
if best_world is not None and ours is not None and ours < best_world:
keep.add(dest)
else:
drop.add(dest)
else:
keep |= {dest for _rank, dest in regional}
return drop - keep
def entry_systems(entry: dict) -> list[str]:
"""The platform systems a file or an omission belongs to.
An omission's `system` is spelled the way its profile spells it; only
`systems` names the platform's own, the ones --system accepts.
"""
return list(entry.get("systems") or [])
def narrow(
files: list[dict],
omitted: list[dict],
systems: list[str],
cores: list[str],
regions: list[str],
) -> tuple[list[dict], list[dict]]:
"""Keep what the chosen systems, cores and regions need.
A core choice keeps the platform's own list and narrows only the files
cores load, the rule --target already follows. Regions are then decided
the way the pack builder decides them under --system: over the chosen
systems' declarations and every core extra. The system filter comes last.
"""
if cores:
files = _filter_by_target(files, cores)
omitted = _filter_by_target(omitted, cores)
if regions:
dropped = region_drops(files + omitted, regions, systems)
files = [f for f in files if f["dest"] not in dropped]
omitted = [o for o in omitted if o["dest"] not in dropped]
if systems:
wanted = set(systems)
files = [f for f in files if _chosen(f, wanted)]
omitted = [o for o in omitted if _chosen(o, wanted)]
return files, omitted
def _chosen(entry: dict, wanted: set[str]) -> bool:
systems = entry_systems(entry)
if not systems:
return OTHER_SYSTEMS in wanted
return bool(wanted & set(systems))
def records_selection(files: list[dict]) -> bool:
"""Whether a manifest carries what narrowing reads; older ones do not."""
return any("systems" in entry for entry in files)
def available_choices(files: list[dict], omitted: list[dict]) -> dict[str, list[str]]:
"""The systems, cores and regions a manifest lets one narrow to."""
systems = {s for e in files + omitted for s in entry_systems(e)}
ordered = sorted(systems)
if any(not entry_systems(f) for f in files):
ordered.append(OTHER_SYSTEMS)
cores = {c for f in files for c in (f.get("cores") or [])}
regions = {
r for e in files + omitted for r in (e.get("regions") or [])
if r != WORLD_REGION
}
return {
"systems": ordered,
"cores": sorted(cores),
"regions": sorted(regions),
}
def resolve_choices(values: list[str], known: list[str], label: str) -> list[str]:
"""Names given on the command line, matched without regard to case.
Each value is one name or a comma-separated list. A whole value that is
itself a name wins over splitting it: Recalbox names one system
`msx1,msx2,msxturbor`. An unknown name is refused, never ignored, since
carrying on would install something other than what was asked.
"""
by_lower = {name.lower(): name for name in known}
chosen: list[str] = []
unknown: list[str] = []
for value in values:
value = value.strip()
tokens = [value] if value.lower() in by_lower else value.split(",")
for token in (t.strip() for t in tokens):
if not token:
continue
name = by_lower.get(token.lower())
if name is None:
unknown.append(token)
elif name not in chosen:
chosen.append(name)
if unknown:
available = ", ".join(known) if known else "none"
raise ValueError(
f"unknown {label}: {', '.join(unknown)} (available: {available})"
)
if values and not chosen:
raise ValueError(f"--{label} needs at least one name")
return chosen
def resolve_regions(values: list[str]) -> list[str]:
"""A region priority list, best first, from names or aliases."""
chosen: list[str] = []
for value in values:
for token in value.split(","):
if token.strip():
region = canonical_region(token)
if region not in chosen:
chosen.append(region)
if values and not chosen:
raise ValueError("--region needs at least one region")
return chosen
def parse_selection(text: str, count: int, ordered: bool = False) -> list[int]:
"""Numbers typed at a prompt: `3`, `1,4`, `2-5`, or `all`, 1-based.
Returned sorted, or in the typed order when the order is a priority.
"""
if text.strip().lower() in ("all", "*"):
return list(range(1, count + 1))
chosen: list[int] = []
for token in (t.strip() for t in text.split(",")):
if not token:
continue
low, sep, high = token.partition("-")
try:
start = int(low)
end = int(high) if sep else start
except ValueError:
raise ValueError(f"not a number or range: {token}") from None
if start > end or start < 1 or end > count:
raise ValueError(f"out of range: {token} (1-{count})")
for number in range(start, end + 1):
if number not in chosen:
chosen.append(number)
return chosen if ordered else sorted(chosen)
def _digest_file(path: Path, algorithms: tuple[str, ...]) -> dict[str, str]:
"""Compute several digests of a file in a single read.
@@ -1294,7 +1600,7 @@ def download_files(
def do_standalone_copies(
manifest: dict, bios_path: Path, os_type: str,
extra_dirs: dict[str, Path] | None = None,
) -> tuple[int, int]:
) -> tuple[int, int, int]:
"""Copy BIOS files to standalone emulator directories.
Supports:
@@ -1307,16 +1613,19 @@ def do_standalone_copies(
default per-OS locations, for setups such as LaunchBox that keep their
emulators outside them. The layout below the root is the same.
Returns (copied_count, skipped_count).
Returns (copied, skipped, failed): skipped is a target directory that
does not exist, failed a copy the system refused (permission, disk
full, read-only mount), which used to be counted as "dir not found".
"""
from fnmatch import fnmatch
copies = manifest.get("standalone_copies", [])
if not copies:
return 0, 0
return 0, 0, 0
copied = 0
skipped = 0
failed = 0
for entry in copies:
# Note entries: print message if emulator detected
@@ -1375,10 +1684,11 @@ def do_standalone_copies(
try:
shutil.copy2(src, dest)
copied += 1
except OSError:
skipped += 1
except OSError as exc:
print(f" ERROR: {dest}: {exc.strerror or exc}")
failed += 1
return copied, skipped
return copied, skipped, failed
def format_size(n: int) -> str:
@@ -1487,6 +1797,155 @@ def _prompt_platform_choice(
return platforms
def _ask(prompt: str) -> str:
try:
return input(prompt).strip()
except (EOFError, KeyboardInterrupt):
print()
sys.exit(0)
def _sized(files: list[dict]) -> str:
return f"{_plural(len(files), 'file')}, {format_size(sum(f.get('size', 0) for f in files))}"
def _pick(title: str, rows: list[tuple[str, list[dict]]], ordered: bool = False) -> list[str]:
"""Numbered list of names; an empty answer keeps every one."""
if not rows:
return []
print(f"\n{title}")
width = len(str(len(rows)))
name_width = min(max(len(name) for name, _files in rows), 32)
for index, (name, files) in enumerate(rows, 1):
print(f" {index:>{width}}) {name:<{name_width}} {_sized(files)}")
hint = "order of preference, e.g. 2,1" if ordered else "e.g. 1,3-5"
while True:
text = _ask(f"Numbers ({hint}), Enter for all, q to quit: ")
if not text:
return []
if text.lower() == "q":
sys.exit(0)
try:
chosen = parse_selection(text, len(rows), ordered=ordered)
except ValueError as exc:
print(f" {exc}")
continue
if chosen:
return [rows[number - 1][0] for number in chosen]
def _prompt_custom_selection(
plat: str, files: list[dict], omitted: list[dict]
) -> tuple[list[str], list[str], list[str]] | None:
"""Offer to narrow the install by system, core and region.
Enter installs everything, the default most runs want. Returns None
then, or the three choices; each empty list keeps everything on its axis.
"""
print(f"\n{plat.capitalize()}: {_sized(files)}.")
print(" Enter) install everything")
print(" c) choose systems, cores and regions")
print(" q) quit")
while True:
answer = _ask("> ").lower()
if answer == "":
return None
if answer == "q":
sys.exit(0)
if answer == "c":
break
choices = available_choices(files, omitted)
if OTHER_SYSTEMS in choices["systems"]:
print(f"\n'{OTHER_SYSTEMS}' holds what cores load for systems this platform")
print("does not list, such as game engines and extra computers.")
systems = _pick("Systems:", [
(name, [f for f in files if _chosen(f, {name})])
for name in choices["systems"]
])
kept, kept_omitted = narrow(files, omitted, systems, [], [])
cores: list[str] = []
core_names = available_choices(kept, kept_omitted)["cores"]
if core_names:
print("\nThe platform's own files for these systems are always kept;")
print("the extra files each core loads can be narrowed.")
cores = _pick("Cores:", [
(name, [f for f in kept if name in (f.get("cores") or [])])
for name in core_names
])
kept, kept_omitted = narrow(kept, kept_omitted, [], cores, [])
regions: list[str] = []
region_names = available_choices(kept, kept_omitted)["regions"]
if region_names:
print("\nSome systems have one BIOS per region. Keeping only the")
print("preferred region removes the others where a match exists.")
regions = _pick("Regions:", [
(name, [f for f in kept if name in (f.get("regions") or [])])
for name in region_names
], ordered=True)
return systems, cores, regions
def _same_choice_hint(plat: str, systems: list[str], cores: list[str], regions: list[str]) -> str:
"""The options that repeat a choice made at the prompts."""
def quoted(value: str) -> str:
return f'"{value}"' if any(c in value for c in " ;&|") else value
parts = [f"--platform {plat}"]
parts += [f"--system {quoted(name)}" for name in systems]
parts += [f"--core {quoted(name)}" for name in cores]
if regions:
parts.append(f"--region {','.join(regions)}")
return " ".join(parts)
def _print_choices(
plat: str, files: list[dict], omitted: list[dict], systems: bool
) -> None:
"""What --system or --core accepts for a platform, with what each holds."""
choices = available_choices(files, omitted)
names = choices["systems"] if systems else choices["cores"]
if not names:
print(f" {plat} records no {'systems' if systems else 'cores'}")
return
width = min(max(len(name) for name in names), 40)
for name in names:
held = (
[f for f in files if _chosen(f, {name})]
if systems
else [f for f in files if name in (f.get("cores") or [])]
)
print(f" {name:<{width}} {_sized(held)}")
def _requested_narrowing(
args: argparse.Namespace, plat: str, files: list[dict], omitted: list[dict]
) -> tuple[list[str], list[str], list[str]] | None:
"""The systems, cores and regions named on the command line, checked."""
if not (args.system or args.core or args.region):
return None
if not records_selection(files):
# Without the fields, a region filter would match nothing and install
# everything: refused rather than ignored.
print(
f"Error: the {plat} file list records no systems or regions; "
"narrowing needs a newer one",
file=sys.stderr,
)
sys.exit(1)
choices = available_choices(files, omitted)
try:
systems = resolve_choices(args.system or [], choices["systems"], "system")
cores = resolve_choices(args.core or [], choices["cores"], "core")
regions = resolve_regions(args.region or [])
except ValueError as exc:
print(f"Error: {plat}: {exc}", file=sys.stderr)
sys.exit(1)
return systems, cores, regions
def main() -> None:
"""Entry point."""
parser = argparse.ArgumentParser(
@@ -1536,10 +1995,56 @@ def main() -> None:
action="store_true",
help="opt in to copies into detected standalone-emulator directories",
)
parser.add_argument(
"--system",
action="append",
metavar="NAME",
help="install only these systems (repeat or comma-separate; see --list-systems)",
)
parser.add_argument(
"--core",
action="append",
metavar="NAME",
help="keep only the extra files these cores load (see --list-cores)",
)
parser.add_argument(
"--region",
action="append",
metavar="LIST",
help="preferred regions, best first, e.g. us,eu,jp: keep one BIOS per "
"region where a system has several",
)
parser.add_argument(
"--list-systems",
action="store_true",
help="list a platform's systems with their file counts and exit",
)
parser.add_argument(
"--list-cores",
action="store_true",
help="list the cores whose extra files a platform installs and exit",
)
parser.add_argument(
"--no-input",
action="store_true",
help="never ask a question; fail where an answer is needed",
)
args = parser.parse_args()
if not 1 <= args.jobs <= 32:
parser.error("--jobs must be between 1 and 32")
if args.region:
try:
resolve_regions(args.region)
except ValueError as exc:
parser.error(f"{exc} (known: {', '.join(sorted(REGIONS))})")
for option, values in (("--system", args.system), ("--core", args.core)):
if values is not None and not any(
token.strip() for value in values for token in value.split(",")
):
parser.error(f"{option} needs at least one name")
interactive = sys.stdin.isatty() and not args.no_input
listing = args.list_targets or args.list_systems or args.list_cores
print("RetroBIOS\n")
os_type = detect_os()
@@ -1587,7 +2092,7 @@ def main() -> None:
platforms = detect_platforms(os_type)
if not platforms:
print(" No supported platform detected.")
if not sys.stdin.isatty() or args.list_targets:
if not interactive or listing:
for line in _manual_usage_hint(os_type):
print(line)
sys.exit(1)
@@ -1595,7 +2100,7 @@ def main() -> None:
for name, path in platforms:
print(f" Found {name.capitalize()} at {path}")
if len(platforms) > 1 and not args.list_targets and sys.stdin.isatty():
if len(platforms) > 1 and not listing and interactive:
platforms = _prompt_platform_choice(platforms)
total_downloaded = 0
@@ -1661,6 +2166,27 @@ def main() -> None:
omitted_files = _filter_by_target(omitted_files, target_cores)
print(f" Filtered {before} -> {len(files)} files for target {args.target}")
selection = _requested_narrowing(args, plat_name, files, omitted_files)
if (
selection is None
and interactive
and not args.check
and not listing
and records_selection(files)
):
selection = _prompt_custom_selection(plat_name, files, omitted_files)
if selection is not None:
print("\n Same choice without questions: "
+ _same_choice_hint(plat_name, *selection))
if selection is not None:
before = len(files)
files, omitted_files = narrow(files, omitted_files, *selection)
print(f" Narrowed {before} -> {len(files)} files")
if args.list_systems or args.list_cores:
_print_choices(plat_name, files, omitted_files, args.list_systems)
continue
total_size = sum(f.get("size", 0) for f in files)
print(f" {len(files)} files ({format_size(total_size)})")
if omitted_files:
@@ -1672,7 +2198,7 @@ def main() -> None:
reason = entry.get("reason", "unknown")
reasons[reason] = reasons.get(reason, 0) + 1
reason_summary = ", ".join(
f"{reason.replace('_', ' ')}: {count}"
f"{OMISSION_REASONS.get(reason, reason)}: {count}"
for reason, count in sorted(reasons.items())
)
print(
@@ -1738,18 +2264,22 @@ def main() -> None:
print("\nStandalone emulators:")
lb_root = launchbox_root(os_type)
extra_dirs = launchbox_bios_dirs(lb_root) if lb_root else None
copied, skipped = do_standalone_copies(
copied, skipped, copy_failed = do_standalone_copies(
manifest, bios_path, os_type, extra_dirs
)
if copied or skipped:
print(f" {copied} copied, {skipped} skipped (dir not found)")
if copied or skipped or copy_failed:
print(
f" {copied} copied, {skipped} skipped (dir not found), "
f"{copy_failed} failed"
)
total_errors += copy_failed
elif manifest.get("standalone_copies") and not args.check:
print(
"\nStandalone copies skipped "
"(use --standalone-copies to opt in)."
)
if not args.check and not args.list_targets:
if not args.check and not listing:
_report_outcome(
installed_paths,
total_downloaded,
+9 -2
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="60e18da18b5a9a43b18d37020b676ad47babd6d12c5314e8fcc1370e4864c4e5"
DEFAULT_INSTALL_SHA256="d5f352fbe34cfd8ae40c0980c3986158ec1d9dd1babfe2bbc0918ffc0fa0bdf0"
MAX_INSTALLER_BYTES=2097152
cleanup() {
@@ -97,4 +97,11 @@ if [ -z "$PYTHON" ]; then
exit 1
fi
"$PYTHON" "$INSTALLER" "$@"
# Piped from curl, standard input is this script, not the terminal: the
# installer would skip every question it can ask. Hand it the terminal when
# there is one.
if [ ! -t 0 ] && (: </dev/tty) 2>/dev/null; then
"$PYTHON" "$INSTALLER" "$@" </dev/tty
else
"$PYTHON" "$INSTALLER" "$@"
fi
+7242 -564
View File
File diff suppressed because it is too large. Load diff
+2395 -192
View File
File diff suppressed because it is too large. Load diff
+2007 -141
View File
File diff suppressed because it is too large. Load diff
+6214 -713
View File
File diff suppressed because it is too large. Load diff
+325 -82
View File
@@ -5,7 +5,7 @@
"platform": "misterfpga",
"display_name": "MiSTer FPGA",
"version": "1.0",
"generated": "2026-10-04T20:41:16Z",
"generated": "2026-10-10T05:24:26Z",
"base_destination": "games",
"detect": [
{
@@ -29,7 +29,10 @@
"sha256": "41b5b8e7c44e55eaf5cfd4f2a58df42f4a1bbc776723368fb25bf118dd631b1b",
"size": 1048576,
"repo_path": "bios/3DO Company/3DO/panafz1.bin",
"cores": null
"cores": null,
"systems": [
"3do"
]
},
{
"dest": "3DO/kanji.rom",
@@ -37,7 +40,10 @@
"sha256": "8974193e76cf255ebc40fe20b95b405db2cc1ea07910584380e50c6d9ca181aa",
"size": 1048576,
"repo_path": "bios/3DO Company/3DO/panafz1j-kanji.bin",
"cores": null
"cores": null,
"systems": [
"3do"
]
},
{
"dest": "Apple-IIgs/boot.rom",
@@ -45,7 +51,10 @@
"sha256": "01398a51b3aa16c40bb3d5df43494316cc12eebb87871712cecc396e1beb2df8",
"size": 262144,
"repo_path": "bios/Apple/Apple II/apple2gs.rom",
"cores": null
"cores": null,
"systems": [
"apple-iigs"
]
},
{
"dest": "Apple-IIgs/boot1.rom",
@@ -53,7 +62,10 @@
"sha256": "34cd454c6201bfd26839d6ace2ff6b1231e09d6279e49b4890311756dc3825fb",
"size": 131072,
"repo_path": "bios/Apple/Apple IIGS/ROM",
"cores": null
"cores": null,
"systems": [
"apple-iigs"
]
},
{
"dest": "Jaguar/boot.rom",
@@ -61,7 +73,10 @@
"sha256": "f0bd29599b3dfca7f5620c011256c1dc45c9d82c428a318f965c2ba3ded2e9f9",
"size": 131072,
"repo_path": "bios/Atari/Jaguar/boot.rom",
"cores": null
"cores": null,
"systems": [
"atari-jaguar"
]
},
{
"dest": "Jaguar/boot1.rom",
@@ -69,7 +84,10 @@
"sha256": "7ebadb56f8082c86d6f74e2c38e02b218db420d3049f8f9c988f6490dc7f9fc0",
"size": 262144,
"repo_path": "bios/Atari/Jaguar/boot1.rom",
"cores": null
"cores": null,
"systems": [
"atari-jaguar"
]
},
{
"dest": "Jaguar/boot2.rom",
@@ -77,7 +95,10 @@
"sha256": "bf02591cfe4ab4f082ea23c447da5c53afbfddace6d700b785ba04b7ac5c64e0",
"size": 131072,
"repo_path": "bios/Atari/Jaguar/boot2.rom",
"cores": null
"cores": null,
"systems": [
"atari-jaguar"
]
},
{
"dest": "AtariLynx/boot.rom",
@@ -85,7 +106,10 @@
"sha256": "c26a36c1990bcf841155e5a6fea4d2ee1a4d53b3cc772e70f257a962ad43b383",
"size": 512,
"repo_path": "bios/Atari/Lynx/Atari_LYNX_boot.img",
"cores": null
"cores": null,
"systems": [
"atari-lynx"
]
},
{
"dest": "Astrocade/boot.rom",
@@ -93,7 +117,10 @@
"sha256": "f01220d94b82145a6d18f114ff59be9c178f69de24f8ad0f4d19eee8b86b17c7",
"size": 8192,
"repo_path": "bios/Bally/Astrocade/astro.bin",
"cores": null
"cores": null,
"systems": [
"bally-astrocade"
]
},
{
"dest": "Casio_PV-2000/boot0.rom",
@@ -101,7 +128,10 @@
"sha256": "2587d206eb63917848ea30e14232448ed4f873c6796a22e2bf6543b01f46308e",
"size": 16384,
"repo_path": "bios/Casio/PV-2000/hn613128pc64.bin",
"cores": null
"cores": null,
"systems": [
"casio-pv2000"
]
},
{
"dest": "CreatiVision/boot.rom",
@@ -109,7 +139,10 @@
"sha256": "48a7fda99c1b9c0d90b70de0b4a9431a5a781f94d1874ee6d91830a638c9e5c3",
"size": 16384,
"repo_path": "bios/VTech/CreatiVision/laser2001.rom",
"cores": null
"cores": null,
"systems": [
"creativision"
]
},
{
"dest": "SCV/boot.rom",
@@ -117,7 +150,10 @@
"sha256": "25c7ff2d735d1ae895af9262f31e083c5c1bd99a8f31b5b378dfbc0f166ec97f",
"size": 6144,
"repo_path": "bios/Epoch/Super Cassette Vision/boot.rom",
"cores": null
"cores": null,
"systems": [
"epoch-scv"
]
},
{
"dest": "Gamate/boot.rom",
@@ -125,7 +161,10 @@
"sha256": "26f206fa4eedbe040f619e3af78efa1d38588535b1d746f6a462da639ced4b1e",
"size": 4096,
"repo_path": "bios/Bit Corporation/Gamate/gamate_bios_umc.bin",
"cores": null
"cores": null,
"systems": [
"gamate"
]
},
{
"dest": "GameKing/boot.rom",
@@ -133,7 +172,10 @@
"sha256": "7843fd082889cac046d446160f38755f7c8c4a8e4f9dd9d5104b185f0bc1dec4",
"size": 524288,
"repo_path": "bios/TimeTop/GameKing/boot.rom",
"cores": null
"cores": null,
"systems": [
"gameking"
]
},
{
"dest": "Interact/boot.rom",
@@ -141,7 +183,10 @@
"sha256": "e0888ba82382aabb7557aa4a3445e613bd7f33bae1af5ece211e2cb6bc9ffa82",
"size": 2048,
"repo_path": "bios/Interact/Home Computer/interact.rom",
"cores": null
"cores": null,
"systems": [
"interact"
]
},
{
"dest": "Loopy/boot0.rom",
@@ -149,7 +194,10 @@
"sha256": "82a8d6add06e324e36c71b0a7a92d607af3db5e65574a6892794d70df668e9d5",
"size": 32768,
"repo_path": "bios/Casio/Loopy/boot0.rom",
"cores": null
"cores": null,
"systems": [
"loopy"
]
},
{
"dest": "Loopy/boot1.rom",
@@ -157,7 +205,10 @@
"sha256": "7540ff64268e500a34fb83c8642510d341440ac6258f6c36851e182870e40f75",
"size": 524288,
"repo_path": "bios/Casio/Loopy/boot1.rom",
"cores": null
"cores": null,
"systems": [
"loopy"
]
},
{
"dest": "Marty/mrom.m36",
@@ -165,7 +216,10 @@
"sha256": "2cd7466183ba965259df35ff078b7b057a99086feea0050ddf87aebc6932f429",
"size": 2097152,
"repo_path": "bios/Fujitsu/FM Towns/mrom.m36",
"cores": null
"cores": null,
"systems": [
"marty"
]
},
{
"dest": "Marty/mrom.m37",
@@ -173,7 +227,10 @@
"sha256": "10fc6d984d0a440c3410d805f4bea247fb5dd5a509befff481164923f883797d",
"size": 2097152,
"repo_path": "bios/Fujitsu/FM Towns/mrom.m37",
"cores": null
"cores": null,
"systems": [
"marty"
]
},
{
"dest": "Intellivision/boot0.rom",
@@ -181,7 +238,10 @@
"sha256": "1aeb614856beba95463166daf09304b414d5617d3f37d221724b3337fc4b2722",
"size": 8192,
"repo_path": "bios/Mattel/Intellivision/INTV_EROM.bin",
"cores": null
"cores": null,
"systems": [
"mattel-intellivision"
]
},
{
"dest": "Intellivision/boot1.rom",
@@ -189,7 +249,10 @@
"sha256": "a80b6841182547d08635ad30a6af71441c4c9eed9391b3dd22feb30d8e50cc85",
"size": 2048,
"repo_path": "bios/Mattel/Intellivision/INTV_GROM.bin",
"cores": null
"cores": null,
"systems": [
"mattel-intellivision"
]
},
{
"dest": "Intellivision/boot2.rom",
@@ -197,7 +260,10 @@
"sha256": "dabade432af1523f43029057071ca8c1ed3604498c784603e8733023382ad7a5",
"size": 2048,
"repo_path": "bios/Mattel/Intellivision/IVOICE.BIN",
"cores": null
"cores": null,
"systems": [
"mattel-intellivision"
]
},
{
"dest": "Intellivision/boot3.rom",
@@ -205,7 +271,10 @@
"sha256": "2fcea60039c4a8836b9bb71e391d70a145c724b4dae516be733fe842ba6687c7",
"size": 24576,
"repo_path": "bios/Mattel/Intellivision/ECS.bin",
"cores": null
"cores": null,
"systems": [
"mattel-intellivision"
]
},
{
"dest": "MSX1/boot.rom",
@@ -213,7 +282,10 @@
"sha256": "04fd77f02f652770cbb3cc6b4a594cc736d56486a106c1068965f1fe090746a5",
"size": 32768,
"repo_path": "bios/Microsoft/MSX/share/systemroms/vg8020_basic-bios1.rom",
"cores": null
"cores": null,
"systems": [
"microsoft-msx"
]
},
{
"dest": "PC8801/boot.rom",
@@ -221,7 +293,10 @@
"sha256": "0dc3fcf58c90c1f119a710babd54b57babf81ba8573c070b33f0cc21948b3086",
"size": 393216,
"repo_path": "bios/NEC/PC-88/PC8801 MKII SR BIOS.rom",
"cores": null
"cores": null,
"systems": [
"nec-pc-88"
]
},
{
"dest": "TGFX16-CD/cd_bios.rom",
@@ -229,7 +304,10 @@
"sha256": "b057e09822c3767120ba56f2ce02f089b5824d4b489ea3cd7ad9405b3a339a52",
"size": 262144,
"repo_path": "bios/NEC/PC Engine CD/Super CD 3.1.pce",
"cores": null
"cores": null,
"systems": [
"nec-pc-engine-cd"
]
},
{
"dest": "NGPC/boot0.rom",
@@ -237,7 +315,10 @@
"sha256": "8fb845a2f71514cec20728e2f0fecfade69444f8d50898b92c2259f1ba63e10d",
"size": 65536,
"repo_path": "bios/SNK/Neo Geo Pocket/SNK Neo-Geo Pocket Color BIOS (1999)(SNK)(en-ja).bin",
"cores": null
"cores": null,
"systems": [
"ngpc"
]
},
{
"dest": "NGPC/boot1.rom",
@@ -245,7 +326,10 @@
"sha256": "0293555b21c4fac516d25199df7809b26beeae150e1d4504a050db32264a6ad7",
"size": 65536,
"repo_path": "bios/SNK/Neo Geo Pocket/SNK Neo-Geo Pocket BIOS (1998)(SNK)(en-ja).bin",
"cores": null
"cores": null,
"systems": [
"ngpc"
]
},
{
"dest": "N64/boot.rom",
@@ -253,7 +337,10 @@
"sha256": "fa7b09795ef1e54461e59f6f2d902368133e3f1cd980e34383e6a780d74beffd",
"size": 1984,
"repo_path": "bios/Nintendo/Nintendo 64/boot.rom",
"cores": null
"cores": null,
"systems": [
"nintendo-64"
]
},
{
"dest": "N64/boot1.rom",
@@ -261,7 +348,10 @@
"sha256": "79c81fffae934b6df251da6c3a394f52c6a0eaa07115a3b9677743e3c1335f4a",
"size": 1984,
"repo_path": "bios/Nintendo/Nintendo 64/boot1.rom",
"cores": null
"cores": null,
"systems": [
"nintendo-64"
]
},
{
"dest": "N64/boot3.rom",
@@ -269,7 +359,10 @@
"sha256": "806400ec0df94b0755de6c5b8249d6b6a9866124c5ddbdac198bde22499bfb8b",
"size": 4194304,
"repo_path": "bios/Nintendo/64DD/64DD_IPL_v12_JPN.bin",
"cores": null
"cores": null,
"systems": [
"nintendo-64"
]
},
{
"dest": "N64/boot4.rom",
@@ -277,7 +370,10 @@
"sha256": "9c2962a8b994a29e4cd04b3a6e4ed730a751414655ab6a9799ebf5fc08b79d44",
"size": 4194304,
"repo_path": "bios/Nintendo/64DD/64DD_IPL_DEV.bin",
"cores": null
"cores": null,
"systems": [
"nintendo-64"
]
},
{
"dest": "N64/boot5.rom",
@@ -285,7 +381,10 @@
"sha256": "e9fec87a45fba02399e88064b9e2f8cf0f2106e351c58279a87f05da5bc984ad",
"size": 4194304,
"repo_path": "bios/Nintendo/64DD/64DD_IPL_USA.bin",
"cores": null
"cores": null,
"systems": [
"nintendo-64"
]
},
{
"dest": "GAMEBOY/boot1.rom",
@@ -293,7 +392,10 @@
"sha256": "b4f2e416a35eef52cba161b159c7c8523a92594facb924b3ede0d722867c50c7",
"size": 2304,
"repo_path": "bios/Nintendo/Game Boy Color/GBC_cgb.bin",
"cores": null
"cores": null,
"systems": [
"nintendo-gb"
]
},
{
"dest": "GBA/boot.rom",
@@ -301,7 +403,10 @@
"sha256": "fd2547724b505f487e6dcb29ec2ecff3af35a841a77ab2e85fd87350abd36570",
"size": 16384,
"repo_path": "bios/Nintendo/Game Boy Advance/GBA_bios.rom",
"cores": null
"cores": null,
"systems": [
"nintendo-gba"
]
},
{
"dest": "NES/boot0.rom",
@@ -309,7 +414,10 @@
"sha256": "99c18490ed9002d9c6d999b9d8d15be5c051bdfa7cc7e73318053c9a994b0178",
"size": 8192,
"repo_path": "bios/Arcade/FBNeo/fdsbios.nes",
"cores": null
"cores": null,
"systems": [
"nintendo-nes"
]
},
{
"dest": "PokemonMini/boot.rom",
@@ -317,7 +425,10 @@
"sha256": "45a1c7f28b9ad585e67f047abe9c1c956724bfcab8c9011002af4274e7c50e8f",
"size": 4096,
"repo_path": "bios/Nintendo/Pokemon Mini/bios.min",
"cores": null
"cores": null,
"systems": [
"nintendo-pokemon-mini"
]
},
{
"dest": "SGB/Super Game Boy 2.sfc",
@@ -325,7 +436,10 @@
"sha256": "c172498a23d1176672931bab33b629c7d28f914a43dca9e540b8af1b37ccf2c6",
"size": 524288,
"repo_path": "bios/Nintendo/Super Game Boy/SGB2.sfc/program.rom",
"cores": null
"cores": null,
"systems": [
"nintendo-sgb"
]
},
{
"dest": "SGB/Super Game Boy.sfc",
@@ -333,7 +447,10 @@
"sha256": "a75160f7b89b1f0e20fd2f6441bb86285c7378db5035ef6885485eaff6059376",
"size": 262144,
"repo_path": "bios/Nintendo/Super Game Boy/SGB1.sfc/program.rom",
"cores": null
"cores": null,
"systems": [
"nintendo-sgb"
]
},
{
"dest": "SNES/bsx_bios.rom",
@@ -341,7 +458,10 @@
"sha256": "a49827b45ff9ac9cf5b4658190e1428e59251bc82d8a63d8e9e0f71e439f008f",
"size": 1048576,
"repo_path": "bios/Nintendo/SNES/BS-X.bin",
"cores": null
"cores": null,
"systems": [
"nintendo-snes"
]
},
{
"dest": "CD-i/boot0.rom",
@@ -349,7 +469,10 @@
"sha256": "fd123e66beadaf844cb220a44166ea33f9fd0d64bafb9e6399febff445429db2",
"size": 524288,
"repo_path": "bios/Philips/CD-i/cdi220b.rom",
"cores": null
"cores": null,
"systems": [
"philips-cdi"
]
},
{
"dest": "CD-i/boot1.rom",
@@ -357,7 +480,10 @@
"sha256": "15794460f2ad630f6dd483a02ef958818c7a5c65f8afe76364bc9ffb7ccad3cc",
"size": 8192,
"repo_path": "bios/Philips/CD-i/zx405042p__cdi_slave_2.0__b43t__zzmk9213.mc68hc705c8a_withtestrom.7206",
"cores": null
"cores": null,
"systems": [
"philips-cdi"
]
},
{
"dest": "CD-i/boot2.rom",
@@ -365,7 +491,10 @@
"sha256": "e8a8cabb23650b53c2cb0763c3a1409f6c0d580a52fbe8ef834d44d4021db165",
"size": 131072,
"repo_path": "bios/Philips/CD-i/vmpega_split.rom",
"cores": null
"cores": null,
"systems": [
"philips-cdi"
]
},
{
"dest": "PocketChallengeV2/boot.rom",
@@ -373,7 +502,10 @@
"sha256": "bf4480dbea1c47c8b54ce7be9382bc1006148f431fbe4277e136351fa74f635e",
"size": 4096,
"repo_path": "bios/Bandai/WonderSwan/bootrom.ws",
"cores": null
"cores": null,
"systems": [
"pocket-challenge-v2"
]
},
{
"dest": "PocketChallengeV2/boot1.rom",
@@ -381,7 +513,10 @@
"sha256": "f5a5c044d84ce1681f94e9ef74287cb989784497be5bd5108df17908dfa55db2",
"size": 8192,
"repo_path": "bios/Bandai/WonderSwan/bootrom.wsc",
"cores": null
"cores": null,
"systems": [
"pocket-challenge-v2"
]
},
{
"dest": "MegaCD/Europe/cd_bios.rom",
@@ -389,7 +524,10 @@
"sha256": "fe608a2a07676a23ab5fd5eee2f53c9e2526d69a28aa16ccd85c0ec42e6933cb",
"size": 131072,
"repo_path": "bios/Sega/Mega CD/eu_mcd2_9303.bin",
"cores": null
"cores": null,
"systems": [
"sega-mega-cd"
]
},
{
"dest": "MegaCD/Japan/cd_bios.rom",
@@ -397,7 +535,10 @@
"sha256": "7133fc2dd2fe5b7d0acd53a5f10f3d00b5d31270239ad20d74ef32393e24af88",
"size": 131072,
"repo_path": "bios/Sega/Mega CD/jp_mcd2_921222.bin",
"cores": null
"cores": null,
"systems": [
"sega-mega-cd"
]
},
{
"dest": "MegaCD/USA/cd_bios.rom",
@@ -405,7 +546,10 @@
"sha256": "fb477cdbf94c84424c2feca4fe40656d85393fe7b7b401911b45ad2eb991258c",
"size": 131072,
"repo_path": "bios/Sega/Mega CD/SegaCDBIOS9303.bin",
"cores": null
"cores": null,
"systems": [
"sega-mega-cd"
]
},
{
"dest": "MegaCD/boot.rom",
@@ -413,7 +557,10 @@
"sha256": "59403e7f8be1d4e98d673cca17cfec072770a56415165ad7ac88dcd3f7273317",
"size": 131072,
"repo_path": "bios/Sega/Mega CD/US Sega CD 2 (Region Free) 930601 l_oliveira.bin",
"cores": null
"cores": null,
"systems": [
"sega-mega-cd"
]
},
{
"dest": "Saturn/boot.rom",
@@ -421,7 +568,10 @@
"sha256": "37561c4444bec52ae1aae31de5579f1856d5b23002ee083ade42f9ed13c8616f",
"size": 524288,
"repo_path": "bios/Sega/Saturn/.variants/hisaturn_v103.bin",
"cores": null
"cores": null,
"systems": [
"sega-saturn"
]
},
{
"dest": "NEOGEO/000-lo.lo",
@@ -429,7 +579,10 @@
"sha256": "2a76f023dc578804c6bcd58ed514ffc04fcb433b3bd75d4452575ffda57a0707",
"size": 131072,
"repo_path": "bios/SNK/Neo Geo CD/000-lo.lo",
"cores": null
"cores": null,
"systems": [
"snk-neogeo"
]
},
{
"dest": "NEOGEO/neo-epo.sp1",
@@ -437,7 +590,10 @@
"sha256": "70f7906d68acbc3630b6e7792ebb485288b05ca72c6d4c243e07e230aae8d1e4",
"size": 131072,
"repo_path": "bios/SNK/Neo Geo/neo-epo.bin",
"cores": null
"cores": null,
"systems": [
"snk-neogeo"
]
},
{
"dest": "NEOGEO/sfix.sfix",
@@ -445,7 +601,10 @@
"sha256": "fcf51e688c006408be92c5adaf37d4302d05e7e681193dd0623072e53915c90e",
"size": 131072,
"repo_path": "bios/SNK/Neo Geo/sfix.sfix",
"cores": null
"cores": null,
"systems": [
"snk-neogeo"
]
},
{
"dest": "NEOGEO/sp-s2.sp1",
@@ -453,7 +612,10 @@
"sha256": "ae1c5cc9a0acdead8a3d5a16ee84f575582f2209677464b05a2b8b0451f658a1",
"size": 131072,
"repo_path": "bios/SNK/Neo Geo/sp-s2.sp1",
"cores": null
"cores": null,
"systems": [
"snk-neogeo"
]
},
{
"dest": "NEOGEO/uni-bios.rom",
@@ -461,7 +623,10 @@
"sha256": "e016ce75097df0b5f5910e8eb4914439f5c77511de65df5a1e089eef147b256b",
"size": 131072,
"repo_path": "bios/SNK/Neo Geo/uni-bios_4_0.rom",
"cores": null
"cores": null,
"systems": [
"snk-neogeo"
]
},
{
"dest": "NeoGeo-CD/neocd.bin",
@@ -469,7 +634,10 @@
"sha256": "2e93af5848080ea04d17a7841b742f009330d30e4ff40c3410547581d921c892",
"size": 524288,
"repo_path": "bios/SNK/Neo Geo CD/neocd.bin",
"cores": null
"cores": null,
"systems": [
"snk-neogeo-cd"
]
},
{
"dest": "NeoGeo-CD/top-sp1.bin",
@@ -477,7 +645,10 @@
"sha256": "c11c33589b2057008a7e4c7c700fcd989a8c0f95f869e7e7539fdd00414d99a7",
"size": 524288,
"repo_path": "bios/SNK/Neo Geo CD/top-sp1.bin",
"cores": null
"cores": null,
"systems": [
"snk-neogeo-cd"
]
},
{
"dest": "NeoGeo-CD/uni-bioscd.rom",
@@ -485,7 +656,10 @@
"sha256": "1c3ec20824a58e5f5cbf47ccc2c91a10f34d21cfa2791b3413cea89b0c920db8",
"size": 524288,
"repo_path": "bios/SNK/Neo Geo/uni-bioscd33.rom",
"cores": null
"cores": null,
"systems": [
"snk-neogeo-cd"
]
},
{
"dest": "PSX/boot.rom",
@@ -493,7 +667,10 @@
"sha256": "39dcc1a0717036c9b6ac52fefd1ee7a57d3808e8cfbc755879fa685a0a738278",
"size": 524288,
"repo_path": "bios/Sony/PlayStation/scph7001.bin",
"cores": null
"cores": null,
"systems": [
"sony-playstation"
]
},
{
"dest": "PSX/boot1.rom",
@@ -501,7 +678,10 @@
"sha256": "e900504d1755f021f861b82c8258c5e6658c7b592f800cccd91f5d32ea380d28",
"size": 524288,
"repo_path": "bios/Sony/PlayStation/scph7000.bin",
"cores": null
"cores": null,
"systems": [
"sony-playstation"
]
},
{
"dest": "PSX/boot2.rom",
@@ -509,7 +689,10 @@
"sha256": "5e84a94818cf5282f4217591fefd88be36b9b174b3cc7cb0bcd75199beb450f1",
"size": 524288,
"repo_path": "bios/Sony/PlayStation/scph7002.bin",
"cores": null
"cores": null,
"systems": [
"sony-playstation"
]
},
{
"dest": "PSX/sbi.zip",
@@ -517,7 +700,10 @@
"sha256": "32db7bb64131623fa912ef30a85f7d70cee2abbca56c21d360d2025e12b8aca9",
"size": 218953,
"repo_path": "bios/Sony/PlayStation/sbi.zip",
"cores": null
"cores": null,
"systems": [
"sony-playstation"
]
},
{
"dest": "Studio-II/boot0.rom",
@@ -525,7 +711,10 @@
"sha256": "1e7ae3cd972eb39681e6c6df5f1ac6f7d86c9e59788e40d6b4c948375e9ca5f7",
"size": 2048,
"repo_path": "bios/RCA/Studio II/boot0.rom",
"cores": null
"cores": null,
"systems": [
"studio-ii"
]
},
{
"dest": "Studio-II/boot1.rom",
@@ -533,7 +722,10 @@
"sha256": "e90cb0c5be993689a2d4fa03e664f5943967160153520d435391aaefff06da35",
"size": 4096,
"repo_path": "bios/RCA/Studio II/boot1.rom",
"cores": null
"cores": null,
"systems": [
"studio-ii"
]
},
{
"dest": "Studio-II/boot2.rom",
@@ -541,7 +733,10 @@
"sha256": "a0d6c1852fb407f86d25c802441ff15ec7fd041683c6a9ae0d23db0ca0df8c0b",
"size": 4096,
"repo_path": "bios/RCA/Studio II/boot2.rom",
"cores": null
"cores": null,
"systems": [
"studio-ii"
]
},
{
"dest": "Studio-II/boot3.rom",
@@ -549,7 +744,10 @@
"sha256": "7a95530b9be7fe487e027a5ea7ffe4a7561762cc3fc8cdc535d6f36e5f23c8a0",
"size": 2048,
"repo_path": "bios/RCA/Studio II/boot3.rom",
"cores": null
"cores": null,
"systems": [
"studio-ii"
]
},
{
"dest": "Studio-II/chip8.bin",
@@ -557,7 +755,10 @@
"sha256": "8764ba7e02fe00489997b45ac1f15f188f726cbcd5311e252225e62eb58d6d04",
"size": 768,
"repo_path": "bios/RCA/Studio II/boot4.rom",
"cores": null
"cores": null,
"systems": [
"studio-ii"
]
},
{
"dest": "Studio-II/openstudio2.bin",
@@ -565,7 +766,10 @@
"sha256": "36ddd9ffa17a194bd8103efb807e104a529134685502839a4f14ea4d5de648ad",
"size": 2048,
"repo_path": "bios/RCA/Studio II/openstudio2.bin",
"cores": null
"cores": null,
"systems": [
"studio-ii"
]
},
{
"dest": "SuperAcan/boot0.rom",
@@ -573,7 +777,10 @@
"sha256": "2e4d88bec69b5e7e4803368c233ce0d20f6dd107c5af0cfcc0089d310c695d7c",
"size": 4096,
"repo_path": "bios/Funtech/Super A'Can/boot0.rom",
"cores": null
"cores": null,
"systems": [
"superacan"
]
},
{
"dest": "SuperAcan/boot1.rom",
@@ -581,7 +788,10 @@
"sha256": "219f51bcb8544fe733bf784e087544f97aa5457945260c7fa07a8639f30f3a68",
"size": 8192,
"repo_path": "bios/Funtech/Super A'Can/boot1.rom",
"cores": null
"cores": null,
"systems": [
"superacan"
]
},
{
"dest": "SuperAcan/boot2.rom",
@@ -589,7 +799,10 @@
"sha256": "9889590805a97b7bb439d853d9ae4d6b31067bacb8225ab0538f3491dedab4b8",
"size": 8192,
"repo_path": "bios/Funtech/Super A'Can/boot2.rom",
"cores": null
"cores": null,
"systems": [
"superacan"
]
},
{
"dest": "COCO3/boot0.rom",
@@ -597,7 +810,10 @@
"sha256": "ad358430568250eb8330a37f85361d9ce67e5ae6d5a28c17b31802cd3953a5d2",
"size": 32768,
"repo_path": "bios/Tandy/CoCo/coco3.rom",
"cores": null
"cores": null,
"systems": [
"tandy-coco"
]
},
{
"dest": "COCO3/boot1.rom",
@@ -605,7 +821,10 @@
"sha256": "1c40c5a74e72edaeecc2511fee1aab347eae2c3d5fc6778cb622e3df14d63157",
"size": 8192,
"repo_path": "bios/Tandy/CoCo/disk11.rom",
"cores": null
"cores": null,
"systems": [
"tandy-coco"
]
},
{
"dest": "COCO3/boot2.rom",
@@ -613,7 +832,10 @@
"sha256": "1a5a3e95522296f66a192e9a7ca0725ecc88862f9bb31f50ef37ae789404692f",
"size": 8192,
"repo_path": "bios/Tandy/CoCo/orch90.rom",
"cores": null
"cores": null,
"systems": [
"tandy-coco"
]
},
{
"dest": "TI-99_4A/boot0.rom",
@@ -621,7 +843,10 @@
"sha256": "53ad354861a62b9144e02e878845c7e1a5dd75342b715047db64b780954f7c88",
"size": 196608,
"repo_path": "bios/Texas Instruments/TI-99/boot0.rom",
"cores": null
"cores": null,
"systems": [
"ti99"
]
},
{
"dest": "GameCom/boot.rom",
@@ -629,7 +854,10 @@
"sha256": "64cbaa1a5e8bae8fae90a7affd6743df5d23edfc4e1e23002ca77c8b7ec1bb64",
"size": 262144,
"repo_path": "bios/Tiger/Game.com/GameCom External BIOS (Kitrinx v0.03).bin",
"cores": null
"cores": null,
"systems": [
"tiger-game-com"
]
},
{
"dest": "VideoBrain/boot.rom",
@@ -637,7 +865,10 @@
"sha256": "545b466e7cc0c2cce7e9479857dbedee1476fc56245f0de45f816c1b99b75562",
"size": 4096,
"repo_path": "bios/VideoBrain/Family Computer/boot.rom",
"cores": null
"cores": null,
"systems": [
"videobrain"
]
},
{
"dest": "WonderSwan/boot.rom",
@@ -645,7 +876,10 @@
"sha256": "bf4480dbea1c47c8b54ce7be9382bc1006148f431fbe4277e136351fa74f635e",
"size": 4096,
"repo_path": "bios/Bandai/WonderSwan/bootrom.ws",
"cores": null
"cores": null,
"systems": [
"wonderswan"
]
},
{
"dest": "WonderSwan/boot1.rom",
@@ -653,7 +887,10 @@
"sha256": "f5a5c044d84ce1681f94e9ef74287cb989784497be5bd5108df17908dfa55db2",
"size": 8192,
"repo_path": "bios/Bandai/WonderSwan/bootrom.wsc",
"cores": null
"cores": null,
"systems": [
"wonderswan"
]
},
{
"dest": "WonderSwanColor/boot.rom",
@@ -661,7 +898,10 @@
"sha256": "bf4480dbea1c47c8b54ce7be9382bc1006148f431fbe4277e136351fa74f635e",
"size": 4096,
"repo_path": "bios/Bandai/WonderSwan/bootrom.ws",
"cores": null
"cores": null,
"systems": [
"wonderswan-color"
]
},
{
"dest": "WonderSwanColor/boot1.rom",
@@ -669,7 +909,10 @@
"sha256": "f5a5c044d84ce1681f94e9ef74287cb989784497be5bd5108df17908dfa55db2",
"size": 8192,
"repo_path": "bios/Bandai/WonderSwan/bootrom.wsc",
"cores": null
"cores": null,
"systems": [
"wonderswan-color"
]
}
]
}
+5202 -467
View File
File diff suppressed because it is too large. Load diff
+6214 -713
View File
File diff suppressed because it is too large. Load diff
+6290 -443
View File
File diff suppressed because it is too large. Load diff
+13173 -2194
View File
File diff suppressed because it is too large. Load diff
+7137 -726
View File
File diff suppressed because it is too large. Load diff
+1990 -153
View File
File diff suppressed because it is too large. Load diff
+4675 -542
View File
File diff suppressed because it is too large. Load diff
+4
View File
@@ -805,6 +805,10 @@ platforms:
target_source: null
install:
detect:
# installer.iss: DefaultDirName=C:\RetroBat, the first place to look.
- os: windows
method: path_exists
path: 'C:\RetroBat\bios'
- os: windows
method: path_exists
path: '%USERPROFILE%\RetroBat\bios'
+9 -37
View File
@@ -163,22 +163,15 @@ shared_groups:
# QUASI88 searches "quasi88/" subfolder first
# ref: quasi88-libretro/src/LIBRETRO/libretro.c:463 — snprintf(..., "%s%cquasi88%c%s", ...)
quasi88:
- name: N88.ROM
destination: quasi88/N88.ROM
required: true
md5: "4f984e04a99d56c4cfe36115415d6eb8"
- name: N88SUB.ROM
destination: quasi88/N88SUB.ROM
required: true
md5: "793f86784e5608352a5d7f03f03e0858"
- name: N88N.ROM
destination: quasi88/N88N.ROM
required: true
md5: "2ff07b8769367321128e03924af668a0"
- name: N88KNJ1.ROM
destination: quasi88/N88KNJ1.ROM
required: true
md5: "d81c6d5d7ad1a4bbbd6ae22a01257603"
# Only what System.dat does not declare for nec-pc-88: the mkII SR
# extension ROMs that match N88.ROM (MAME pc8801mk2sr: 710a63ec, c0bd2aa6,
# af2b6efa, 7713c519). The core reads N88EXTn.ROM before n88_n.rom
# (src/LIBRETRO/libretro.c:109-112), so they win over the n88_n.rom dumps
# System.dat pairs with that main ROM, which come from other models (n88_0
# 61984bab is the original PC-8801's). N88SUB.ROM, N88.ROM, N88N.ROM and
# N88KNJ1.ROM are the native disk.rom, n88.rom, n88n.rom and n88knj1.rom
# under the other spelling the core tries: aliases in the profile, not
# files of their own here, or the pack carried disk.rom twice.
- name: N88EXT0.ROM
destination: quasi88/N88EXT0.ROM
required: true
@@ -195,27 +188,6 @@ shared_groups:
destination: quasi88/N88EXT3.ROM
required: true
md5: "fc4b76a402ba501e6ba6de4b3e8b4273"
# N88EXT0-3.ROM above are the mkII SR extension ROMs that match N88.ROM
# (MAME pc8801mk2sr: 710a63ec, c0bd2aa6, af2b6efa, 7713c519). The core
# reads N88EXTn.ROM before n88_n.rom (src/LIBRETRO/libretro.c:109-112),
# so they win over the n88_n.rom dumps System.dat pairs with that main ROM,
# which come from other models (n88_0 61984bab is the original PC-8801's).
- name: n88_0.rom
destination: quasi88/n88_0.rom
required: false
md5: "e28fe3f520bea594350ea8fb00395370"
- name: n88_1.rom
destination: quasi88/n88_1.rom
required: false
md5: "a8e298da7ac947669bcb1ff25cee0a83"
- name: n88_2.rom
destination: quasi88/n88_2.rom
required: false
md5: "9d03154fd9abfc28c4e6d4dc705e6e23"
- name: n88_3.rom
destination: quasi88/n88_3.rom
required: false
md5: "e1791f8154f1cdf22b576a1a365b6e1f"
# Sinclair ZX Spectrum — Fuse core (Pentagon/Scorpion ROMs)
# VERIFIED: fuse-libretro/src/compat/paths.c compat_get_next_path()
+14
View File
@@ -384,6 +384,7 @@ systems:
- name: qsound.zip
destination: qsound.zip
required: true
curated: true
native_id: Arcade
core: fbneo
manufacturer: Various
@@ -1907,24 +1908,31 @@ systems:
- name: gc-ntsc-12.bin
destination: dolphin-emu/Sys/GC/USA/IPL.bin
required: false
curated: true
- name: gc-pal-12.bin
destination: dolphin-emu/Sys/GC/EUR/IPL.bin
required: false
curated: true
- name: gc-ntsc-12.bin
destination: dolphin-emu/Sys/GC/JAP/IPL.bin
required: false
curated: true
- name: dsp_coef.bin
destination: dolphin-emu/Sys/GC/dsp_coef.bin
required: true
curated: true
- name: dsp_rom.bin
destination: dolphin-emu/Sys/GC/dsp_rom.bin
required: true
curated: true
- name: font_western.bin
destination: dolphin-emu/Sys/GC/font_western.bin
required: false
curated: true
- name: font_japanese.bin
destination: dolphin-emu/Sys/GC/font_japanese.bin
required: false
curated: true
native_id: Nintendo - GameCube
core: dolphin
manufacturer: Nintendo
@@ -1997,15 +2005,19 @@ systems:
- name: dsi_bios7.bin
destination: dsi_bios7.bin
required: true
curated: true
- name: dsi_bios9.bin
destination: dsi_bios9.bin
required: true
curated: true
- name: dsi_firmware.bin
destination: dsi_firmware.bin
required: true
curated: true
- name: dsi_nand.bin
destination: dsi_nand.bin
required: true
curated: true
native_id: Nintendo - Nintendo DS
core: desmume
manufacturer: Nintendo
@@ -2554,6 +2566,7 @@ systems:
- name: segasp.zip
destination: dc/segasp.zip
required: true
curated: true
native_id: Sega - Dreamcast-based Arcade
sega-game-gear:
files:
@@ -4731,6 +4744,7 @@ systems:
- name: data.zip
destination: xrick/data.zip
required: true
curated: true
core: xrick
manufacturer: Other
docs: "https://docs.libretro.com/library/xrick/"
+7
View File
@@ -787,6 +787,7 @@ systems:
crc32: 51a12d90
size: 32768
native_system: turbografx-cd
mirror_of: tg16
- name: gexpress.pce
destination: turbografx-cd/gexpress.pce
required: true
@@ -795,6 +796,7 @@ systems:
crc32: 51a12d90
size: 32768
native_system: turbografx-cd
mirror_of: tg16
- name: syscard1.pce
destination: turbografx-cd/syscard1.pce
required: true
@@ -803,6 +805,7 @@ systems:
crc32: 3f9f95a4
size: 262144
native_system: turbografx-cd
mirror_of: tg16
- name: syscard2.pce
destination: turbografx-cd/syscard2.pce
required: true
@@ -811,6 +814,7 @@ systems:
crc32: 283b74e0
size: 262144
native_system: turbografx-cd
mirror_of: tg16
- name: syscard2u.pce
destination: turbografx-cd/syscard2u.pce
required: true
@@ -819,6 +823,7 @@ systems:
crc32: ff2a5ec3
size: 262144
native_system: turbografx-cd
mirror_of: tg16
- name: syscard3.pce
destination: turbografx-cd/syscard3.pce
required: true
@@ -827,6 +832,7 @@ systems:
crc32: 6d9a73ef
size: 262144
native_system: turbografx-cd
mirror_of: tg16
- name: syscard3u.pce
destination: turbografx-cd/syscard3u.pce
required: true
@@ -835,6 +841,7 @@ systems:
crc32: 2b5b75fe
size: 262144
native_system: turbografx-cd
mirror_of: tg16
nec-pc-98:
files:
- name: 2608_bd.wav
+62 -59
View File
@@ -1,100 +1,103 @@
{
"tag": "v2026.09.04",
"tag": "v2026.10.10",
"packs": {
"Batocera_43.1_BIOS_Pack.zip": {
"files": 1839,
"extracted_size": 4320230269,
"download_size": 2557851727,
"files": 12810,
"extracted_size": 8062660183,
"download_size": 5570768859,
"assets": [
"Batocera_43.1_BIOS_Pack.zip.001",
"Batocera_43.1_BIOS_Pack.zip.002"
"Batocera_43.1_BIOS_Pack.part1of3.zip",
"Batocera_43.1_BIOS_Pack.part2of3.zip",
"Batocera_43.1_BIOS_Pack.part3of3.zip"
]
},
"BizHawk_2.11.1_BIOS_Pack.zip": {
"files": 542,
"extracted_size": 2332771486,
"download_size": 1223296442,
"files": 950,
"extracted_size": 2585360680,
"download_size": 1469752558,
"assets": [
"BizHawk_2.11.1_BIOS_Pack.zip"
]
},
"EmuDeck_2.3.8_BIOS_Pack.zip": {
"files": 624,
"extracted_size": 3398423896,
"download_size": 1889509442,
"EmuDeck_2.7EA_BIOS_Pack.zip": {
"files": 620,
"extracted_size": 3473777719,
"download_size": 1939696164,
"assets": [
"EmuDeck_2.3.8_BIOS_Pack.zip"
"EmuDeck_2.7EA_BIOS_Pack.zip"
]
},
"MiSTer_FPGA_2026-08-29_BIOS_Pack.zip": {
"files": 74,
"extracted_size": 25209623,
"download_size": 16769418,
"MiSTer_FPGA_2026-09-29_BIOS_Pack.zip": {
"files": 83,
"extracted_size": 29989684,
"download_size": 18787872,
"assets": [
"MiSTer_FPGA_2026-08-29_BIOS_Pack.zip"
"MiSTer_FPGA_2026-09-29_BIOS_Pack.zip"
]
},
"ROCKNIX_20260901_BIOS_Pack.zip": {
"files": 1741,
"extracted_size": 5715015067,
"download_size": 3337595108,
"ROCKNIX_20261001_BIOS_Pack.zip": {
"files": 5804,
"extracted_size": 6538611412,
"download_size": 4022886600,
"assets": [
"ROCKNIX_20260901_BIOS_Pack.zip.001",
"ROCKNIX_20260901_BIOS_Pack.zip.002"
"ROCKNIX_20261001_BIOS_Pack.part1of2.zip",
"ROCKNIX_20261001_BIOS_Pack.part2of2.zip"
]
},
"Recalbox_10.0.8_BIOS_Pack.zip": {
"files": 1330,
"extracted_size": 3883703707,
"download_size": 2096847659,
"Recalbox_10.1.1_BIOS_Pack.zip": {
"files": 3222,
"extracted_size": 4173452215,
"download_size": 2367991387,
"assets": [
"Recalbox_10.0.8_BIOS_Pack.zip.001",
"Recalbox_10.0.8_BIOS_Pack.zip.002"
"Recalbox_10.1.1_BIOS_Pack.part1of2.zip",
"Recalbox_10.1.1_BIOS_Pack.part2of2.zip"
]
},
"RetroArch_Lakka_v1.22.2_BIOS_Pack.zip": {
"files": 4525,
"extracted_size": 5882727352,
"download_size": 3349430771,
"files": 8504,
"extracted_size": 6407344187,
"download_size": 3853113197,
"assets": [
"RetroArch_Lakka_v1.22.2_BIOS_Pack.zip.001",
"RetroArch_Lakka_v1.22.2_BIOS_Pack.zip.002"
"RetroArch_Lakka_v1.22.2_BIOS_Pack.part1of2.zip",
"RetroArch_Lakka_v1.22.2_BIOS_Pack.part2of2.zip"
]
},
"RetroBat_8.2.1_BIOS_Pack.zip": {
"files": 1466,
"extracted_size": 4724194892,
"download_size": 3105818817,
"files": 12399,
"extracted_size": 8493976396,
"download_size": 6134642511,
"assets": [
"RetroBat_8.2.1_BIOS_Pack.zip.001",
"RetroBat_8.2.1_BIOS_Pack.zip.002"
"RetroBat_8.2.1_BIOS_Pack.part1of3.zip",
"RetroBat_8.2.1_BIOS_Pack.part2of3.zip",
"RetroBat_8.2.1_BIOS_Pack.part3of3.zip"
]
},
"RetroDECK_0.10.9b_BIOS_Pack.zip": {
"files": 3519,
"extracted_size": 6627934502,
"download_size": 4132852872,
"RetroDECK_0.10.10b_BIOS_Pack.zip": {
"files": 7793,
"extracted_size": 8590201314,
"download_size": 5469112852,
"assets": [
"RetroDECK_0.10.9b_BIOS_Pack.zip.001",
"RetroDECK_0.10.9b_BIOS_Pack.zip.002",
"RetroDECK_0.10.9b_BIOS_Pack.zip.003"
"RetroDECK_0.10.10b_BIOS_Pack.part1of3.zip",
"RetroDECK_0.10.10b_BIOS_Pack.part2of3.zip",
"RetroDECK_0.10.10b_BIOS_Pack.part3of3.zip"
]
},
"RetroPie_v1.22.2_BIOS_Pack.zip": {
"files": 4525,
"extracted_size": 5882738533,
"download_size": 3349391169,
"RetroPie_4.8.12_BIOS_Pack.zip": {
"files": 12533,
"extracted_size": 8742145940,
"download_size": 5482623403,
"assets": [
"RetroPie_v1.22.2_BIOS_Pack.zip.001",
"RetroPie_v1.22.2_BIOS_Pack.zip.002"
"RetroPie_4.8.12_BIOS_Pack.part1of3.zip",
"RetroPie_4.8.12_BIOS_Pack.part2of3.zip",
"RetroPie_4.8.12_BIOS_Pack.part3of3.zip"
]
},
"RomM_5.2.0_BIOS_Pack.zip": {
"files": 617,
"extracted_size": 1370456481,
"download_size": 765186250,
"RomM_5.3.1_BIOS_Pack.zip": {
"files": 1087,
"extracted_size": 1581830590,
"download_size": 973353236,
"assets": [
"RomM_5.2.0_BIOS_Pack.zip"
"RomM_5.3.1_BIOS_Pack.zip"
]
}
}
+105 -24
View File
@@ -4,55 +4,136 @@
"title": "RetroBIOS content database",
"type": "object",
"additionalProperties": false,
"required": ["schema_version", "generated_at", "total_files", "total_size", "files", "indexes"],
"required": [
"schema_version",
"generated_at",
"total_files",
"total_size",
"files",
"indexes"
],
"properties": {
"schema_version": { "const": 1 },
"generated_at": { "type": "string", "format": "date-time" },
"total_files": { "type": "integer", "minimum": 0 },
"total_size": { "type": "integer", "minimum": 0 },
"schema_version": {
"const": 1
},
"generated_at": {
"type": "string",
"format": "date-time"
},
"total_files": {
"type": "integer",
"minimum": 0
},
"total_size": {
"type": "integer",
"minimum": 0
},
"bios_dir": {
"type": "string",
"description": "Directory the files were scanned from; _mame_clones.json sits beside it."
},
"files": {
"type": "object",
"propertyNames": { "pattern": "^[a-f0-9]{40}$" },
"propertyNames": {
"pattern": "^[a-f0-9]{40}$"
},
"additionalProperties": {
"type": "object",
"additionalProperties": false,
"required": ["path", "name", "size", "sha1", "md5", "sha256", "crc32", "adler32"],
"required": [
"path",
"name",
"size",
"sha1",
"md5",
"sha256",
"crc32",
"adler32"
],
"properties": {
"path": { "type": "string", "minLength": 1 },
"name": { "type": "string", "minLength": 1 },
"size": { "type": "integer", "minimum": 0 },
"sha1": { "type": "string", "pattern": "^[a-f0-9]{40}$" },
"md5": { "type": "string", "pattern": "^[a-f0-9]{32}$" },
"sha256": { "type": "string", "pattern": "^[a-f0-9]{64}$" },
"crc32": { "type": "string", "pattern": "^[a-f0-9]{8}$" },
"adler32": { "type": "string", "pattern": "^[a-f0-9]{8}$" },
"provenance": { "type": "object" }
"path": {
"type": "string",
"minLength": 1
},
"name": {
"type": "string",
"minLength": 1
},
"size": {
"type": "integer",
"minimum": 0
},
"sha1": {
"type": "string",
"pattern": "^[a-f0-9]{40}$"
},
"md5": {
"type": "string",
"pattern": "^[a-f0-9]{32}$"
},
"sha256": {
"type": "string",
"pattern": "^[a-f0-9]{64}$"
},
"crc32": {
"type": "string",
"pattern": "^[a-f0-9]{8}$"
},
"adler32": {
"type": "string",
"pattern": "^[a-f0-9]{8}$"
},
"provenance": {
"type": "object"
}
}
}
},
"indexes": {
"type": "object",
"additionalProperties": false,
"required": ["by_md5", "by_name", "by_crc32", "by_sha256", "by_path_suffix"],
"required": [
"by_md5",
"by_name",
"by_crc32",
"by_sha256",
"by_path_suffix"
],
"properties": {
"by_md5": { "$ref": "#/$defs/hashIndex" },
"by_crc32": { "$ref": "#/$defs/hashIndex" },
"by_sha256": { "$ref": "#/$defs/hashIndex" },
"by_name": { "$ref": "#/$defs/listIndex" },
"by_path_suffix": { "$ref": "#/$defs/listIndex" }
"by_md5": {
"$ref": "#/$defs/hashIndex"
},
"by_crc32": {
"$ref": "#/$defs/hashIndex"
},
"by_sha256": {
"$ref": "#/$defs/hashIndex"
},
"by_name": {
"$ref": "#/$defs/listIndex"
},
"by_path_suffix": {
"$ref": "#/$defs/listIndex"
}
}
}
},
"$defs": {
"hashIndex": {
"type": "object",
"additionalProperties": { "type": "string", "pattern": "^[a-f0-9]{40}$" }
"additionalProperties": {
"type": "string",
"pattern": "^[a-f0-9]{40}$"
}
},
"listIndex": {
"type": "object",
"additionalProperties": {
"type": "array",
"items": { "type": "string", "pattern": "^[a-f0-9]{40}$" },
"items": {
"type": "string",
"pattern": "^[a-f0-9]{40}$"
},
"minItems": 1,
"uniqueItems": true
}
+51 -3
View File
@@ -515,9 +515,24 @@
"pattern": "^[a-fA-F0-9]{8}$"
},
"known_hash_adler32": {
"type": [
"string",
"integer"
"description": "Adler-32 values the code accepts; a list when several revisions pass.",
"oneOf": [
{
"type": [
"string",
"integer"
]
},
{
"type": "array",
"items": {
"type": [
"string",
"integer"
]
},
"minItems": 1
}
]
},
"validation": {
@@ -644,6 +659,39 @@
]
}
},
{
"if": {
"anyOf": [
{
"required": [
"path"
],
"properties": {
"path": {
"type": "string",
"pattern": "/$"
}
}
},
{
"required": [
"standalone_path"
],
"properties": {
"standalone_path": {
"type": "string",
"pattern": "/$"
}
}
}
]
},
"then": {
"required": [
"type"
]
}
},
{
"if": {
"required": [
+176 -1
View File
@@ -129,7 +129,8 @@
"hash_mismatch",
"not_found",
"external",
"user_provided"
"user_provided",
"no_platform_slug"
]
},
"cores": {
@@ -145,6 +146,93 @@
"uniqueItems": true
}
]
},
"regions": {
"description": "The regions the emulator code selects the file for. Absent when it never competes.",
"type": "array",
"items": {
"type": "string",
"enum": [
"argentina",
"asia",
"asia-ntsc",
"asia-pal",
"australia",
"brazil",
"canada",
"china",
"denmark",
"europe",
"finland",
"france",
"germany",
"greece",
"hong-kong",
"india",
"italy",
"japan",
"latin-america",
"mexico",
"netherlands",
"new-zealand",
"north-america",
"norway",
"oceania",
"poland",
"portugal",
"russia",
"singapore",
"south-korea",
"spain",
"sweden",
"taiwan",
"uk",
"world"
]
},
"minItems": 1,
"maxItems": 1000,
"uniqueItems": true
},
"region_groups": {
"description": "Groups the file competes in as a core extra, whatever systems are chosen.",
"type": "array",
"items": {
"type": "string",
"minLength": 1,
"maxLength": 256
},
"minItems": 1,
"maxItems": 1000,
"uniqueItems": true
},
"region_system_groups": {
"description": "Groups the file competes in as the platform's own declaration: present only when that system is kept.",
"type": "array",
"items": {
"type": "string",
"minLength": 1,
"maxLength": 256
},
"minItems": 1,
"maxItems": 1000,
"uniqueItems": true
},
"systems": {
"description": "Every platform system that declares the file, for the installer's --system.",
"type": "array",
"items": {
"type": "string",
"minLength": 1,
"maxLength": 256
},
"minItems": 1,
"maxItems": 1000,
"uniqueItems": true
},
"priority": {
"description": "The rank the code searches the file at, lower first: a world file withdraws an unmatched regional one only when it ranks no worse.",
"type": "integer"
}
}
}
@@ -202,6 +290,93 @@
"release_asset": {
"type": "string",
"pattern": "^[^/\\\\]+$"
},
"systems": {
"description": "Every platform system that declares the file, for the installer's --system.",
"type": "array",
"items": {
"type": "string",
"minLength": 1,
"maxLength": 256
},
"minItems": 1,
"maxItems": 1000,
"uniqueItems": true
},
"regions": {
"description": "The regions the emulator code selects the file for. Absent when it never competes.",
"type": "array",
"items": {
"type": "string",
"enum": [
"argentina",
"asia",
"asia-ntsc",
"asia-pal",
"australia",
"brazil",
"canada",
"china",
"denmark",
"europe",
"finland",
"france",
"germany",
"greece",
"hong-kong",
"india",
"italy",
"japan",
"latin-america",
"mexico",
"netherlands",
"new-zealand",
"north-america",
"norway",
"oceania",
"poland",
"portugal",
"russia",
"singapore",
"south-korea",
"spain",
"sweden",
"taiwan",
"uk",
"world"
]
},
"minItems": 1,
"maxItems": 1000,
"uniqueItems": true
},
"region_groups": {
"description": "Groups the file competes in as a core extra, whatever systems are chosen.",
"type": "array",
"items": {
"type": "string",
"minLength": 1,
"maxLength": 256
},
"minItems": 1,
"maxItems": 1000,
"uniqueItems": true
},
"region_system_groups": {
"description": "Groups the file competes in as the platform's own declaration: present only when that system is kept.",
"type": "array",
"items": {
"type": "string",
"minLength": 1,
"maxLength": 256
},
"minItems": 1,
"maxItems": 1000,
"uniqueItems": true
},
"priority": {
"description": "The rank the code searches the file at, lower first: a world file withdraws an unmatched regional one only when it ranks no worse.",
"type": "integer"
}
},
"oneOf": [
+8
View File
@@ -280,6 +280,14 @@
"type": "string",
"description": "System id the platform itself uses for this file"
},
"mirror_of": {
"type": "string",
"description": "Native system whose entry this one repeats; the platform's own file does not carry the copy"
},
"curated": {
"type": "boolean",
"description": "Added by our scraper from the cores' source, not declared in the platform's own file"
},
"native_name": {
"type": "string",
"description": "Display name the platform gives its own system"
+69 -7
View File
@@ -43,24 +43,86 @@ def write_if_changed(path: str, content: str, normalize=None) -> bool:
)
if _strip_timestamps(before) == _strip_timestamps(after):
return False
# Truncate-then-write leaves a half-written artifact behind an interrupt,
# and every generator in the repo funnels through here: a partial
# database.json or README.md is committed-looking and silently wrong.
# The scratch file sits beside the target so the rename stays on one
# filesystem, which is what makes it atomic.
write_text_atomic(path, content)
return True
def write_text_atomic(path: str, content: str) -> None:
"""Write a whole file or nothing.
Truncate-then-write leaves a half-written artifact behind an interrupt:
a partial database.json, manifest or README.md is committed-looking and
silently wrong. The scratch file sits beside the target so the rename
stays on one filesystem, which is what makes it atomic.
"""
directory = os.path.dirname(os.path.abspath(path))
handle, scratch = tempfile.mkstemp(
dir=directory, prefix=f".{os.path.basename(path)}.", suffix=".tmp"
)
try:
with os.fdopen(handle, "w") as f:
with os.fdopen(handle, "w", encoding="utf-8") as f:
f.write(content)
os.replace(scratch, path)
except BaseException:
with contextlib.suppress(OSError):
os.unlink(scratch)
raise
return True
def write_bytes_atomic(path: str, content: bytes) -> None:
"""Write a whole binary file or nothing, as write_text_atomic does."""
directory = os.path.dirname(os.path.abspath(path))
handle, scratch = tempfile.mkstemp(
dir=directory, prefix=f".{os.path.basename(path)}.", suffix=".tmp"
)
try:
with os.fdopen(handle, "wb") as f:
f.write(content)
os.replace(scratch, path)
except BaseException:
with contextlib.suppress(OSError):
os.unlink(scratch)
raise
@contextlib.contextmanager
def file_lock(lock_path: str | os.PathLike, shared: bool = False):
"""Hold a lock on lock_path, waiting for it if taken.
Several sessions refresh the same caches: without it, two swaps of one
tree interleave, or two read-modify-writes of one index lose an entry.
On platforms without flock the lock is a no-op.
"""
try:
import fcntl
except ImportError:
yield
return
os.makedirs(os.path.dirname(os.path.abspath(lock_path)), exist_ok=True)
with open(lock_path, "a") as handle:
fcntl.flock(handle, fcntl.LOCK_SH if shared else fcntl.LOCK_EX)
try:
yield
finally:
fcntl.flock(handle, fcntl.LOCK_UN)
def copy_file_atomic(source: str, path: str) -> None:
"""Copy a file into place whole or not at all, metadata included."""
import shutil
directory = os.path.dirname(os.path.abspath(path))
handle, scratch = tempfile.mkstemp(
dir=directory, prefix=f".{os.path.basename(path)}.", suffix=".tmp"
)
os.close(handle)
try:
shutil.copy2(source, scratch)
os.replace(scratch, path)
except BaseException:
with contextlib.suppress(OSError):
os.unlink(scratch)
raise
def _strip_timestamps(text: str) -> str:
"""Remove known timestamp patterns for content comparison."""
+12 -4
View File
@@ -152,12 +152,13 @@ def print_report(report: dict) -> None:
print(f"\nSummary: {', '.join(parts)}")
def update_changed(report: dict) -> None:
"""Refresh entries that have changed."""
def update_changed(report: dict) -> list[str]:
"""Refresh entries that have changed; the keys whose refresh failed."""
failed: list[str] = []
for e in report.get("entries", []):
if e["status"] == "UPDATED" and e.get("key"):
log.info("refreshing %s ...", e["key"])
subprocess.run(
result = subprocess.run(
[
sys.executable,
"scripts/refresh_data_dirs.py",
@@ -167,6 +168,10 @@ def update_changed(report: dict) -> None:
],
check=False,
)
if result.returncode != 0:
log.error("refresh of %s failed (exit %d)", e["key"], result.returncode)
failed.append(e["key"])
return failed
def main() -> None:
@@ -194,7 +199,10 @@ def main() -> None:
print_report(report)
if args.update:
update_changed(report)
failed = update_changed(report)
if failed:
print(f"ERROR: refresh failed for {', '.join(failed)}", file=sys.stderr)
sys.exit(1)
# Unreachable upstream means the freshness question was not answered, and
# a zero exit says it was answered "fresh".
+1 -1
View File
@@ -1057,7 +1057,7 @@ def main() -> int:
parser.add_argument("--profiles", action="store_true", help="also run profile_sync (slow)")
parser.add_argument("--offline", action="store_true", help="no network, local ages only")
parser.add_argument("--jobs", type=int, default=4, help="parallel scrapers")
parser.add_argument("--cache-dir", default=".cache/upstream")
parser.add_argument("--cache-dir", default=upstream.CACHE_DIR)
parser.add_argument("--native-cache-dir", default=export_native.DEFAULT_CACHE)
parser.add_argument("--truth-dir", default="dist/truth")
parser.add_argument("--platforms-dir", default="platforms")
+280 -85
View File
@@ -6,6 +6,8 @@ and file resolution - eliminates DRY violations across scripts.
from __future__ import annotations
from collections import Counter
import hashlib
import functools
import json
@@ -157,7 +159,11 @@ def load_platform_config(platform_name: str, platforms_dir: str = "platforms") -
key = (gf.get("name"), gf.get("destination", gf.get("name")))
dest_lower = gf.get("destination", gf.get("name", "")).lower()
if key not in existing and dest_lower not in existing_lower:
system.setdefault("files", []).append(gf)
# Marked as ours: the platform's own file does not
# carry it, and an export must not count it kept.
system.setdefault("files", []).append(
{**gf, "shared_group": group_name}
)
existing.add(key)
# Merge metadata from _registry.yml. The registry is our curated source;
@@ -239,6 +245,50 @@ def list_registered_platforms(
return platforms
def _target_overrides(platform_name: str, targets_dir: str) -> dict:
overrides_file = os.path.join(targets_dir, "_overrides.yml")
if not os.path.exists(overrides_file):
return {}
with open(overrides_file) as f:
all_overrides = yaml_load(f) or {}
return all_overrides.get(platform_name, {}).get("targets", {})
def _target_alias_index(targets: dict, overrides: dict) -> dict[str, str]:
"""Every name a target answers to, mapped to the name its file uses."""
alias_index: dict[str, str] = {}
for tname in targets:
alias_index[tname] = tname
for alias in overrides.get(tname, {}).get("aliases", []):
alias_index[alias] = tname
return alias_index
def canonical_target_name(
platforms: list[str], target: str, platforms_dir: str = "platforms"
) -> str:
"""The name a target is filed under, whichever alias was typed.
`switch`, `nx` and `nintendo-switch` named three packs of one target, and
--verify-packs looked for a name no build had written. The typed name is
kept when no platform knows it or when platforms file it differently.
"""
targets_dir = os.path.join(platforms_dir, "targets")
found: set[str] = set()
for platform_name in platforms:
target_file = os.path.join(targets_dir, f"{platform_name}.yml")
if not os.path.exists(target_file):
continue
with open(target_file) as f:
targets = (yaml_load(f) or {}).get("targets", {})
canonical = _target_alias_index(
targets, _target_overrides(platform_name, targets_dir)
).get(target)
if canonical:
found.add(canonical)
return found.pop() if len(found) == 1 else target
def load_target_config(
platform_name: str,
target: str,
@@ -260,19 +310,8 @@ def load_target_config(
data = yaml_load(f) or {}
targets = data.get("targets", {})
overrides_file = os.path.join(targets_dir, "_overrides.yml")
overrides = {}
if os.path.exists(overrides_file):
with open(overrides_file) as f:
all_overrides = yaml_load(f) or {}
overrides = all_overrides.get(platform_name, {}).get("targets", {})
alias_index: dict[str, str] = {}
for tname in targets:
alias_index[tname] = tname
for alias in overrides.get(tname, {}).get("aliases", []):
alias_index[alias] = tname
overrides = _target_overrides(platform_name, targets_dir)
alias_index = _target_alias_index(targets, overrides)
canonical = alias_index.get(target)
if canonical is None:
@@ -324,21 +363,20 @@ def list_available_targets(
with open(target_file) as f:
data = yaml_load(f) or {}
overrides_file = os.path.join(targets_dir, "_overrides.yml")
overrides = {}
if os.path.exists(overrides_file):
with open(overrides_file) as f:
all_overrides = yaml_load(f) or {}
overrides = all_overrides.get(platform_name, {}).get("targets", {})
# The count --target filters on: overrides applied, as load_target_config
# applies them. The scraped list counted Batocera's machine variants and
# launchers, 198 cores shown for 187 used.
overrides = _target_overrides(platform_name, targets_dir)
result = []
for tname, tdata in sorted(data.get("targets", {}).items()):
aliases = overrides.get(tname, {}).get("aliases", [])
aliases = (overrides.get(tname) or {}).get("aliases", [])
cores = {str(c) for c in tdata.get("cores", [])}
result.append(
{
"name": tname,
"architecture": tdata.get("architecture", ""),
"core_count": len(tdata.get("cores", [])),
"core_count": len(apply_target_overrides(cores, overrides, tname)),
"aliases": aliases,
}
)
@@ -489,6 +527,51 @@ def _owner_tokens(file_entry: dict) -> set[str]:
return tokens
def _foreign_tree(path: str, owners: set[str]) -> bool:
"""Whether a path lives in the tree of an emulator that is not the asker.
bios/Other/<emulator>/ holds what one emulator ships. A same-named file
found there answers that emulator's entry, not another's: EmuCoreX's
unlock.wav was served from NetherSX2's tree, and upstream PCSX2's
GameIndex.yaml from EmuCoreX's, while the system directory held a copy.
"""
parts = path.split("/")
if not owners or len(parts) < 4 or parts[0] != "bios" or parts[1] != "Other":
return False
return not (owners & _affinity_tokens(parts[2]))
def _rank_tail_candidates(
candidates: list[str], start: int, tail: str, files_db: dict, owners: set[str]
) -> list[str]:
"""Order the files a destination tail designates, the likeliest first.
A shortened tail found only in another emulator's tree is that
emulator's asset, not evidence about this entry. A full tail claimed
twice goes to the file whose path carries the least on top of the
destination, then to the owner's own copy (super3's Games.xml was served
to Supermodel-Dojo by index order alone), then to any copy outside
another emulator's tree (upstream PCSX2 took EmuCoreX's GameIndex.yaml
over the system directory's).
"""
def path_of(sha1: str) -> str:
return files_db.get(sha1, {}).get("path", "")
if start:
candidates = [h for h in candidates if not _foreign_tree(path_of(h), owners)]
if len(candidates) < 2:
return candidates
depth = len(tail.split("/"))
return sorted(
candidates,
key=lambda h: (
len(path_of(h).split("/")) - depth,
not owners & _affinity_tokens(path_of(h).rsplit("/", 1)[0]),
_foreign_tree(path_of(h), owners),
),
)
def _by_affinity(paths: list[str], file_entry: dict, dest_hint: str) -> list[str]:
"""Same-named candidates, the likeliest first.
@@ -507,14 +590,15 @@ def _by_affinity(paths: list[str], file_entry: dict, dest_hint: str) -> list[str
owners = _owner_tokens(file_entry)
sized = any(file_entry.get(k) for k in ("size", "min_size", "max_size"))
def score(path: str) -> tuple[int, bool, int]:
def score(path: str) -> tuple[int, bool, bool, int]:
fits = 0
if sized and os.path.exists(path):
fits = int(size_fits(file_entry, os.path.getsize(path)))
tokens = _affinity_tokens(path.rsplit("/", 1)[0])
# The owner's own copy ranks above any shared tree segment: NetherSX2's
# shaders/common/ beat armsx2's own fxaa.fx on two directory tokens.
return fits, bool(owners & tokens), len(wanted & tokens)
# Another emulator's own tree ranks below everything else.
return fits, bool(owners & tokens), not _foreign_tree(path, owners | wanted), len(wanted & tokens)
return sorted(paths, key=score, reverse=True)
@@ -716,9 +800,14 @@ def resolve_local_file(
# stops describing this file and starts describing whichever emulator
# happens to store the same asset tree.
hint_parts = dest_hint.split("/")
# The asking profile and the destination's own directories both name
# whose tree a copy may come from.
owners = _owner_tokens(file_entry) | _affinity_tokens("/".join(hint_parts[:-1]))
for start in range(min(2, len(hint_parts) - 1)):
tail = "/".join(hint_parts[start:])
candidates = by_path_suffix.get(tail, [])
candidates = _rank_tail_candidates(
by_path_suffix.get(tail, []), start, tail, files_db, owners
)
if start and len(candidates) > 1:
continue
# The index names the file this destination designates. Not on
@@ -729,20 +818,6 @@ def resolve_local_file(
for h in candidates
):
own_file_absent = True
if len(candidates) > 1:
depth = len(tail.split("/"))
# At equal depth the owner's own copy: super3's Games.xml was
# served to Supermodel-Dojo by index order alone.
owners = _owner_tokens(file_entry)
candidates = sorted(
candidates,
key=lambda h: (
len(files_db.get(h, {}).get("path", "").split("/")) - depth,
not owners & _affinity_tokens(
files_db.get(h, {}).get("path", "").rsplit("/", 1)[0]
),
),
)
for match_sha1 in candidates:
if match_sha1 not in files_db:
continue
@@ -875,7 +950,7 @@ def resolve_local_file(
# MAME clone fallback: if a file was deduped, resolve via canonical
if _depth < 3 and not has_strong_hash:
clone_map = get_mame_clone_map()
clone_map = get_mame_clone_map(db.get("bios_dir"))
canonical = clone_map.get(name)
if canonical and canonical != name:
canonical_entry = {"name": canonical}
@@ -923,28 +998,34 @@ def resolve_local_file(
return None, "not_found"
_mame_clone_map_cache: dict[str, str] | None = None
_mame_clone_map_cache: dict[str, dict[str, str]] = {}
def get_mame_clone_map() -> dict[str, str]:
"""Load and cache the MAME clone map (clone_name -> canonical_name)."""
global _mame_clone_map_cache
if _mame_clone_map_cache is not None:
return _mame_clone_map_cache
clone_path = os.path.join(
os.path.dirname(os.path.dirname(os.path.abspath(__file__))),
"_mame_clones.json",
)
def get_mame_clone_map(bios_dir: str | None = None) -> dict[str, str]:
"""The MAME clone map (clone_name -> canonical_name) of a scanned tree.
dedup.py writes _mame_clones.json beside the tree it scanned, and the
map of one tree says nothing about another: read from the repository
root whatever ``--bios-dir`` said, an alternate tree's renamed clones
fell out of its packs. Without a tree the repository's own is read.
"""
if bios_dir is None:
bios_dir = os.path.join(
os.path.dirname(os.path.dirname(os.path.abspath(__file__))), "bios"
)
clone_path = os.path.join(os.path.dirname(os.path.abspath(bios_dir)), "_mame_clones.json")
cached = _mame_clone_map_cache.get(clone_path)
if cached is not None:
return cached
clone_map: dict[str, str] = {}
if os.path.exists(clone_path):
with open(clone_path) as f:
data = json.load(f)
_mame_clone_map_cache = {}
for canonical, info in data.items():
for clone in info.get("clones", []):
_mame_clone_map_cache[clone] = canonical
else:
_mame_clone_map_cache = {}
return _mame_clone_map_cache
clone_map[clone] = canonical
_mame_clone_map_cache[clone_path] = clone_map
return clone_map
@@ -957,6 +1038,27 @@ class ProfileSelectionError(ValueError):
"""A named profile cannot answer for itself."""
def profiles_for_systems(
profiles: dict, system_ids: list[str], standalone: bool = False
) -> list[str]:
"""Profile keys that serve any of the systems, spelled either way.
Compared on the normalized id: stella2014 writes atari_2600 where every
other profile writes atari-2600, and an exact match built two different
packs under one file name, the second replacing the first.
"""
wanted = {_norm_system_id(sid) for sid in system_ids}
matching = []
for name, profile in sorted(profiles.items()):
if profile.get("type") in ("launcher", "alias", "test"):
continue
if standalone and "standalone" not in profile.get("type", "libretro"):
continue
if wanted & {_norm_system_id(sid) for sid in profile.get("systems", [])}:
matching.append(name)
return matching
def select_emulator_profiles(
profile_names: list[str],
all_profiles: dict,
@@ -1491,6 +1593,11 @@ SYSTEM_ALIASES: dict[str, str] = {
"sega32x": "sega-32x",
"segastv": "sega-stv",
"ti994a": "ti99",
# Other spellings of one machine: RomM files the Mega CD as sega-mega-cd
# and the disk system as nintendo-fds, which normalize to the ids the
# profiles use only through these.
"sega-segacd": "sega-megacd",
"nes-fds": "nintendo-fds",
}
@@ -1554,13 +1661,47 @@ def filter_systems_by_target(
norm_key = _norm_sid(sid)
norm_plat_system_cores.setdefault(norm_key, set()).add(name)
# A platform can file a system under an id no profile uses: Batocera's
# enterprise-64-128 is ep128emu's enterprise-64 and enterprise-128, and
# only CLK, off most targets, carries the joined id. The destinations a
# system declares name the cores that read its files. A bare name proves
# nothing (bios.bin belongs to many systems), so only a path counts.
dest_cores: dict[str, set[str]] = {}
for name, p in profiles.items():
if p.get("type") == "alias":
continue
for f in p.get("files", []):
for key in ("path", "standalone_path"):
dest = f.get(key)
if not isinstance(dest, str):
continue
if dest.endswith("/"):
dest += f.get("name", "")
dest = sanitize_pack_path(dest).lower()
if "/" in dest:
dest_cores.setdefault(dest, set()).add(name)
filtered = {}
for sys_id, sys_data in systems.items():
norm_key = _norm_sid(sys_id)
file_cores = {
core
for fe in sys_data.get("files", [])
for core in dest_cores.get(
sanitize_pack_path(fe.get("destination") or fe.get("name", "")).lower(),
(),
)
}
all_cores = norm_system_cores.get(norm_key, set())
plat_cores_here = norm_plat_system_cores.get(norm_key, set())
if not all_cores and not plat_cores_here:
if file_cores & expanded_target:
# An on-target core reads the system's files. The evidence only
# keeps: a path shared with an off-target core says nothing of the
# other files, and Batocera's bbc runs on MAME, which no profile
# ties to bbcb.zip, while CLK reads two of its ROMs.
filtered[sys_id] = sys_data
elif not all_cores and not plat_cores_here:
# No profile maps to this system -keep it
filtered[sys_id] = sys_data
elif all_cores & expanded_target:
@@ -1573,40 +1714,85 @@ def filter_systems_by_target(
return filtered
def expand_platform_declared_names(config: dict, db: dict) -> set[str]:
"""Build set of file names declared by a platform config.
def platform_declarations(
config: dict, db: dict, *, enrich: bool = True
) -> dict[str, list[tuple[int | None, str]]]:
"""Every file name a platform declares, with each declaration's size and slot.
Enriches the set with canonical names and aliases from the database
by resolving each platform file's MD5 through by_md5. This handles
cases where a platform declares a file under a different name than
the emulator profile (e.g. Batocera ROM1 vs gsplus ROM).
A name alone does not say which file a declaration is: RetroArch declares
galaksija/ROM1.BIN, a 4 KiB ROM, and DOSBox reads a 32 KiB SC-55 ROM1.BIN.
The size, from the platform entry or else from the file its hash names,
tells a declaration of the same file from a same-named one; None stands
for a size nobody knows. The slot is the declared destination, sanitized
and case-folded, relative to the directory core files go to: RetroDECK
writes bios/ in front of every destination, the others put it in
base_destination.
With ``enrich``, a declaration also answers for the canonical name and
the aliases the database knows its MD5 under. This handles a platform
declaring a file under a different name than the emulator profile
(e.g. Batocera ROM1 vs gsplus ROM).
"""
declared: set[str] = set()
prefix = declared_root(config).lower()
declared: dict[str, list[tuple[int | None, str]]] = {}
by_md5 = db.get("indexes", {}).get("by_md5", {})
files_db = db.get("files", {})
for system in config.get("systems", {}).values():
for fe in system.get("files", []):
name = fe.get("name", "")
slot = sanitize_pack_path(fe.get("destination") or name).lower()
if prefix and slot.startswith(prefix + "/"):
slot = slot[len(prefix) + 1:]
# A zipped_file entry pins a member of the archive it names: its
# md5 and its size, when stated, are not the archive's.
by_hash: dict = {}
size = None
if not fe.get("zipped_file"):
md5 = (fe.get("md5") or "").lower()
if md5 and "," not in md5:
by_hash = files_db.get(by_md5.get(md5, ""), {})
size = fe.get("size")
if size is None:
size = files_db.get(
(fe.get("sha1") or "").lower(), by_hash
).get("size")
if name:
declared.add(name)
md5 = fe.get("md5", "")
if not md5:
declared.setdefault(name, []).append((size, slot))
if not enrich:
continue
# Skip multi-hash and zipped_file entries (inner ROM MD5, not file MD5)
if "," in md5 or fe.get("zipped_file"):
continue
sha1 = by_md5.get(md5.lower())
if not sha1:
continue
entry = files_db.get(sha1, {})
db_name = entry.get("name", "")
if db_name:
declared.add(db_name)
for alias in entry.get("aliases", []):
declared.add(alias)
for other in (by_hash.get("name", ""), *by_hash.get("aliases", [])):
if other:
declared.setdefault(other, []).append((by_hash.get("size"), slot))
return declared
def declared_root(config: dict) -> str:
"""The BIOS directory a platform writes into every destination, if any.
Only a platform whose base_destination is explicitly empty does that
(RetroDECK writes bios/ in front of each file), and core files go under
the same directory. A config that does not state a base says nothing,
and its common folder is a system's, not the BIOS root.
"""
if config.get("base_destination", None) != "":
return ""
roots = [
d.split("/", 1)[0]
for system in config.get("systems", {}).values()
for f in system.get("files", [])
if "/" in (d := f.get("destination", "") or "")
]
if not roots:
return ""
root, count = Counter(roots).most_common(1)[0]
return root if count / len(roots) > 0.9 else ""
def expand_platform_declared_names(config: dict, db: dict) -> set[str]:
"""The names a platform declares, enriched as `platform_declarations`."""
return set(platform_declarations(config, db))
import re
@@ -1645,17 +1831,24 @@ def list_emulator_profiles(emulators_dir: str, skip_aliases: bool = True) -> Non
def list_system_ids(emulators_dir: str) -> None:
"""Print available system IDs with emulator count."""
"""Print available system IDs with emulator count.
Counted on the normalized id, as --system selects: listed per spelling,
3do showed two emulators and panasonic-3do six for one system.
"""
profiles = load_emulator_profiles(emulators_dir)
system_emus: dict[str, list[str]] = {}
for name, p in profiles.items():
system_emus: dict[str, set[str]] = {}
spelling: dict[str, str] = {}
for name, p in sorted(profiles.items()):
if p.get("type") in ("alias", "test", "launcher"):
continue
for sys_id in p.get("systems", []):
system_emus.setdefault(sys_id, []).append(name)
for sys_id in sorted(system_emus):
count = len(system_emus[sys_id])
print(f" {sys_id:35s} ({count} emulator{'s' if count > 1 else ''})")
key = _norm_system_id(sys_id)
system_emus.setdefault(key, set()).add(name)
spelling.setdefault(key, sys_id)
for key in sorted(system_emus, key=lambda k: spelling[k]):
count = len(system_emus[key])
print(f" {spelling[key]:35s} ({count} emulator{'s' if count > 1 else ''})")
def list_platform_system_ids(platform_name: str, platforms_dir: str) -> None:
@@ -1731,6 +1924,8 @@ from ziptools import ( # noqa: E402,F401
)
from artifacts import ( # noqa: E402,F401
write_if_changed,
write_text_atomic,
copy_file_atomic,
ArtifactLockBusy,
artifact_lock,
hold_artifact_lock,
+41 -9
View File
@@ -70,6 +70,25 @@ def load_platform_files(
return declared, platform_data_dirs
def declared_names(platforms_dir: str, platforms: list[str] | None, db: dict) -> set[str]:
"""Every name the platforms declare, under every spelling the database knows.
The report judged "undeclared" per normalized system id, which does not
bring bk and elektronika-bk, or nintendo-sgb and nintendo-super-game-boy,
together: 646 entries whose exact name a platform declares were counted
undeclared, while verify and the site read one flat set.
"""
from common import expand_platform_declared_names
names: set[str] = set()
for platform_name in platforms or list_registered_platforms(
platforms_dir, include_archived=True
):
config = load_platform_config(platform_name, platforms_dir)
names.update(expand_platform_declared_names(config, db))
return names
def _build_supplemental_index(
data_root: str = "data", bios_root: str = "bios"
) -> set[str]:
@@ -135,6 +154,7 @@ def _resolve_source(
by_path_suffix: dict | None = None,
file_entry: dict | None = None,
db_files: dict | None = None,
bios_dir: str | None = None,
) -> str | None:
"""Return the source category for a file, or None if not found.
@@ -177,7 +197,7 @@ def _resolve_source(
return "bios"
# bios/ under the canonical MAME set name, as resolve_local_file does:
# a renamed archive is held once, under the name the dedup kept.
canonical = get_mame_clone_map().get(fname)
canonical = get_mame_clone_map(bios_dir).get(fname)
if canonical and canonical != fname:
if canonical in by_name and _name_hit(canonical):
return "bios"
@@ -222,10 +242,17 @@ class FileConsumers:
self.platforms: dict[str, set[str]] = {}
self.emulators: dict[str, set[str]] = {}
def sha1_of(self, entry: dict, dest: str = "") -> str | None:
"""The collected file an entry resolves to, or None."""
def sha1_of(self, entry: dict, dest: str = "", owner: str = "") -> str | None:
"""The collected file an entry resolves to, or None.
A profile entry names its owner, as the builder does: without it the
name step chose another tree's copy, and the page credited the file
the pack does not ship.
"""
if not entry.get("name"):
return None
if owner:
entry = {**entry, "source_profile": owner}
path, status = resolve_local_file(
entry, self._db, self._zip_contents, dest_hint=dest
)
@@ -246,7 +273,7 @@ class FileConsumers:
if profile.get("type") == "alias":
continue
for entry in profile.get("files", []):
sha1 = self.sha1_of(entry, entry.get("path") or "")
sha1 = self.sha1_of(entry, entry.get("path") or "", owner=name)
if sha1:
self.emulators.setdefault(sha1, set()).add(name)
@@ -269,6 +296,7 @@ def entry_source(f: dict, index: dict) -> str | None:
continue
source = _resolve_source(
candidate, by_name, by_name_lower, data_names, by_path_suffix, f, db_files,
index.get("bios_dir"),
)
if source is not None:
return source
@@ -374,8 +402,11 @@ def _cross_reference_profile(
archive = f.get("archive")
# Check platform declaration (by name or archive)
in_platform = fname in platform_names
# Check platform declaration: by name, by an alias the core answers
# to (RetroArch lists amiberry's cd32.rom as kick40060.CD32), or by
# archive.
answers = {fname, *f.get("aliases", [])}
in_platform = bool(answers & platform_names)
if not in_platform and archive:
in_platform = archive in platform_names
@@ -513,6 +544,7 @@ def cross_reference(
"db_files": db_files,
"data_names": data_names,
"all_declared": all_declared,
"bios_dir": db.get("bios_dir"),
}
for emu_name, profile in profiles.items():
_cross_reference_profile(
@@ -611,13 +643,13 @@ def main():
print("No emulator profiles found.", file=sys.stderr)
return
declared, plat_data_dirs = load_platform_files(
args.platforms_dir, [args.platform] if args.platform else None
)
selected = [args.platform] if args.platform else None
declared, plat_data_dirs = load_platform_files(args.platforms_dir, selected)
db = load_database(args.db)
data_names = _build_supplemental_index()
report = cross_reference(
profiles, declared, db, plat_data_dirs, data_names,
all_declared=declared_names(args.platforms_dir, selected, db),
standalone_cores=standalone_cores,
)
+10 -7
View File
@@ -88,13 +88,16 @@ class Pack:
def get_latest_release() -> dict:
"""Fetch latest release info from GitHub API."""
url = f"{API}/repos/{REPO}/releases/latest"
req = urllib.request.Request(
url,
headers={
"User-Agent": "retrobios-downloader/1.0",
"Accept": "application/vnd.github.v3+json",
},
)
headers = {
"User-Agent": "retrobios-downloader/1.0",
"Accept": "application/vnd.github.v3+json",
}
# The anonymous quota is 60 calls an hour per address. The token goes to
# GitHub's API only: RETROBIOS_API can name any host.
token = os.environ.get("GITHUB_TOKEN")
if token and urllib.parse.urlsplit(url).hostname == "api.github.com":
headers["Authorization"] = f"Bearer {token}"
req = urllib.request.Request(url, headers=headers)
try:
with urllib.request.urlopen(req, timeout=30) as resp:
+43 -8
View File
@@ -24,6 +24,7 @@ from pathlib import Path
sys.path.insert(0, str(Path(__file__).resolve().parent))
from artifacts import file_lock, write_bytes_atomic, write_text_atomic
from common import list_registered_platforms, load_platform_config, yaml_load
from exporter import discover_exporters
from exporter.baseline import build_native_model
@@ -80,9 +81,12 @@ def fetch(
it is what a rescrape calls, so the original and its transcription
describe the same moment.
"""
recorded = _load_sources(index)
key = source_key(destination, index)
if not refresh and destination.exists() and recorded.get(key, url) == url:
if (
not refresh
and destination.exists()
and _load_sources(index).get(key, url) == url
):
return destination.read_bytes()
request = urllib.request.Request(url, headers={"User-Agent": _USER_AGENT})
with urllib.request.urlopen(request, timeout=60) as response:
@@ -90,13 +94,17 @@ def fetch(
if len(payload) > _MAX_BYTES:
raise ValueError(f"{url}: response larger than {_MAX_BYTES} bytes")
destination.parent.mkdir(parents=True, exist_ok=True)
destination.write_bytes(payload)
write_bytes_atomic(str(destination), payload)
if index is not None:
recorded[key] = url
# Platforms refresh in parallel: the index is read again under the
# lock, or the last writer erased what the others had recorded.
index.parent.mkdir(parents=True, exist_ok=True)
index.write_text(
json.dumps(recorded, indent=2, sort_keys=True) + "\n", encoding="utf-8"
)
with file_lock(index.with_name(f".{index.name}.lock")):
recorded = _load_sources(index)
recorded[key] = url
write_text_atomic(
str(index), json.dumps(recorded, indent=2, sort_keys=True) + "\n"
)
return payload
@@ -197,7 +205,34 @@ def load_inputs(
scraped = load_platform_config(platform, platforms_dir)
except (FileNotFoundError, OSError):
scraped = None
return truth, scraped
return truth, _native_layer(scraped)
def _native_layer(config: dict | None) -> dict | None:
"""The platform config without what we add to it.
A shared group's files join the config for the pack, but the platform's
file does not carry them: counted kept, they were written into
libretro's System.dat (N88EXT0-3.ROM) as if libretro declared them. What
a core needs from a group reaches the export through the truth, as an
addition the format's gates apply to. A scraper's mirror of an entry
under another system (RomM's tg16 firmware under turbografx-cd), and a
file our scraper adds from the cores' source (Dolphin's DSP ROMs in
RetroArch's config), are not in the platform's file either.
"""
if config is None:
return None
systems = {
sys_id: {
**system,
"files": [
f for f in system.get("files", [])
if not ({"shared_group", "mirror_of", "curated"} & f.keys())
],
}
for sys_id, system in config.get("systems", {}).items()
}
return {**config, "systems": systems}
def refresh_cache(
+6 -1
View File
@@ -325,8 +325,13 @@ def build_native_model(
def by_destination(candidate: NativeFile, t_dest: str = t_dest) -> bool:
# Dolphin writes dolphin-emu/Sys/GC/USA/IPL.bin for the truth's
# GC/USA/IPL.bin: a destination ending in the path is the file.
# A bare name is no path: dc/boot.bin ends in /boot.bin, and
# fbneo's 480-byte boot.bin is not that 2 MB Dreamcast BIOS.
# Names go through by_name and its size guard.
theirs = _match_key(candidate.platform or {})[0]
return bool(t_dest) and (theirs == t_dest or theirs.endswith("/" + t_dest))
if not t_dest:
return False
return theirs == t_dest or ("/" in t_dest and theirs.endswith("/" + t_dest))
def by_name(
candidate: NativeFile,
+43 -10
View File
@@ -62,10 +62,29 @@ class Exporter(BaseExporter):
# The data block is a fraction of the file; the rest is the checker.
return True
def _bios_files(self, files: list[NativeFile]) -> str:
return ", ".join(self._bios_items(files))
def _bios_files(self, files: list[NativeFile], before: dict | None = None) -> str:
return ", ".join(self._bios_items(files, before))
def _bios_items(self, files: list[NativeFile]) -> list[str]:
@staticmethod
def _runner_keys(item: dict | None) -> list[str]:
"""The emulator and core checkBios reads through coreExists().
Not in our model, so they travel from the maintainer's own entry: a
rewritten item without them made the checker treat the BIOS as
wanted by every build (vectrex, tvc, macintosh, bk).
"""
return [
f'"{key}": "{item[key]}"'
for key in ("emulator", "core")
if item and isinstance(item.get(key), str)
]
def _bios_items(self, files: list[NativeFile], before: dict | None = None) -> list[str]:
originals = {
str(item.get("file", "")): item
for item in (before or {}).get("biosFiles", [])
if isinstance(item, dict)
}
parts: list[str] = []
for fe in files:
# The platform states an unhashed file as an empty md5 rather
@@ -80,14 +99,25 @@ class Exporter(BaseExporter):
zipped = fe.native("zipped_file", "")
if zipped:
item.append(f'"zippedFile": "{zipped}"')
item.extend(self._runner_keys(originals.get(path)))
parts.append("{ " + ", ".join(item) + " }")
return parts
def _entry_line(self, system: NativeSystem, files: list[NativeFile]) -> str:
@staticmethod
def _own_entry(system: NativeSystem, before: dict | None) -> dict:
"""The maintainer's entry for this system, out of the parsed pair."""
inner = (before or {}).get(system.native_id)
return inner if isinstance(inner, dict) else {}
def _entry_line(
self, system: NativeSystem, files: list[NativeFile], before: dict | None = None
) -> str:
own = self._own_entry(system, before)
runner = "".join(f"{key}, " for key in self._runner_keys(own))
return (
f'{_INDENT}"{system.native_id}": '
f'{{ "name": "{self.display_name(system)}", '
f'"biosFiles": [ {self._bios_files(files)} ] }},'
f'{{ "name": "{self.display_name(system)}", {runner}'
f'"biosFiles": [ {self._bios_files(files, own)} ] }},'
)
@staticmethod
@@ -127,14 +157,17 @@ class Exporter(BaseExporter):
) -> list[str]:
"""One entry, keeping the layout and the notes it was written with."""
trailing, leading = self._item_notes(original)
items = self._bios_items(files)
before = self._parse_entry(original)
own = self._own_entry(system, before)
items = self._bios_items(files, own)
one_line = len(original) == 1 and not trailing and not leading
if one_line:
return [self._entry_line(system, files)]
return [self._entry_line(system, files, before)]
runner = "".join(f"{key}, " for key in self._runner_keys(own))
head = (
f'{_INDENT}"{system.native_id}": '
f'{{ "name": "{self.display_name(system)}", "biosFiles": ['
f'{{ "name": "{self.display_name(system)}", {runner}"biosFiles": ['
)
pad = " " * (len(_INDENT) + 4)
lines = [head]
@@ -244,8 +277,8 @@ class Exporter(BaseExporter):
continue
written.add(key)
original_lines = body[start:end + 1]
replacement = self._entry_line(*pair)
before = self._parse_entry(original_lines)
replacement = self._entry_line(*pair, before)
after = self._parse_entry([replacement])
if before is not None and before == after:
# Nothing changed: keep the maintainer's own lines, comments
+9 -2
View File
@@ -82,8 +82,15 @@ class Exporter(BaseExporter):
for fe in system.files:
# A SHA1 BizHawk declares is BizHawk's own code, the authority
# for its cores: the truth's MSX.rom came from FBNeo and would
# have made MSXHawk refuse the dump it accepts.
if fe.hash("sha1") and not _hash_values(fe.platform or {}, "sha1"):
# have made MSXHawk refuse the dump it accepts. An entry the
# database never declared (can_add refuses it) names no call
# of its own either: by name it would rewrite the homonym of
# another system.
if (
fe.platform is not None
and fe.hash("sha1")
and not _hash_values(fe.platform, "sha1")
):
seen.setdefault(fe.name.casefold(), []).append(fe)
resolved: dict[str, NativeFile] = {}
for name, entries in seen.items():
+8 -6
View File
@@ -52,12 +52,15 @@ class Exporter(BaseExporter):
def native_sources() -> dict[str, str]:
return {"es_bios.xml": SOURCE_URL, "es_bios.xsd": SCHEMA_URL}
def _path(self, fe: NativeFile, native_id: str) -> str:
def _path(self, fe: NativeFile) -> str:
"""The path Recalbox reads, pipe-joined when it accepts several.
A path Recalbox already states is reproduced exactly: several of its
entries sit at the BIOS root with no directory at all, and prefixing
them with the system would point the frontend somewhere else.
them with the system would point the frontend somewhere else. An
addition goes where the core reads it, relative to the BIOS directory
Recalbox gives its cores: DuckStation reads scph5000.bin at the root,
not under psx/.
"""
if fe.platform is not None:
path = str(fe.platform.get("destination") or fe.name)
@@ -65,11 +68,10 @@ class Exporter(BaseExporter):
if alternatives:
return "|".join([path, *[str(a) for a in alternatives]])
return path
dest = fe.destination or fe.name
return dest if "/" in dest else f"{native_id}/{dest}"
return fe.destination or fe.name
def _bios_element(self, fe: NativeFile, native_id: str) -> str:
attrs = [f"path={quoteattr(self._path(fe, native_id))}"]
attrs = [f"path={quoteattr(self._path(fe))}"]
attrs.append(f'md5={quoteattr(",".join(fe.hashes("md5")))}')
attrs.append(f'core={quoteattr(",".join(fe.cores()))}')
@@ -162,6 +164,6 @@ class Exporter(BaseExporter):
for fe in system.files:
if not self.writable(fe):
continue
if self._path(fe, system.native_id).casefold() not in exported:
if self._path(fe).casefold() not in exported:
issues.append(f"absent: {system.native_id}/{fe.name}")
return issues
+48 -11
View File
@@ -37,6 +37,14 @@ def _md5_set(value: object) -> set[str]:
return {m.strip().lower() for m in str(value or "").split(",") if m.strip()}
def _paths_key(entry: dict) -> tuple[str, ...]:
"""Where an entry says the file goes: no paths is the BIOS root."""
paths = entry.get("paths")
if isinstance(paths, list):
return tuple(sorted(str(p) for p in paths))
return (str(paths),) if paths else ()
def _matching_keys(
entry: dict, by_key: dict[tuple[str, str], OrderedDict]
) -> list[tuple[str, str]]:
@@ -176,8 +184,13 @@ class Exporter(BaseExporter):
return nested, "bios"
return None
@staticmethod
def _merge(existing: object, ours: list[OrderedDict]) -> list[OrderedDict]:
@classmethod
def _merge(
cls,
existing: object,
ours: list[OrderedDict],
additions: list[OrderedDict] | None = None,
) -> list[OrderedDict]:
"""Correct the component's own list; never replace it.
Assigning our entries wholesale dropped every file RetroDECK declares
@@ -206,6 +219,9 @@ class Exporter(BaseExporter):
for system in _systems_of(entry):
key = (str(entry.get("filename", "")), system)
seen_keys[key] = seen_keys.get(key, 0) + 1
# A hash no revision shares is a revision the platform does not
# know: appended, not counted corrected against entries kept as
# they were (the 64DD IPL declared twice, both contradicted).
for entry in entries:
keys = _matching_keys(entry, by_key)
other_revision = (
@@ -213,18 +229,17 @@ class Exporter(BaseExporter):
and seen_keys.get(keys[0], 0) > 1
and not _md5_set(entry.get("md5")) & _md5_set(by_key[keys[0]].get("md5"))
)
if other_revision:
merged.append(OrderedDict(entry))
corrected.update(keys)
continue
if not keys:
if other_revision or not keys:
merged.append(OrderedDict(entry))
continue
declared = entry.get("system")
combined = OrderedDict(entry)
# Only what the format says it corrects: the maintainer's
# description and search paths are theirs (neogeo.zip lost its
# four roms directories to a path that does not exist).
combined.update(
(field, value) for field, value in by_key[keys[0]].items()
if not (field == "system" and declared)
if field in cls.carries() and not (field == "system" and declared)
)
merged.append(combined)
corrected.update(keys)
@@ -232,6 +247,21 @@ class Exporter(BaseExporter):
merged.extend(
entry for key, entry in by_key.items() if key not in corrected
)
# A file the platform does not declare is appended unless the list
# already holds that name for that system at that path. The key
# above is name and system only, and folded melonDS's SkyEmu/
# firmware.bin into the root firmware.bin the platform declares,
# while the report counted it added.
held = {
(str(e.get("filename", "")), system, _paths_key(e))
for e in merged
for system in (_systems_of(e) or [""])
}
for entry in additions or []:
key = (str(entry.get("filename", "")), str(entry.get("system", "")), _paths_key(entry))
if key[0] and key not in held:
held.add(key)
merged.append(entry)
return merged
def render(
@@ -255,16 +285,17 @@ class Exporter(BaseExporter):
except json.JSONDecodeError:
continue
entries = [self._entry(fe) for fe in files]
entries = [self._entry(fe) for fe in files if fe.platform is not None]
additions = [self._entry(fe) for fe in files if fe.platform is None]
for component_value in manifest.values():
if not isinstance(component_value, dict):
continue
holder = self._bios_holder(component_value)
if holder is None:
component_value["bios"] = self._merge(None, entries)
component_value["bios"] = self._merge(None, entries, additions)
else:
container, key = holder
container[key] = self._merge(container.get(key), entries)
container[key] = self._merge(container.get(key), entries, additions)
break
produced[path] = json.dumps(manifest, indent=2, ensure_ascii=False) + "\n"
@@ -291,6 +322,7 @@ class Exporter(BaseExporter):
continue
declared: set[str] = set()
placed: set[tuple[str, tuple[str, ...]]] = set()
for component_value in manifest.values():
if not isinstance(component_value, dict):
continue
@@ -300,6 +332,7 @@ class Exporter(BaseExporter):
container, key = holder
for entry in container[key]:
declared.add(entry.get("filename", ""))
placed.add((entry.get("filename", ""), _paths_key(entry)))
if not component_value.get("name") and not component_value.get(
"system"
):
@@ -308,4 +341,8 @@ class Exporter(BaseExporter):
for fe in files:
if fe.name not in declared:
issues.append(f"absent from {path}: {fe.name}")
elif fe.platform is None and (
fe.name, _paths_key(self._entry(fe))
) not in placed:
issues.append(f"absent from {path}: {fe.destination or fe.name}")
return issues
Loaded 100 of 180 files, more files were not shown because too many files have changed in this diff. Show more