mirror of
https://github.com/Abdess/retroarch_system.git
synced 2026-10-23 20:29:06 -05:00
chore: merge the copy rewrite
This commit is contained in:
commit
dc3bf41d26
28 files changed
+1995
-1385
No files matched your search
@@ -4,8 +4,17 @@ level: contribute
|
||||
|
||||
# Adding a platform
|
||||
|
||||
How to add support for a new retrogaming platform (e.g. a frontend like Batocera,
|
||||
a manager like EmuDeck, or a firmware database like BizHawk).
|
||||
Adding a platform gives its users a pack and a one-line install with the files
|
||||
their setup checks, in the place it checks them, plus every file its emulators
|
||||
need that its own list leaves out. The work is to read how the platform
|
||||
declares and checks BIOS files, then teach this project to read that
|
||||
declaration. A platform can be a frontend like Batocera, a manager like EmuDeck
|
||||
or a firmware database like BizHawk.
|
||||
|
||||
Example: RomM declares its BIOS files in
|
||||
`backend/models/fixtures/known_bios_files.json` and checks size plus any one
|
||||
hash (`firmware.py`, `verify_file_hashes`). Its scraper turns that JSON into
|
||||
`platforms/romm.yml`, and the pack, the installer and its site page follow.
|
||||
|
||||
## Prerequisites
|
||||
|
||||
@@ -171,6 +180,14 @@ page. The groups and their labels are `DEVICE_GROUPS` in
|
||||
(what it is, where its BIOS folder is, where the install command runs). A
|
||||
test fails when a registered platform has no group or no guide.
|
||||
|
||||
The guide text is read by someone who knows their device and little else.
|
||||
`summary` is one plain sentence, with no chip or board names. `notes` hold
|
||||
one fact each that the reader acts on. A source citation, a list of models or
|
||||
how the installer finds the folder goes in `reference_notes`, which open the
|
||||
Reference part of the page, and a rare build goes in `more_folders`, shown
|
||||
folded. The guide part of every setup page is held to the word budgets of
|
||||
[Pages for newcomers](testing-guide.md#pages-for-newcomers).
|
||||
|
||||
A platform without a scraper (`scraper: null`, `schedule: null`) keeps its YAML
|
||||
as a hand-maintained file. Every registered platform has a scraper today, so
|
||||
none is edited by hand: RetroPie inherits RetroArch's file set and its scraper
|
||||
|
||||
@@ -4,8 +4,15 @@ level: contribute
|
||||
|
||||
# Adding a scraper
|
||||
|
||||
How to create or modify a scraper for fetching BIOS requirements from upstream
|
||||
platform sources.
|
||||
A scraper reads a platform's own BIOS list and writes it as
|
||||
`platforms/<name>.yml`, the file every pack, check and page of that platform
|
||||
starts from. It copies what the platform declares, as the platform wrote it,
|
||||
and leaves the corrections to the emulator profiles.
|
||||
|
||||
Example: `scripts/scraper/romm_scraper.py` reads RomM's
|
||||
`known_bios_files.json` and writes `platforms/romm.yml`. Adding a scraper means
|
||||
one `*_scraper.py` file with a class that extends `BaseScraper`, the base class
|
||||
every scraper extends.
|
||||
|
||||
## Scraper architecture
|
||||
|
||||
|
||||
@@ -4,7 +4,9 @@ level: reference
|
||||
|
||||
# Build your own packs
|
||||
|
||||
Fine-grained control over pack generation, hardware filtering, truth analysis, and verification.
|
||||
Fine-grained control over pack generation, hardware filtering, truth analysis (the file
|
||||
list a platform would have if it were written from the emulators' code) and
|
||||
verification.
|
||||
|
||||
The [latest release](https://github.com/Abdess/retrobios/releases/latest)
|
||||
carries one pack for each platform, and that pack holds everything the
|
||||
|
||||
+40
-31
@@ -4,37 +4,16 @@ level: reference
|
||||
|
||||
# Architecture
|
||||
|
||||
## Principles
|
||||
How a BIOS list on a platform's site becomes a pack on your drive. Scrapers
|
||||
copy each platform's own list. Emulator profiles record what each emulator's
|
||||
code opens. `database.json` indexes every file the collection holds by its
|
||||
contents. The pack builder joins the three and ships every file a platform's
|
||||
emulators need, and the verifier checks the result the way the platform itself
|
||||
would.
|
||||
|
||||
Every part of the toolchain follows from a few rules.
|
||||
|
||||
- **The emulator's source code is the authority.** A profile records what the
|
||||
code opens, under which names, what it checks and whether it runs without
|
||||
the file. Documentation, `.info` files and platform lists are starting
|
||||
points to verify. When they disagree with the code, the code wins.
|
||||
- **Every statement rests on a fact anyone can check.** A field, a deletion or
|
||||
a wording names what settles it: a `file:line` at a pinned revision, a hash,
|
||||
a command and its output. Where no fact settles a question, the answer is
|
||||
"not verified" until one is found. A sentence on this site once said
|
||||
Batocera matches md5 prefixes. Its script compares the full string
|
||||
(`batocera-systems:1088`).
|
||||
- **The collection serves the user.** A pack carries what the user has to
|
||||
obtain to run their emulators. When something forces the user or a
|
||||
contributor to work around the toolchain, the toolchain is changed rather
|
||||
than the workaround documented.
|
||||
- **Profiles document the emulator, not this repository.** A profile can be
|
||||
taken into another project as is. No field refers to this repository's
|
||||
folders, file names or database, nor to one platform's conventions. The
|
||||
toolchain resolves a profile against the collection.
|
||||
- **Other projects are peers.** A finding about another project says what
|
||||
changes, never who erred, and comes with its evidence. Our data can be
|
||||
wrong too, and an issue that shows it is as welcome as a finding sent
|
||||
upstream.
|
||||
- **An inconsistency found is fixed now.** A fix comes with a test that fails
|
||||
without it, so the same mistake cannot return unnoticed.
|
||||
- **Collect everything a working setup needs.** BIOS, firmware, keys, fonts,
|
||||
boot and DSP ROMs, databases, data files. Age and licence are not criteria.
|
||||
A file the collection lacks is an acquisition target, not an end state.
|
||||
Example: libretro's `System.dat` names 526 RetroArch files. The cores RetroArch
|
||||
runs load 7,650 more, and the RetroArch pack carries both (counts of
|
||||
[What the packs do not hold](../gaps.md) on 2026-10-22).
|
||||
|
||||
## Directory structure
|
||||
|
||||
@@ -130,6 +109,36 @@ for the full pipeline reference.
|
||||
|
||||
<!-- image: pipeline -->
|
||||
|
||||
## Principles
|
||||
|
||||
Every part of the toolchain follows from a few rules.
|
||||
|
||||
- **The emulator's source code is the authority.** A profile records what the
|
||||
code opens, under which names, what it checks and whether it runs without
|
||||
the file. Documentation, `.info` files and platform lists are starting
|
||||
points to verify. When they disagree with the code, the code wins.
|
||||
- **Every statement rests on a fact anyone can check.** A field, a deletion or
|
||||
a wording names what settles it: a `file:line` at a pinned revision, a hash,
|
||||
a command and its output. Where no fact settles a question, the answer is
|
||||
"not verified" until one is found.
|
||||
- **The collection serves the user.** A pack carries what the user has to
|
||||
obtain to run their emulators. When something forces the user or a
|
||||
contributor to work around the toolchain, the toolchain is changed rather
|
||||
than the workaround documented.
|
||||
- **Profiles document the emulator, not this repository.** A profile can be
|
||||
taken into another project as is. No field refers to this repository's
|
||||
folders, file names or database, nor to one platform's conventions. The
|
||||
toolchain resolves a profile against the collection.
|
||||
- **Other projects are peers.** A finding about another project says what
|
||||
changes, never who erred, and comes with its evidence. Our data can be
|
||||
wrong too, and an issue that shows it is as welcome as a finding sent
|
||||
upstream.
|
||||
- **An inconsistency found is fixed now.** A fix comes with a test that fails
|
||||
without it, so the same mistake cannot return unnoticed.
|
||||
- **Collect everything a working setup needs.** BIOS, firmware, keys, fonts,
|
||||
boot and DSP ROMs, databases, data files. Age and licence are not criteria.
|
||||
A file the collection lacks is an acquisition target, not an end state.
|
||||
|
||||
## Three layers of data
|
||||
|
||||
| Layer | Source | Role |
|
||||
@@ -168,7 +177,7 @@ Some entries in a platform YAML are not the platform's own: files a
|
||||
to a twin system (`mirror_of`) and additions the libretro scraper makes
|
||||
(`curated`). `native_layer()` removes them wherever the question is what the
|
||||
platform itself declares: the export, the truth diff and the site's
|
||||
comparison tables. Counted as the platform's, they were written into
|
||||
comparison tables. Counted as the platform's, they would be written into
|
||||
System.dat as if libretro had declared them.
|
||||
|
||||
<!-- image: data-layers -->
|
||||
|
||||
+52
-156
@@ -4,209 +4,105 @@ level: start
|
||||
|
||||
# FAQ
|
||||
|
||||
The questions people ask before installing anything. Questions about how files
|
||||
are identified and checked are in the
|
||||
Reference: [technical questions](technical-faq.md).
|
||||
|
||||
## Do I need BIOS files?
|
||||
|
||||
For many consoles, yes: PlayStation, PlayStation 2, Saturn, Mega-CD, Neo Geo,
|
||||
Dreamcast and many home computers. For cartridge consoles such as the NES or
|
||||
the Super Nintendo, usually not. [What BIOS files are](what-are-bios-files.md)
|
||||
explains why, console by console.
|
||||
For many consoles, yes: PlayStation 1 and 2, Saturn, Dreamcast, Neo Geo and
|
||||
many home computers. For NES or Super Nintendo cartridges, usually not.
|
||||
[What is a BIOS?](what-are-bios-files.md)
|
||||
|
||||
## How do I know which BIOS I need?
|
||||
|
||||
Two approaches:
|
||||
Run the installer with `--dry-run`. It lists what it would install and changes
|
||||
nothing.
|
||||
|
||||
1. **Ask the installer.** `--dry-run` lists what it would install for your platform and writes nothing, `--list-systems` gives the file count per system, and `--emulator` narrows to what one core reads:
|
||||
```sh
|
||||
curl -fsSL https://raw.githubusercontent.com/Abdess/retrobios/main/install.sh | sh -s -- --dry-run
|
||||
```
|
||||
|
||||
```bash
|
||||
curl -fsSL https://raw.githubusercontent.com/Abdess/retrobios/main/install.sh | sh -s -- --emulator beetle_psx --dry-run
|
||||
```
|
||||
Your setup's page also lists every file, console by console.
|
||||
|
||||
2. **Check the project site.** Each platform page lists all required and optional BIOS files per system, and each emulator page the files that core loads, with the source references and expected values.
|
||||
## Is the command safe? { #is-piping-the-installer-into-a-shell-safe }
|
||||
|
||||
## Is piping the installer into a shell safe?
|
||||
- It checks the installer's fingerprint before running it. If the download
|
||||
does not match its expected fingerprint, it stops.
|
||||
- It checks every file before saving it.
|
||||
- It writes only in your BIOS folder.
|
||||
|
||||
The one-liner runs a small bootstrap, not the installer. That bootstrap fetches
|
||||
`install.py` over HTTPS only, refuses anything over 2 MB, and requires its
|
||||
SHA-256 to equal the value written inside the bootstrap itself. A substituted
|
||||
installer aborts with "the downloaded installer does not match its expected
|
||||
fingerprint" before a single line of it runs.
|
||||
To read the script before you run it:
|
||||
|
||||
The installer then verifies every file it downloads against the size, SHA-256
|
||||
and SHA-1 the manifest declares, and moves it into place only once those match.
|
||||
The manifest is treated as untrusted: a destination cannot be absolute, carry a
|
||||
drive letter or climb out of the BIOS directory.
|
||||
|
||||
Reading the bootstrap before running it is two lines:
|
||||
|
||||
```bash
|
||||
```sh
|
||||
curl -fsSL https://raw.githubusercontent.com/Abdess/retrobios/main/install.sh -o install.sh
|
||||
less install.sh && sh install.sh
|
||||
```
|
||||
|
||||
Details: [All installer options](installer.md), with the full behaviour.
|
||||
Details: [How the installer checks itself](installer.md#what-the-bootstrap-does).
|
||||
|
||||
## Will the installer change my other files?
|
||||
## Will it change my other files?
|
||||
|
||||
No. It writes only inside the BIOS folder and `retrobios-backup` beside it, and games and saves are never
|
||||
touched. Inside that folder, a BIOS file whose contents differ from the
|
||||
expected one is replaced with a checked copy, and your old file is moved to a
|
||||
`retrobios-backup` folder beside the BIOS folder. Files the installer does not
|
||||
know are never read, moved or deleted. Copies into the folders of standalone
|
||||
emulators happen only when you ask for them with `--standalone-copies`.
|
||||
No. It never touches games or saves, or a file it does not know. It replaces a
|
||||
BIOS file with the wrong contents, and keeps yours.
|
||||
|
||||
## What if Windows or an antivirus blocks the command?
|
||||
## Windows or my antivirus blocks the command
|
||||
|
||||
The PowerShell execution policy governs script files, and the PowerShell line
|
||||
writes none, so the policy does not block it. Where a security tool still
|
||||
blocks it, download the pack of your setup from
|
||||
[Get your files](../which-pack.md) and extract it into the BIOS folder: it holds
|
||||
the same files.
|
||||
Download the ZIP of your setup instead, from [Get your files](../which-pack.md).
|
||||
It holds the same files.
|
||||
|
||||
## Can I run the installer again?
|
||||
## Can I run it again?
|
||||
|
||||
Yes, and re-running is the normal way to update. A file already present with
|
||||
the expected hash is left untouched, one whose contents do not match is
|
||||
replaced by the verified copy (the old one is kept), and files the manifest does not name are never
|
||||
read, moved or deleted. `--check` does the same inspection and exits without
|
||||
writing.
|
||||
Yes. That is how you update. It downloads only what is missing or wrong.
|
||||
|
||||
## Can I undo it?
|
||||
|
||||
Yes. A file you had that the installer replaced is kept in a dated folder
|
||||
inside `retrobios-backup`, beside the BIOS folder. The end of the run prints
|
||||
that folder and the command that puts the files back, the same command with
|
||||
`--restore` and the folder. Copying the contents of the dated folder into the folder that holds
|
||||
`retrobios-backup` does the same. Files that were not there before can be
|
||||
deleted from the BIOS folder. The installer changed nothing outside it, apart
|
||||
from the backup folder.
|
||||
Details: [kept files](installer.md#files-you-already-had).
|
||||
Yes. It keeps every file it replaces in a `retrobios-backup` folder, beside
|
||||
your BIOS folder. The end of the run prints the line that puts them back: the
|
||||
same command with `--restore` and that folder.
|
||||
|
||||
## Can I install onto an SD card or another machine's drive?
|
||||
Details: [Files you already had](installer.md#files-you-already-had).
|
||||
|
||||
Yes, `--dest` takes any path and the one-liner forwards arguments:
|
||||
## Fill an SD card from a computer?
|
||||
|
||||
```bash
|
||||
Yes. Name your setup and the BIOS folder on the card:
|
||||
|
||||
```sh
|
||||
curl -fsSL https://raw.githubusercontent.com/Abdess/retrobios/main/install.sh \
|
||||
| sh -s -- --platform retroarch --dest /path/to/sdcard/retroarch/cores/system
|
||||
```
|
||||
|
||||
`--dest` is the BIOS folder itself: on a card, `retroarch/cores/system` for
|
||||
RetroArch on Switch, `RetroArch/system` on Android.
|
||||
On Windows the line is different. Details: [Passing options](installer.md#passing-options).
|
||||
|
||||
On Windows the arguments need a script block, since `iex` would read them as
|
||||
its own. Details: [the Windows form](installer.md#passing-options).
|
||||
## Does a BIOS work on every setup?
|
||||
|
||||
## Can I use BIOS from one platform on another?
|
||||
Yes. Only the folder changes, and sometimes the name.
|
||||
|
||||
Yes. BIOS files are console-specific, not platform-specific. A PlayStation BIOS works in RetroArch, Batocera, Recalbox, and any other platform that emulates PlayStation. The only differences between platforms are:
|
||||
## Why is a file missing from the ZIP?
|
||||
|
||||
- **Where the file goes** (each platform has its own BIOS directory)
|
||||
- **What filename is expected** (usually the same, occasionally different)
|
||||
- **How verification works** (MD5 check vs. existence check)
|
||||
Some files come with the emulator when you install it. The ZIP leaves those
|
||||
out.
|
||||
|
||||
The packs differ per platform because each platform declares its own set of supported systems and expected files.
|
||||
## Required or optional?
|
||||
|
||||
## Why is a file the emulator reads not in the pack?
|
||||
|
||||
A pack brings what the user has to obtain. A file the emulator installs itself, a
|
||||
font, a shader, a game database, a free replacement BIOS, is already on the
|
||||
machine once the emulator is installed, so the pack leaves it out. This is decided
|
||||
per build and per platform: the PPSSPP standalone release ships its `assets/`
|
||||
folder, the PPSSPP libretro core does not, so RetroArch packs carry those files and
|
||||
a standalone PPSSPP pack does not. When a platform's own package installs data
|
||||
beside a core (Batocera with blueMSX), that platform's pack leaves it out too. The
|
||||
emulator's page on the site marks these files as installed with the emulator.
|
||||
|
||||
## How often are packs updated?
|
||||
|
||||
Upstream sources (libretro System.dat, batocera-systems, etc.) are re-scraped by hand and the diff is reviewed before it lands. Releases happen as needed when new BIOS files are added or profiles are updated.
|
||||
|
||||
## What's the difference between required and optional?
|
||||
|
||||
**Required** means the emulator will not start games for that system without
|
||||
the file. **Optional** means the emulator works without it, but with reduced
|
||||
accuracy or missing features (e.g., boot screen animation, wrong font
|
||||
rendering, or degraded audio).
|
||||
|
||||
## What's HLE?
|
||||
|
||||
HLE (High-Level Emulation) is a software reimplementation of what the original
|
||||
BIOS does. Some cores can boot games without a real BIOS file by using their
|
||||
built-in HLE fallback. The trade-off is lower accuracy: some games may have
|
||||
glitches or fail to boot entirely. The file is still included in packs because
|
||||
the real BIOS gives better results.
|
||||
|
||||
## What's a hash?
|
||||
|
||||
A hash is a fingerprint computed from a file's contents. If even one byte
|
||||
differs, the hash changes completely. Batocera, Recalbox, EmuDeck and several
|
||||
other setups compare the MD5 hash of each BIOS file with their list and refuse
|
||||
a file that does not match. RetroArch only checks that the file is there. The
|
||||
kinds of hash and where each is used are in the
|
||||
Reference: [technical questions](technical-faq.md#whats-a-hashchecksum).
|
||||
|
||||
## Are these files verified against original hardware dumps?
|
||||
|
||||
The hashes here come from what emulator code loads and accepts. Whether a file
|
||||
matches a catalogued dump of the original chip is a separate question, and the
|
||||
system pages mark the files that do. The full answer is in the
|
||||
Reference: [technical questions](technical-faq.md#are-these-files-verified-against-original-hardware-dumps).
|
||||
- **Required:** the emulator does not start games without it.
|
||||
- **Optional:** games start, with small differences, like no start-up screen.
|
||||
|
||||
## My game shows a black screen
|
||||
|
||||
Most often a BIOS file is missing, or is not the version the emulator expects.
|
||||
[When a game does not start](troubleshooting.md) goes through it step by step,
|
||||
starting with a check of what is in your BIOS folder.
|
||||
Most of the time, a BIOS file is missing or is the wrong version.
|
||||
[When a game does not start](troubleshooting.md) shows how to check.
|
||||
|
||||
## Is this legal?
|
||||
|
||||
Redistributing firmware is not settled law, and this page does not pretend otherwise. What follows is the reasoning the project acts on, with the strength of each argument stated plainly so anyone can weigh it. None of it is legal advice, and none of it has been tested in court.
|
||||
Laws on copying console firmware differ by country. The question is not
|
||||
settled, and nothing here is legal advice. Details: [The project's legal position](legal.md).
|
||||
|
||||
### Emulation and BIOS redistribution
|
||||
To ask for a file to be removed, [open an issue](https://github.com/Abdess/retrobios/issues)
|
||||
and name the file. A file is removed when the owner of its rights asks.
|
||||
|
||||
- **Writing an emulator is lawful.** *Sony v. Connectix* (2000) and *Sega v. Accolade* (1992) held that copying a work during reverse engineering, to reach the functional elements needed for interoperability, is fair use. Both concern the act of copying while developing, and *Connectix* specifically involved copying Sony's BIOS in the course of that work. Neither decision addresses distributing firmware to third parties, so they support the legality of emulation itself rather than of this collection.
|
||||
- **Fair use (US, 17 USC 107) is a defence, argued case by case.** The project's position is that non-commercial redistribution for personal backup and archival weighs favourably on purpose and on market effect, since these files are not sold separately. It weighs poorly on the amount used: each file is copied whole. Manufacturers do still monetise some of this firmware indirectly, through re-releases, subscription services and mini consoles, so the market factor is contestable rather than clear.
|
||||
- **Interoperability in the EU.** The Software Directive (2009/24/EC, Art. 5-6) permits decompilation and use to achieve interoperability, subject to conditions, and Art. 6 restricts passing the resulting information to others. It supports the emulation use case, but it is not a general redistribution permission.
|
||||
- **Discontinued hardware.** Most firmware here is for hardware no longer sold or supported. This bears on the fair-use market factor and on the practical likelihood of complaint. "Abandonware" is not a legal doctrine in any jurisdiction, and nothing here rests on it.
|
||||
## Why keep recent consoles too?
|
||||
|
||||
### Encryption keys (Switch prod.keys, 3DS AES keys, Wii U keys)
|
||||
|
||||
This is the most contested area, and the weakest part of the project's position.
|
||||
|
||||
- **Keys are unlikely to be copyrightable.** A bare numeric value has no author's creative expression, so copyright is a poor fit. This says nothing about the DMCA, which is the provision that actually applies.
|
||||
- **DMCA 1201(f) is narrow.** Section 1201(f) allows a person who has lawfully obtained the right to use a copy to circumvent for the sole purpose of achieving interoperability with an independently created program, and 1201(f)(3) allows the means to be made available to others only for that same purpose. Publishing keys openly is not obviously within that allowance, and the trafficking prohibitions in 1201(a)(2) and 1201(b) remain in play. This is the clearest legal risk the project carries.
|
||||
- **Library of Congress exemptions do not cover this repository.** The triennial exemptions at 37 CFR 201.40 let an eligible library, archive or museum circumvent access controls to preserve a lawfully acquired video game whose server support has ended, with access limited to the institution's premises. The Ninth Triennial Proceeding (2024 cycle) renewed them and declined to extend them to off-premises remote access. A public repository is neither an eligible institution nor an on-premises reading room, so these exemptions show which way preservation policy is moving without authorising what is done here.
|
||||
- **Keys come from consumer hardware.** They are extracted from retail devices their owners bought. *Chamberlain v. Skylink* (2004) held that a 1201 claim requires some nexus to copyright infringement, in a dispute over a garage-door opener. Later cases have narrowed its reach, and it is a weak foundation for a general post-sale right.
|
||||
- **Trade secret is not a live issue.** Keys embedded in millions of shipped devices and widely republished are not kept secret by reasonable measures.
|
||||
|
||||
### Recent firmware (Switch 19.0.0, PS3UPDAT, PSVUPDAT)
|
||||
|
||||
- **Free download is not a licence.** Manufacturers publish these updates on open CDNs without authentication, which makes them easy to obtain but does not grant a right to redistribute them, and PlayStation firmware ships under an end-user licence agreement. The practical argument is that mirroring a file the manufacturer already gives away for free causes no identifiable loss, not that doing so is expressly permitted.
|
||||
- **Functional necessity.** Emulators cannot run the software these systems were built for without this firmware. That is why the files are collected. It is a statement of purpose, not a legal defence in itself.
|
||||
- **Yuzu context.** The Yuzu settlement (2024) concerned the emulator and its alleged facilitation of piracy. Yuzu settled without admitting liability, so it set no precedent either way on firmware or key redistribution. It does show that rights holders in this space litigate.
|
||||
|
||||
### Summary
|
||||
|
||||
This project preserves BIOS files, firmware and keys for personal use, archival and interoperability. The strongest ground is the older, discontinued firmware, where fair use and the absence of a market both point the same way. The weakest is the encryption keys, where DMCA 1201 applies and the interoperability exemption is narrower than the use made of it here. The project accepts that risk deliberately, in the belief that these files are worth preserving while they can still be obtained.
|
||||
|
||||
This reflects the project's good-faith understanding, not legal advice.
|
||||
|
||||
### Asking for a file to be removed
|
||||
|
||||
A rights holder, or anyone acting for one, can [open an issue](https://github.com/Abdess/retrobios/issues) identifying the file by path or hash. A file whose removal is requested by its rights holder is removed from the repository and from the next release. No formal notice is required and none will be demanded. State the file and the basis of the claim. The same channel is open to anyone else with a concern about a specific file.
|
||||
|
||||
## Isn't the Switch or PS3 too recent for a retro project?
|
||||
|
||||
Age is not what decides inclusion here: availability is. Firmware distribution depends on manufacturer servers, and those disappear: Nintendo closed the 3DS and Wii U eShops in March 2023, Sony shut the PSP store in 2021. Once a CDN goes offline, the files only survive where someone archived them.
|
||||
|
||||
The project tries to archive files while they are still available rather than after they have become rare. "Retro" is a moving window: the PlayStation 2 was current hardware when its BIOS was first preserved, and today's consoles will be tomorrow's retro systems. A file is included for the same reason at any age: an emulator needs it, and nothing guarantees it stays available.
|
||||
Files disappear when stores close, like the 3DS and Wii U shops in 2023. We keep
|
||||
them while they can still be found.
|
||||
|
||||
!!! tip "Next"
|
||||
|
||||
- [Get your files](../which-pack.md)
|
||||
- [When a game does not start](troubleshooting.md)
|
||||
- [Glossary](glossary.md)
|
||||
- [Words used on this site](glossary.md)
|
||||
+86
-200
@@ -4,89 +4,66 @@ level: start
|
||||
|
||||
# First install
|
||||
|
||||
One path, from an empty BIOS folder to files the emulator can read. Every step
|
||||
shows what the screen looks like when it worked.
|
||||
From an empty BIOS folder to games that start.
|
||||
|
||||
If something on this page does not match what happens, the last section covers
|
||||
the cases that come up.
|
||||
**You need:** internet and some free space. The installer says how much.
|
||||
|
||||
## 1. Open a terminal and paste
|
||||
|
||||
A **terminal** is a window where you type commands. Paste the line for your
|
||||
system, then press Enter.
|
||||
|
||||
=== "Windows"
|
||||
|
||||
Open the Start menu. Type **PowerShell** and open it.
|
||||
|
||||
```powershell
|
||||
irm https://raw.githubusercontent.com/Abdess/retrobios/main/install.ps1 | iex
|
||||
```
|
||||
|
||||
=== "Mac"
|
||||
|
||||
Open **Terminal**. It is in Applications, then Utilities.
|
||||
|
||||
```sh
|
||||
curl -fsSL https://raw.githubusercontent.com/Abdess/retrobios/main/install.sh | sh
|
||||
```
|
||||
|
||||
=== "Linux and Steam Deck"
|
||||
|
||||
On a Steam Deck, switch to Desktop Mode and open **Konsole**.
|
||||
|
||||
```sh
|
||||
curl -fsSL https://raw.githubusercontent.com/Abdess/retrobios/main/install.sh | sh
|
||||
```
|
||||
|
||||
=== "Android"
|
||||
|
||||
Install **Termux**, a terminal app. Run these three lines in it.
|
||||
|
||||
```sh
|
||||
pkg install python
|
||||
termux-setup-storage
|
||||
curl -fsSL https://raw.githubusercontent.com/Abdess/retrobios/main/install.sh | sh
|
||||
```
|
||||
|
||||
On Batocera, Recalbox and other game systems, follow
|
||||
[your setup's page](../which-pack.md).
|
||||
|
||||
<!-- image: install-flow -->
|
||||
|
||||
## Before starting
|
||||
## 2. Check the folder it found
|
||||
|
||||
Three things, and a few minutes:
|
||||
|
||||
- The BIOS folder the emulator reads. The installer finds it by itself on most
|
||||
systems. On a handheld, that usually means plugging the SD card into a
|
||||
computer.
|
||||
- `curl` or `wget`, and Python 3.8 or newer. The command below checks for both
|
||||
and stops with a message if either is absent.
|
||||
- Room on the drive. The size depends on the platform and changes with each
|
||||
release: the run prints it before downloading (Step 3), and asks first when it
|
||||
reaches 1 GB. The installer also measures the free space and refuses before
|
||||
writing anything if there is not enough.
|
||||
|
||||
Nothing is written outside the BIOS folder, and games and saves are never
|
||||
touched.
|
||||
|
||||
## Step 1. Run the command
|
||||
|
||||
The command runs in a terminal. On Windows, open the Start menu, type
|
||||
PowerShell and open it. On a Mac, open Terminal from Applications, then
|
||||
Utilities. On a Steam Deck, switch to Desktop Mode and open Konsole. Paste the
|
||||
line and press Enter.
|
||||
|
||||
On Linux, macOS, a Steam Deck, or a handheld running Batocera, Recalbox,
|
||||
KNULLI, ROCKNIX, AmberELEC, EmuELEC or Lakka:
|
||||
|
||||
```bash
|
||||
curl -fsSL https://raw.githubusercontent.com/Abdess/retrobios/main/install.sh | sh
|
||||
```
|
||||
|
||||
On Windows, in PowerShell:
|
||||
|
||||
```powershell
|
||||
irm https://raw.githubusercontent.com/Abdess/retrobios/main/install.ps1 | iex
|
||||
```
|
||||
|
||||
PowerShell's execution policy does not block that line. The policy governs
|
||||
script files, and this command never writes one. Changing the policy is not
|
||||
part of installing anything here.
|
||||
|
||||
On Android, from Termux, three commands instead of one:
|
||||
|
||||
```bash
|
||||
pkg install python
|
||||
termux-setup-storage
|
||||
curl -fsSL https://raw.githubusercontent.com/Abdess/retrobios/main/install.sh | sh
|
||||
```
|
||||
|
||||
Before running anything, that first line downloads the installer, compares it
|
||||
against the SHA-256 written inside the command's own script, and refuses to
|
||||
continue if the two differ. To read the script first:
|
||||
|
||||
```bash
|
||||
curl -fsSL https://raw.githubusercontent.com/Abdess/retrobios/main/install.sh | less
|
||||
```
|
||||
|
||||
## Step 2. Watch it find the platform
|
||||
|
||||
The first lines name what it found and where it will write:
|
||||
It shows your setup and its BIOS folder:
|
||||
|
||||
```
|
||||
RetroBIOS 8c0e9c762d2f
|
||||
|
||||
Detecting platform...
|
||||
Found Batocera at /userdata/bios
|
||||
```
|
||||
|
||||
The code after RetroBIOS identifies the installer: it is the start of the
|
||||
SHA-256 the command checked before running it.
|
||||
- **Right folder?** Go on.
|
||||
- **Wrong folder?** Press Ctrl+C to stop. Then see [If it stops](#if-it-stops).
|
||||
|
||||
That path is the one thing worth reading twice. If it is not where the emulator
|
||||
keeps its BIOS files, stop with Ctrl+C and see the last section.
|
||||
|
||||
At a terminal, the installer then asks what to install:
|
||||
## 3. Choose what to install
|
||||
|
||||
```
|
||||
Enter) install everything
|
||||
@@ -95,170 +72,79 @@ At a terminal, the installer then asks what to install:
|
||||
q) quit
|
||||
```
|
||||
|
||||
Enter installs everything, which is what the rest of this page shows. **c**
|
||||
lets you pick consoles, emulator cores and regions. The **i** line appears
|
||||
only when the installer finds emulator cores installed.
|
||||
**Enter** installs everything. **c** lets you pick consoles.
|
||||
|
||||
## Step 3. Let it work
|
||||
## 4. Wait
|
||||
|
||||
The examples on this page follow the Batocera list as published on 2026-10-21.
|
||||
The figures change with each release.
|
||||
It shows one line per file. You can stop with Ctrl+C at any time. Run the
|
||||
command again to carry on.
|
||||
|
||||
Two phases follow. The first reads what is already in the folder, which takes a
|
||||
few minutes on a memory card because every file is hashed:
|
||||
|
||||
```
|
||||
Fetching file index for batocera...
|
||||
14481 files (9.1 GB)
|
||||
Not installable: 399 files (79 required, not found: 399).
|
||||
|
||||
Checking existing files...
|
||||
0/14481 present (0 verified, 0 wrong hash)
|
||||
```
|
||||
|
||||
`Not installable` counts the files of the list that the collection does not
|
||||
hold. They are named at the end of the run (Step 4).
|
||||
|
||||
On a first install the present count is zero, which is expected, not a fault.
|
||||
On a later run it counts what is already there, and only the rest is
|
||||
downloaded. A download of 1 GB or more is confirmed first
|
||||
(`Download 9.1 GB to /userdata/bios? [Y/n]`).
|
||||
|
||||
The second phase downloads what is missing, one line per file:
|
||||
|
||||
```
|
||||
Downloading 14481 files (9.1 GB)...
|
||||
Press Ctrl+C to stop. Running the same command again carries on from here.
|
||||
[1/14481] 3do_arcade_saot.bin ok
|
||||
[2/14481] 3dobios.zip ok
|
||||
```
|
||||
|
||||
Ctrl+C is safe at any point. Files already installed stay, and running the
|
||||
command again picks up where it stopped.
|
||||
|
||||
## Step 4. Read the end of the run
|
||||
|
||||
This is what a finished run looks like:
|
||||
## 5. Look for "Done."
|
||||
|
||||
```
|
||||
Done. 14481 files installed, 0 files already up to date.
|
||||
Location: /userdata/bios
|
||||
399 files were not installed: the collection does not hold them, or its copy fails their check.
|
||||
Needed to start an emulator (79 files):
|
||||
dark-forces (theforceengine): DARK.GOB, SOUNDS.GOB, SPRITES.GOB, TEXTURES.GOB
|
||||
dark-forces-ii (openjkdf2): openjkdf2/episode/JK1.gob, openjkdf2/episode/JK1CTF.gob, openjkdf2/episode/JK1MP.gob, openjkdf2/resource/Res1hi.gob, openjkdf2/resource/Res2.gob
|
||||
diablo (devilutionx): devilutionx/diabdat.mpq
|
||||
doom3 (dhewm3): base/pak000.pk4, base/pak002.pk4, base/pak003.pk4, base/pak004.pk4
|
||||
droidworks (openjkdf2): dwCD.GOB, dwHD.GOB, dwMin.GOB, dwStream.GOB
|
||||
fallout (fallout1-ce): fallout1-ce/critter.dat, fallout1-ce/master.dat
|
||||
fallout2 (fallout2-ce): fallout2-ce/critter.dat, fallout2-ce/master.dat
|
||||
fury (fury): fury.grp
|
||||
... and 9 more systems (--check --verbose lists them all)
|
||||
Each emulator's page says what these files are: https://abdess.github.io/retrobios/emulators/
|
||||
To check this later, run the same command with --check.
|
||||
```
|
||||
|
||||
The word `Done` and a location are the confirmation. Any other ending (`Stopped`,
|
||||
`Finished with errors`, `Nothing was installed`) means something was left undone,
|
||||
and the run says which case it was.
|
||||
`Done.` means it worked. It may list files it could not install.
|
||||
|
||||
The lines between `Location:` and the `--check` hint name the files of the list
|
||||
that the collection does not hold. `Needed to start an emulator` gives, for each
|
||||
system, the emulators that read it and the files they cannot start without. On
|
||||
the run above, all 79 belong to games (Dark Forces, Diablo, Doom 3, Tomb Raider
|
||||
and the others): the engine reads them from a copy of the game itself. The
|
||||
other 320 are optional, and the emulators reading them start without them.
|
||||
## Check it later
|
||||
|
||||
## Step 5. Confirm it later
|
||||
Add `--check` to the same command. It changes nothing.
|
||||
|
||||
The same command with `--check` reads the folder and writes nothing:
|
||||
|
||||
```bash
|
||||
```sh
|
||||
curl -fsSL https://raw.githubusercontent.com/Abdess/retrobios/main/install.sh | sh -s -- --check
|
||||
```
|
||||
|
||||
```
|
||||
Checking existing files...
|
||||
14481/14481 present (14481 verified, 0 wrong hash)
|
||||
All good when you see `0 wrong hash`.
|
||||
|
||||
All files up to date.
|
||||
```
|
||||
## Undo
|
||||
|
||||
The files the collection does not hold are listed after it again, as long as
|
||||
they are absent from the folder. `0 wrong hash` is the line that matters. A number there means a file is present
|
||||
whose contents the platform will reject, and running the install again replaces
|
||||
it. Your old file is kept in `retrobios-backup`, beside the BIOS folder.
|
||||
It keeps every file it replaces in a `retrobios-backup` folder, beside your
|
||||
BIOS folder. Nothing is deleted.
|
||||
|
||||
## When the screen says something else
|
||||
To put your files back, run the command with `--restore` and that folder. The
|
||||
end of the run prints the exact line.
|
||||
|
||||
## If it stops
|
||||
|
||||
### No supported platform detected.
|
||||
|
||||
At a terminal, a menu follows that line. The platform is picked by its number,
|
||||
then the run asks for the BIOS folder, offering the platform's usual folder on
|
||||
this system as the default when it has one.
|
||||
At a terminal, a menu follows. Pick your setup by its number, then type its
|
||||
BIOS folder.
|
||||
|
||||
Without a terminal, or with `--no-input`, the run stops there and prints the
|
||||
command to use instead, with the platform and the folder named:
|
||||
|
||||
```bash
|
||||
curl -fsSL https://raw.githubusercontent.com/Abdess/retrobios/main/install.sh \
|
||||
| sh -s -- --platform retroarch --dest /path/to/system
|
||||
```
|
||||
|
||||
The accepted names come from `--list-platforms`. The page of each setup,
|
||||
listed on [Get your files](../which-pack.md), gives its BIOS folder.
|
||||
With `--no-input`, or without a terminal, it stops and prints the command to
|
||||
use.
|
||||
|
||||
### Error: Python 3.8 or newer is required.
|
||||
|
||||
No Python 3.8 or newer was found: Python is missing, or older. The message
|
||||
names the command that installs it on the system it runs on: `sudo apt install
|
||||
python3` on Debian and Ubuntu, `sudo dnf install python3` on Fedora, `sudo
|
||||
pacman -S python` on Arch, `xcode-select --install` on macOS and `pkg install
|
||||
python` in Termux, where it offers to run that command itself (Termux installs
|
||||
without root). On Windows, `install.ps1` offers to run `winget install
|
||||
Python.Python.3.12`. On a handheld running Batocera or Recalbox it is already there, so
|
||||
this message usually means the command ran on the computer rather than on the
|
||||
console.
|
||||
The message shows the command that installs Python. Run it, then run the
|
||||
installer again.
|
||||
|
||||
A stock RetroPie 4.8 image is Debian Buster, where `python3` is 3.7.3 and apt
|
||||
has nothing newer, so the same command changes nothing. The RetroPie pack from
|
||||
the [releases page](https://github.com/Abdess/retrobios/releases/latest),
|
||||
extracted into `~/RetroPie/BIOS/`, installs the same files.
|
||||
A RetroPie 4.8 image has Python 3.7.3, and its update command finds nothing
|
||||
newer. Use the [RetroPie ZIP](../platforms/retropie.md#download) there,
|
||||
unzipped into `~/RetroPie/BIOS/`.
|
||||
|
||||
### Error: the downloaded installer does not match its expected fingerprint.
|
||||
|
||||
Nothing was run and nothing was written. The download did not match the
|
||||
fingerprint the script carries, which is almost always a transfer cut short.
|
||||
Running the command again, on another network if possible, is the answer.
|
||||
The download was cut short. Nothing was changed. Run the command again.
|
||||
|
||||
### Cannot create ...
|
||||
|
||||
The user running the command cannot write there. On Batocera, Recalbox and
|
||||
ROCKNIX the BIOS folder belongs to root, so the same command with `sudo` in
|
||||
front of it succeeds.
|
||||
You do not have the right to write there. On Batocera, Recalbox and ROCKNIX,
|
||||
put `sudo` and a space before the command. It then runs as the administrator.
|
||||
|
||||
### Not enough space on the drive holding ...
|
||||
|
||||
The run stopped before writing. The message names how much is needed and how
|
||||
much is free. `--dest` installs to another drive.
|
||||
It stopped before writing. Free some space, or use `--dest` to pick another
|
||||
drive.
|
||||
|
||||
### The game still shows a black screen
|
||||
### The game still does not start
|
||||
|
||||
A file can be in place and still be the wrong one for that game, or the console
|
||||
may need a file that nobody has dumped yet.
|
||||
[When a game does not start](troubleshooting.md) goes through that case.
|
||||
See [When a game does not start](troubleshooting.md).
|
||||
|
||||
## What comes next
|
||||
!!! tip "Next"
|
||||
|
||||
- The page of your setup, from [Get your files](../which-pack.md): where its
|
||||
folder is and how the setup itself checks the files
|
||||
- [When a game does not start](troubleshooting.md)
|
||||
- [FAQ](faq.md), for what the words mean and why a pack is this large
|
||||
- Details: [All installer options](installer.md), for every option, what it
|
||||
detects and what it is allowed to write
|
||||
|
||||
To remove what the installer wrote, delete the files from the BIOS folder.
|
||||
A file you had that it replaced is in `retrobios-backup`, beside that folder:
|
||||
the end of the run printed the `--restore` command that puts it back
|
||||
(Details: [kept files](installer.md#files-you-already-had)). Nothing else outside the
|
||||
BIOS folder was changed.
|
||||
- [Your setup's page](../which-pack.md): its folder and how it checks files
|
||||
- [When a game does not start](troubleshooting.md)
|
||||
- Details: [Reading the installer's output, line by line](installer.md#reading-a-run)
|
||||
+9
-14
@@ -4,25 +4,20 @@ level: start
|
||||
|
||||
# Getting started
|
||||
|
||||
What this page held now lives on the pages written for each step.
|
||||
Three pages take you from nothing to games that start.
|
||||
|
||||
## What are BIOS files?
|
||||
[Get your files](../which-pack.md){ .md-button .md-button--primary }
|
||||
|
||||
[What BIOS files are](what-are-bios-files.md) explains what they do, and which
|
||||
consoles need them.
|
||||
## What is a BIOS?
|
||||
|
||||
## Installation
|
||||
[What is a BIOS?](what-are-bios-files.md) tells you which consoles need one.
|
||||
|
||||
[Get your files](../which-pack.md) gives the command and the packs for every
|
||||
setup. [First install, step by step](first-install.md) shows what each step of
|
||||
the command prints.
|
||||
## Install
|
||||
|
||||
## BIOS directory by platform
|
||||
[Get your files](../which-pack.md) gives the command and the ZIP for your
|
||||
setup. [First install, step by step](first-install.md) shows each step.
|
||||
|
||||
The page of each setup opens on where its files go. All setups are on
|
||||
[Get your files](../which-pack.md), grouped by the device they run on.
|
||||
|
||||
## Checking what you installed
|
||||
## Check your folder
|
||||
|
||||
[When a game does not start](troubleshooting.md#checking-what-you-installed)
|
||||
shows how to check the files in your BIOS folder.
|
||||
shows how to check your BIOS folder.
|
||||
+22
-127
@@ -2,152 +2,47 @@
|
||||
level: start
|
||||
---
|
||||
|
||||
# Glossary
|
||||
# Words used on this site
|
||||
|
||||
The first part holds the words anyone meets when setting up BIOS files. The
|
||||
second part holds the words this project uses in its reference pages.
|
||||
|
||||
## Words you will meet
|
||||
|
||||
**BIOS, or firmware**
|
||||
: A small program built into a console. Many emulators need a copy of it to
|
||||
start games. [What BIOS files are](what-are-bios-files.md) says more.
|
||||
**BIOS**, or **firmware**
|
||||
: A small program inside a console. It starts the games.
|
||||
|
||||
**Emulator**
|
||||
: A program that lets a computer, a phone or a handheld act like an older
|
||||
console.
|
||||
: An app that acts like a console.
|
||||
|
||||
**Core**
|
||||
: One emulator inside RetroArch. RetroArch loads a different core for each
|
||||
: One emulator inside RetroArch. RetroArch uses a different core for each
|
||||
console.
|
||||
|
||||
**Frontend**
|
||||
: The menu you pick and start games from, such as EmulationStation, MinUI or
|
||||
the RetroArch menu. It starts the emulator for you.
|
||||
|
||||
**Setup, or platform**
|
||||
: The software you play with: RetroArch, Batocera, EmuDeck, KNULLI and the
|
||||
others. Each one keeps its BIOS files in a folder of its own.
|
||||
**Setup**
|
||||
: What you play with: RetroArch, Batocera, EmuDeck and others.
|
||||
|
||||
**BIOS folder**
|
||||
: The folder where your setup looks for BIOS files. Its place depends on the
|
||||
setup, and the page of each setup gives it.
|
||||
: The folder where your setup looks for BIOS files.
|
||||
|
||||
**Pack**
|
||||
: One ZIP file with every BIOS file a setup uses. A pack over 2 GB comes in
|
||||
several parts, and every part is needed.
|
||||
**ZIP**
|
||||
: One file that holds many files. You unzip it to get them out.
|
||||
|
||||
**Terminal**
|
||||
: A window where you type commands.
|
||||
|
||||
**Installer**
|
||||
: A small program started by one line pasted into a terminal. It finds your
|
||||
BIOS folder and downloads only the files that are missing.
|
||||
: The small program the command starts. It fills your BIOS folder.
|
||||
|
||||
**Terminal, or command line**
|
||||
: A window where you type commands. On Windows it is PowerShell, on a Mac it
|
||||
is Terminal, on a Steam Deck it is Konsole.
|
||||
|
||||
**Hash, or checksum (MD5, SHA1)**
|
||||
: A fingerprint of a file's contents. Two files with the same hash hold the
|
||||
same bytes. Some setups use it to refuse a file that is not the expected
|
||||
version.
|
||||
**Hash**
|
||||
: A fingerprint of a file's contents. A different file gets a different hash.
|
||||
|
||||
**Region**
|
||||
: The market a console was sold in, such as Japan, North America or Europe.
|
||||
Some emulators pick the BIOS of the same region as the game.
|
||||
: Where a console was sold: Japan, North America, Europe.
|
||||
|
||||
**Required and optional**
|
||||
: Required: the emulator does not start games without the file. Optional:
|
||||
games start without it, with small differences such as a missing start-up
|
||||
screen.
|
||||
|
||||
**HLE**
|
||||
: High-level emulation: code in the emulator that stands in for the BIOS.
|
||||
Many games work with it, some glitch or do not start.
|
||||
**Required** and **optional**
|
||||
: Required: games do not start without it. Optional: games start anyway.
|
||||
|
||||
**Game data**
|
||||
: Files of a game that a game engine reads, such as the data of Doom or
|
||||
Diablo. They come from your own copy of the game, and their absence does not
|
||||
affect any console.
|
||||
|
||||
## Project terms
|
||||
|
||||
**Profile**
|
||||
: A YAML file in `emulators/` that documents what one emulator loads, read
|
||||
from its source code.
|
||||
|
||||
**Ground truth**
|
||||
: The emulator's source code, the reference every profile is checked against.
|
||||
|
||||
**System**
|
||||
: A console or computer being emulated, named by an id such as
|
||||
`sony-playstation` or `nintendo-gba`.
|
||||
|
||||
**Verification mode**
|
||||
: How a setup checks a file: by its name only (existence), by MD5 or by SHA1.
|
||||
Reference: [How each platform checks files](verification-modes.md).
|
||||
|
||||
**Status**
|
||||
: The outcome of one file check: `ok`, `untested` (present, but not the
|
||||
expected hash) or `missing`.
|
||||
|
||||
**Severity**
|
||||
: How much a check result matters: OK, INFO (negligible), WARNING (degraded),
|
||||
CRITICAL (the emulator cannot start games).
|
||||
|
||||
**Discrepancy**
|
||||
: A file that passes the setup's own check but fails the emulator's size or
|
||||
hash check.
|
||||
|
||||
**hle_fallback**
|
||||
: A flag on a profile entry: the emulator has HLE for this file, so its
|
||||
absence is reported at INFO.
|
||||
|
||||
**Variant**
|
||||
: Another version of a BIOS file (a revision, a region or another dump), kept
|
||||
in `.variants/` in the repository.
|
||||
|
||||
**Cross-reference**
|
||||
: The comparison of emulator profiles with a setup's own list, which finds the
|
||||
files the setup's emulators load and its list does not name.
|
||||
|
||||
**Shared group**
|
||||
: A group of files in `_shared.yml` that several setups include, with the
|
||||
folder an emulator expects.
|
||||
|
||||
**Data directory**
|
||||
: A whole folder an emulator needs, such as Dolphin's `Sys/` or the PPSSPP
|
||||
assets, kept in `data/` and not indexed in the database.
|
||||
|
||||
**Storage tier**
|
||||
: Where a file comes from: `embedded` (in `bios/`), `external` (downloaded at
|
||||
build time) or `user_provided`.
|
||||
|
||||
**Target**
|
||||
: A hardware architecture a setup runs on, such as `switch`, `rpi4` or
|
||||
`x86_64`.
|
||||
|
||||
**Manifest**
|
||||
: The JSON list of files per setup in `install/`, which the installer reads.
|
||||
|
||||
**Scraper**
|
||||
: A script that reads a setup's own BIOS list (System.dat, es_bios.xml and
|
||||
others) into this project's format.
|
||||
|
||||
**Exporter**
|
||||
: A script that writes the project's data back in a setup's own format.
|
||||
|
||||
**Truth**
|
||||
: A setup's file list generated from the emulator profiles, compared with the
|
||||
list the setup publishes.
|
||||
|
||||
**Dump catalog**
|
||||
: A preservation project (Redump, No-Intro, TOSEC) that publishes lists of
|
||||
verified hardware dumps.
|
||||
|
||||
**Provenance**
|
||||
: The catalogs that list a file, joined to the database by hash. It informs,
|
||||
it never overrides the emulator code.
|
||||
: Files from your own copy of a PC game, like Doom. Not a BIOS.
|
||||
|
||||
!!! tip "Next"
|
||||
|
||||
- [What BIOS files are](what-are-bios-files.md)
|
||||
- [What is a BIOS?](what-are-bios-files.md)
|
||||
- [Get your files](../which-pack.md)
|
||||
- Reference: [Terms of the reference pages](reference-terms.md)
|
||||
+5
-4
@@ -12,7 +12,7 @@ toolchain works. To set up BIOS files on a device, start with
|
||||
|
||||
- **[How each platform checks files](verification-modes.md)** - existence, MD5 and SHA1 modes, severity matrix, resolution chain, reading `verify.py` output
|
||||
- **[What the packs do not hold](../gaps.md)** - files emulators load that no pack can carry yet, by platform and by emulator
|
||||
- **[Cross-reference](../cross-reference.md)** - files the emulators of a platform load and its own list does not name
|
||||
- **[Cores by platform](../cross-reference.md)** - every core each platform runs, the systems it emulates, the upstream project it comes from
|
||||
- **[Dump provenance](../provenance.md)** - how the collection lines up against the No-Intro, Redump and TOSEC catalogs
|
||||
- **[Updated platform files](../exports.md)** - each platform's own file, with the changes the emulator source supports
|
||||
- **[Technical questions](technical-faq.md)** - multiple hashes, MAME versions, UNTESTED, dump verification
|
||||
@@ -53,7 +53,8 @@ at run time, so the source is the primary reference:
|
||||
|
||||
See [contributing](../contributing.md) for submission guidelines.
|
||||
|
||||
## Glossary
|
||||
## Terms
|
||||
|
||||
The words these pages use, from BIOS to provenance, are in the
|
||||
[glossary](glossary.md).
|
||||
The words these pages use, from profile to provenance, are in
|
||||
[Terms of the reference pages](reference-terms.md). The everyday words are in
|
||||
the [glossary](glossary.md).
|
||||
+292
-82
@@ -4,9 +4,19 @@ level: explore
|
||||
|
||||
# All installer options
|
||||
|
||||
Reference for `install.sh`, `install.ps1` and `install.py`: what the one-liner
|
||||
runs, what it detects, where the bytes come from and what it is allowed to
|
||||
write. For the BIOS folder of each setup, see
|
||||
The one-line command finds your setup and its BIOS folder. It downloads only
|
||||
the files that are missing or wrong, and checks each one against its
|
||||
fingerprint before writing it. The options below are for anything else: fewer
|
||||
files (one console, one region, only the cores you have), another folder, an
|
||||
SD card, a check without download, or a run from a script.
|
||||
|
||||
Example: `--platform retroarch --system sony-playstation --region north-america`
|
||||
installs only the PlayStation files, and the North American version where
|
||||
there is one per region.
|
||||
|
||||
How the command protects your machine is under
|
||||
[What the bootstrap does](#what-the-bootstrap-does) and
|
||||
[Trust boundary](#trust-boundary). The BIOS folder of each setup is on
|
||||
[Get your files](../which-pack.md).
|
||||
|
||||
## One line
|
||||
@@ -50,43 +60,6 @@ from the text and calling it passes the arguments through:
|
||||
--platform retroarch --dest D:\bios
|
||||
```
|
||||
|
||||
## What the bootstrap does
|
||||
|
||||
Both wrappers do the same four things before any BIOS file is considered.
|
||||
|
||||
They fetch `install.py` over HTTPS only, from `RETROBIOS_INSTALL_URL` or the
|
||||
pinned raw URL. A URL with any other scheme is refused outright.
|
||||
|
||||
They cap the download at 2 MB and require the SHA-256 to equal the 64 hex
|
||||
characters embedded in the wrapper, `RETROBIOS_INSTALL_SHA256` when set. A
|
||||
mismatch aborts with "the downloaded installer does not match its expected
|
||||
fingerprint" and nothing runs. Right after an update of this project the
|
||||
wrapper and `install.py` can come from caches a few minutes apart, which reads
|
||||
the same way: waiting five minutes settles it. Any change to `install.py`
|
||||
therefore means recomputing that pin in both wrappers.
|
||||
|
||||
They locate a Python 3.8 or newer interpreter (`python3` then `python` on
|
||||
POSIX, `py -3` then `python3` then `python` on Windows). Without one,
|
||||
`install.sh` names the command that installs it on the system it runs on
|
||||
(`pkg install python` in Termux, which it offers to run since Termux installs
|
||||
without root, `xcode-select --install` on macOS, apt, dnf, pacman, zypper or apk
|
||||
from `/etc/os-release`), and `install.ps1` at a console offers to run `winget
|
||||
install Python.Python.3.12`, then reads the new PATH and carries on.
|
||||
`install.sh` needs `curl` or `wget` (GNU or BusyBox) and `sha256sum` or `shasum`.
|
||||
Windows PowerShell 5.1 still negotiates SSL 3.0 and TLS 1.0 by default and
|
||||
GitHub refuses both, so `install.ps1` raises the floor to TLS 1.2 before
|
||||
downloading, and `install.sh` pins the same floor with `curl --tlsv1.2`.
|
||||
|
||||
They delete the temporary installer on the way out, including on interrupt.
|
||||
Run from a clone, `install.sh` and `install.ps1` reuse the `install.py` sitting
|
||||
next to them and skip the download entirely. Piped from stdin, `install.sh`
|
||||
never treats the working directory as a trusted location for it.
|
||||
|
||||
Piped from `curl`, the shell's standard input is the script itself, so
|
||||
`install.sh` hands the installer the terminal (`/dev/tty`) when there is one.
|
||||
Without that, every question the installer can ask was skipped on Linux and
|
||||
macOS.
|
||||
|
||||
## What the installer does
|
||||
|
||||
1. Detects the host OS and the platforms installed on it.
|
||||
@@ -131,6 +104,119 @@ ones, grouped by system with the emulators that read them, and point at the
|
||||
emulator pages. They do not change the exit code of `--check`, since no run of
|
||||
the installer can fetch them.
|
||||
|
||||
## Reading a run { #reading-a-run }
|
||||
|
||||
Each line a first install prints, and what it means. The run below is a
|
||||
Batocera install into an empty folder, from the list as published on
|
||||
2026-10-21. The figures change with each release.
|
||||
|
||||
### Before the run
|
||||
|
||||
The size depends on the platform and changes with each release. The run prints
|
||||
it before downloading, and asks first when the download reaches 1 GB. The
|
||||
installer also measures the free space and refuses before writing anything if
|
||||
there is not enough.
|
||||
|
||||
`curl` or `wget`, and Python 3.8 or newer, are checked by the command itself:
|
||||
it stops with a message naming what is absent. PowerShell's execution policy
|
||||
does not block the Windows line. The policy governs script files, and the
|
||||
command never writes one.
|
||||
|
||||
### The first lines
|
||||
|
||||
```
|
||||
RetroBIOS 8c0e9c762d2f
|
||||
|
||||
Detecting platform...
|
||||
Found Batocera at /userdata/bios
|
||||
```
|
||||
|
||||
The code after RetroBIOS identifies the installer: it is the start of the
|
||||
SHA-256 the command checked before running it. The path is the folder it will
|
||||
write to.
|
||||
|
||||
### The file index and the download
|
||||
|
||||
Two phases follow. The first reads what is already in the folder. It takes a
|
||||
few minutes on a memory card, because every file is hashed:
|
||||
|
||||
```
|
||||
Fetching file index for batocera...
|
||||
14481 files (9.1 GB)
|
||||
Not installable: 399 files (79 required, not found: 399).
|
||||
|
||||
Checking existing files...
|
||||
0/14481 present (0 verified, 0 wrong hash)
|
||||
```
|
||||
|
||||
`Not installable` counts the files of the list that the collection does not
|
||||
hold. They are named at the end of the run.
|
||||
|
||||
On a first install the present count is zero. On a later run it counts what
|
||||
is already there, and only the rest is downloaded. A download of 1 GB or more
|
||||
is confirmed first (`Download 9.1 GB to /userdata/bios? [Y/n]`).
|
||||
|
||||
The second phase downloads what is missing, one line per file:
|
||||
|
||||
```
|
||||
Downloading 14481 files (9.1 GB)...
|
||||
Press Ctrl+C to stop. Running the same command again carries on from here.
|
||||
[1/14481] 3do_arcade_saot.bin ok
|
||||
[2/14481] 3dobios.zip ok
|
||||
```
|
||||
|
||||
Ctrl+C is safe at any point. Files already installed stay, and running the
|
||||
command again picks up where it stopped.
|
||||
|
||||
### The end of the run
|
||||
|
||||
```
|
||||
Done. 14481 files installed, 0 files already up to date.
|
||||
Location: /userdata/bios
|
||||
399 files were not installed: the collection does not hold them, or its copy fails their check.
|
||||
Needed to start an emulator (79 files):
|
||||
dark-forces (theforceengine): DARK.GOB, SOUNDS.GOB, SPRITES.GOB, TEXTURES.GOB
|
||||
dark-forces-ii (openjkdf2): openjkdf2/episode/JK1.gob, openjkdf2/episode/JK1CTF.gob, openjkdf2/episode/JK1MP.gob, openjkdf2/resource/Res1hi.gob, openjkdf2/resource/Res2.gob
|
||||
diablo (devilutionx): devilutionx/diabdat.mpq
|
||||
doom3 (dhewm3): base/pak000.pk4, base/pak002.pk4, base/pak003.pk4, base/pak004.pk4
|
||||
droidworks (openjkdf2): dwCD.GOB, dwHD.GOB, dwMin.GOB, dwStream.GOB
|
||||
fallout (fallout1-ce): fallout1-ce/critter.dat, fallout1-ce/master.dat
|
||||
fallout2 (fallout2-ce): fallout2-ce/critter.dat, fallout2-ce/master.dat
|
||||
fury (fury): fury.grp
|
||||
... and 9 more systems (--check --verbose lists them all)
|
||||
Each emulator's page says what these files are: https://abdess.github.io/retrobios/emulators/
|
||||
To check this later, run the same command with --check.
|
||||
```
|
||||
|
||||
The word `Done` and a location are the confirmation. Any other ending
|
||||
(`Stopped`, `Finished with errors`, `Nothing was installed`) means something
|
||||
was left undone, and the run says which case it was.
|
||||
|
||||
The lines between `Location:` and the `--check` hint name the files of the
|
||||
list that the collection does not hold. `Needed to start an emulator` gives,
|
||||
for each system, the emulators that read it and the files they cannot start
|
||||
without. On the run above, all 79 belong to games (Dark Forces, Diablo, Doom 3,
|
||||
Tomb Raider and the others): the engine reads them from a copy of the game
|
||||
itself. The other 320 are optional, and the emulators reading them start
|
||||
without them.
|
||||
|
||||
### A later check
|
||||
|
||||
The same command with `--check` reads the folder and writes nothing:
|
||||
|
||||
```
|
||||
Checking existing files...
|
||||
14481/14481 present (14481 verified, 0 wrong hash)
|
||||
|
||||
All files up to date.
|
||||
```
|
||||
|
||||
The files the collection does not hold are listed after it again, as long as
|
||||
they are absent from the folder. A number before `wrong hash` means a file is
|
||||
present with contents the platform does not accept. Running the install again
|
||||
replaces it and keeps the old one, see
|
||||
[Files you already had](#files-you-already-had).
|
||||
|
||||
## Files you already had
|
||||
|
||||
A file in the BIOS folder whose contents differ from the expected one (another
|
||||
@@ -344,46 +430,6 @@ whose contents do not match is re-downloaded and replaced by the verified copy,
|
||||
the old one kept beside the BIOS folder.
|
||||
Files the list does not name are never read, moved or deleted.
|
||||
|
||||
## Machine-readable events
|
||||
|
||||
With `--events`, standard output carries only JSON objects, one per line, and
|
||||
the text a person reads goes to standard error. A program driving the installer
|
||||
(the [handheld port](#on-a-handheld-the-retrobios-port) is one) reads the
|
||||
objects and never parses the text. Every object has an `event` key naming its
|
||||
kind, and each kind has exactly the keys below, in this order. The schema is
|
||||
`EVENT_KEYS` in `install.py`, and a test holds this table to it.
|
||||
|
||||
| Kind | Keys | When |
|
||||
|------|------|------|
|
||||
| `start` | `schema`, `installer`, `mode` | First line. `schema` is 1, `installer` the identity `--version` prints, `mode` one of `install`, `check`, `dry-run`, `list` |
|
||||
| `detect` | `os`, `os_name`, `platforms` | Once the platforms are known. `os_name` comes from `/etc/os-release`. `platforms` lists `{platform, name, bios_dir}`, and is empty when nothing supported was found |
|
||||
| `error` | `stage`, `reason`, `platform`, `message` | The file list could not be read (`stage` is `manifest`). `reason` is `network`, `not_found` or `invalid` |
|
||||
| `file` | `platform`, `dest`, `systems`, `size`, `state` | Each file of the list after the check. `state` is `present` (hash verified), `wrong_hash` or `missing` |
|
||||
| `system` | `platform`, `system`, `name`, `files`, `present`, `missing`, `wrong_hash`, `bytes_needed` | Each system, sorted by id. Files with no system count under `other`. `name` is the platform's own name for it |
|
||||
| `check` | `platform`, `name`, `bios_dir`, `files`, `present`, `missing`, `wrong_hash`, `bytes_needed`, `data_missing`, `not_installable` | The platform's totals. `data_missing` counts data-tree files to fetch, `not_installable` the files the collection cannot supply |
|
||||
| `download` | `platform`, `files`, `bytes` | Before the downloads start |
|
||||
| `progress` | `files_done`, `files_total`, `bytes_done`, `bytes_total` | At most every half second while bytes arrive |
|
||||
| `downloaded` | `dest`, `ok`, `reason`, `size`, `files_done`, `files_total`, `bytes_done`, `bytes_total` | Each finished file. `reason` says why one failed, and is empty otherwise |
|
||||
| `summary` | `mode`, `installed`, `up_to_date`, `pending`, `failed`, `skipped`, `left_out`, `kept`, `interrupted` | The outcome. `pending` counts what a next run would still fetch, `failed` lists `{dest, reason}`, `skipped` lists `{reason, label, files, required}` for the files the collection cannot supply, `left_out` lists `{category, label, files, dests}` for what `--no-game-data` left out, and is empty without it. `kept` lists `{folder, files, bytes}`, one per backup folder, for the files in place the run moved aside before replacing them (with `--dry-run`, would move), and is empty when none. Not written for a listing |
|
||||
| `end` | `code` | Last line, with the exit status the process returns (see [Exit status](#exit-status)) |
|
||||
|
||||
An option refused before the run starts (`install.py: error:`, code 2) writes
|
||||
no event at all. A program reads a missing `end` as that case.
|
||||
|
||||
## Environment overrides
|
||||
|
||||
| Variable | Effect |
|
||||
|----------|--------|
|
||||
| `RETROBIOS_REF` | Branch or tag the file list and the files committed to the repository are read from. Defaults to `main`. Files the manifest marks `release_asset` always come from the `large-files` release, whatever the ref, and that release replaces an asset in place when it is rebuilt. Each release deletes the previous release tags ([release process](release-process.md#cutting-a-release)), so a tag holds a file list until the next release |
|
||||
| `RETROBIOS_BASE_URL` | Base URL for the manifest and the files it declares. HTTPS only, plain HTTP allowed to loopback for end-to-end tests. Whoever controls this base controls the expected hashes, hence the check. A file list that cannot be fetched names the address, and this variable when it is set |
|
||||
| `RETROBIOS_OS` | Names the host outright (`linux`, `wsl`, `windows`, `darwin`, `android`) instead of detecting it |
|
||||
| `EXTERNAL_STORAGE` | Android only, the shared storage root RetroArch builds its default directories from. Defaults to `/storage/emulated/0` |
|
||||
| `RETROBIOS_INSTALL_URL` | Where the bootstrap fetches `install.py`. HTTPS only |
|
||||
| `RETROBIOS_INSTALL_SHA256` | The SHA-256 the bootstrap requires of that installer, 64 hex characters. When either of these two is set and the fingerprint does not match, the error names the variable instead of suggesting a retry |
|
||||
| `RETROBIOS_BOOTSTRAP` | Set by `install.sh` (`sh`) and `install.ps1` (`ps1`) for the temporary installer they run, so that its hints give back the one-line command rather than `python3 install.py` |
|
||||
| `NO_COLOR` | Plain text, no colour, even at a terminal. `TERM=dumb` also turns the live progress line off |
|
||||
| `HTTPS_PROXY`, `NO_PROXY` | Honoured for every download through the standard library's default proxy handling: one names the proxy, the other the hosts to reach directly |
|
||||
|
||||
## Platform detection
|
||||
|
||||
Detection reads what the system itself writes, never a guess from a directory
|
||||
@@ -749,6 +795,43 @@ counts the data files missing, `--dry-run` names each tree it would fetch, and
|
||||
narrowing with `--system`, `--core` or `--target` keeps only the trees of the
|
||||
systems that stay.
|
||||
|
||||
## What the bootstrap does
|
||||
|
||||
Both wrappers do the same four things before any BIOS file is considered.
|
||||
|
||||
They fetch `install.py` over HTTPS only, from `RETROBIOS_INSTALL_URL` or the
|
||||
pinned raw URL. A URL with any other scheme is refused outright.
|
||||
|
||||
They cap the download at 2 MB and require the SHA-256 to equal the 64 hex
|
||||
characters embedded in the wrapper, `RETROBIOS_INSTALL_SHA256` when set. A
|
||||
mismatch aborts with "the downloaded installer does not match its expected
|
||||
fingerprint" and nothing runs. Right after an update of this project the
|
||||
wrapper and `install.py` can come from caches a few minutes apart, which reads
|
||||
the same way: waiting five minutes settles it. Any change to `install.py`
|
||||
therefore means recomputing that pin in both wrappers.
|
||||
|
||||
They locate a Python 3.8 or newer interpreter (`python3` then `python` on
|
||||
POSIX, `py -3` then `python3` then `python` on Windows). Without one,
|
||||
`install.sh` names the command that installs it on the system it runs on
|
||||
(`pkg install python` in Termux, which it offers to run since Termux installs
|
||||
without root, `xcode-select --install` on macOS, apt, dnf, pacman, zypper or apk
|
||||
from `/etc/os-release`), and `install.ps1` at a console offers to run `winget
|
||||
install Python.Python.3.12`, then reads the new PATH and carries on.
|
||||
`install.sh` needs `curl` or `wget` (GNU or BusyBox) and `sha256sum` or `shasum`.
|
||||
Windows PowerShell 5.1 still negotiates SSL 3.0 and TLS 1.0 by default and
|
||||
GitHub refuses both, so `install.ps1` raises the floor to TLS 1.2 before
|
||||
downloading, and `install.sh` pins the same floor with `curl --tlsv1.2`.
|
||||
|
||||
They delete the temporary installer on the way out, including on interrupt.
|
||||
Run from a clone, `install.sh` and `install.ps1` reuse the `install.py` sitting
|
||||
next to them and skip the download entirely. Piped from stdin, `install.sh`
|
||||
never treats the working directory as a trusted location for it.
|
||||
|
||||
Piped from `curl`, the shell's standard input is the script itself, so
|
||||
`install.sh` hands the installer the terminal (`/dev/tty`) when there is one.
|
||||
That keeps the installer's questions working when the script is piped from
|
||||
`curl`.
|
||||
|
||||
## Trust boundary
|
||||
|
||||
The manifest is fetched over the network and treated as untrusted input. Every
|
||||
@@ -808,7 +891,134 @@ in the session.
|
||||
Failures that are per-file, such as a download exhausting its three attempts,
|
||||
are counted and reported at the end.
|
||||
|
||||
## Machine-readable events
|
||||
|
||||
With `--events`, standard output carries only JSON objects, one per line, and
|
||||
the text a person reads goes to standard error. A program driving the installer
|
||||
(the [handheld port](#on-a-handheld-the-retrobios-port) is one) reads the
|
||||
objects and never parses the text. Every object has an `event` key naming its
|
||||
kind, and each kind has exactly the keys below, in this order. The schema is
|
||||
`EVENT_KEYS` in `install.py`, and a test holds this table to it.
|
||||
|
||||
| Kind | Keys | When |
|
||||
|------|------|------|
|
||||
| `start` | `schema`, `installer`, `mode` | First line. `schema` is 1, `installer` the identity `--version` prints, `mode` one of `install`, `check`, `dry-run`, `list` |
|
||||
| `detect` | `os`, `os_name`, `platforms` | Once the platforms are known. `os_name` comes from `/etc/os-release`. `platforms` lists `{platform, name, bios_dir}`, and is empty when nothing supported was found |
|
||||
| `error` | `stage`, `reason`, `platform`, `message` | The file list could not be read (`stage` is `manifest`). `reason` is `network`, `not_found` or `invalid` |
|
||||
| `file` | `platform`, `dest`, `systems`, `size`, `state` | Each file of the list after the check. `state` is `present` (hash verified), `wrong_hash` or `missing` |
|
||||
| `system` | `platform`, `system`, `name`, `files`, `present`, `missing`, `wrong_hash`, `bytes_needed` | Each system, sorted by id. Files with no system count under `other`. `name` is the platform's own name for it |
|
||||
| `check` | `platform`, `name`, `bios_dir`, `files`, `present`, `missing`, `wrong_hash`, `bytes_needed`, `data_missing`, `not_installable` | The platform's totals. `data_missing` counts data-tree files to fetch, `not_installable` the files the collection cannot supply |
|
||||
| `download` | `platform`, `files`, `bytes` | Before the downloads start |
|
||||
| `progress` | `files_done`, `files_total`, `bytes_done`, `bytes_total` | At most every half second while bytes arrive |
|
||||
| `downloaded` | `dest`, `ok`, `reason`, `size`, `files_done`, `files_total`, `bytes_done`, `bytes_total` | Each finished file. `reason` says why one failed, and is empty otherwise |
|
||||
| `summary` | `mode`, `installed`, `up_to_date`, `pending`, `failed`, `skipped`, `left_out`, `kept`, `interrupted` | The outcome. `pending` counts what a next run would still fetch, `failed` lists `{dest, reason}`, `skipped` lists `{reason, label, files, required}` for the files the collection cannot supply, `left_out` lists `{category, label, files, dests}` for what `--no-game-data` left out, and is empty without it. `kept` lists `{folder, files, bytes}`, one per backup folder, for the files in place the run moved aside before replacing them (with `--dry-run`, would move), and is empty when none. Not written for a listing |
|
||||
| `end` | `code` | Last line, with the exit status the process returns (see [Exit status](#exit-status)) |
|
||||
|
||||
An option refused before the run starts (`install.py: error:`, code 2) writes
|
||||
no event at all. A program reads a missing `end` as that case.
|
||||
|
||||
## Environment overrides
|
||||
|
||||
| Variable | Effect |
|
||||
|----------|--------|
|
||||
| `RETROBIOS_REF` | Branch or tag the file list and the files committed to the repository are read from. Defaults to `main`. Files the manifest marks `release_asset` always come from the `large-files` release, whatever the ref, and that release replaces an asset in place when it is rebuilt. Each release deletes the previous release tags ([release process](release-process.md#cutting-a-release)), so a tag holds a file list until the next release |
|
||||
| `RETROBIOS_BASE_URL` | Base URL for the manifest and the files it declares. HTTPS only, plain HTTP allowed to loopback for end-to-end tests. Whoever controls this base controls the expected hashes, hence the check. A file list that cannot be fetched names the address, and this variable when it is set |
|
||||
| `RETROBIOS_OS` | Names the host outright (`linux`, `wsl`, `windows`, `darwin`, `android`) instead of detecting it |
|
||||
| `EXTERNAL_STORAGE` | Android only, the shared storage root RetroArch builds its default directories from. Defaults to `/storage/emulated/0` |
|
||||
| `RETROBIOS_INSTALL_URL` | Where the bootstrap fetches `install.py`. HTTPS only |
|
||||
| `RETROBIOS_INSTALL_SHA256` | The SHA-256 the bootstrap requires of that installer, 64 hex characters. When either of these two is set and the fingerprint does not match, the error names the variable instead of suggesting a retry |
|
||||
| `RETROBIOS_BOOTSTRAP` | Set by `install.sh` (`sh`) and `install.ps1` (`ps1`) for the temporary installer they run, so that its hints give back the one-line command rather than `python3 install.py` |
|
||||
| `NO_COLOR` | Plain text, no colour, even at a terminal. `TERM=dumb` also turns the live progress line off |
|
||||
| `HTTPS_PROXY`, `NO_PROXY` | Honoured for every download through the standard library's default proxy handling: one names the proxy, the other the hosts to reach directly |
|
||||
|
||||
## When something goes wrong
|
||||
|
||||
See [Troubleshooting](troubleshooting.md#installation-script-fails) for network,
|
||||
permission and detection failures.
|
||||
The common cases, with the short answer, are on
|
||||
[When a game does not start](troubleshooting.md). The details follow.
|
||||
|
||||
### Network
|
||||
|
||||
The installer fetches its manifest, then downloads only the repository or
|
||||
`large-files` release objects it needs. When a download fails, check that
|
||||
`https://github.com` opens. Behind a proxy, set `HTTPS_PROXY` in the
|
||||
environment. A file that fails three attempts is counted and reported at the
|
||||
end, and the next run fetches only what is still missing.
|
||||
|
||||
### Permission denied
|
||||
|
||||
The installer needs to write to the BIOS folder. On Linux and macOS, check who
|
||||
owns it (`ls -la`). On Batocera, Recalbox and ROCKNIX the folder belongs to
|
||||
root, so the same command with `sudo` in front of it succeeds. On Windows, run
|
||||
PowerShell as Administrator only for a protected folder.
|
||||
|
||||
A file system mounted read-only refuses root too, so the installer does not
|
||||
suggest `sudo` for it. Linux remounts a card or drive read-only after an error,
|
||||
an unclean removal for one: check it (`fsck`, or `chkdsk` on Windows) and
|
||||
mount it read-write again.
|
||||
|
||||
A file already in the BIOS folder with the read-only attribute is replaced
|
||||
like any other: on Windows the installer clears the attribute first.
|
||||
`file in place is read-only` appears only when Windows refuses that too, which
|
||||
a file owned by another account can cause.
|
||||
|
||||
### Platform not detected
|
||||
|
||||
The installer finds a platform from the config files it knows. When it finds
|
||||
none, name the platform and its BIOS folder:
|
||||
|
||||
```bash
|
||||
curl -fsSL https://raw.githubusercontent.com/Abdess/retrobios/main/install.sh | sh -s -- --platform retroarch --dest ~/.config/retroarch/system
|
||||
curl -fsSL https://raw.githubusercontent.com/Abdess/retrobios/main/install.sh | sh -s -- --platform batocera --dest /userdata/bios
|
||||
```
|
||||
|
||||
```powershell
|
||||
&([scriptblock]::Create((irm https://raw.githubusercontent.com/Abdess/retrobios/main/install.ps1))) `
|
||||
--platform retroarch --dest C:\RetroArch-Win64\system
|
||||
```
|
||||
|
||||
`--list-platforms` lists the platforms the installer knows and the ones it
|
||||
finds here. `--help` lists the options with examples.
|
||||
|
||||
### No file list
|
||||
|
||||
The installer reads its manifests from the revision the bootstrap checked it
|
||||
against. A platform name is checked before anything is downloaded, so a
|
||||
"No file list" message comes from the revision: `RETROBIOS_REF` naming a tag
|
||||
that does not exist, or one older than the platform. Unset it, or pick a tag
|
||||
from the releases page ([Environment overrides](#environment-overrides)).
|
||||
|
||||
### Upper and lower case
|
||||
|
||||
Linux file systems tell `Bios.ROM` and `bios.rom` apart. Windows and macOS do
|
||||
not, by default.
|
||||
|
||||
The RetroArch pack is built for every system RetroArch runs on, so it holds
|
||||
one name per file: `BIOS.col`, never `bios.col` beside it, since unzipping both
|
||||
on Windows or macOS would overwrite one with the other. On Linux, Mesen-CE
|
||||
opens `bios.col` and NP2kai opens the lowercase `np2kai/2608_*.wav`, which the
|
||||
pack only holds as `BIOS.col` and `2608_*.WAV`. The installer checks whether
|
||||
the BIOS folder keeps case and, when it does, also fetches these names. On
|
||||
Linux, use the installer rather than unzipping the pack by hand.
|
||||
|
||||
The reverse happens on Batocera and Recalbox, whose lists hold both spellings
|
||||
because their systems keep case: NP2kai reads `np2kai/bios.rom` and
|
||||
`np2kai/BIOS.ROM` as two files. Written to a folder that folds case (the share
|
||||
opened from Windows, an exFAT card), one overwrites the other. The installer
|
||||
checks the folder first, keeps one file per name there and lists the ones it
|
||||
left out.
|
||||
|
||||
### Packs and their parts
|
||||
|
||||
`scripts/download.py --list` and `scripts/download.sh --list` print the packs of
|
||||
a release. A pack's name lists every platform it serves. Releases up to
|
||||
v2026.10.10 ship RetroArch and Lakka as one `RetroArch_Lakka` pack, and the
|
||||
next ones give Lakka its own, since Lakka runs on Linux where two names that
|
||||
differ by case are two files. The installer and the download scripts find the
|
||||
right pack either way.
|
||||
|
||||
Parts named `Pack.part1of2.zip` are ordinary ZIPs: unzip each one into the same
|
||||
folder, and check that all of them were downloaded. The name says how many
|
||||
there are. `scripts/download.sh` and `scripts/download.py` download every part
|
||||
and check it against the release's checksums before unzipping. Both stage
|
||||
inside the destination folder, never in `/tmp`, which is a RAM disk on most of
|
||||
these systems.
|
||||
@@ -0,0 +1,45 @@
|
||||
---
|
||||
level: explore
|
||||
---
|
||||
|
||||
# The project's legal position
|
||||
|
||||
Redistributing firmware is not settled law. Below is the reasoning the project acts on, with the strength of each argument, so anyone can weigh it. None of it is legal advice, and none of it has been tested in court.
|
||||
|
||||
## Emulation and BIOS redistribution
|
||||
|
||||
- **Writing an emulator is lawful.** *Sony v. Connectix* (2000) and *Sega v. Accolade* (1992) held that copying a work during reverse engineering, to reach the functional elements needed for interoperability, is fair use. Both concern the act of copying while developing, and *Connectix* specifically involved copying Sony's BIOS in the course of that work. Neither decision addresses distributing firmware to third parties, so they support the legality of emulation itself rather than of this collection.
|
||||
- **Fair use (US, 17 USC 107) is a defence, argued case by case.** The project's position is that non-commercial redistribution for personal backup and archival weighs favourably on purpose and on market effect, since these files are not sold separately. It weighs poorly on the amount used: each file is copied whole. Manufacturers do still monetise some of this firmware indirectly, through re-releases, subscription services and mini consoles, so the market factor is contestable rather than clear.
|
||||
- **Interoperability in the EU.** The Software Directive (2009/24/EC, Art. 5-6) permits decompilation and use to achieve interoperability, subject to conditions, and Art. 6 restricts passing the resulting information to others. It supports the emulation use case, but it is not a general redistribution permission.
|
||||
- **Discontinued hardware.** Most firmware here is for hardware no longer sold or supported. This bears on the fair-use market factor and on the practical likelihood of complaint. "Abandonware" is not a legal doctrine in any jurisdiction, and nothing here rests on it.
|
||||
|
||||
## Encryption keys (Switch prod.keys, 3DS AES keys, Wii U keys)
|
||||
|
||||
This is the most contested area, and the weakest part of the project's position.
|
||||
|
||||
- **Keys are unlikely to be copyrightable.** A bare numeric value has no author's creative expression, so copyright is a poor fit. This says nothing about the DMCA, which is the provision that actually applies.
|
||||
- **DMCA 1201(f) is narrow.** Section 1201(f) allows a person who has lawfully obtained the right to use a copy to circumvent for the sole purpose of achieving interoperability with an independently created program, and 1201(f)(3) allows the means to be made available to others only for that same purpose. Publishing keys openly is not obviously within that allowance, and the trafficking prohibitions in 1201(a)(2) and 1201(b) remain in play. This is the clearest legal risk the project carries.
|
||||
- **Library of Congress exemptions do not cover this repository.** The triennial exemptions at 37 CFR 201.40 let an eligible library, archive or museum circumvent access controls to preserve a lawfully acquired video game whose server support has ended, with access limited to the institution's premises. The Ninth Triennial Proceeding (2024 cycle) renewed them and declined to extend them to off-premises remote access. A public repository is neither an eligible institution nor an on-premises reading room, so these exemptions show which way preservation policy is moving without authorising what is done here.
|
||||
- **Keys come from consumer hardware.** They are extracted from retail devices their owners bought. *Chamberlain v. Skylink* (2004) held that a 1201 claim requires some nexus to copyright infringement, in a dispute over a garage-door opener. Later cases have narrowed its reach, and it is a weak foundation for a general post-sale right.
|
||||
- **Trade secret is not a live issue.** Keys embedded in millions of shipped devices and widely republished are not kept secret by reasonable measures.
|
||||
|
||||
## Recent firmware (Switch 19.0.0, PS3UPDAT, PSVUPDAT)
|
||||
|
||||
- **Free download is not a licence.** Manufacturers publish these updates on open CDNs without authentication, which makes them easy to obtain but does not grant a right to redistribute them, and PlayStation firmware ships under an end-user licence agreement. The practical argument is that mirroring a file the manufacturer already gives away for free causes no identifiable loss, not that doing so is expressly permitted.
|
||||
- **Functional necessity.** Emulators cannot run the software these systems were built for without this firmware. That is why the files are collected. It is a statement of purpose, not a legal defence in itself.
|
||||
- **Yuzu context.** The Yuzu settlement (2024) concerned the emulator and its alleged facilitation of piracy. Yuzu settled without admitting liability, so it set no precedent either way on firmware or key redistribution. It does show that rights holders in this space litigate.
|
||||
|
||||
## Summary
|
||||
|
||||
This project preserves BIOS files, firmware and keys for personal use, archival and interoperability. The strongest ground is the older, discontinued firmware, where fair use and the absence of a market both point the same way. The weakest is the encryption keys, where DMCA 1201 applies and the interoperability exemption is narrower than the use made of it here. The project accepts that risk deliberately, in the belief that these files are worth preserving while they can still be obtained.
|
||||
|
||||
This reflects the project's good-faith understanding, not legal advice.
|
||||
|
||||
## Asking for a file to be removed
|
||||
|
||||
A rights holder, or anyone acting for one, can [open an issue](https://github.com/Abdess/retrobios/issues) identifying the file by path or hash. A file whose removal is requested by its rights holder is removed from the repository and from the next release. No formal notice is required and none will be demanded. State the file and the basis of the claim. The same channel is open to anyone else with a concern about a specific file.
|
||||
|
||||
!!! tip "Next"
|
||||
|
||||
- [FAQ](faq.md)
|
||||
- [What is a BIOS?](what-are-bios-files.md)
|
||||
+31
-13
@@ -4,7 +4,24 @@ level: contribute
|
||||
|
||||
# Profiling guide
|
||||
|
||||
How to create an emulator profile from source code.
|
||||
A profile is a YAML file that says which files one emulator opens, under which
|
||||
names, what it checks in them and whether it runs without them. Each line
|
||||
points at the code that proves it, at a fixed revision of that code (the pin,
|
||||
`source_commit`), so anyone can check it. Packs, checks and every emulator page
|
||||
on this site are built from profiles.
|
||||
|
||||
Example, one entry of `emulators/duckstation.yml`:
|
||||
|
||||
```yaml
|
||||
- name: "scph5501.bin"
|
||||
region: [north-america, latin-america]
|
||||
required: true
|
||||
md5: "490f666e1afb15b7362b406ed1cea246"
|
||||
priority: 5
|
||||
source_ref: "src/core/bios.cpp:47"
|
||||
```
|
||||
|
||||
This guide shows how to read an emulator's code to write one.
|
||||
|
||||
## Approach
|
||||
|
||||
@@ -15,15 +32,13 @@ but are verified against the code.
|
||||
|
||||
### Source hierarchy
|
||||
|
||||
Documentation and metadata are valuable starting points, but they can
|
||||
fall out of sync with the actual code over time. The desmume2015 .info
|
||||
file is a good illustration: it declares `firmware_count=3`, but the
|
||||
source code at the pinned version opens zero firmware files. Cross-checking
|
||||
against the source helps catch that kind of gap early.
|
||||
The desmume2015 `.info` file declares `firmware_count=3`. The source at the
|
||||
pinned revision opens no firmware file. Documentation and metadata are where a
|
||||
profile starts, and the code is where it is checked.
|
||||
|
||||
When sources conflict, priority follows the chain of actual execution:
|
||||
|
||||
1. **Original emulator source** (ground truth, what the code actually does)
|
||||
1. **Original emulator source** (ground truth, what the code does)
|
||||
2. **Libretro port** (may adapt paths, add compatibility shims, or drop features)
|
||||
3. **.info metadata** (declarative, may be outdated or copied from another core)
|
||||
|
||||
@@ -144,11 +159,13 @@ degraded functionality (missing boot animation, different fonts, reduced
|
||||
audio in menus), it is optional. This keeps the classification objective
|
||||
and consistent across all profiles.
|
||||
|
||||
When a core has HLE (high-level emulation), the real BIOS typically
|
||||
gives better accuracy, but the core functions without it. These files
|
||||
are marked with `hle_fallback: true` and `required: false`. The file
|
||||
still ships in packs (better experience for the user), but its absence
|
||||
does not raise alarms during verification.
|
||||
When a core has HLE (high-level emulation), code of its own that stands
|
||||
in for the file, mark the entry `hle_fallback: true`. The flag records the
|
||||
stand-in. It does not decide `required`, which still comes from what the
|
||||
code does without the file: most of the 778 entries that carry the flag
|
||||
are optional, and 13 are required, among them Beetle PSX's three region
|
||||
BIOS (`emulators/beetle_psx.yml`). The file still ships in packs, and
|
||||
verification reports its absence at INFO whatever `required` says.
|
||||
|
||||
MAME is read the same way. A missing ROM is fatal only when it is neither
|
||||
`ROM_OPTIONAL` nor `NO_DUMP` (`src/emu/romload.cpp`), so a set made only of
|
||||
@@ -216,7 +233,8 @@ selection, and a Hong Kong PS2 is an NTSC-J console.
|
||||
|
||||
### 3c. Record the search order
|
||||
|
||||
When several files can fill one slot, `priority:` records the order the code
|
||||
When several files can fill one slot (one role for one system and region, such
|
||||
as the North American PlayStation BIOS), `priority:` records the order the code
|
||||
looks for them, lowest first, read from the source alone. Two cores can rank
|
||||
the same file differently: pcsx1 walks `scph1001`, `scph5501`, `scph7001` in
|
||||
that order while DuckStation prefers `scph5501` (5) to `scph1001` (10). The
|
||||
|
||||
@@ -0,0 +1,153 @@
|
||||
---
|
||||
level: reference
|
||||
---
|
||||
|
||||
# Terms of the reference pages
|
||||
|
||||
The words the reference and contributor pages use, each with a real case. The
|
||||
everyday words (BIOS, emulator, core, hash) are in the [glossary](glossary.md).
|
||||
|
||||
**Frontend**
|
||||
: The menu you pick and start games from, such as EmulationStation, MinUI or
|
||||
the RetroArch menu. It starts the emulator.
|
||||
|
||||
**Pack**
|
||||
: One ZIP file with every BIOS file a setup uses. A pack over 2 GB comes in
|
||||
several parts, and every part is needed.
|
||||
|
||||
**Profile and source_ref**
|
||||
: A profile records which files one emulator opens, read from its code.
|
||||
Every entry has a `source_ref`, the line of code that proves it, at the
|
||||
revision named by `source_commit` (the pin). Example:
|
||||
`emulators/duckstation.yml` lists `scph5501.bin` at
|
||||
`src/core/bios.cpp:47`, commit `4122fed9`.
|
||||
|
||||
**Alias**
|
||||
: Another name the same emulator accepts for a file, listed under `aliases:`
|
||||
in its profile, never as a second file.
|
||||
|
||||
**Region and priority**
|
||||
: `region:` is the territory for which the code picks a file. `priority:` is
|
||||
the order the code tries files that fill the same role, lowest first.
|
||||
Example: DuckStation gives `scph5501.bin` priority 5 and `scph1001.bin`
|
||||
priority 10, so with both present it loads `scph5501.bin`.
|
||||
|
||||
**Slot**
|
||||
: One role a file fills for one system and region, such as the North
|
||||
American PlayStation BIOS. `scph5501.bin`, `scph1001.bin` and `scph7001.bin`
|
||||
fill the same slot. `--one-per-slot` keeps the one the emulator prefers.
|
||||
|
||||
**Category: firmware, game data, unread**
|
||||
: Each entry of a platform's list is sorted by what its emulators do with
|
||||
it: firmware they load, game data, or a file none of them opens. Only
|
||||
missing firmware counts as a fault. Example: AmberELEC lists
|
||||
`hardwareconfig.xml` in each blueMSX machine folder, and blueMSX never
|
||||
opens it, so it is `unread`.
|
||||
|
||||
**Romset and recipe**
|
||||
: An arcade BIOS is a ZIP of several chips, and each MAME or FBNeo version
|
||||
expects a slightly different ZIP. A recipe is the list of chips (name and
|
||||
CRC32) one version expects, enough to rebuild that exact ZIP from chips
|
||||
already held. Example: `spec128.zip` (MD5 `1a524bfa...`) was rebuilt from
|
||||
the FBNeo recipe.
|
||||
|
||||
**Profile**
|
||||
: A YAML file in `emulators/` that documents what one emulator loads, read
|
||||
from its source code.
|
||||
|
||||
**Ground truth**
|
||||
: The emulator's source code, the reference every profile is checked against.
|
||||
|
||||
**System**
|
||||
: A console or computer being emulated, named by an id such as
|
||||
`sony-playstation` or `nintendo-gba`.
|
||||
|
||||
**Verification mode**
|
||||
: How a setup checks a file: by its name only (existence), by MD5 or by SHA1.
|
||||
Reference: [How each platform checks files](verification-modes.md).
|
||||
|
||||
**Status**
|
||||
: The outcome of one file check: `ok`, `untested` (present, but not the
|
||||
expected hash) or `missing`. Batocera's own checker prints the same
|
||||
`UNTESTED` for a file whose MD5 is not on its list (`batocera-systems`,
|
||||
`checkBios`).
|
||||
|
||||
**Severity**
|
||||
: How much a check result matters: OK, INFO (negligible), WARNING (degraded),
|
||||
CRITICAL (the emulator cannot start games).
|
||||
|
||||
**Discrepancy**
|
||||
: A file that passes the setup's own check but fails the emulator's size or
|
||||
hash check. Example: RetroBat accepts `d64_1.rom`, while XRoar checks its
|
||||
CRC32 and expects `84f68bf9`, not `60a4634c`. `verify.py` prints it as
|
||||
`DISCREPANCY`, and the gaps page lists it under that name, with the check
|
||||
that failed (size or hash) in the row.
|
||||
|
||||
**HLE**
|
||||
: High-level emulation: code inside the emulator that does the BIOS's job,
|
||||
so some games start without the file. Some games glitch or do not start
|
||||
with it, so the real file still ships.
|
||||
|
||||
**hle_fallback**
|
||||
: A flag on a profile entry: the emulator has HLE for this file, so its
|
||||
absence is reported at INFO. It does not make the file optional: 13 of
|
||||
the 778 entries that carry it are `required: true`, among them Beetle
|
||||
PSX's `scph5501.bin`.
|
||||
|
||||
**Variant**
|
||||
: Another version of a BIOS file (a revision, a region or another dump), kept
|
||||
in `.variants/` in the repository.
|
||||
|
||||
**Cross-reference**
|
||||
: The comparison of emulator profiles with a setup's own list, which finds the
|
||||
files the setup's emulators load and its list does not name. The packs add
|
||||
those files, and [What the packs do not hold](../gaps.md) counts them. The
|
||||
page [Cores by platform](../cross-reference.md) lists the cores this
|
||||
comparison reads.
|
||||
|
||||
**Shared group**
|
||||
: A group of files in `_shared.yml` that several setups include, with the
|
||||
folder an emulator expects.
|
||||
|
||||
**Data directory**
|
||||
: A whole folder an emulator needs, such as Dolphin's `Sys/` or the PPSSPP
|
||||
assets, kept in `data/` and not indexed in the database.
|
||||
|
||||
**Storage tier**
|
||||
: Where a file comes from: `embedded` (in `bios/`), `external` (downloaded at
|
||||
build time) or `user_provided`.
|
||||
|
||||
**Target**
|
||||
: A hardware architecture a setup runs on, such as `switch`, `rpi4` or
|
||||
`x86_64`.
|
||||
|
||||
**Manifest**
|
||||
: The JSON list of files per setup in `install/`, which the installer reads.
|
||||
|
||||
**Scraper**
|
||||
: A script that reads a setup's own BIOS list (System.dat, es_bios.xml and
|
||||
others) into this project's format.
|
||||
|
||||
**Exporter**
|
||||
: A script that writes the project's data back in a setup's own format.
|
||||
|
||||
**Truth**
|
||||
: A setup's file list generated from the emulator profiles, compared with the
|
||||
list the setup publishes.
|
||||
|
||||
**Dump catalog**
|
||||
: A preservation project (Redump, No-Intro, TOSEC) that publishes lists of
|
||||
verified hardware dumps.
|
||||
|
||||
**Provenance**
|
||||
: Whether a file is byte for byte a dump that Redump, No-Intro or TOSEC
|
||||
catalogues, joined to the database by hash. Example: `scph5501.bin` is
|
||||
Redump's `ps-30a.bin`. It says where a dump is known from, not whether an
|
||||
emulator accepts it, and it never overrides the emulator code. Where a pack
|
||||
takes a file from (the collection, a data folder, a release asset) is its
|
||||
source, not its provenance.
|
||||
|
||||
!!! tip "Next"
|
||||
|
||||
- [How each platform checks files](verification-modes.md)
|
||||
- [Glossary](glossary.md)
|
||||
+63
-27
@@ -4,8 +4,32 @@ level: reference
|
||||
|
||||
# Technical questions
|
||||
|
||||
Questions about how the files are identified and checked. The questions asked
|
||||
before installing are in the [FAQ](faq.md).
|
||||
Answers to "how do you know?" questions: how a file is identified, why one BIOS
|
||||
has several fingerprints, why some files are not BIOS, and which MAME version an
|
||||
arcade set belongs to. Each answer gives a real file as its example, so you can
|
||||
check it on the system pages. Questions asked before installing are in the
|
||||
[FAQ](faq.md).
|
||||
|
||||
## What's a hash/checksum?
|
||||
|
||||
A hash is a fixed-length fingerprint computed from a file's contents. If even one byte differs, the hash changes completely. Every file in the database carries these:
|
||||
|
||||
| Type | Length | Example | Used for |
|
||||
|------|--------|---------|----------|
|
||||
| SHA1 | 40 hex chars | `10155d8d6e6e832d8ea1571511e40dfb15fede05` | database primary key, BizHawk, installer downloads |
|
||||
| MD5 | 32 hex chars | `924e392ed05558ffdb115408c263dccf` | most platform verification |
|
||||
| SHA256 | 64 hex chars | `9a1c...` | emulator profiles whose upstream publishes SHA256 |
|
||||
| CRC32 | 8 hex chars | `2F468B96` | ROM-set matching, arcade DATs |
|
||||
|
||||
Emulator profiles add Adler-32 where the code checks it, which is how Dolphin
|
||||
checks its DSP ROMs (`dsp_rom.bin` and `dsp_coef.bin`, hashed byte-swapped).
|
||||
`IPL.bin` is not one of them: Dolphin loads it without a hash check.
|
||||
|
||||
Verification uses whichever one the platform itself uses: MD5 for Batocera,
|
||||
RetroBat, Recalbox, EmuDeck, RetroDECK, RomM, ROCKNIX, KNULLI, AmberELEC, EmuELEC
|
||||
and MiSTer FPGA, SHA1 for
|
||||
BizHawk, and nothing at all for RetroArch, Lakka and RetroPie, which only check
|
||||
that the file exists.
|
||||
|
||||
## How is a missing file ranked?
|
||||
|
||||
@@ -29,19 +53,52 @@ Platforms that verify by MD5 accept specific hashes. If yours doesn't match any
|
||||
A filename is never allowed to stand in for a declared hash. When a file entry
|
||||
carries a hash, resolution matches on content and reports `hash_mismatch` if the
|
||||
only same-named copy disagrees. What happens next depends on the platform: an
|
||||
MD5 or SHA1 platform would reject the file, so the pack omits it and says why,
|
||||
MD5 or SHA1 platform would report the file as not the expected one, so the pack
|
||||
omits it and says why,
|
||||
while an existence platform only checks presence, so the file ships and the divergence
|
||||
is reported instead.
|
||||
|
||||
## Why are there files that aren't BIOS?
|
||||
|
||||
A file earns its place when an emulator loads it from disk and does not bundle it. That covers actual BIOS ROMs, console firmware, arcade BIOS sets, and also game data like `prboom.wad` for the PrBoom core or soundfonts for EasyRPG.
|
||||
A file earns its place when an emulator loads it from disk and does not bundle it. That covers actual BIOS ROMs, console firmware, arcade BIOS sets, and also game data, such as `doom.wad` for the PrBoom core (`category: game_data` in `emulators/prboom.yml`) or soundfonts for EasyRPG.
|
||||
|
||||
This follows the platforms themselves: Batocera lists `prboom.wad` in its BIOS checker, and libretro declares these files in the `firmware` field of its core info. The word "BIOS" is their vocabulary for "external file the emulator needs". Files are tagged by category (`bios`, `game_data`, `bios_zip`) in the emulator profiles, so the distinction stays visible.
|
||||
This follows the platforms themselves: EmuELEC lists Diablo's `diabdat.mpq` in its BIOS list (`platforms/emuelec.yml`, destination `ports/diablo/diabdat.mpq`), and libretro declares such files in the `firmware` field of its core info. The word "BIOS" is their vocabulary for "external file the emulator needs". Files are tagged by category (`bios`, `game_data`, `bios_zip`) in the emulator profiles, so the distinction stays visible.
|
||||
|
||||
A file the emulator carries inside itself is not one of them. PrBoom compiles its engine data `prboom.wad` into the core from `src/prboom_wad_data.h` and never opens it on disk (`emulators/prboom.yml`, `src/d_main.c:1449-1465`), so no PrBoom pack needs it.
|
||||
|
||||
## Why is a file the emulator reads not in the pack?
|
||||
|
||||
A pack brings what the user has to obtain. A file the emulator installs itself
|
||||
(a font, a shader, a game database, a free replacement BIOS) is already on the
|
||||
machine once the emulator is installed, so the pack leaves it out. This is
|
||||
decided per build and per platform: the PPSSPP standalone release ships its
|
||||
`assets/` folder, the PPSSPP libretro core does not, so RetroArch packs carry
|
||||
those files and a standalone PPSSPP pack does not. When a platform's own
|
||||
package installs data beside a core (Batocera with blueMSX), that platform's
|
||||
pack leaves it out too. The emulator's page marks these files as installed with
|
||||
the emulator.
|
||||
|
||||
## What's HLE?
|
||||
|
||||
HLE (high-level emulation) is code inside an emulator that does the BIOS's job,
|
||||
so some games start without the file. Beetle PSX, for one, carries OpenBIOS for
|
||||
that (`emulators/beetle_psx.yml`, notes). The real file still ships, because
|
||||
the stand-in is not perfect: some games glitch or do not start.
|
||||
|
||||
A profile entry records it as `hle_fallback: true`. That flag does not decide
|
||||
`required`: 13 of the 778 entries that carry it are required, among them Beetle
|
||||
PSX's three region BIOS. Verification reports a missing `hle_fallback` file at
|
||||
INFO either way.
|
||||
|
||||
## How often are packs updated?
|
||||
|
||||
The platforms' own lists (libretro's System.dat, batocera-systems and the
|
||||
others) are read again by hand, and the difference is reviewed before it lands.
|
||||
A release follows when files are added or profiles change.
|
||||
|
||||
## Are these files verified against original hardware dumps?
|
||||
|
||||
No, and that is a deliberate boundary. The hashes here document what
|
||||
No. The hashes here document what
|
||||
emulator code loads and accepts, read from the source. When several
|
||||
revisions or regions pass, all of them are kept (`.variants/` in the
|
||||
repository, per-emulator pages list each one), and the pack ships the
|
||||
@@ -75,27 +132,6 @@ compiles two MAME versions of its own, 0.258 and 0.278, profiled as
|
||||
ships the sets matching the core you run, and a generic unversioned arcade
|
||||
pack cannot do that.
|
||||
|
||||
## What's a hash/checksum?
|
||||
|
||||
A hash is a fixed-length fingerprint computed from a file's contents. If even one byte differs, the hash changes completely. Every file in the database carries these:
|
||||
|
||||
| Type | Length | Example | Used for |
|
||||
|------|--------|---------|----------|
|
||||
| SHA1 | 40 hex chars | `10155d8d6e6e832d8ea1571511e40dfb15fede05` | database primary key, BizHawk, installer downloads |
|
||||
| MD5 | 32 hex chars | `924e392ed05558ffdb115408c263dccf` | most platform verification |
|
||||
| SHA256 | 64 hex chars | `9a1c...` | emulator profiles whose upstream publishes SHA256 |
|
||||
| CRC32 | 8 hex chars | `2F468B96` | ROM-set matching, arcade DATs |
|
||||
|
||||
Emulator profiles add Adler-32 where the code checks it, which is how Dolphin
|
||||
checks its DSP ROMs (`dsp_rom.bin` and `dsp_coef.bin`, hashed byte-swapped).
|
||||
`IPL.bin` is not one of them: Dolphin loads it without a hash check.
|
||||
|
||||
Verification uses whichever one the platform itself uses: MD5 for Batocera,
|
||||
RetroBat, Recalbox, EmuDeck, RetroDECK, RomM, ROCKNIX, KNULLI, AmberELEC, EmuELEC
|
||||
and MiSTer FPGA, SHA1 for
|
||||
BizHawk, and nothing at all for RetroArch, Lakka and RetroPie, which only check
|
||||
that the file exists.
|
||||
|
||||
## Why does my verification report say UNTESTED?
|
||||
|
||||
`untested` means the file exists on disk but its hash does not match the expected value. This happens on MD5 and SHA1 platforms (Batocera, Recalbox, BizHawk, ROCKNIX, MiSTer FPGA, and the rest) when the file is present but contains different data than what the platform declares.
|
||||
|
||||
+42
-5
@@ -4,10 +4,13 @@ level: contribute
|
||||
|
||||
# Testing guide
|
||||
|
||||
The suite is discovered dynamically across focused modules, so its exact count
|
||||
is reported by the test runner instead of being hand-maintained here. Tests do
|
||||
not require network access. Most build synthetic fixtures under the repository's
|
||||
`tmp/`. Modules that read real artifacts skip cleanly when those inputs are absent.
|
||||
The tests hold what users and platforms rely on: a pack holds what its
|
||||
platform checks, the site states what the code does, the installer writes only
|
||||
where it should.
|
||||
|
||||
No test needs network access. Most build synthetic fixtures under the
|
||||
repository's `tmp/`, and modules that read real artifacts skip when those are
|
||||
absent. The test runner prints the count.
|
||||
|
||||
## Running tests
|
||||
|
||||
@@ -51,7 +54,7 @@ Every module in `tests/`, by the area it guards.
|
||||
| Handheld port | stubbed PortMaster dialogs, fake installer | `test_port` |
|
||||
| Truth and native export | synthetic + cached originals | `test_export_counts`, `test_export_native_layer`, `test_export_report`, `test_exporters`, `test_truth_data_dir_readers`, `test_truth_diff`, `test_truth_layout` |
|
||||
| Scrapers, upstream and provenance | inline sources, synthetic | `test_check_freshness`, `test_dedup`, `test_elec_scrapers`, `test_fbneo_parser`, `test_find_pinned_revision`, `test_hash_merge`, `test_launchers`, `test_launchers_emudeck`, `test_launchers_recalbox`, `test_launchers_retrobat`, `test_launchers_retrodeck`, `test_launchers_retropie`, `test_launchers_rocknix`, `test_mame_devices`, `test_mame_parser`, `test_mame_ref_audit`, `test_profile_sync`, `test_provenance`, `test_refresh_data_dirs`, `test_refresh_failures`, `test_refresh_stale`, `test_retrodeck_scraper_errors`, `test_romset_recipes`, `test_scraper_contract`, `test_upstream`, `test_upstream_index` |
|
||||
| Site, docs and repository contracts | rendered pages, sources | `test_contributing_text`, `test_coverage_cache`, `test_data_dir_refs`, `test_dataclass_defaults`, `test_doc_pages`, `test_doc_surfaces`, `test_optional_dependencies`, `test_prose_style`, `test_site_availability`, `test_site_cores`, `test_site_emulator_page`, `test_site_exports`, `test_site_funnel`, `test_site_images`, `test_site_platform_hashes`, `test_site_render`, `test_site_system_links`, `test_site_validation`, `test_site_weight`, `test_site_write`, `test_validate_pr`, `test_validate_pr_flow`, `test_validate_pr_hashes`, `test_workflow_paths` |
|
||||
| Site, docs and repository contracts | rendered pages, sources | `test_contributing_text`, `test_coverage_cache`, `test_data_dir_refs`, `test_dataclass_defaults`, `test_doc_pages`, `test_doc_surfaces`, `test_optional_dependencies`, `test_prose_style`, `test_site_availability`, `test_site_copy`, `test_site_cores`, `test_site_emulator_page`, `test_site_exports`, `test_site_funnel`, `test_site_images`, `test_site_platform_hashes`, `test_site_render`, `test_site_system_links`, `test_site_validation`, `test_site_weight`, `test_site_write`, `test_validate_pr`, `test_validate_pr_flow`, `test_validate_pr_hashes`, `test_workflow_paths` |
|
||||
|
||||
## Test architecture
|
||||
|
||||
@@ -325,6 +328,40 @@ what it is not. A reply on an issue or a pull request thanks once, gives the
|
||||
facts, describes the script or the file rather than the person, and leaves
|
||||
the door open.
|
||||
|
||||
### Pages for newcomers
|
||||
|
||||
The Start here pages and the guide part of each setup page are read by someone
|
||||
who knows nothing about BIOS files, often on a phone. Each word costs that
|
||||
reader attention, so `tests/test_site_copy.py` holds them to numbers measured
|
||||
on the generated pages in `docs/`, code blocks left out:
|
||||
|
||||
| Budget | Start here | Setup guide |
|
||||
|--------|-----------:|------------:|
|
||||
| Longest sentence | 20 words | 25 words |
|
||||
| Median sentence | 12 words | 14 words |
|
||||
| Longest paragraph, list item or definition | 35 words | 40 words |
|
||||
| Words before the first button or command | 50 (home page 40) | 90 |
|
||||
| Items in one list | 5 | 6 |
|
||||
| Heading | 8 words | 8 words |
|
||||
|
||||
Each Start here page has its own ceiling (home 220 words, FAQ 450), a setup
|
||||
guide 220 and the setup index 300. Of a group of tabs only the first counts
|
||||
toward a page's words, since a reader opens one. A folded block counts toward
|
||||
the words, not toward what comes before the first command.
|
||||
|
||||
The same test refuses filler ("simply", "just", "in order to", "this page",
|
||||
"what follows") and words a newcomer does not know yet, unless the sentence
|
||||
explains them: "Termux, a terminal app", "SSH, a terminal over the network",
|
||||
"its hash, a fingerprint of its contents". A word that needs more than that
|
||||
(manifest, libretro, revision, standalone) belongs one level down, behind a
|
||||
link labelled with that level ("Details:", "Reference:"). On Start here pages
|
||||
a pack is a ZIP and a platform is a setup.
|
||||
|
||||
The reasons: a reader holds about four things at once, scans more than reads,
|
||||
and reads less on a phone. Facts a newcomer does not act on (legal analysis,
|
||||
source lines, annotated runs) are kept, on the page one level down. To see
|
||||
the numbers of every page, run `python -m tests.test_site_copy --report docs`.
|
||||
|
||||
## Landing a change
|
||||
|
||||
A commit subject is English, 50 characters at most, `type: description` with a
|
||||
|
||||
+43
-222
@@ -4,259 +4,80 @@ level: start
|
||||
|
||||
# When a game does not start
|
||||
|
||||
Start here when a game does not start, or says that a BIOS file is missing.
|
||||
Each section is one check, in the order that finds the cause soonest.
|
||||
Most of the time, a BIOS file is missing or is the wrong version. Three checks
|
||||
find it.
|
||||
|
||||
## Game won't start / black screen
|
||||
## 1. Check your BIOS folder { #checking-what-you-installed }
|
||||
|
||||
Most launch failures are caused by a missing or incorrect BIOS file.
|
||||
<span id="game-wont-start-black-screen"></span>
|
||||
|
||||
### Check what is in your BIOS folder
|
||||
Run the command with `--check`. It changes nothing.
|
||||
|
||||
```bash
|
||||
```sh
|
||||
curl -fsSL https://raw.githubusercontent.com/Abdess/retrobios/main/install.sh | sh -s -- --check
|
||||
```
|
||||
|
||||
It hashes what is there and writes nothing. Anything counted as needing
|
||||
downloading is absent, and a required file that is absent means the core cannot
|
||||
start games for that system at all. `--system` narrows the check to one
|
||||
system (`--list-systems` names them):
|
||||
|
||||
```bash
|
||||
curl -fsSL https://raw.githubusercontent.com/Abdess/retrobios/main/install.sh | sh -s -- --check --system sony-playstation --verbose
|
||||
```
|
||||
|
||||
### Check if the hash matches
|
||||
|
||||
The count `--check` prints says how many files are present with contents the
|
||||
platform does not accept:
|
||||
Read the count line:
|
||||
|
||||
```
|
||||
Checking existing files...
|
||||
1/109 present (0 verified, 1 wrong hash)
|
||||
```
|
||||
|
||||
With `--verbose` the list under it names each one (`wrong hash: scph5501.bin`).
|
||||
The check hashes every file, on RetroArch too, where the frontend itself only
|
||||
looks for the name. Common causes:
|
||||
- **`wrong hash`**: a file is there, but its contents are wrong. It may be for
|
||||
another region or model, or damaged.
|
||||
- **Fewer present than the total**: some files are missing.
|
||||
- **`0 wrong hash` and all present**: your files are fine. Go to step 3.
|
||||
|
||||
- Wrong region (a PAL BIOS instead of NTSC, or vice versa)
|
||||
- Wrong hardware revision (e.g. SCPH-5501 vs SCPH-1001 for PlayStation)
|
||||
- Corrupted download
|
||||
## 2. Fix the files
|
||||
|
||||
Running the same command without `--check` replaces each file with a wrong
|
||||
hash by a verified copy, and keeps yours in `retrobios-backup` beside the BIOS
|
||||
folder (Details: [putting it back](installer.md#files-you-already-had)). Each system page on the site also lists the expected
|
||||
hashes, to compare against your file's MD5 or SHA1 by hand.
|
||||
Run the same command without `--check`. It adds the missing files and replaces
|
||||
the wrong ones. It keeps the old ones in `retrobios-backup`, beside your BIOS
|
||||
folder.
|
||||
|
||||
### Wrong region BIOS
|
||||
## 3. Check the folder and the names
|
||||
|
||||
Some cores require region-specific BIOS files. A Japanese BIOS won't boot
|
||||
North American games on cores that enforce region matching. Check the emulator
|
||||
profile for your core to see which regions are supported and which files
|
||||
correspond to each.
|
||||
- **Right folder?** Your emulator must read the folder the command used.
|
||||
[Your setup's page](../which-pack.md) names it.
|
||||
- **Is the name exact?** `scph5501.bin` and `SCPH-5501.BIN` are two different
|
||||
names. On Linux, capital letters count too.
|
||||
- **Unzipped by hand on Linux?** Use the command. Some emulators there need a
|
||||
lower-case name the ZIP lacks.
|
||||
- **A ZIP in parts will not open?** Download every part, like
|
||||
`Pack.part1of2.zip` and `Pack.part2of2.zip`. Unzip each one into the same
|
||||
folder.
|
||||
|
||||
## Checking what you installed
|
||||
## One console only
|
||||
|
||||
`--check` reads the BIOS folder, hashes what is there and writes nothing:
|
||||
Add `--system` and its name:
|
||||
|
||||
```bash
|
||||
curl -fsSL https://raw.githubusercontent.com/Abdess/retrobios/main/install.sh | sh -s -- --check
|
||||
```sh
|
||||
curl -fsSL https://raw.githubusercontent.com/Abdess/retrobios/main/install.sh | sh -s -- --check --system sony-playstation --verbose
|
||||
```
|
||||
|
||||
It ends on a count:
|
||||
`--verbose` names each missing or wrong file. `--list-systems` shows every
|
||||
console name.
|
||||
|
||||
```
|
||||
Checking existing files...
|
||||
5865/5865 present (5865 verified, 0 wrong hash)
|
||||
## My setup says UNTESTED
|
||||
|
||||
All files up to date.
|
||||
```
|
||||
Batocera shows `UNTESTED` for a file whose contents it does not expect. Run
|
||||
the command without `--check` to replace it.
|
||||
|
||||
`0 wrong hash` is the line that matters. A number there means a file is present
|
||||
whose contents the platform will reject, which is how a wrong revision or a bad
|
||||
dump shows up.
|
||||
## If the command fails { #installation-script-fails }
|
||||
|
||||
The installer's `--check` hashes every file against the list on every
|
||||
platform, so it catches a wrong revision even where the frontend would not:
|
||||
RetroArch, Lakka, RetroPie, MinUI, NextUI and MyMinUI only check that a file
|
||||
exists, while Batocera, RetroBat, Recalbox, EmuDeck, RetroDECK, RomM, ROCKNIX,
|
||||
KNULLI, AmberELEC, EmuELEC and MiSTer FPGA compare
|
||||
MD5 and BizHawk compares SHA1.
|
||||
- **Network error:** check that github.com opens, then try again.
|
||||
- **Permission denied:** on Batocera, Recalbox and ROCKNIX, put `sudo` and a
|
||||
space before the command. It then runs as the administrator.
|
||||
- **No setup found:** name it yourself, with your BIOS folder:
|
||||
|
||||
For a single system, or the files a single emulator core reads (`--list-systems`
|
||||
and `--list-cores` give the names):
|
||||
|
||||
```bash
|
||||
curl -fsSL https://raw.githubusercontent.com/Abdess/retrobios/main/install.sh | sh -s -- --check --system sony-playstation
|
||||
curl -fsSL https://raw.githubusercontent.com/Abdess/retrobios/main/install.sh | sh -s -- --check --emulator beetle_psx
|
||||
```
|
||||
|
||||
`--verbose` names every file still to fetch, wrong hashes included.
|
||||
Details: [All installer options](installer.md).
|
||||
|
||||
## BIOS not found by emulator
|
||||
|
||||
The file exists on disk, but the emulator reports it as missing.
|
||||
|
||||
### Wrong directory
|
||||
|
||||
Each platform expects BIOS files in a specific base directory:
|
||||
|
||||
- RetroArch: `system/` inside the RetroArch directory
|
||||
- Lakka: `/storage/system/`
|
||||
- Batocera: `/userdata/bios/`
|
||||
- Recalbox: `/recalbox/share/bios/`
|
||||
- RetroPie: `~/RetroPie/BIOS/`
|
||||
- ROCKNIX: `/storage/roms/bios/`
|
||||
- KNULLI: `/userdata/bios/`
|
||||
- AmberELEC and EmuELEC: `/storage/roms/` (the pack holds `bios/` and the other folders their lists name)
|
||||
- MiSTer FPGA: `/media/fat/games/`
|
||||
- BizHawk: `Firmware/` inside the BizHawk directory
|
||||
- EmuDeck: `~/Emulation/bios/`
|
||||
- RetroDECK: `~/retrodeck/bios/`
|
||||
- RetroBat: `bios/` inside the RetroBat directory
|
||||
- MinUI, NextUI, MyMinUI: `Bios/<TAG>/` at the root of the SD card, one folder
|
||||
per tag in parentheses of the Roms folders (`Bios/PS/` for
|
||||
`Roms/Sony PlayStation (PS)/`)
|
||||
|
||||
Some cores expect files in subdirectories (e.g. `dc/` for Dreamcast, `pcsx2/bios/`
|
||||
for PlayStation 2). Check the `path:` field in the emulator profile for the exact
|
||||
expected location relative to the base directory.
|
||||
|
||||
### Wrong filename
|
||||
|
||||
Cores match BIOS files by exact filename. If a core expects `scph5501.bin` and your
|
||||
file is named `SCPH-5501.BIN`, it won't be found on platforms that do exact name matching.
|
||||
|
||||
Check the emulator profile for the expected filename and any aliases listed under
|
||||
`aliases:`. Aliases are alternative names that the core also accepts.
|
||||
|
||||
### Case sensitivity
|
||||
|
||||
Linux filesystems are case-sensitive. A file named `Bios.ROM` won't match a lookup
|
||||
for `bios.rom`. Windows and macOS are case-insensitive by default, so the same
|
||||
file works there but fails on Linux.
|
||||
|
||||
Batocera's verification uses `casefold()` for case-insensitive matching, but
|
||||
the actual emulator may still require exact case. When in doubt, use the exact
|
||||
filename from the emulator profile.
|
||||
|
||||
The RetroArch pack is built for every system RetroArch runs on, so it holds one
|
||||
name per file: `BIOS.col`, never `bios.col` beside it, since extracting both on
|
||||
Windows or macOS would overwrite one with the other. On Linux, Mesen-CE opens
|
||||
`bios.col` and NP2kai opens the lowercase `np2kai/2608_*.wav`, which the pack
|
||||
only holds as `BIOS.col` and `2608_*.WAV`. The installer checks whether the
|
||||
BIOS directory keeps case and, if it does, also fetches these names. On Linux, use the installer
|
||||
rather than extracting the ZIP by hand.
|
||||
|
||||
The reverse happens on Batocera and Recalbox, whose lists hold both spellings
|
||||
because their systems keep case: NP2kai reads `np2kai/bios.rom` and
|
||||
`np2kai/BIOS.ROM` as two different files. Written to a folder that folds case
|
||||
(the share opened from Windows, an exFAT card), one overwrites the other. The
|
||||
installer checks the folder first, keeps one file per name there and lists
|
||||
the ones it left out.
|
||||
|
||||
## Installation script fails
|
||||
|
||||
Problems with `install.py`, `install.sh`, or `download.sh`.
|
||||
|
||||
### Network issues
|
||||
|
||||
The installer fetches its manifest, then downloads only the repository or
|
||||
`large-files` release objects it needs. If a download fails:
|
||||
|
||||
- Check your internet connection
|
||||
- Verify that `https://github.com` is reachable
|
||||
- If behind a proxy, set `HTTPS_PROXY` in your environment
|
||||
- Try again later if GitHub is experiencing issues
|
||||
|
||||
### Permission denied
|
||||
|
||||
The installer needs write access to the target directory.
|
||||
|
||||
- On Linux/macOS: check directory ownership (`ls -la`) and run with appropriate
|
||||
permissions. Avoid running as root unless the target directory requires it.
|
||||
- On Windows: run PowerShell as Administrator if installing to a protected directory.
|
||||
- A file system mounted read-only refuses root too, so the installer does not
|
||||
suggest sudo for it. Linux remounts a card or drive read-only after an error
|
||||
(an unclean removal, for one): check it (`fsck`, or `chkdsk` on Windows) and
|
||||
mount it read-write again.
|
||||
|
||||
A file already in the BIOS folder with the read-only attribute is replaced
|
||||
like any other: on Windows the installer clears the attribute before putting
|
||||
the verified copy in place. `file in place is read-only` only appears when
|
||||
Windows refuses that too, which a file owned by another account can cause.
|
||||
|
||||
### Platform not detected
|
||||
|
||||
The installer finds your platform from the config files it knows. If it finds
|
||||
none, name the platform and its BIOS folder.
|
||||
|
||||
Linux, macOS, Android (Termux):
|
||||
|
||||
```bash
|
||||
```sh
|
||||
curl -fsSL https://raw.githubusercontent.com/Abdess/retrobios/main/install.sh | sh -s -- --platform retroarch --dest ~/.config/retroarch/system
|
||||
curl -fsSL https://raw.githubusercontent.com/Abdess/retrobios/main/install.sh | sh -s -- --platform batocera --dest /userdata/bios
|
||||
```
|
||||
|
||||
Windows (PowerShell):
|
||||
|
||||
```powershell
|
||||
&([scriptblock]::Create((irm https://raw.githubusercontent.com/Abdess/retrobios/main/install.ps1))) `
|
||||
--platform retroarch --dest C:\RetroArch-Win64\system
|
||||
```
|
||||
|
||||
`--list-platforms` lists the platforms the installer knows and the ones it
|
||||
finds here, and `--help` lists the options with examples.
|
||||
|
||||
### Manifest or file not found
|
||||
|
||||
The one-line bootstrap verifies the downloaded installer before running it, and
|
||||
the installer reads its manifests from the same revision. A platform name is
|
||||
checked before anything is downloaded, so a "No file list" message comes from
|
||||
the revision: `RETROBIOS_REF` naming a tag that does not exist, or one older
|
||||
than the platform. Unset it, or pick a tag from the releases page. What a tag
|
||||
holds and for how long is under
|
||||
Details: [environment overrides](installer.md#environment-overrides).
|
||||
|
||||
### Manual pack not found in release
|
||||
|
||||
If the installer reports that no pack exists for your platform, check available
|
||||
releases:
|
||||
|
||||
```bash
|
||||
python scripts/download.py --list
|
||||
# or
|
||||
bash scripts/download.sh --list
|
||||
```
|
||||
|
||||
A pack's name lists every platform it serves. Releases up to v2026.10.10
|
||||
ship RetroArch and Lakka as one `RetroArch_Lakka` pack, and the next ones give
|
||||
Lakka its own, since Lakka runs on Linux where two names that differ by case
|
||||
are two files. The installer and the download scripts find the right pack
|
||||
either way.
|
||||
|
||||
### A pack in several parts will not extract
|
||||
|
||||
Parts named `Pack.part1of2.zip` are ordinary ZIPs: extract each one into the
|
||||
same folder, and check that all of them were downloaded, the name says how
|
||||
many there are.
|
||||
|
||||
`scripts/download.sh` and `scripts/download.py` download every part and check
|
||||
it against the release's checksums before extracting. Both stage inside the
|
||||
destination directory, never in `/tmp`, which is a RAM disk on most of these
|
||||
systems.
|
||||
## Checks of the collection itself
|
||||
Other messages: Details: [When something goes wrong](installer.md#when-something-goes-wrong).
|
||||
|
||||
<span id="hash-mismatch-untested"></span><span id="pack-is-missing-files"></span><span id="verifypy-reports-errors"></span>
|
||||
|
||||
`scripts/verify.py` checks this project's own collection against each
|
||||
platform, from a clone of the repository. It never reads your BIOS folder.
|
||||
Reference: [Reading verify.py output](verification-modes.md#hash-mismatch-untested).
|
||||
|
||||
!!! tip "Next"
|
||||
|
||||
- The page of your setup, from [Get your files](../which-pack.md): its folder
|
||||
and how to check it
|
||||
- [FAQ](faq.md), for the questions people ask before installing
|
||||
- [Your setup's page](../which-pack.md): its folder and how it checks files
|
||||
- [FAQ](faq.md)
|
||||
+48
-24
@@ -4,8 +4,22 @@ level: reference
|
||||
|
||||
# How each platform checks files
|
||||
|
||||
Each platform verifies BIOS files differently. `verify.py` replicates the native behavior
|
||||
of each platform so that verification results match what the platform itself would report.
|
||||
Before a game starts, your setup may check its BIOS files, and each setup checks
|
||||
differently. RetroArch only asks whether a file with the right name is in the
|
||||
folder. Batocera computes the file's MD5 fingerprint and compares it with its
|
||||
list, so a renamed or wrong-region file shows as `UNTESTED`: present, but not
|
||||
the expected file. BizHawk does the same with SHA1. The way a setup checks
|
||||
decides what "OK" means there: a file RetroArch accepts can still be one
|
||||
Batocera reports.
|
||||
|
||||
Example: `scph5501.bin`, MD5 `490f666e1afb15b7362b406ed1cea246`. Any file named
|
||||
`scph5501.bin` passes on RetroArch. On Batocera only those exact bytes pass.
|
||||
|
||||
This project's `verify.py` reproduces each setup's own check, so its report
|
||||
says what the setup itself would say. A missing file is then ranked by
|
||||
**severity**: CRITICAL when the setup cannot start that console, WARNING when
|
||||
it runs degraded or the file's version is in doubt, INFO when nothing visible
|
||||
changes ([severity matrix](#severity-matrix)).
|
||||
|
||||
<!-- image: verification-modes -->
|
||||
|
||||
@@ -15,8 +29,8 @@ of each platform so that verification results match what the platform itself wou
|
||||
|
||||
**Source**: RetroArch `core_info.c`, function `path_is_valid()`; minarch for the MinUI family
|
||||
|
||||
The most straightforward mode. A file is OK if it exists at the expected path. No hash is checked.
|
||||
Any file with the correct name passes, regardless of content.
|
||||
A file is OK if it exists at the expected path. No hash is checked. Any file
|
||||
with the correct name passes, regardless of content.
|
||||
|
||||
| Condition | Status | Severity (required) | Severity (optional) |
|
||||
|-----------|--------|---------------------|---------------------|
|
||||
@@ -24,15 +38,15 @@ Any file with the correct name passes, regardless of content.
|
||||
| File missing | MISSING | WARNING | INFO |
|
||||
|
||||
RetroArch does not distinguish between a correct and an incorrect BIOS at the verification
|
||||
level. A corrupt or wrong-region file still shows as present. This is by design in the
|
||||
upstream code: `core_info.c` only calls `path_is_valid()` and does not open or hash the file.
|
||||
level. A corrupt or wrong-region file still shows as present: RetroArch's
|
||||
`core_info.c` only calls `path_is_valid()` and does not open or hash the file.
|
||||
|
||||
Lakka and RetroPie inherit this behavior through platform config inheritance
|
||||
(`inherits: retroarch` in the platform YAML).
|
||||
|
||||
MinUI, NextUI and MyMinUI check nothing at all: minarch returns the folder
|
||||
`Bios/<TAG>/` for `RETRO_ENVIRONMENT_GET_SYSTEM_DIRECTORY` and never opens a
|
||||
file in it (MinUI `workspace/all/minarch/minarch.c:1889-1893` and `:2943`). The
|
||||
MinUI, NextUI and MyMinUI check nothing at all. They hand each core its own
|
||||
folder, `Bios/<TAG>/`, and open nothing in it: minarch answers
|
||||
`RETRO_ENVIRONMENT_GET_SYSTEM_DIRECTORY` with that folder (MinUI `workspace/all/minarch/minarch.c:1889-1893` and `:2943`). The
|
||||
core decides what it loads, so the files are the ones its profile documents,
|
||||
placed below each folder a pak hands it (`core_system_dirs` in the platform
|
||||
YAML).
|
||||
@@ -56,8 +70,9 @@ hashed with MD5, and compared case-insensitively against the expected value.
|
||||
| File present, hash differs | UNTESTED | WARNING | WARNING |
|
||||
| File missing | MISSING | CRITICAL | WARNING |
|
||||
|
||||
If the `resolve_local_file` step already confirmed the MD5 match (status `md5_exact`),
|
||||
`verify.py` skips re-hashing and returns OK directly.
|
||||
If finding the file already confirmed the MD5 match (status `md5_exact` of the
|
||||
[file resolution chain](#file-resolution-chain)), `verify.py` skips re-hashing
|
||||
and returns OK directly.
|
||||
|
||||
### MD5 shorter than 32 characters (Batocera)
|
||||
|
||||
@@ -381,8 +396,10 @@ A local file that contradicts a declared hash is handled by the platform's
|
||||
own mode, never by one global rule. An existence frontend never reads the
|
||||
bytes, so the file is packed and the difference reported: a hash in System.dat
|
||||
that differs from the local dump must not remove a file RetroArch would have
|
||||
loaded. An md5 or sha1 frontend would reject it, so it is left out of the pack
|
||||
and counted as `unsafe excluded`, which is distinct from `missing`. The pack
|
||||
loaded. An md5 or sha1 frontend would report it as not the expected file
|
||||
(Batocera's `checkBios` marks it `UNTESTED`), so it is left out of the pack
|
||||
and counted as `unsafe excluded`, left out because the platform would not
|
||||
accept it, which is distinct from `missing`. The pack
|
||||
report and the installer manifest both record it. The pack builder and the
|
||||
pack verification apply the same rule.
|
||||
|
||||
@@ -401,22 +418,29 @@ pack, verify and the install manifest all read it, so they name the same file.
|
||||
the emulator declares, which finds a dump stored under another name, then
|
||||
from the files sharing the name, `.variants/` included, in a stable order.
|
||||
On a md5 or sha1 platform a candidate must also carry a value the platform
|
||||
entry declares, or the frontend would refuse it.
|
||||
entry declares, or the frontend's own check would not accept it.
|
||||
4. When only a warning-level check fails (`on_mismatch: warn`), the file
|
||||
itself stands: the core runs it.
|
||||
5. Then a held file the core at least runs.
|
||||
6. Failing all of these, the platform-verified file is kept and the
|
||||
disagreement is reported ("<core> says ..."), never as compatible.
|
||||
|
||||
### Practical example
|
||||
### Worked example
|
||||
|
||||
A `scph5501.bin` file passes Batocera MD5 verification (hash matches upstream
|
||||
declaration) but fails an emulator profile's size check because the profile
|
||||
was verified against a different revision. The search looks for a held file
|
||||
carrying a Batocera-accepted md5 that also passes the size check, under that
|
||||
name or any name the emulator's hashes reach. If found, it ships. If not, the
|
||||
Batocera-verified file ships and the discrepancy stays visible in verification
|
||||
and gap reporting.
|
||||
RetroBat lists `dragon/d64_1.rom` with MD5 `5f0bee59710e55f5880e74890912ed78`
|
||||
(`platforms/retrobat.yml`). The collection holds that dump, CRC32 `60a4634c`,
|
||||
and RetroBat's check passes. XRoar, which RetroBat runs for the Dragon, checks
|
||||
the CRC32 of the same file and accepts `84f68bf9` only. The collection holds a
|
||||
dump with that CRC32 too (`bios/Dragon/Dragon/d64_1.rom`), but its MD5 is
|
||||
`be9bc86ee5eb401d0a40d0377f65fefa`, not the one RetroBat lists, so RetroBat
|
||||
would not accept it at that path (step 3). The RetroBat file ships, and the
|
||||
[gaps page](../gaps.md) lists the discrepancy with the dump XRoar accepts.
|
||||
|
||||
## Reading this project's own reports
|
||||
|
||||
The sections below are about `verify.py` run on a clone of the repository.
|
||||
Your own BIOS folder is checked with the installer's `--check`
|
||||
([When a game does not start](troubleshooting.md)).
|
||||
|
||||
## Hash mismatch / UNTESTED
|
||||
|
||||
@@ -449,8 +473,8 @@ dumps), the primary version lives in the main directory and alternatives live in
|
||||
`.variants/`. `verify.py` checks the primary file first, then falls back to
|
||||
variants when resolving by hash.
|
||||
|
||||
If your file matches a variant hash but not the primary, it's a valid BIOS --
|
||||
just not the preferred version. Some cores accept multiple versions.
|
||||
A file that matches a variant hash but not the primary works. It is not the
|
||||
version the emulator tries first, and some cores accept several versions.
|
||||
|
||||
## Pack is missing files
|
||||
|
||||
|
||||
+35
-48
@@ -2,75 +2,62 @@
|
||||
level: start
|
||||
---
|
||||
|
||||
# What BIOS files are
|
||||
# What is a BIOS?
|
||||
|
||||
Many consoles have a small program built into them. It runs when the console
|
||||
is switched on, sets up the hardware and then starts the game. That program is
|
||||
called the BIOS, or the firmware.
|
||||
A console has a small program inside it. It starts first, then starts the game.
|
||||
This program is the **BIOS**, also called **firmware**.
|
||||
|
||||
An emulator recreates a console in software. To start the games of many
|
||||
consoles, it needs a copy of that built-in program. The copy is a file, and
|
||||
that file is what people call a BIOS file.
|
||||
[Get your files](../which-pack.md){ .md-button .md-button--primary }
|
||||
|
||||
An **emulator** is an app that acts like a console. For many consoles, it needs
|
||||
a copy of the BIOS. That copy is a file: a **BIOS file**.
|
||||
|
||||
<!-- image: bios-chain -->
|
||||
|
||||
## How the pieces fit together
|
||||
## How it works
|
||||
|
||||
1. You pick a game in the **frontend**, the menu you play from (EmulationStation,
|
||||
the RetroArch menu, MinUI and others).
|
||||
2. The frontend starts an **emulator** for that console.
|
||||
3. The emulator reads the **BIOS file** from the **BIOS folder** of your setup.
|
||||
1. You pick a game in your game menu.
|
||||
2. The menu starts the emulator.
|
||||
3. The emulator opens the BIOS file in your **BIOS folder**.
|
||||
4. The game starts.
|
||||
|
||||
When the file is not in the folder, or is not the version the emulator expects,
|
||||
step 3 fails. The emulator then says that a BIOS is missing, or the game stays
|
||||
on a black screen.
|
||||
If step 3 fails, you see "BIOS missing" or a black screen.
|
||||
|
||||
## Do I need them?
|
||||
## Do I need one?
|
||||
|
||||
It depends on the console.
|
||||
- **Yes:** PlayStation 1 and 2, Saturn, Dreamcast, Neo Geo, PC Engine CD and
|
||||
many home computers.
|
||||
- **Usually not:** NES, Super Nintendo, Mega Drive, Game Boy and Game Boy
|
||||
Advance.
|
||||
- **Add-ons need their own:** the Famicom Disk System and the Mega-CD.
|
||||
|
||||
- **Usually yes** for consoles that start every game through their own
|
||||
program: PlayStation, PlayStation 2, Saturn, Mega-CD, PC Engine CD, Neo Geo,
|
||||
Dreamcast, and many home computers.
|
||||
- **Usually not** for cartridge consoles such as the NES, the Super Nintendo,
|
||||
the Mega Drive, the Game Boy and the Game Boy Advance. Their emulators start
|
||||
the games without one. Some can use one to show the original start-up screen.
|
||||
- **Add-ons need their own**, even on those consoles: the Famicom Disk System
|
||||
and the Mega-CD each have a BIOS.
|
||||
Details: [Every console, one by one](../systems/index.md)
|
||||
|
||||
Some emulators can stand in for the BIOS with code of their own. This is called
|
||||
HLE, for high-level emulation. It works for many games, but some glitch or do
|
||||
not start. The real file gives the best results, so the packs include it.
|
||||
## The name must match
|
||||
|
||||
Details: [the files each console needs](../systems/index.md), with the
|
||||
emulators that read them.
|
||||
An emulator looks for one exact name. A PlayStation emulator looks for
|
||||
`scph5501.bin`. A file with another name is not found.
|
||||
|
||||
## Where they go
|
||||
## The version must match
|
||||
|
||||
Each setup keeps its BIOS files in a folder of its own: `system` for RetroArch,
|
||||
`/userdata/bios` on Batocera, `Emulation/bios` with EmuDeck. The page of your
|
||||
setup gives the exact folder.
|
||||
Two files can have the same name and different contents. One may be for Japan,
|
||||
another for Europe.
|
||||
|
||||
The name matters. An emulator looks for an exact name, such as `scph5501.bin`
|
||||
for a PlayStation, and a file with another name is not found.
|
||||
Some setups check each file's **hash**, a fingerprint of its contents.
|
||||
Batocera, Recalbox and EmuDeck report a version they do not expect.
|
||||
|
||||
## Why the right version matters
|
||||
Our files are the versions each setup expects.
|
||||
|
||||
Two files with the same name can hold different versions: one per region, or
|
||||
a newer revision of the same chip. Some setups, among them Batocera, Recalbox
|
||||
and EmuDeck, compare a fingerprint of the file's contents, called a hash, and
|
||||
refuse a version they do not list. RetroBIOS gives each setup the versions it
|
||||
expects.
|
||||
## Can a game start without it?
|
||||
|
||||
Sometimes. Some emulators carry their own code in place of the BIOS. Some games
|
||||
then glitch or do not start. The real file works best, so we include it.
|
||||
|
||||
## Is it legal?
|
||||
|
||||
Laws on copying console firmware differ by country, and the question is not
|
||||
settled. The [project's position](faq.md#is-this-legal) explains where it
|
||||
stands, where its arguments are weakest, and how to ask for a file to be
|
||||
removed.
|
||||
Laws differ by country. [Read the project's position](faq.md#is-this-legal).
|
||||
|
||||
!!! tip "Next"
|
||||
|
||||
- [Get your files](../which-pack.md), for the setup you play on
|
||||
- [Glossary](glossary.md), every word these pages use
|
||||
- [Get your files](../which-pack.md)
|
||||
- [Words used on this site](glossary.md)
|
||||
Reference in new issue
Block a user