diff --git a/.github/ISSUE_TEMPLATE/missing-bios.yml b/.github/ISSUE_TEMPLATE/missing-bios.yml
index 0afedb4c..00356120 100644
--- a/.github/ISSUE_TEMPLATE/missing-bios.yml
+++ b/.github/ISSUE_TEMPLATE/missing-bios.yml
@@ -35,6 +35,7 @@ body:
- RetroArch
- Batocera
- Recalbox
+ - RetroBat
- Lakka
- RetroPie
- Other
diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml
new file mode 100644
index 00000000..4b36eed6
--- /dev/null
+++ b/.github/workflows/build.yml
@@ -0,0 +1,136 @@
+name: Build & Release
+
+on:
+ push:
+ branches: [main]
+ paths: ["bios/**", "platforms/**"]
+ workflow_dispatch:
+ inputs:
+ force_release:
+ description: "Force release even if rate limited"
+ type: boolean
+ default: false
+
+permissions:
+ contents: write
+
+concurrency:
+ group: build
+ cancel-in-progress: true
+
+jobs:
+ regenerate:
+ runs-on: ubuntu-latest
+ steps:
+ - uses: actions/checkout@v6
+
+ - uses: actions/setup-python@v6
+ with:
+ python-version: "3.12"
+
+ - run: pip install pyyaml
+
+ - name: Regenerate database and docs
+ run: |
+ python scripts/generate_db.py --bios-dir bios --output database.json
+ python scripts/generate_readme.py --db database.json --platforms-dir platforms
+
+ - name: Commit if changed
+ id: commit
+ run: |
+ git diff --quiet database.json README.md CONTRIBUTING.md && echo "changed=false" >> "$GITHUB_OUTPUT" && exit 0
+ git config user.name "github-actions[bot]"
+ git config user.email "github-actions[bot]@users.noreply.github.com"
+ git add database.json README.md CONTRIBUTING.md
+ git commit -m "regenerate database and docs"
+ git push
+ echo "changed=true" >> "$GITHUB_OUTPUT"
+
+ release:
+ needs: regenerate
+ if: needs.regenerate.result == 'success' || github.event.inputs.force_release == 'true'
+ runs-on: ubuntu-latest
+ steps:
+ - name: Rate limit
+ if: github.event.inputs.force_release != 'true'
+ id: rate
+ run: |
+ LAST=$(gh release list --repo "${{ github.repository }}" --json createdAt -q '.[0].createdAt' 2>/dev/null || echo "")
+ if [ -n "$LAST" ] && [ "$LAST" != "null" ]; then
+ LAST_TS=$(date -d "$LAST" +%s 2>/dev/null || echo 0)
+ DIFF=$(( ($(date +%s) - LAST_TS) / 86400 ))
+ if [ "$DIFF" -lt 7 ]; then
+ echo "Skipping: last release ${DIFF} days ago"
+ echo "skip=true" >> "$GITHUB_OUTPUT"
+ exit 0
+ fi
+ fi
+ echo "skip=false" >> "$GITHUB_OUTPUT"
+ env:
+ GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}
+
+ - uses: actions/checkout@v6
+ if: steps.rate.outputs.skip != 'true'
+ with:
+ ref: main
+
+ - uses: actions/setup-python@v6
+ if: steps.rate.outputs.skip != 'true'
+ with:
+ python-version: "3.12"
+
+ - name: Build packs
+ if: steps.rate.outputs.skip != 'true'
+ run: |
+ pip install pyyaml
+ python scripts/generate_db.py --bios-dir bios --output database.json
+ python scripts/generate_pack.py --all --output-dir dist/
+
+ - name: Release
+ if: steps.rate.outputs.skip != 'true'
+ run: |
+ DATE=$(date +%Y.%m.%d)
+ EXISTING=$(gh release list --repo "${{ github.repository }}" --json tagName -q ".[].tagName" | grep -c "^v${DATE}" || true)
+ TAG="v${DATE}"
+ [ "$EXISTING" -gt 0 ] && TAG="v${DATE}.$((EXISTING+1))"
+
+ CHANGES=$(git log --oneline -15 --no-merges -- bios/ platforms/ | sed 's/^/- /')
+ TOTAL=$(python3 -c "import json; print(json.load(open('database.json'))['total_files'])")
+ SIZE=$(python3 -c "import json; print(f'{json.load(open(\"database.json\"))[\"total_size\"]/1024/1024:.0f}')")
+ PACKS=$(ls dist/*.zip 2>/dev/null | while read f; do echo "- **$(basename $f)** ($(du -m "$f" | cut -f1) MB)"; done)
+
+ gh release create "$TAG" dist/*.zip \
+ --repo "${{ github.repository }}" \
+ --title "BIOS Pack $TAG" \
+ --notes "${TOTAL} files, ${SIZE} MB, verified checksums.
+
+ ### Packs
+ ${PACKS}
+
+ ### Install
+ Download, extract to your emulator's BIOS directory.
+
+ | Platform | Path |
+ |----------|------|
+ | RetroArch / Lakka | system/ |
+ | Batocera | /userdata/bios/ |
+ | Recalbox | /recalbox/share/bios/ |
+ | RetroBat | bios/ |
+
+ ### Changes
+ ${CHANGES}
+ " \
+ --latest
+ env:
+ GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}
+
+ - name: Cleanup old releases
+ if: steps.rate.outputs.skip != 'true'
+ run: |
+ gh release list --repo "${{ github.repository }}" --json tagName,createdAt \
+ --jq 'sort_by(.createdAt) | reverse | .[].tagName' | \
+ grep -v "^large-files$" | tail -n +4 | while read tag; do
+ gh release delete "$tag" --repo "${{ github.repository }}" --yes --cleanup-tag
+ done
+ env:
+ GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}
diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml
deleted file mode 100644
index 73457ca4..00000000
--- a/.github/workflows/release.yml
+++ /dev/null
@@ -1,214 +0,0 @@
-name: Release BIOS Packs
-
-on:
- push:
- tags: ["v*"]
- workflow_dispatch:
- inputs:
- version:
- description: "Release version (e.g., v2.0.0)"
- required: true
- # Auto-release when update-db finishes (after BIOS push or platform update merge)
- workflow_run:
- workflows: ["Update Database"]
- types: [completed]
- branches: [main]
-
-permissions:
- contents: write
-
-jobs:
- check-changes:
- runs-on: ubuntu-latest
- # Skip auto-release if update-db failed or was triggered by release itself
- if: >
- github.event_name == 'push' ||
- github.event_name == 'workflow_dispatch' ||
- (github.event_name == 'workflow_run' && github.event.workflow_run.conclusion == 'success')
- outputs:
- should_release: ${{ steps.check.outputs.should_release }}
- version: ${{ steps.version.outputs.tag }}
- steps:
- - uses: actions/checkout@v6
- with:
- fetch-depth: 2
-
- - name: Check if BIOS files changed
- id: check
- run: |
- if [ "${{ github.event_name }}" = "workflow_run" ]; then
- # Auto-release: check if bios/ or platforms/ changed in the last commit
- changed=$(git diff --name-only HEAD~1 HEAD | grep -cE '^(bios/|platforms/)' || true)
- if [ "$changed" -gt 0 ]; then
- echo "should_release=true" >> "$GITHUB_OUTPUT"
- else
- echo "should_release=false" >> "$GITHUB_OUTPUT"
- fi
- else
- echo "should_release=true" >> "$GITHUB_OUTPUT"
- fi
-
- - name: Determine version
- id: version
- run: |
- if [ "${{ github.event_name }}" = "workflow_dispatch" ]; then
- echo "tag=${{ github.event.inputs.version }}" >> "$GITHUB_OUTPUT"
- elif [ "${{ github.event_name }}" = "push" ]; then
- echo "tag=${{ github.ref_name }}" >> "$GITHUB_OUTPUT"
- else
- # Auto-release: use date-based version
- echo "tag=auto-$(date +%Y%m%d)" >> "$GITHUB_OUTPUT"
- fi
-
- discover:
- needs: check-changes
- if: needs.check-changes.outputs.should_release == 'true'
- runs-on: ubuntu-latest
- outputs:
- platforms: ${{ steps.list.outputs.platforms }}
- steps:
- - uses: actions/checkout@v6
-
- - uses: actions/setup-python@v6
- with:
- python-version: "3.12"
-
- - name: List platforms
- id: list
- run: python scripts/list_platforms.py
-
- build:
- needs: [check-changes, discover]
- if: needs.check-changes.outputs.should_release == 'true'
- runs-on: ubuntu-latest
- strategy:
- matrix:
- platform: ${{ fromJson(needs.discover.outputs.platforms) }}
- fail-fast: false
- max-parallel: 10
-
- steps:
- - uses: actions/checkout@v6
-
- - uses: actions/setup-python@v6
- with:
- python-version: "3.12"
-
- - name: Install dependencies
- run: pip install pyyaml
-
- - name: Generate database (if not present)
- run: |
- if [ ! -f database.json ]; then
- python scripts/generate_db.py --bios-dir bios --output database.json
- fi
-
- - name: Generate pack for ${{ matrix.platform }}
- run: python scripts/generate_pack.py --platform ${{ matrix.platform }} --output-dir dist/
-
- - name: Upload artifact
- uses: actions/upload-artifact@v6
- with:
- name: pack-${{ matrix.platform }}
- path: dist/*.zip
- retention-days: 1
-
- publish:
- needs: [check-changes, discover, build]
- if: needs.check-changes.outputs.should_release == 'true'
- runs-on: ubuntu-latest
- steps:
- - uses: actions/checkout@v6
-
- - name: Download all pack artifacts
- uses: actions/download-artifact@v6
- with:
- path: dist/
- pattern: pack-*
- merge-multiple: true
-
- - name: Copy database.json
- run: cp database.json dist/database.json 2>/dev/null || true
-
- - uses: actions/setup-python@v6
- with:
- python-version: "3.12"
-
- - name: Install dependencies
- run: pip install pyyaml
-
- - name: Generate release notes
- id: notes
- run: |
- python3 << 'PYEOF'
- import json, os, subprocess, textwrap
-
- with open("database.json") as f:
- db = json.load(f)
-
- total = db["total_files"]
- size_mb = db["total_size"] / (1024 * 1024)
- date = db["generated_at"]
-
- packs = sorted(f for f in os.listdir("dist") if f.endswith(".zip"))
- pack_list = "\n".join(f"- **{p}** ({os.path.getsize(f'dist/{p}') / 1024 / 1024:.0f} MB)" for p in packs)
-
- # Get recent changes
- try:
- log = subprocess.run(
- ["git", "log", "--oneline", "-20", "--no-merges", "--", "bios/", "platforms/"],
- capture_output=True, text=True
- ).stdout.strip()
- changes = "\n".join(f"- {line}" for line in log.split("\n") if line) if log else "- Initial release"
- except Exception:
- changes = "- See commit history"
-
- notes = textwrap.dedent(f"""\
- {total} BIOS/firmware files, {size_mb:.0f} MB, 50+ systems, verified checksums.
-
- ### Packs
- {pack_list}
-
- ### Install
- Download, extract to your emulator's BIOS directory:
-
- | Platform | Path |
- |----------|------|
- | RetroArch / Lakka | `system/` |
- | Batocera | `/userdata/bios/` |
- | Recalbox | `/recalbox/share/bios/` |
-
- CLI & archived platforms
-
- ```bash
- # CLI download
- python scripts/download.py retroarch ~/RetroArch/system/
-
- # Archived platforms (RetroPie, etc.)
- git clone https://github.com/Abdess/retrobios.git
- cd retrobios && pip install pyyaml
- python scripts/generate_pack.py --platform retropie -o ~/Downloads/
- ```
-
-
- ### Changes
- {changes}
-
- ---
- *{date} - [Full checksums & file listing](../../blob/main/README.md)*
- """)
-
- with open("/tmp/release_notes.md", "w") as f:
- f.write(notes)
- PYEOF
-
- - name: Create Release
- uses: softprops/action-gh-release@v2
- with:
- tag_name: ${{ needs.check-changes.outputs.version }}
- name: "BIOS Pack ${{ needs.check-changes.outputs.version }}"
- body_path: /tmp/release_notes.md
- files: dist/*
- fail_on_unmatched_files: false
- generate_release_notes: true
- make_latest: true
diff --git a/.github/workflows/update-db.yml b/.github/workflows/update-db.yml
deleted file mode 100644
index d0e1b3ec..00000000
--- a/.github/workflows/update-db.yml
+++ /dev/null
@@ -1,41 +0,0 @@
-name: Update Database
-
-on:
- push:
- branches: [main]
- paths:
- - "bios/**"
- workflow_dispatch:
-
-permissions:
- contents: write
-
-concurrency:
- group: update-db
- cancel-in-progress: true
-
-jobs:
- update:
- runs-on: ubuntu-latest
- steps:
- - uses: actions/checkout@v6
-
- - uses: actions/setup-python@v6
- with:
- python-version: "3.12"
-
- - name: Install dependencies
- run: pip install pyyaml
-
- - name: Generate database
- run: python scripts/generate_db.py --bios-dir bios --output database.json
-
- - name: Generate README and CONTRIBUTING
- run: python scripts/generate_readme.py --db database.json --platforms-dir platforms
-
- - name: Commit changes
- uses: stefanzweifel/git-auto-commit-action@v7
- with:
- commit_message: "chore: update database and documentation"
- file_pattern: "database.json README.md CONTRIBUTING.md"
- commit_author: "github-actions[bot] "
diff --git a/.github/workflows/validate.yml b/.github/workflows/validate.yml
index 4f56ec7e..80cba7fb 100644
--- a/.github/workflows/validate.yml
+++ b/.github/workflows/validate.yml
@@ -1,4 +1,4 @@
-name: Validate PR
+name: PR Validation
on:
pull_request:
@@ -10,6 +10,10 @@ permissions:
contents: read
pull-requests: write
+concurrency:
+ group: validate-${{ github.event.pull_request.number }}
+ cancel-in-progress: true
+
jobs:
validate-bios:
runs-on: ubuntu-latest
diff --git a/.github/workflows/watch-updates.yml b/.github/workflows/watch.yml
similarity index 95%
rename from .github/workflows/watch-updates.yml
rename to .github/workflows/watch.yml
index 2bdd856c..5c4e9cbe 100644
--- a/.github/workflows/watch-updates.yml
+++ b/.github/workflows/watch.yml
@@ -1,4 +1,4 @@
-name: Watch Platform Updates
+name: Weekly Platform Sync
on:
schedule:
@@ -8,7 +8,10 @@ on:
permissions:
contents: write
pull-requests: write
- issues: write
+
+concurrency:
+ group: watch-updates
+ cancel-in-progress: true
jobs:
scrape-and-update:
@@ -87,9 +90,9 @@ jobs:
git config user.email "github-actions[bot]@users.noreply.github.com"
git checkout -b "$BRANCH"
- git add -A
+ git add bios/ platforms/ database.json README.md CONTRIBUTING.md
git commit -m "chore: auto-update platform data ($DATE)"
- git push origin "$BRANCH" --force
+ git push origin "$BRANCH" --force-with-lease
existing_pr=$(gh pr list --head "$BRANCH" --json number --jq '.[0].number' 2>/dev/null || true)
diff --git a/.gitignore b/.gitignore
index 711e5dac..00d03770 100644
--- a/.gitignore
+++ b/.gitignore
@@ -15,3 +15,8 @@ bios/Other/Batocera42/dsi_nand.bin
bios/Sony/PlayStation 3/PS3UPDAT.PUP
bios/Sony/PlayStation Vita/PSVUPDAT.PUP
bios/Sony/PlayStation Vita/PSP2UPDAT.PUP
+
+# Large files stored as GitHub Release assets (additional)
+bios/Arcade/MAME/artwork/snspell.zip
+bios/Arcade/MAME/MAME 0.174 Arcade XML.dat
+bios/Sony/PlayStation Vita/.variants/PSP2UPDAT.PUP
diff --git a/LICENSE b/LICENSE
new file mode 100644
index 00000000..1779d940
--- /dev/null
+++ b/LICENSE
@@ -0,0 +1,21 @@
+MIT License
+
+Copyright (c) 2020 Abdess
+
+Permission is hereby granted, free of charge, to any person obtaining a copy
+of this software and associated documentation files (the "Software"), to deal
+in the Software without restriction, including without limitation the rights
+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+copies of the Software, and to permit persons to whom the Software is
+furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in all
+copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+SOFTWARE.
diff --git a/bios/3DO Company/3DO/panafz1.bin.fstree b/bios/3DO Company/3DO/panafz1.bin.fstree
deleted file mode 100644
index 08d92120..00000000
--- a/bios/3DO Company/3DO/panafz1.bin.fstree
+++ /dev/null
@@ -1,144 +0,0 @@
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
diff --git a/bios/3DO Company/3DO/panafz10.bin.fstree b/bios/3DO Company/3DO/panafz10.bin.fstree
deleted file mode 100644
index 8a416554..00000000
--- a/bios/3DO Company/3DO/panafz10.bin.fstree
+++ /dev/null
@@ -1,186 +0,0 @@
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
diff --git a/bios/Other/Batocera42/_info.txt b/bios/Other/Batocera42/_info.txt
deleted file mode 100644
index 942e9153..00000000
--- a/bios/Other/Batocera42/_info.txt
+++ /dev/null
@@ -1 +0,0 @@
-Place your prod.keys, title.keys, and dev.keys files here and switch firmware here if you intend to use Ryujinx
\ No newline at end of file
diff --git a/bios/Other/Batocera42/mac755.chd b/bios/Other/Batocera42/mac755.chd
deleted file mode 100644
index b642e1fe..00000000
Binary files a/bios/Other/Batocera42/mac755.chd and /dev/null differ
diff --git a/bios/Other/Batocera42/prod.keys b/bios/Other/Batocera42/prod.keys
deleted file mode 100644
index 99e7c501..00000000
--- a/bios/Other/Batocera42/prod.keys
+++ /dev/null
@@ -1,233 +0,0 @@
-aes_kek_generation_source = 4d870986c45d20722fba1053da92e8a9
-aes_key_generation_source = 89615ee05c31b6805fe58f3da24f7aa8
-bis_kek_source = 34c1a0c48258f8b4fa9e5e6adafc7e4f
-bis_key_00 = f5b00fe9880aee8faf55e15e5b9a1d4514287164af9775d276b370172efd1e03
-bis_key_01 = 00cae74f3b8f04598726587b716182b08e0a755fe6ad98a06a61c46501df7a89
-bis_key_02 = c4e8e97c90b1e8fbffd6ffeedd2b8a512b9c86baa322f518f8ccc834cf73fe7a
-bis_key_03 = c4e8e97c90b1e8fbffd6ffeedd2b8a512b9c86baa322f518f8ccc834cf73fe7a
-bis_key_source_00 = f83f386e2cd2ca32a89ab9aa29bfc7487d92b03aa8bfdee1a74c3b6e35cb7106
-bis_key_source_01 = 41003049ddccc065647a7eb41eed9c5f44424edab49dfcd98777249adc9f7ca4
-bis_key_source_02 = 52c2e9eb09e3ee2932a10c1fb6a0926c4d12e14b2a474c1c09cb0359f015f4e4
-device_key = 892b49ab89d635042c64a5977b48b912
-device_key_4x = 06a152a18c7cdcd1e5ea8cd76eb14cbe
-eticket_rsa_kek = 19c8b441d318802bad63a5beda283a84
-eticket_rsa_kek_source = dba451124ca0a9836814f5ed95e3125b
-eticket_rsa_kekek_source = 466e57b74a447f02f321cde58f2f5535
-eticket_rsa_keypair = 4f9ea87b446e134c20634ee9e35d1f8de9d20207b217efaa7e3b1c11292e5ea8ae59d09210c68c6703ebff87d8272a9717563126a6c8c8421eaefbde097ade8f55f38026c8ef4b9e2ba502cf559f8aa65149ce052ce31ad8b5152e5340f981f215c690b9adff7794e21406077ab0955ada4aef9a49ee158b785e971730f73ae58ef3c8e1fe45a70c6ec1045912189e5c27b562d142b280a7b3bbea5a742861d1c738b839abd5c388f1b8dff4016dacb82d5c6c0b3af6db3cd0740f7a255cdd3cef8e2ad8555c8313d700a771d831e9ffbfc4b20540e747eaec5f87209bff7c4099133dbbcc65fc049cd9b7c2b9ee66cec17780741ca760d09f5fc6d49560ace1ae49ffb108895b3f17d3763db451534007ef3481e751c91ba9236d9d2e73b95ce9863ee18737c09128e82158b1a42bef909cb8c56b208b5e0a5254bf119d1a4b935c98bc430e30bc0a87096f34b03ff0ea7ef8e7197998f6541a9ad2b36aef4344210fb5b34f52495cbd84e1ea89c963e982823ce94d102a64cbe0f5823d577a8311f11db9ee5998458a00133682c7bc0af93261f03f9c369ffba5356f165e10b7447a0d34de92a5149e1042b8650570d281bb15ca1cb65d04aff23e0e1a361e49780f66b43443a853f9f79607f78ee454f74d0a1c343b40a8d4f35d6a0b57207d72d82ccc8cac0168b06a96b961c6cb1eaeb0257e8c4829c2231e0ff8cc7be300010001000000000000000000000000
-header_kek_source = 1f12913a4acbf00d4cde3af6d523882a
-header_key = aeaab1ca08adf9bef12991f369e3c567d6881e4e4a6a47a51f6e4877062d542d
-header_key_source = 5a3ed84fdec0d82631f7e25d197bf5d01c9b7bfaf628183d71f64d73f150b9d2
-key_area_key_application_00 = ef979e289a132c23d39c4ec5a0bba969
-key_area_key_application_01 = cdedbab97b69729073dfb2440bff2c13
-key_area_key_application_02 = 75716ed3b524a01dfe21456ce26c7270
-key_area_key_application_03 = f428306544cf5707c25eaa8bc0583fd1
-key_area_key_application_04 = 798844ec099eb6a04b26c7c728a35a4d
-key_area_key_application_05 = a57c6eecc5410ada22712eb3ccbf45f1
-key_area_key_application_06 = 2a60f6c4275df1770651d5891b8e73ec
-key_area_key_application_07 = 32221bd6ed19b938bec06b9d36ed9e51
-key_area_key_application_08 = fb20aa9e3dbf67350e86479eb431a0b3
-key_area_key_application_09 = ce8d5fa79e220d5f48470e9f21be018b
-key_area_key_application_0a = 38b865725adcf568a81d2db3ceaa5bcc
-key_area_key_application_0b = bbddfd40a59d0ff555c0954239972213
-key_area_key_application_0c = 3fee7204e21c6b0ff1373226c0c3e055
-key_area_key_application_0d = 7b05d214fa554bc3e91b044fb412fc0d
-key_area_key_application_0e = 061667d7668b76a423e3f1aea52a8baa
-key_area_key_application_0f = 7ee19b046987ba2588e852cc24bc2953
-key_area_key_application_10 = fd8a4be923d9a464793cd2f3a27557ee
-key_area_key_application_11 = d8178dba2fb20ed3141612b6cb2e8e9d
-key_area_key_application_12 = 56debb519556d05e8ab3ddb9a1e4c1d9
-key_area_key_application_source = 7f59971e629f36a13098066f2144c30d
-key_area_key_ocean_00 = b33813e4c9c4399c75fabc673ab4947b
-key_area_key_ocean_01 = c54166efa8c9c0f6511fa8b580191677
-key_area_key_ocean_02 = 3061ce73461e0b0409d6a33da85843c8
-key_area_key_ocean_03 = 06f170025a64921c849df168e74d37f2
-key_area_key_ocean_04 = dc857fd6dc1c6213076ec7b902ec5bb6
-key_area_key_ocean_05 = 131d76b70bd8a60036d8218c15cb610f
-key_area_key_ocean_06 = 17d565492ba819b0c19bed1b4297b659
-key_area_key_ocean_07 = 37255186f7678324bf2b2d773ea2c412
-key_area_key_ocean_08 = 4115c119b7bd8522ad63c831b6c816a6
-key_area_key_ocean_09 = 792bfc652870cca7491d1685384be147
-key_area_key_ocean_0a = dfcc9e87e61c9fba54a9b1c262d41e4d
-key_area_key_ocean_0b = 66fe3107f5a6a8d8eda2459d920b07a1
-key_area_key_ocean_0c = b79b6bf3d6cdc5ec10277fc07a4fec93
-key_area_key_ocean_0d = 9a20ffbdcb03cfc5b8e88b058d27ae6c
-key_area_key_ocean_0e = 1e8bba40c91ca4d55163cdfb779a2f4e
-key_area_key_ocean_0f = 2a51262c614e175f22cb0bf7907418b0
-key_area_key_ocean_10 = 97b66913f9683a9e7b733b96a35cabf3
-key_area_key_ocean_11 = 42da6ca5bc5dc88dac81ba0729414af1
-key_area_key_ocean_12 = 0a9a14c74c9f46a3e0826c6e0857d199
-key_area_key_ocean_source = 327d36085ad1758dab4e6fbaa555d882
-key_area_key_system_00 = 6dd02aa15b440d6231236b6677de86bc
-key_area_key_system_01 = 4ab155e7f29a292037fd147592770b12
-key_area_key_system_02 = b7a74adeaf89c2a198c327bdff322d7d
-key_area_key_system_03 = d5aab1acd23a8aec284a316df859d377
-key_area_key_system_04 = 9b44b45b37de9d14754b1d22c2ca742c
-key_area_key_system_05 = 0012e957530d3dc7af34fbbe6fd44559
-key_area_key_system_06 = 01744e3b0818445cd54ee9f89da43192
-key_area_key_system_07 = d0d30e46f5695b875f11522c375c5a80
-key_area_key_system_08 = bd06cb1b86bd5c433667470a09eb63de
-key_area_key_system_09 = e19f788f658eda8bbf34a1dd2a9503a9
-key_area_key_system_0a = 7070e7ff5cfe448630143a9874903c38
-key_area_key_system_0b = 3fa471d4483e58b8f7756fcb64f63890
-key_area_key_system_0c = 7bfd381df3369407ab1c6bdd9fabf522
-key_area_key_system_0d = 53ed531cd657edf443b551a964f44ecc
-key_area_key_system_0e = fa9d4958e8f8f2c8c8ae33b1034a0a02
-key_area_key_system_0f = 91eae4eeb5335cc5a706c4fe81d8d8af
-key_area_key_system_10 = ae11fa6821b123419e0a54f3a89d9a8b
-key_area_key_system_11 = 6cb02ff14b6bb1145345dcbe6daaa0a9
-key_area_key_system_12 = 9ba3e06e93313a726e23bd2d32c494a2
-key_area_key_system_source = 8745f1bba6be79647d048ba67b5fda4a
-keyblob_00 = f759024f8199101dddc1ef91e6eecf37e24b95ac9272f7ae441d5d8060c843a48322d21cdd06d4fc958c68d3800eb4db939ffbec930177f77d136144ff615aa8835e811bb958deda218f8486b5a10f531b30cb9d269645ac9fc25c53fc80525e56bd3602988a9fcf06bbf99ca910ad6530791d512c9d57e17abf49220de6419bf4eca1685c1e4df77f19db7b44a985ca
-keyblob_01 = bd27264ae07e979756411d0c66e679e3c50851f3e902d9c2cd1a438b948159a517ec1566c10570326ea2697ee62da46f14bb5d581bfc06fd0c9387ea33d2d4dc63e7809ba90f03dd2c7112ffbfa548951b9b8c688b5e4f2951d24a73da29c668154a5d4838dba71ee068ace83fe720e8c2a495c596f73525dc3c05994b40ad27f8c60322f75cd548b821af9162e16f76
-keyblob_02 = a3d4a8e153b8e6ae6e6aef3e8f219cb4b7790f47856accc76268f9afa99a1ff8b1a72f63d1f99f480a3c1532078bb59abdd25203cfb12a38b33e9ba6a09afb6f24283b3ba76a0161230a73669ddf5493c2b7919d094fd795b484794854f71e4f4c672245d7770e29397722444d111b4229cdbf35707b70634ea8f140766e884cc580cb1e2d9aa9866ffef920010fc409
-keyblob_03 = 1558f525ae8c5be9243fb6d8a8b0a8ee0e886a59035668740a936619b7a5c83e821198b171d18e51445054df68688e45703b936818a827d8e540dd6bef2e11ec9ddc6cfe5fc736dd769b9f6e0a23a62e2e5f49e86143646a04ec3a23f828373a336a5c224a91f8a0c6c6a7b5844dd6415804209f83c943aeca9cfd856db6bd4ec32009c8cb268ed053052c9237dfd8bc
-keyblob_04 = 9fbeb1957fc1629e08b753a9086d6e01ffb4f11466b7417e3fa7f5f1efb754406704fd75afaf91a408a0b524c1fc80d36c2046fa4757412efe4c11e382f72e8a10d90ed580017d9deb87af2549b6b02661af48ff94f6072c0fef7fc2833b8bdae503898e2e927ac0663e8b6391dd4f1d685313935e2c48ece7d177c88bc9c883ede36c3677495784b838d7265c6ba7a1
-keyblob_05 = 94a92da1d73c2b3e165c891ced5607fc6628ca2a0654f3fbc05711c063377c6e9c96a9d0192e530dd510e4fd41aa62ef4213c5f6e059e7e21db098a9b22d1e6c29bee148aaef15c52549d9165de96e85b0d029ecdc5843e2f32cb18be707eec61909cf3385d45bc2a4c8d76e9bfad5a40c4b92dcb982aa50d474897ac9ebb5351a7015dcc277a08f1214ad41384d7941
-keyblob_key_00 = 008891f23d1be101fd042d842d296ef8
-keyblob_key_01 = 7968938f324b42aa7803b9fd3ca47bfb
-keyblob_key_02 = 8577c79b28711b250fd62dae31add612
-keyblob_key_03 = 0a6cc78cc89493354593ed478b65cb9b
-keyblob_key_04 = 58ed4fd6dbb15da8775c1c1ae7ddcc5d
-keyblob_key_05 = 49dc9d174b86be15c14bf721d1a2e460
-keyblob_key_source_00 = df206f594454efdc7074483b0ded9fd3
-keyblob_key_source_01 = 0c25615d684ceb421c2379ea822512ac
-keyblob_key_source_02 = 337685ee884aae0ac28afd7d63c0433b
-keyblob_key_source_03 = 2d1f4880edeced3e3cf248b5657df7be
-keyblob_key_source_04 = bb5a01f988aff5fc6cff079e133c3980
-keyblob_key_source_05 = d8cce1266a353fcc20f32d3b517de9c0
-keyblob_mac_key_00 = e0c736471f8a05355783d05c41c4eacb
-keyblob_mac_key_01 = 89bd8c8d0533bf3ec038f918a33fd770
-keyblob_mac_key_02 = a8508a7e3c885f49ef5af653907d717f
-keyblob_mac_key_03 = 5764db8b1c40705ae4ff5af38bdaba18
-keyblob_mac_key_04 = 203bcfd41dd4c3f6fdc51581810c56b5
-keyblob_mac_key_05 = 6fbdb3293e3df676ff06504e2938f244
-keyblob_mac_key_source = 59c7fb6fbe9bbe87656b15c0537336a5
-mariko_master_kek_source_05 = 77605ad2ee6ef83c3f72e2599dac5e56
-mariko_master_kek_source_06 = 1e80b8173ec060aa11be1a4aa66fe4ae
-mariko_master_kek_source_07 = 940867bd0a00388411d31adbdd8df18a
-mariko_master_kek_source_08 = 5c24e3b8b4f700c23cfd0ace13c3dc23
-mariko_master_kek_source_09 = 8669f00987c805aeb57b4874de62a613
-mariko_master_kek_source_0a = 0e440cedb436c03faa1daebf62b10982
-mariko_master_kek_source_0b = e541acecd1a7d1abed0377f127caf8f1
-mariko_master_kek_source_0c = 52719bdfa78b61d8d58511e48e4f74c6
-mariko_master_kek_source_0d = d268c6539d94f9a8a5a8a7c88f534b7a
-mariko_master_kek_source_0e = ec61bc821e0f5ac32b643f9dd619222d
-mariko_master_kek_source_0f = a5ec16391a3016082ecf096f5e7ceea9
-mariko_master_kek_source_10 = 8dee9e11363a9b0a6ac7bbe9d103f780
-mariko_master_kek_source_11 = 4f413c3bfb6a012a689f83e953bd16d2
-mariko_master_kek_source_12 = 31be25fbdbb4ee495c7705c2369f3480
-master_kek_00 = f759024f8199101dddc1ef91e6eecf37
-master_kek_01 = bd27264ae07e979756411d0c66e679e3
-master_kek_02 = a3d4a8e153b8e6ae6e6aef3e8f219cb4
-master_kek_03 = 1558f525ae8c5be9243fb6d8a8b0a8ee
-master_kek_04 = 9fbeb1957fc1629e08b753a9086d6e01
-master_kek_05 = 94a92da1d73c2b3e165c891ced5607fc
-master_kek_08 = e42f1ec8002043d746575ae6dd9f283f
-master_kek_09 = cec2885fbeef5f6a989db84a4cc4b393
-master_kek_0a = dd1a730232522b5cb4590cd43869ab6a
-master_kek_0b = fc6f0c891d42710180724ed9e112e72a
-master_kek_0c = 43f7fc20fcec22a5b2a744790371b094
-master_kek_0d = 8dc9a8223671daa73ccd8b93cdaaed9f
-master_kek_0e = f3f857257c3f63ca63b9c9710b8f673e
-master_kek_0f = 1e8f01c4927a76a66097df44c3bad27d
-master_kek_10 = 8b523b9d476508daadc2036582ce5aa8
-master_kek_11 = c618d3fd0ee15ffcea22bc98ad2489b5
-master_kek_12 = f540a14ea2cce8d0ede62a56586bfb0e
-master_kek_source_06 = 374b772959b4043081f6e58c6d36179a
-master_kek_source_07 = 9a3ea9abfd56461c9bf6487f5cfa095c
-master_kek_source_08 = dedce339308816f8ae97adec642d4141
-master_kek_source_09 = 1aec11822b32387a2bedba01477e3b67
-master_kek_source_0a = 303f027ed838ecd7932534b530ebca7a
-master_kek_source_0b = 8467b67f1311aee6589b19af136c807a
-master_kek_source_0c = 683bca54b86f9248c305768788707923
-master_kek_source_0d = f013379ad56351c3b49635bc9ce87681
-master_kek_source_0e = 6e7786ac830a8d3e7db766a022b76e67
-master_kek_source_0f = 99220957a7f95e94fe787f41d6e756e6
-master_kek_source_10 = 71b9a6c0ff976b0cb440b9d5815d8190
-master_kek_source_11 = 00045df04dcd14a31cbfde4855ba35c1
-master_kek_source_12 = d76374464eba780a7c9db3e87a3d71e3
-master_key_00 = c2caaff089b9aed55694876055271c7d
-master_key_01 = 54e1b8e999c2fd16cd07b66109acaaa6
-master_key_02 = 4f6b10d33072af2f250562bff06b6da3
-master_key_03 = 84e04ec20b9373818c540829cf147f3d
-master_key_04 = cfa2176790a53ff74974bff2af180921
-master_key_05 = c1dbedcebf0dd6956079e506cfa1af6e
-master_key_06 = 0aa90e6330cdc12d819b3254d11a4e1e
-master_key_07 = 929f86fbfe4ef7732892bf3462511b0e
-master_key_08 = 23cfb792c3cb50cd715da0f84880c877
-master_key_09 = 75c93b716255319b8e03e14c19dea64e
-master_key_0a = 73767484c73088f629b0eeb605f64aa6
-master_key_0b = 8500b14bf4766b855a26ffc614097a8f
-master_key_0c = b3c503709135d4b35de31be4b0b9c0f7
-master_key_0d = 6d2b26416ab030dc504cbfd6bb2977b7
-master_key_0e = 3b995e3bf23207c3cacb07f8c57415e6
-master_key_0f = ff22454d86237004c750e2dcb4b16c80
-master_key_10 = 252c7d95f296d07f2369bdba6d42c615
-master_key_11 = 03d1d722e91bf7f2c8f3c00283bf5c6c
-master_key_12 = 32ecadc8986540f930f54d159fcba88e
-master_key_source = d8a2410ac6c59001c61d6a267c513f3c
-package1_key_00 = f4eca1685c1e4df77f19db7b44a985ca
-package1_key_01 = f8c60322f75cd548b821af9162e16f76
-package1_key_02 = c580cb1e2d9aa9866ffef920010fc409
-package1_key_03 = c32009c8cb268ed053052c9237dfd8bc
-package1_key_04 = ede36c3677495784b838d7265c6ba7a1
-package1_key_05 = 1a7015dcc277a08f1214ad41384d7941
-package2_key_00 = a35a19cb14404b2f4460d343d178638d
-package2_key_01 = a0dd1eacd438610c85a191f02c1db8a8
-package2_key_02 = 7e5ba2aafd57d47a85fd4a57f2076679
-package2_key_03 = bf03e9889fa18f0d7a55e8e9f684323d
-package2_key_04 = 09df6e361e28eb9c96c9fa0bfc897179
-package2_key_05 = 444b1a4f9035178b9b1fe262462acb8e
-package2_key_06 = 442cd9c21cfb8914587dc12e8e7ed608
-package2_key_07 = 70c821e7d6716feb124acbac09f7b863
-package2_key_08 = 8accebcc3d15a328a48365503f8369b6
-package2_key_09 = f562a7c6c42e3d4d3d13ffd504d77346
-package2_key_0a = 0803167ec7fc0bc753d8330e5592a289
-package2_key_0b = 341db6796aa7bdb8092f7aae6554900a
-package2_key_0c = 4e97dc4225d00c6ae33d49bddd17637d
-package2_key_0d = db13c2de2c313540b18a32b4f106d4a1
-package2_key_0e = 254d393b26e6d98963c1c8c4fa6d11e2
-package2_key_0f = 1c87f9650cca54af03df3590021e457d
-package2_key_10 = 2d64ee13cece88746b375f1a43b9fdf6
-package2_key_11 = 73a9680bbd12d3a05c6eddb9545c4077
-package2_key_12 = 64f022a4150139a118608f55e5621c72
-package2_key_source = fb8b6a9c7900c849efd24d854d30a0c7
-per_console_key_source = 4f025f0eb66d110edc327d4186c2f478
-retail_specific_aes_key_source = e2d6b87a119cb880e822888a46fba195
-save_mac_kek_source = d89c236ec9124e43c82b038743f9cf1b
-save_mac_key = e59956b2e87c5b2a9f6cc9b894a5b4d7
-save_mac_key_source = e4cd3d4ad50f742845a487e5a063ea1f
-save_mac_sd_card_kek_source = 0489ef5d326e1a59c4b7ab8c367aab17
-save_mac_sd_card_key_source = 6f645947c56146f9ffa045d595332918
-sd_card_custom_storage_key_source = 370c345e12e4cefe21b58e64db52af354f2ca5a3fc999a47c03ee004485b2fd0
-sd_card_kek_source = 88358d9c629ba1a00147dbe0621b5432
-sd_card_nca_key_source = 5841a284935b56278b8e1fc518e99f2b67c793f0f24fded075495dca006d99c2
-sd_card_save_key_source = 2449b722726703a81965e6e3ea582fdd9a951517b16e8f7f1f68263152ea296a
-sd_seed = be3e82d2ac0cd8a239147d56caff1372
-secure_boot_key = 97e30891cdd6567b3e6c03599fc25dbc
-ssl_rsa_kek = b011100660d1dccbad1b1b733afa9f95
-ssl_rsa_kek_source = 9a383bf431d0bd8132534ba964397de3
-ssl_rsa_kekek_source = 7f5bb0847b25aa67fac84be23d7b6903
-ssl_rsa_key = 3d2b0e3ea6dfb598114fa59fa4a6ecc60b02f8abfc3f044594d5c1e1e2745d05ad401918398f9ed95bfa0a55338f8249ced675853a969e456166d0b23002806b993f1adccab183bfe367fd9624b3aaeb5fe9d6aae74fb14f46df245d69bcb403cce8d10fa21b20a01fa5ed7cd1375890a4c73c3f473c0194495861acf644e9d353dd3beca0a18cae8aacc95d442a57a8aa9ee67e478128db58b4580c3788b0180c6c56e833804b403199b386f3140b7ba0881debf6e418e3acae993b5ea7d139cd5119f913c2c3c0892352c9d8053a9801f4c91df9de6ff3901f82a2d446a67467c816a224ce15700da702a38f8a75159f1fe711728686e3222d10981f4f65c1
-titlekek_00 = 62a24d6e6d0d0e0abf3554d259be3dc9
-titlekek_01 = 8821f642176969b1a18021d2665c0111
-titlekek_02 = 5d15b9b95a5739a0ac9b20f600283962
-titlekek_03 = 1b3f63bcb67d4b06da5badc7d89acce1
-titlekek_04 = e45c1789a69c7afbbf1a1e61f2499459
-titlekek_05 = ddc67f7189f4527a37b519cb051eee21
-titlekek_06 = b1532b9d38ab036068f074c0d78706ac
-titlekek_07 = 81dc1b1783df268789a6a0edbf058343
-titlekek_08 = 47dfe4bf0eeda88b17136b8005ab08ea
-titlekek_09 = adaa785d90e1a9c182ac07bc276bf600
-titlekek_0a = 42daa957c128f75bb1fda56a8387e17b
-titlekek_0b = d08903363f2c8655d3de3ccf85d79406
-titlekek_0c = be2682599db34caa9bc7ebb2cc7c654c
-titlekek_0d = 41071f95beddc4114a03e0072e6ccab7
-titlekek_0e = e342365a0fa0fa4a28a7bc00e45b3f68
-titlekek_0f = 105999eaf8b71d199bf201f525b2c68d
-titlekek_10 = 3796fcdb27351d58cc3f3379dda04202
-titlekek_11 = b16d793f4be5394e60a6e426e172c16a
-titlekek_12 = 0cd263cbddcbeca9ffa779edbe708664
-titlekek_source = 1edc7b3b60e6b4d878b81715985e629b
-tsec_key = 92f4d2204af8f728ff121d528b170859
-tsec_root_key_02 = 4b4fbcf58e23cf4902d478b76c8048ec
diff --git a/bios/Other/Batocera42/title.keys b/bios/Other/Batocera42/title.keys
deleted file mode 100644
index 94fb4ced..00000000
--- a/bios/Other/Batocera42/title.keys
+++ /dev/null
@@ -1,18 +0,0 @@
-01007300020fa0000000000000000008 = dad4a8795aee049073fc30f2b716f4da
-01007300020fa8000000000000000008 = fcd2887bb23365d3f06623e5e55b4680
-01001520000220000000000000000000 = a5e87b09e1700ffa6dc41ed868f3fca9
-01001520000228000000000000000004 = 5ac982f853e174d8bb8b1f67e022af02
-01007f200b0c00000000000000000004 = 60dcd6e322cfca22b76d7b276e3bffce
-01007f200b0c08000000000000000004 = 78bce3ec7bf86f238fe6c43eac605810
-010057d0064920000000000000000004 = 237a2cb0af9196e3329b0e7d45d820fd
-010057d0064928000000000000000004 = 82297c5f69d7af908ca001038681708f
-010069c01ab828000000000000000011 = 5426a1c6af5e69ebf643f603306642ea
-010044401e8260000000000000000012 = af41fcbe3c28eed71db386a1693ffb6d
-010066401d88e0000000000000000011 = cceb1dae5f2151b80d1b1c832b0fbede
-010066401d88e8000000000000000012 = a46aa480ea394d071fc2eace3fde6a53
-0100bf500207c8000000000000000008 = bf7264036ffd7c4e7e5fa8a62d8b61ed
-01004ba017cd68000000000000000011 = c0858a80029bce1e0cdf5507827b692e
-01007ef00011e0000000000000000000 = 17f3acad0780b72844fc13d363ee66ae
-01007ef00011e8000000000000000003 = 2566d59be1cb9bfcc2c1b8c648b8ed0d
-010007500f27c0000000000000000010 = 327a04ec6f1a197deaafdf3075108cc8
-01007b0017c900000000000000000011 = e0e348aba40d1ecff2b4e5409fe22de4
diff --git a/bios/Other/RetroBat/auth.db b/bios/Other/RetroBat/auth.db
deleted file mode 100644
index 3932d7b8..00000000
Binary files a/bios/Other/RetroBat/auth.db and /dev/null differ
diff --git a/bios/Other/RetroBat/craft.db b/bios/Other/RetroBat/craft.db
deleted file mode 100644
index 8c8d0e0b..00000000
Binary files a/bios/Other/RetroBat/craft.db and /dev/null differ
diff --git a/bios/Other/RetroBat/data.zip b/bios/Other/RetroBat/data.zip
deleted file mode 100644
index 5d9c1f7d..00000000
Binary files a/bios/Other/RetroBat/data.zip and /dev/null differ
diff --git a/bios/Other/RetroBat/data/roms/NEM-4/SYM.ROM b/bios/Other/RetroBat/data/roms/NEM-4/SYM.ROM
deleted file mode 100644
index 219f4d8d..00000000
Binary files a/bios/Other/RetroBat/data/roms/NEM-4/SYM.ROM and /dev/null differ
diff --git a/bios/Other/RetroBat/mctv.bin b/bios/Other/RetroBat/mctv.bin
deleted file mode 100644
index f9074f95..00000000
--- a/bios/Other/RetroBat/mctv.bin
+++ /dev/null
@@ -1,972 +0,0 @@
-Full Pack BIOS RETROBAT V7.5.3
-By THE MINI CAKE TV
-https://www.youtube.com/c/TheMiniCakeTV
-
-
-place the BIOS & EMULATORS folders in the RETROBAT folder and overwrite the files.
-
-NEW UPDATE V7.5.3
-
-Dragon 32/64
-
-d32.rom 3420b96031078a4ef408cad7bf21a33f
-d64_1.rom 5f0bee59710e55f5880e74890912ed78
-d64_2.rom\ fd91edce7be5e7c2d88e46b76956a8aa
-ddos10.rom 1c965da49b6c5459b8353630aa1482e7
-deltados.rom 024eac3db20f1b5cf98c30a0e4743201
-
-3DO:
-
-BIOS md5
-panafz1.bin f47264dd47fe30f73ab3c010015c155b
-panafz10.bin 51f2f43ae2f3508a14d9f56597e2d3ce
-goldstar.bin 8639fd5e549bd6238cfee79e3e749114
-
-adam.zip
-- alf @1 rev 57 e3d5.u8 "01bba3bcd46d8a586dd6ec555accc133"
-- alf @2 rev 57 ae6a.u20 "feabe33e8f2dab88da1458b4d27f3faa"
-- alf @3 rev 57 8534.u21 "a720bc872a772ed471fac14e36ec8bcb"
-- eos 6 rev 57 08dd.u22 "cf10b154f2e006a9740d7653cfc47cab"
-- master rev a 174b.u6 "7916bb9635d502366326ec39aea5fc89"
-- os7.u2 "2c66f5911e5b42b8ebe113403548eee7"
-- wp_r80.rom "4fe4f6800076ea3d897d4285653447bd"
-
-adam_ddp.zip
-- tape rev a 8865.u24 "0423e9e9bf5036aa1e9d656b6a1f842c"
-
-adam_fdc.zip
-- 1440k micro innovations hd-dd.u10 "ae12d0b83832b059cb6cb43029bbfdb3"
-- 320ta.u10 "4c38a7df1e645c8d9f417bf7165c46d0"
-- a720dipi 7607 mmsg =c= 1988.u10 "afea14c826f3cfbc89b76725a4a41951"
-- adam disk u10 ad 31 rev a 09-27-84.u10 "976d2a7d85319d9104bc9ec176fbfa9c"
-- dbl2-4.u10 "29569dc029e95e48907b3c81d636987f"
-- doug.u10 "a121855c20a638429bbfcf0448349515"
-- fastpack 720a,t.u10 "e05ababa16e2d5cb92b678cb6e6e2004"
-- pmhdfdc.u10 "a1a2a353dea4b8769a2da733822abfdc"
-
-adam_kb.zip
-- keyboard.u2 "d81e0b2bb6b98999541c5f40b489e88f"
-
-adam_prn.zip
-- printer.u2 "3cdf2fe48ac4224b56f26c03f6c68982"
-
-advision.xml bios\mame\hash
-
-advision.zip
-- b225__ins8048-11kdp_n.u5 "5729638bd856c475678467a353bd921c"
-- b8223__cop411l-kcn_n.u8 "fc5e71445e4947a9d00eedbc66b13a8f"
-
-4688a93aa298b9431c1788c9b90378c8 bios/electron.zip
-2cc67be4624df4dc66617742571a8e3d bios/electron64.zip
-df01cfe5894276de96bbd1c45b7e834c bios/electron64.zip
-f3a39227b401a2ce8cdc7e4b7a860aaf bios/electron_plus1.zip
-9aa334b4e8f6d7565e6323e0f77110de bios/electron_plus3.zip
-83e15ca501899b0d5b2ce3f5ef696069 bios/electron_plus3.zip
-b60ee811f4b805638478acd5297b16e0 bios/electron_plus3.zip
-62f5e1d3dae3a68d8fe4406a6f603dc3 bios/electron_plus3.zip
-5c39baa89fe8a40a5167a53cc5ae7791 bios/electron_plus3.zip
-
-AMIGA 500+
-
-Kickstart v2.04 r37.175 (1991-05)(Commodore)(A500+)[!].rom
-kick37175.A500
-
-AMIGA 500
-kick33180.A500 85ad74194e87c08904327de1a9443b7a
-
-kick34005.A500 82a21c1890cae844b3df741f2762d48d
-
-kick37175.A500 dc10d7bdd1b6f450773dfb558477c230
-
-Kickstart v3.1 r40.063 (1993-07)(Commodore)(A500-A600-A2000)[!].rom
-Kickstart v1.3 r34.5 (1987)(Commodore)(A500-A1000-A2000-CDTV)[!].rom
-Kickstart v1.3 r34.5 (1987)(Commodore)(A500-A1000-A2000-CDTV)[o].rom
-kick34005.A500
-kick37175.A500
-kick33180.A500
-
-Kickstart v3.1 r40.068 (1993-12)(Commodore)(A1200)[!].rom 646773759326fbac3b2311fd8c8793ee
-Kickstart - 391774-01 (USA, Europe) (v3.1 Rev 40.068) (A1200).rom
-kick40068.A1200
-
-Kickstart v3.1 r40.068 (1993-12)(Commodore)(A4000)[!].rom 9bdedde6a4f33555b4a270c8ca53297d
-kick40068.A4000
-
-kick40060.CD32.ext bb72565701b1b6faece07d68ea5da639
-
-kick40060.CD32 5f8924d013dd57a89cf349f4cdedc6b1
-Kickstart v3.1 r40.060 (1993-05)(Commodore)(CD32)[!].rom
-Kickstart v3.1 r40.60 (1993)(Commodore)(CD32).rom
-kick40060.CD32
-
-CD32 Extended-ROM r40.60 (1993)(Commodore)(CD32).rom
-kick40060.CD32.ext
-
-kick34005.CDTV 89da1838a24460e4b93f4f0c5d92d48d
-
-Kickstart v1.3 r34.5 (1987)(Commodore)(A500-A1000-A2000-CDTV)[!].rom
-Kickstart v1.3 r34.005 (1987-12)(Commodore)(A500-A1000-A2000-CDTV)[!].rom
-Kickstart v1.3 r34.005 (1987-12)(Commodore)(A500-A1000-A2000-CDTV)[o].rom
-kick34005.CDTV
-CDTV Extended-ROM v1.0 (1991)(Commodore)(CDTV)[!].rom
-CDTV Extended-ROM v2.7 (1992)(Commodore)(CDTV).rom
-kick40060.CD32.ext
-
-apfm1000.xml
-
-\bios\mame\hash
-
-apfm1000.zip
-- apf_4000.rom "1f4a976350202ee1e32c2b0477c3fc1b"
-- mod_bios.bin "b325543b36d37edf3fc20761f00c7a37"
-- trash-ii.bin "89a7cfa5469ce24773721d65b28f8544"
-
-"apple2.zip"
-- "341-0001-00.e0" size="2048" crc="c0a4ad3b" sha1="bf32195efcb34b694c893c2d342321ec3a24b98f"
-- "341-0002-00.e8" size="2048" crc="a99c2cf6" sha1="9767d92d04fc65c626223f25564cca31f5248980"
-- "341-0003-00.f0" size="2048" crc="62230d38" sha1="f268022da555e4c809ca1ae9e5d2f00b388ff61c"
-- "341-0004-00.f8" size="2048" crc="020a86d0" sha1="52a18bd578a4694420009cad7a7a5779a8c00226"
-- "341-0016-00.d0" size="2048" crc="4234e88a" sha1="c9a81d704dc2f0c3416c20f9c4ab71fedda937ed"
-- "341-0020-00.f8" size="2048" crc="079589c4" sha1="a28852ff997b4790e53d8d0352112c4b1a395098"
-- "341-0027-a.p5" size="256" crc="ce7144f6" sha1="d4181c9f046aafc3fb326b381baac809d9e38d16"
-- "341-0028-a.rom" size="256" crc="b72a2c70" sha1="bc39fbd5b9a8d2287ac5d0a42e639fc4d3c2f9d4"
-- "a2.chr" size="2048" crc="64f415c6" sha1="f9d312f128c9557d9d6ac03bfad6c3ddf83e5659"
-- "sc01a.bin" size="512" crc="fc416227" sha1="1d6da90b1807a01b5e186ef08476119a862b5e6d"
-
-"apple2e.zip"
-- "341-0027-a.p5" size="256" crc="ce7144f6" sha1="d4181c9f046aafc3fb326b381baac809d9e38d16"
-- "341-0028-a.rom" size="256" crc="b72a2c70" sha1="bc39fbd5b9a8d2287ac5d0a42e639fc4d3c2f9d4"
-- "342-0132-c.e12" size="2048" crc="e47045f4" sha1="12a2e718f5f4acd69b6c33a45a4a940b1440a481"
-- "342-0133-a.chr" size="4096" crc="b081df66" sha1="7060de104046736529c1e8a687a0dd7b84f8c51b"
-- "342-0134-a.64" size="8192" crc="fc3d59d8" sha1="8895a4b703f2184b673078f411f4089889b61c54"
-- "342-0135-b.64" size="8192" crc="e248835e" sha1="523838c19c79f481fa02df56856da1ec3816d16e"
-- "sc01a.bin" size="512" crc="fc416227" sha1="1d6da90b1807a01b5e186ef08476119a862b5e6d"
-
-"apple2ee.zip"
-- "341-0027-a.p5" size="256" crc="ce7144f6" sha1="d4181c9f046aafc3fb326b381baac809d9e38d16"
-- "341-0028-a.rom" size="256" crc="b72a2c70" sha1="bc39fbd5b9a8d2287ac5d0a42e639fc4d3c2f9d4"
-- "341-0132-d.e12" size="2048" crc="c506efb9" sha1="8e14e85c645187504ec9d162b3ea614a0c421d32"
-- "342-0265-a.chr" size="4096" crc="2651014d" sha1="b2b5d87f52693817fc747df087a4aa1ddcdb1f10"
-- "342-0303-a.e8" size="8192" crc="95e10034" sha1="afb09bb96038232dc757d40c0605623cae38088e"
-- "342-0304-a.e10" size="8192" crc="443aa7c4" sha1="3aecc56a26134df51e65e17f33ae80c1f1ac93e6"
-- "sc01a.bin" size="512" crc="fc416227" sha1="1d6da90b1807a01b5e186ef08476119a862b5e6d"
-
-"apple2p.zip"
- dict:
- with open(db_path) as f:
- return json.load(f)
-
-
def find_missing(config: dict, db: dict) -> list[dict]:
"""Find BIOS files required by platform but not in database."""
missing = []
diff --git a/scripts/common.py b/scripts/common.py
index 4e7bc953..45dd635f 100644
--- a/scripts/common.py
+++ b/scripts/common.py
@@ -7,6 +7,7 @@ and file resolution - eliminates DRY violations across scripts.
from __future__ import annotations
import hashlib
+import json
import os
import zipfile
import zlib
@@ -38,6 +39,12 @@ def compute_hashes(filepath: str | Path) -> dict[str, str]:
}
+def load_database(db_path: str) -> dict:
+ """Load database.json and return parsed dict."""
+ with open(db_path) as f:
+ return json.load(f)
+
+
def md5sum(filepath: str | Path) -> str:
"""Compute MD5 of a file - matches Batocera's md5sum()."""
h = hashlib.md5()
diff --git a/scripts/dedup.py b/scripts/dedup.py
index 0e165a8f..4bfe345c 100644
--- a/scripts/dedup.py
+++ b/scripts/dedup.py
@@ -87,7 +87,7 @@ def deduplicate(bios_dir: str, dry_run: bool = False) -> dict:
if len(paths) <= 1:
continue
- paths.sort(key=path_priority)
+ paths.sort(key=path_priority)
canonical = paths[0]
duplicates = paths[1:]
diff --git a/scripts/generate_db.py b/scripts/generate_db.py
index 02feeaa3..cae3b354 100644
--- a/scripts/generate_db.py
+++ b/scripts/generate_db.py
@@ -11,14 +11,15 @@ Use --force to rehash all files.
from __future__ import annotations
import argparse
-import hashlib
import json
import os
import sys
-import zlib
from datetime import datetime, timezone
from pathlib import Path
+sys.path.insert(0, os.path.dirname(__file__))
+from common import compute_hashes
+
CACHE_DIR = ".cache"
CACHE_FILE = os.path.join(CACHE_DIR, "db_cache.json")
DEFAULT_BIOS_DIR = "bios"
@@ -27,31 +28,6 @@ DEFAULT_OUTPUT = "database.json"
SKIP_PATTERNS = {".git", ".github", "__pycache__", ".cache", ".DS_Store", "desktop.ini"}
-def compute_hashes(filepath: Path) -> dict:
- """Compute SHA1, MD5, SHA256, CRC32 for a file."""
- sha1 = hashlib.sha1()
- md5 = hashlib.md5()
- sha256 = hashlib.sha256()
- crc = 0
-
- with open(filepath, "rb") as f:
- while True:
- chunk = f.read(65536)
- if not chunk:
- break
- sha1.update(chunk)
- md5.update(chunk)
- sha256.update(chunk)
- crc = zlib.crc32(chunk, crc)
-
- return {
- "sha1": sha1.hexdigest(),
- "md5": md5.hexdigest(),
- "sha256": sha256.hexdigest(),
- "crc32": format(crc & 0xFFFFFFFF, "08x"),
- }
-
-
def should_skip(path: Path) -> bool:
"""Check if a path should be skipped. Allows .variants/ directories."""
for part in path.parts:
@@ -276,8 +252,7 @@ def _collect_all_aliases(files: dict) -> dict:
pass
try:
- import sys as _sys
- _sys.path.insert(0, "scripts")
+ sys.path.insert(0, "scripts")
from scraper.coreinfo_scraper import Scraper as CoreInfoScraper
ci_reqs = CoreInfoScraper().fetch_requirements()
for r in ci_reqs:
diff --git a/scripts/generate_pack.py b/scripts/generate_pack.py
index 0dd7b9e8..68726539 100644
--- a/scripts/generate_pack.py
+++ b/scripts/generate_pack.py
@@ -24,7 +24,7 @@ import zipfile
from pathlib import Path
sys.path.insert(0, os.path.dirname(__file__))
-from common import load_platform_config
+from common import load_database, load_platform_config
try:
import yaml
@@ -40,11 +40,6 @@ LARGE_FILES_RELEASE = "large-files"
LARGE_FILES_REPO = "Abdess/retrobios"
-def load_database(db_path: str) -> dict:
- with open(db_path) as f:
- return json.load(f)
-
-
def fetch_large_file(name: str, dest_dir: str = ".cache/large") -> str | None:
"""Download a large file from the 'large-files' GitHub release if not cached."""
cached = os.path.join(dest_dir, name)
@@ -380,9 +375,7 @@ def main():
if new_path != zip_path:
os.rename(zip_path, new_path)
print(f" Renamed -> {os.path.basename(new_path)}")
- except FileNotFoundError as e:
- print(f" ERROR: {e}")
- except Exception as e:
+ except (FileNotFoundError, OSError, yaml.YAMLError) as e:
print(f" ERROR: {e}")
@@ -392,8 +385,6 @@ def _group_identical_platforms(platforms: list[str], platforms_dir: str) -> list
Returns [(group_of_platform_names, representative_platform), ...].
Platforms with the same resolved systems+files+base_destination are grouped.
"""
- import hashlib as _hl
-
fingerprints = {}
representatives = {}
@@ -413,7 +404,7 @@ def _group_identical_platforms(platforms: list[str], platforms_dir: str) -> list
full_dest = f"{base_dest}/{dest}" if base_dest else dest
entries.append(full_dest)
- fingerprint = _hl.sha1("|".join(sorted(entries)).encode()).hexdigest()
+ fingerprint = hashlib.sha1("|".join(sorted(entries)).encode()).hexdigest()
fingerprints.setdefault(fingerprint, []).append(platform)
representatives.setdefault(fingerprint, platform)
diff --git a/scripts/generate_readme.py b/scripts/generate_readme.py
index e4e744d7..7f26cdec 100644
--- a/scripts/generate_readme.py
+++ b/scripts/generate_readme.py
@@ -15,7 +15,7 @@ from datetime import datetime, timezone
from pathlib import Path
sys.path.insert(0, os.path.dirname(__file__))
-from common import load_platform_config
+from common import load_database, load_platform_config
try:
import yaml
@@ -24,11 +24,6 @@ except ImportError:
sys.exit(1)
-def load_database(db_path: str) -> dict:
- with open(db_path) as f:
- return json.load(f)
-
-
def load_platform_configs(platforms_dir: str) -> dict:
"""Load all platform configs with inheritance resolved."""
configs = {}
diff --git a/scripts/scraper/base_scraper.py b/scripts/scraper/base_scraper.py
index 4857b1c3..d44ad176 100644
--- a/scripts/scraper/base_scraper.py
+++ b/scripts/scraper/base_scraper.py
@@ -111,7 +111,7 @@ class BaseScraper(ABC):
try:
self.fetch_requirements()
return True
- except Exception:
+ except (ConnectionError, ValueError, OSError):
return False
@abstractmethod
diff --git a/scripts/scraper/batocera_scraper.py b/scripts/scraper/batocera_scraper.py
index 8bdce133..b24c8af9 100644
--- a/scripts/scraper/batocera_scraper.py
+++ b/scripts/scraper/batocera_scraper.py
@@ -239,7 +239,7 @@ class Scraper(BaseScraper):
_versions.append(int(_num))
if _versions:
batocera_version = str(max(_versions))
- except Exception:
+ except (ConnectionError, ValueError, OSError):
pass
return {
diff --git a/scripts/scraper/libretro_scraper.py b/scripts/scraper/libretro_scraper.py
index 8473f5d3..e487ebd0 100644
--- a/scripts/scraper/libretro_scraper.py
+++ b/scripts/scraper/libretro_scraper.py
@@ -208,7 +208,7 @@ class Scraper(BaseScraper):
}
except (urllib.error.URLError, urllib.error.HTTPError):
continue
- except Exception:
+ except (ConnectionError, ValueError, OSError):
pass
return metadata
diff --git a/scripts/validate_pr.py b/scripts/validate_pr.py
index 057fe208..866efbea 100644
--- a/scripts/validate_pr.py
+++ b/scripts/validate_pr.py
@@ -18,16 +18,14 @@ Outputs a structured report suitable for PR comments.
from __future__ import annotations
import argparse
-import hashlib
import json
import os
import subprocess
import sys
-import zlib
from pathlib import Path
sys.path.insert(0, os.path.dirname(__file__))
-from common import compute_hashes
+from common import compute_hashes, load_database as _load_database
try:
import yaml
@@ -93,11 +91,10 @@ class ValidationResult:
def load_database(db_path: str) -> dict | None:
- """Load database.json if available."""
- if os.path.exists(db_path):
- with open(db_path) as f:
- return json.load(f)
- return None
+ try:
+ return _load_database(db_path)
+ except (FileNotFoundError, json.JSONDecodeError):
+ return None
def load_platform_hashes(platforms_dir: str) -> dict:
diff --git a/scripts/verify.py b/scripts/verify.py
index a4aed915..4b092751 100644
--- a/scripts/verify.py
+++ b/scripts/verify.py
@@ -67,7 +67,7 @@ def check_inside_zip(container: str, file_name: str, expected_md5: str) -> str:
return Status.UNTESTED
return "not_in_zip"
- except Exception:
+ except (zipfile.BadZipFile, OSError, KeyError):
return "error"