docs: rework wiki copy

# Conflicts:
#	tests/test_site_funnel.py
#	wiki/testing-guide.md
This commit is contained in:
Abdessamad Derraz committed 2026-10-23 02:42:58 +02:00
commit d1dd7ef0f5
28 files changed
+1046 -443

No files matched your search

+2 -2
View File
@@ -1,6 +1,6 @@
---
level: reference
order: 100
level: contribute
order: 80
---
# Build your own packs
+2 -2
View File
@@ -1,6 +1,6 @@
---
level: reference
order: 90
level: contribute
order: 60
---
# Architecture
+1
View File
@@ -1,6 +1,7 @@
---
level: reference
order: 140
group: Data
---
# Projects using this data
+46 -50
View File
@@ -1,10 +1,9 @@
---
level: start
order: 50
nav_title: Common questions
---
# FAQ
# Common questions
## Do I need BIOS files?
@@ -14,36 +13,55 @@ many home computers. For NES or Super Nintendo cartridges, usually not.
## How do I know which BIOS I need?
Run the installer with `--dry-run`. It lists what it would install and changes
Run the command with `--dry-run`. It lists what it would install and changes
nothing.
<!-- os-tabs -->
```sh
curl -fsSL https://raw.githubusercontent.com/Abdess/retrobios/main/install.sh | sh -s -- --dry-run
```
Your setup's page also lists every file, console by console.
Your setup's page lists every file.
## Do I need every file of a console?
No. A console often has one BIOS per region. The ZIP holds them all. To keep
only yours, add your region, like `--region us`.
## Zip or unzip? { #zip-or-unzip }
Unzip the ZIP you downloaded once, into the folder your setup's page names.
Leave the ZIP files inside it as they are, like `neogeo.zip`. Arcade emulators
read them zipped.
## Does a BIOS work on every setup?
The same file usually works everywhere. Some setups also check the version and
report one they do not expect. Arcade files like `neogeo.zip` change with the
emulator. The command installs the version your setup expects.
## Can I play without the BIOS?
Sometimes. Some emulators carry a stand-in for it. Some games then glitch or
do not start.
## Is the command 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.
To read the script before you run it:
```sh
curl -fsSL https://raw.githubusercontent.com/Abdess/retrobios/main/install.sh -o install.sh
less install.sh && sh install.sh
```
- It checks the installer's fingerprint first. If it does not match its expected
fingerprint, it stops.
- It checks each file before saving it.
- It writes in your BIOS folder. For some emulators it also adds files to your
save folder.
- It never changes or deletes a game or a save.
- It keeps any file it replaces in a `retrobios-backup` folder, next to your
BIOS folder. `--restore` puts it back
([details](installer.md#files-you-already-had)).
Read the script first: [install.sh](https://github.com/Abdess/retrobios/blob/main/install.sh),
[install.ps1](https://github.com/Abdess/retrobios/blob/main/install.ps1) and
[install.py](https://github.com/Abdess/retrobios/blob/main/install.py).
Details: [How the installer checks itself](installer.md#what-the-bootstrap-does).
## Will it change my other files?
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.
## Windows or my antivirus blocks the command
Download the ZIP of your setup instead, from [Get your files](../which-pack.md).
@@ -51,35 +69,22 @@ It holds the same files.
## Can I run it again?
Yes. That is how you update. It downloads only what is missing or wrong.
## Can I undo it?
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.
Details: [Files you already had](installer.md#files-you-already-had).
Yes, to update. It downloads only what is missing or wrong.
## Fill an SD card from a computer?
Yes. Name your setup and the BIOS folder on the card:
Yes. Name your setup and the BIOS folder on the card. On Windows, `E:` stands
for the card.
<!-- os-tabs windows: --platform retroarch --dest E:\retroarch\cores\system -->
```sh
curl -fsSL https://raw.githubusercontent.com/Abdess/retrobios/main/install.sh \
| sh -s -- --platform retroarch --dest /path/to/sdcard/retroarch/cores/system
```
On Windows the line is different. Details: [Passing options](installer.md#passing-options).
## Does a BIOS work on every setup?
Yes. Only the folder changes, and sometimes the name.
## Why is a file missing from the ZIP?
Some files come with the emulator when you install it. The ZIP leaves those
out.
Some files come with the emulator. The ZIP leaves those out.
## Required or optional?
@@ -93,19 +98,10 @@ Most of the time, a BIOS file is missing or is the wrong version.
## Is this legal?
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).
Laws differ by country, and nothing here is legal advice. Details, and how to
ask for a file to be removed: [Is it legal?](legal.md)
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.
## Next steps
## Why keep recent consoles too?
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)
- [Words used on this site](glossary.md)
:::
+39 -34
View File
@@ -1,10 +1,9 @@
---
level: start
order: 30
nav_title: First install, step by step
---
# First install
# First install, step by step
From an empty BIOS folder to games that start.
@@ -20,34 +19,43 @@ system, then press Enter.
Open the Start menu. Type **PowerShell** and open it.
```powershell
```powershell title="PowerShell"
irm https://raw.githubusercontent.com/Abdess/retrobios/main/install.ps1 | iex
```
</TabItem>
<TabItem label="Mac">
<TabItem label="macOS">
Open **Terminal**. It is in Applications, then Utilities.
```sh
```sh title="Terminal"
curl -fsSL https://raw.githubusercontent.com/Abdess/retrobios/main/install.sh | sh
```
</TabItem>
<TabItem label="Linux and Steam Deck">
<TabItem label="Linux">
On a Steam Deck, switch to Desktop Mode and open **Konsole**.
Open a terminal.
```sh
```sh title="Terminal"
curl -fsSL https://raw.githubusercontent.com/Abdess/retrobios/main/install.sh | sh
```
</TabItem>
<TabItem label="Android">
<TabItem label="Steam Deck">
Switch to Desktop Mode and open **Konsole**.
```sh title="Terminal"
curl -fsSL https://raw.githubusercontent.com/Abdess/retrobios/main/install.sh | sh
```
</TabItem>
<TabItem label="Android (Termux)">
Install **Termux**, a terminal app. Run these three lines in it.
```sh
```sh title="Terminal"
pkg install python
termux-setup-storage
curl -fsSL https://raw.githubusercontent.com/Abdess/retrobios/main/install.sh | sh
@@ -56,22 +64,20 @@ curl -fsSL https://raw.githubusercontent.com/Abdess/retrobios/main/install.sh |
</TabItem>
</Tabs>
On Batocera, Recalbox and other game systems, follow
On Batocera, Recalbox and similar setups, follow
[your setup's page](../which-pack.md).
<!-- image: install-flow -->
## 2. Check the folder it found
It shows your setup and its BIOS folder:
```
Found Batocera at /userdata/bios
Found <your setup> at <its folder>
```
- **Right folder?** Go on.
- **Wrong folder?** Press Ctrl+C to stop. Then see [If it stops](#if-it-stops).
- **Wrong folder?** Press Ctrl+C. Run the command again with `--dest` and your
folder.
## 3. Choose what to install
@@ -86,22 +92,25 @@ It shows your setup and its BIOS folder:
## 4. Wait
It shows one line per file. You can stop with Ctrl+C at any time. Run the
command again to carry on.
You can stop with Ctrl+C at any time. Run the command again to carry on.
## 5. Look for "Done."
## 5. Read the last line
```
Done. 14481 files installed, 0 files already up to date.
Location: /userdata/bios
```
- **`Done.`** All files are in place.
- **`Finished with errors.`** Some files failed. Run the same command again.
It retries only those.
- **`Nothing was installed.`** The lines above it say why. See
[If it stops](#if-it-stops).
`Done.` means it worked. It may list files it could not install.
## What the command does
<!-- image: install-flow -->
## Check it later
Add `--check` to the same command. It changes nothing.
<!-- os-tabs -->
```sh
curl -fsSL https://raw.githubusercontent.com/Abdess/retrobios/main/install.sh | sh -s -- --check
```
@@ -110,11 +119,8 @@ All good when you see `0 wrong hash`.
## Undo
It keeps every file it replaces in a `retrobios-backup` folder, beside your
BIOS folder. Nothing is deleted.
To put your files back, run the command with `--restore` and that folder. The
end of the run prints the exact line.
It keeps every file it replaces in a `retrobios-backup` folder, next to your
BIOS folder. The end of the run prints the line that puts them back.
## If it stops
@@ -141,8 +147,8 @@ The download was cut short. Nothing was changed. Run the command again.
### Cannot create ...
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.
You do not have the right to write there. Do what the message says. It names
what to run.
### Not enough space on the drive holding ...
@@ -153,9 +159,8 @@ drive.
See [When a game does not start](troubleshooting.md).
:::tip[Next]
## Next steps
- [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)
:::
-24
View File
@@ -1,24 +0,0 @@
---
level: start
nav: false
---
# Getting started
Three pages take you from nothing to games that start.
<a class="rb-button rb-button-primary" href="../which-pack.md">Get your files</a>
## What is a BIOS?
[What is a BIOS?](what-are-bios-files.md) tells you which consoles need one.
## Install
[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.
## Check your folder
[When a game does not start](troubleshooting.md#checking-what-you-installed)
shows how to check your BIOS folder.
+12 -4
View File
@@ -1,7 +1,6 @@
---
level: start
order: 60
nav_title: Glossary
---
# Words used on this site
@@ -22,6 +21,12 @@ nav_title: Glossary
**BIOS folder**
: The folder where your setup looks for BIOS files.
**Pack**
: The ZIP file with every BIOS file for one setup.
**Platform**
: A setup, as the project's data calls it.
**ZIP**
: One file that holds many files. You unzip it to get them out.
@@ -34,6 +39,9 @@ nav_title: Glossary
**Hash**
: A fingerprint of a file's contents. A different file gets a different hash.
**MD5** / **SHA-1**
: Two kinds of hash, a file's fingerprint. Setups that check files list one.
**Region**
: Where a console was sold: Japan, North America, Europe.
@@ -43,9 +51,9 @@ nav_title: Glossary
**Game data**
: Files from your own copy of a PC game, like Doom. Not a BIOS.
:::tip[Next]
## Next steps
- [What is a BIOS?](what-are-bios-files.md)
- [Get your files](../which-pack.md)
- Reference: [Terms of the reference pages](reference-terms.md)
:::
- For contributors: [Terms of the reference pages](reference-terms.md)
+22 -21
View File
@@ -9,27 +9,25 @@ These pages describe how the files are checked, what the data holds and how the
toolchain works. To set up BIOS files on a device, start with
[Get your files](../which-pack.md).
## How the files are checked
## Checking files
- **[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
- **[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
- **[Find a file](../files/index.md)**: any SHA1, MD5, CRC32 or SHA256 gives the file, the platforms that declare it and the emulators that check it
- **[How each platform checks files](verification-modes.md)**: existence, MD5 and SHA1 modes, severity matrix, resolution chain
- **[Reading this project's own reports](reading-reports.md)**: `verify.py` output, status codes and severity levels
- **[What the packs do not hold](../gaps.md)**: files emulators load that no pack can carry yet, by platform and by emulator
- **[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
## Data
- **[Data and API](../data.md)** - JSON, CSV and SQLite exports with their checksums
- **[Find a file](../files/index.md)** - any SHA1, MD5, CRC32 or SHA256: the file, the platforms that declare it, the emulators that check it
- **[Data model](data-model.md)** - database.json structure, indexes, file resolution order, YAML formats
- **[Data and API](../data.md)**: JSON, CSV and SQLite exports with their checksums
- **[Data model](data-model.md)**: database.json structure, indexes, file resolution order, YAML formats
- **[Updated platform files](../exports.md)**: each platform's own file, with the changes the emulator source supports
- **[Projects using this data](community-tools.md)**: projects built on RetroBIOS data
## The toolchain
## Questions
- **[Architecture](architecture.md)** - directory structure, data flow, platform inheritance, pack grouping, security, edge cases, CI workflows
- **[Build your own packs](advanced-usage.md)** - custom packs, region filtering, one file per slot, target filtering, truth generation, emulator verification, offline workflow
- **[Command-line tools](tools.md)** - every script, pipeline usage, scrapers
- **[Projects using this data](community-tools.md)** - projects built on RetroBIOS data
- **[Technical questions](technical-faq.md)**: multiple hashes, MAME versions, UNTESTED, dump verification
## Methodology
@@ -46,11 +44,14 @@ at run time, so the source is the primary reference:
## For contributors
- **[Profiling an emulator](profiling.md)** - create an emulator profile from source code, YAML field reference
- **[Adding a platform](adding-a-platform.md)** - scraper, registry, YAML config, exporter, target scraper, install detection
- **[Adding a scraper](adding-a-scraper.md)** - plugin architecture, BaseScraper, parsers, target scrapers
- **[Testing](testing-guide.md)** - run tests, fixture pattern, how to add tests, CI integration
- **[Release process](release-process.md)** - CI workflows, large files, manual release
- **[Profiling guide](profiling.md)**: create an emulator profile from source code, YAML field reference
- **[Adding a platform](adding-a-platform.md)**: scraper, registry, YAML config, exporter, target scraper, install detection
- **[Adding a scraper](adding-a-scraper.md)**: plugin architecture, BaseScraper, parsers, target scrapers
- **[Testing guide](testing-guide.md)**: run tests, fixture pattern, how to add tests, CI integration
- **[Release process](release-process.md)**: CI workflows, large files, manual release
- **[Architecture](architecture.md)**: directory structure, data flow, platform inheritance, pack grouping, security, edge cases, CI workflows
- **[Command-line tools](tools.md)**: every script, pipeline usage, scrapers
- **[Build your own packs](advanced-usage.md)**: custom packs, region filtering, one file per slot, target filtering, truth generation, emulator verification, offline workflow
See [contributing](../contributing.md) for submission guidelines.
@@ -58,4 +59,4 @@ See [contributing](../contributing.md) for submission guidelines.
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).
[Words used on this site](glossary.md).
+11 -4
View File
@@ -1,6 +1,6 @@
---
level: explore
order: 30
level: setup
order: 100
---
# All installer options
@@ -20,6 +20,13 @@ How the command protects your machine is under
[Trust boundary](#trust-boundary). The BIOS folder of each setup is on
[Get your files](../which-pack.md).
## Options at a glance
Read from the installer's own option list, the one `--help` prints. The
[Options](#options) table below gives each one in full.
<!-- installer-options -->
## One line
```bash
@@ -810,7 +817,7 @@ what it must hash to.
Entries the collection cannot satisfy are not silently dropped: they travel in
`omitted_files` with a reason, and the run prints the count before downloading
anything. `not_found` means no file in the collection matches the entry, which
is what the [gap analysis](../gaps.md) tracks.
is what the gap analysis tracks (Reference: [What the packs do not hold](../gaps.md)).
Some cores read a whole tree of data rather than a few files: Dolphin's `Sys/`,
PPSSPP's assets, blueMSX's machines. These are not files of the collection, so
@@ -950,7 +957,7 @@ no event at all. A program reads a missing `end` as that case.
| 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_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, so a tag holds a file list until the next release. For contributors: [release process](release-process.md#cutting-a-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` |
+6 -7
View File
@@ -1,10 +1,9 @@
---
level: explore
order: 40
nav_title: "Is it legal?"
level: start
order: 55
---
# The project's legal position
# Is it legal?
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.
@@ -41,8 +40,8 @@ This reflects the project's good-faith understanding, not legal advice.
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)
## Next steps
- [Common questions](faq.md)
- [What is a BIOS?](what-are-bios-files.md)
:::
-1
View File
@@ -1,7 +1,6 @@
---
level: contribute
order: 10
nav_title: Profiling an emulator
---
# Profiling guide
+152
View File
@@ -0,0 +1,152 @@
---
level: reference
order: 15
group: Checking files
---
# Reading this project's own reports
These sections are about this repository's own tools, run from a clone.
`scripts/verify.py` checks the collection in `bios/` against each platform, never
your BIOS folder: for that, use the installer's `--check`
([When a game does not start](troubleshooting.md)). How each platform checks a
file is on [How each platform checks files](verification-modes.md).
## Hash mismatch / UNTESTED
`verify.py` reports `UNTESTED` for a file of the collection that was hashed
and does not match what the platform declares. The line gives the reason:
```
UNTESTED (required): nintendo-ds/dsifirmware.bin: declared hash contradicted by the local file
```
The system page on the site lists every known version of the file with its
expected MD5 and SHA1.
### Existence-mode platforms never report UNTESTED
On RetroArch, Lakka and RetroPie, the platform check only asks whether the file
is there, so the only outcomes are OK and MISSING. `verify.py` adds the emulator
ground truth from the profiles and flags a `DISCREPANCY` when a file passes the
platform check but fails the emulator's own size or hash validation.
### The .variants/ directory
When multiple versions of the same BIOS exist (different revisions, regions, or
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.
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
A generated pack doesn't contain all the files you expected.
### Severity levels
`verify.py` assigns a severity to each issue, counted under `severity_counts`
in its `--json` output. Not all missing files are equally important:
| Severity | Meaning | Action needed |
|----------|---------|---------------|
| CRITICAL | Required file missing on an MD5 or SHA1 platform | Must fix. Core won't function. |
| WARNING | Optional file missing on an MD5 or SHA1 platform, hash mismatch (UNTESTED) on any hash platform, or a required file missing on an existence platform | Core works but with reduced functionality, or runs on content nobody verified. |
| INFO | Optional file missing on an existence-only platform, or a missing file the core covers with an HLE fallback | Core works fine, BIOS improves accuracy. |
| OK | File present and verified | No action needed. |
The full mapping, including how `hle_fallback` overrides the platform mode, is
in the [severity matrix](verification-modes.md#severity-matrix).
Focus on CRITICAL issues first. WARNING files improve the experience but aren't
strictly necessary. INFO files are nice to have.
### Large files (release assets)
Files like PS3UPDAT.PUP, PSVUPDAT.PUP, and Switch firmware are too large for the
git repository. They are stored as GitHub release assets under the `large-files`
release and downloaded at build time.
If a pack build fails to include these, check your network connection. In offline
mode (`--offline`), large files are only included if already cached locally in
`.cache/large/`.
### Data directories
Some cores need entire directory trees rather than individual files (e.g. Dolphin's
`Sys/` directory, PPSSPP's `assets/`). These are fetched by `refresh_data_dirs.py`
from upstream repositories.
In offline mode, data directories are only included if already cached in `data/`.
Run `python scripts/refresh_data_dirs.py` to fetch them.
## verify.py reports errors
How to read and interpret `verify.py` output.
### Status codes
| Status | Meaning |
|--------|---------|
| `OK` | File present, hash matches (or existence check passed) |
| `UNTESTED` | File present, hash not confirmed against the expected value |
| `MISSING` | File not found in the repository |
| `DISCREPANCY` | The platform check passes, an emulator's own check fails |
### Reading the output
The first line counts the platform's files and names its check. Under it come
the entries that need attention, one per line as `STATUS (required|optional):
system/file`, followed by a reason where there is one, then the counts of the
files the emulator cores add. From `python scripts/verify.py --platform retrodeck`:
```
RetroDECK: 2007/2008 OK, 1 untested [md5]
UNTESTED (required): nintendo-ds/dsifirmware.bin: declared hash contradicted by the local file
DISCREPANCY: nintendo-snes/sgb2.boot.rom: RetroDECK says OK but supersnes9x says size mismatch: got 524288, accepted [256]
supersnes9x [size]
Core files: 1495 in pack, 0 required missing, 1 optional missing
```
`--verbose` also lists the passing entries that an emulator validates, with
the check and the source lines behind it:
```
Recalbox: 351/351 OK [md5]
OK (required): macintosh/MacII.ROM
minivmac validates size=262144 [minivmac/cfg/CNFGRAPI.h:32, minivmac/src/OSGLUERETRO.c:781]
```
### Cross-reference section
After per-file results, `verify.py` prints a cross-reference report. This lists
files that emulator cores need but that the platform YAML doesn't declare. These
files are still included in packs automatically, but the report helps identify
gaps in platform coverage data.
The cross-reference uses `resolve_platform_cores()` to determine which emulator
profiles are relevant for each platform, then checks whether each profile's files
appear in the platform config.
### Filtering output
```bash
# By platform
python scripts/verify.py --platform batocera
# By emulator core
python scripts/verify.py --emulator beetle_psx
# By system
python scripts/verify.py --system sony-playstation
# By hardware target
python scripts/verify.py --platform retroarch --target switch
# JSON for scripted processing: the entries that need attention
python scripts/verify.py --platform retroarch --json
# every entry, passing ones included, with its ground truth
python scripts/verify.py --platform retroarch --json --verbose
```
+5 -6
View File
@@ -1,7 +1,6 @@
---
level: reference
order: 130
nav_title: Project terms
level: contribute
order: 90
---
# Terms of the reference pages
@@ -149,8 +148,8 @@ everyday words (BIOS, emulator, core, hash) are in the [glossary](glossary.md).
takes a file from (the collection, a data folder, a release asset) is its
source, not its provenance.
:::tip[Next]
## Next steps
- [How each platform checks files](verification-modes.md)
- [Glossary](glossary.md)
:::
- [Words used on this site](glossary.md)
+5 -5
View File
@@ -8,8 +8,8 @@ order: 120
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).
check it on the system pages. Questions asked before installing are in
[Common questions](faq.md).
## What's a hash/checksum?
@@ -143,8 +143,8 @@ Running `verify.py --emulator <core> --verbose` shows the emulator-level ground
It reaches only as far as the profiles do. Files no profile states a value for are platform-only, and nothing can be said about their content. The footer of the platform report gives that ratio as `Ground truth: N/M files have emulator validation`.
:::tip[Next]
- [Reference index](index.md), every reference page in one list
## Next steps
- [Reference](index.md), every reference page in one list
- For contributors: [How to contribute](../contributing.md)
:::
+6 -6
View File
@@ -1,7 +1,6 @@
---
level: contribute
order: 40
nav_title: Testing
---
# Testing guide
@@ -56,7 +55,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_schema_semantic_gate`, `test_site_availability`, `test_site_content_data`, `test_site_copy`, `test_site_cores`, `test_site_emulator_page`, `test_site_exports`, `test_site_funnel`, `test_site_images`, `test_site_picker`, `test_site_platform_hashes`, `test_site_r2_components`, `test_site_r2_css`, `test_site_r2_emulators`, `test_site_r2_entry`, `test_site_r2_nav`, `test_site_r2_p0`, `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_schema_semantic_gate`, `test_site_availability`, `test_site_content_data`, `test_site_copy`, `test_site_cores`, `test_site_emulator_page`, `test_site_exports`, `test_site_funnel`, `test_site_images`, `test_site_picker`, `test_site_platform_hashes`, `test_site_r2_components`, `test_site_r2_css`, `test_site_r2_emulators`, `test_site_r2_entry`, `test_site_r2_nav`, `test_site_r2_p0`, `test_site_r2_wiki`, `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
@@ -398,11 +397,12 @@ nav_title: Save files # only when the menu names it otherwise than its headin
two without renumbering. The generated pages (systems, emulators, the gaps
and data pages) hold fixed places among them, set in `generate_nav`.
- `nav_title` is the menu label. Without it the menu shows the page's `# `
heading. It is not `title`, which both MkDocs and Astro Starlight read as
the page's own title.
heading, which is the rule: a page keeps one name in the menu, its heading
and the links to it. It is not `title`, which both MkDocs and Astro
Starlight read as the page's own title.
- `group` places a Reference page under a group of that tab, such as
`Checking files` or `Data`.
- `nav: false` keeps a page out of the menu on purpose.
`getting-started.md` does, since it only links the pages that took its
content.
`python scripts/generate_site.py` stops with the page's name when `level` or
`order` is missing, or when two pages of a tab take the same `order`.
+2 -2
View File
@@ -1,6 +1,6 @@
---
level: reference
order: 110
level: contribute
order: 70
---
# Command-line tools
+18 -16
View File
@@ -14,6 +14,7 @@ find it.
Run the command with `--check`. It changes nothing.
<!-- os-tabs -->
```sh
curl -fsSL https://raw.githubusercontent.com/Abdess/retrobios/main/install.sh | sh -s -- --check
```
@@ -24,16 +25,15 @@ Read the count line:
1/109 present (0 verified, 1 wrong hash)
```
- **`wrong hash`**: a file is there, but its contents are wrong. It may be for
another region or model, or damaged.
- **`wrong hash`**: a file is there with the wrong contents: 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.
## 2. Fix the files
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.
the wrong ones, keeping the old ones.
## 3. Check the folder and the names
@@ -41,8 +41,10 @@ folder.
[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 `bios` folder inside your BIOS folder?** That ZIP holds its own top
folder. Move its files up one level.
- **Unzipped by hand on Linux?** Run the command once. It adds the names that
differ only by capital letters, which some ZIPs leave out.
- **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.
@@ -51,6 +53,7 @@ folder.
Add `--system` and its name:
<!-- os-tabs -->
```sh
curl -fsSL https://raw.githubusercontent.com/Abdess/retrobios/main/install.sh | sh -s -- --check --system sony-playstation --verbose
```
@@ -60,26 +63,25 @@ console name.
## My setup says UNTESTED
Batocera shows `UNTESTED` for a file whose contents it does not expect. Run
the command without `--check` to replace it.
Batocera shows `UNTESTED` for a file with unexpected contents. Run the command
without `--check` to replace it.
## If the command fails { #installation-script-fails }
- **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:
- **Permission denied:** do what the message says. It names what to run.
- **No setup found:** pick it from the list. Or name it and its folder:
<!-- os-tabs windows: --platform retroarch --dest C:\path\to\RetroArch\system -->
```sh
curl -fsSL https://raw.githubusercontent.com/Abdess/retrobios/main/install.sh | sh -s -- --platform retroarch --dest ~/.config/retroarch/system
```
Other messages: Details: [When something goes wrong](installer.md#when-something-goes-wrong).
Other messages: [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>
:::tip[Next]
- [Your setup's page](../which-pack.md): its folder and how it checks files
- [FAQ](faq.md)
:::
## Next steps
- [Your setup's page](../which-pack.md): its folder and how it checks files
- [Common questions](faq.md)
+38 -170
View File
@@ -1,17 +1,18 @@
---
level: reference
order: 10
group: Checking files
---
# How each platform checks files
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.
Most setups can show which BIOS files are missing. Each one checks differently.
RetroArch only asks whether a file with the right name is in the folder.
Batocera computes the file's MD5 and compares it with its list, so a
wrong-region file, or another file given the right name, shows as `UNTESTED`:
present, but not the expected file. BizHawk does the same with SHA1. A file
RetroArch accepts can still be one Batocera reports. The emulator, not the
check, is what fails when a game starts.
Example: `scph5501.bin`, MD5 `490f666e1afb15b7362b406ed1cea246`. Any file named
`scph5501.bin` passes on RetroArch. On Batocera only those exact bytes pass.
@@ -24,11 +25,14 @@ changes ([severity matrix](#severity-matrix)).
<!-- image: verification-modes -->
Each reference to a checker's code below links the revision of that code the
platform's own list was read from.
## Existence mode
**Platforms**: RetroArch, Lakka, RetroPie, MinUI, NextUI, MyMinUI
**Source**: RetroArch `core_info.c`, function `path_is_valid()`; minarch for the MinUI family
**Source**: RetroArch v1.22.2 [`core_info.c:2285`](https://github.com/libretro/RetroArch/blob/v1.22.2/core_info.c#L2285), `path_is_valid()`. For the MinUI family, minarch.
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.
@@ -47,7 +51,7 @@ Lakka and RetroPie inherit this behavior through platform config inheritance
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
`RETRO_ENVIRONMENT_GET_SYSTEM_DIRECTORY` with that folder (MinUI [`workspace/all/minarch/minarch.c:1889-1893`](https://github.com/shauninman/MinUI/blob/dbf89435a5179788418ff3573042cf9c7e75d9e0/workspace/all/minarch/minarch.c#L1889-L1893) and [`:2943`](https://github.com/shauninman/MinUI/blob/dbf89435a5179788418ff3573042cf9c7e75d9e0/workspace/all/minarch/minarch.c#L2943)). 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).
@@ -62,6 +66,9 @@ The details vary by platform.
### Standard MD5 (Batocera, RetroBat)
**Source**: Batocera 43.1 `batocera-systems`, [`md5sum()`](https://github.com/batocera-linux/batocera.linux/blob/batocera-43.1/package/batocera/core/batocera-scripts/scripts/batocera-systems#L987-L992) and
function [`checkBios`](https://github.com/batocera-linux/batocera.linux/blob/batocera-43.1/package/batocera/core/batocera-scripts/scripts/batocera-systems#L1047).
`verify.py` replicates Batocera's `md5sum()` function. The file is read in binary mode,
hashed with MD5, and compared case-insensitively against the expected value.
@@ -77,7 +84,7 @@ and returns OK directly.
### MD5 shorter than 32 characters (Batocera)
Batocera's script compares the full string (`batocera-systems:1088`), so an MD5
Batocera's script compares the full string ([`batocera-systems:1088`](https://github.com/batocera-linux/batocera.linux/blob/batocera-43.1/package/batocera/core/batocera-scripts/scripts/batocera-systems#L1088)), so an MD5
shorter than 32 characters matches no file there. The Batocera scraper completes such
a value when exactly one MD5 in `database.json` starts with it
(`_resolve_truncated_md5` in `scripts/scraper/batocera_scraper.py`) and keeps it as
@@ -86,11 +93,12 @@ characters by prefix, and only for a file whose name the entry also names.
### md5_composite (Recalbox ZIP verification)
Recalbox hashes a ZIP with `Zip::Md5Composite` (`es-core/src/utils/Zip.cpp:71-96` in
recalbox-emulationstation at `f4cd0ae4`): one MD5 over the contents of every member,
read in filename order. The members' own MD5s are not involved, and neither is the
MD5 of the ZIP file itself: `Bios::Scan` takes the composite for every `.zip`
(`es-app/src/bios/Bios.cpp:64-68`). `verify.py` computes the same value with
Recalbox hashes a ZIP with `Zip::Md5Composite`
([`es-core/src/utils/Zip.cpp:71-96`](https://gitlab.com/recalbox/recalbox/-/blob/10.1.1/projects/frontend/es-core/src/utils/Zip.cpp#L71-96) in
Recalbox 10.1.1): one MD5 over the contents of every member, read in filename
order. The members' own MD5s are not involved, and neither is the MD5 of the ZIP
file itself: `Bios::Scan` takes the composite for every `.zip`
([`es-app/src/bios/Bios.cpp:86-91`](https://gitlab.com/recalbox/recalbox/-/blob/10.1.1/projects/frontend/es-app/src/bios/Bios.cpp#L86-91)). `verify.py` computes the same value with
`md5_composite()` (`scripts/hashing.py`).
The registry gives Recalbox `zip_digest: composite`. For a platform so marked, a
@@ -109,8 +117,9 @@ listed hash is OK.
Recalbox colours each entry of `es_bios.xml` from two attributes, `mandatory` and
`hashMatchMandatory`, both true unless written `"false"`
(`es-app/src/bios/Bios.cpp:162-163` in recalbox-emulationstation at `f4cd0ae4`,
colours set by `Bios::Scan` at lines 84-108). The platform YAML carries them as
([`es-app/src/bios/Bios.cpp:187-188`](https://gitlab.com/recalbox/recalbox/-/blob/10.1.1/projects/frontend/es-app/src/bios/Bios.cpp#L187-188) in
Recalbox 10.1.1, colours set by `Bios::Scan` at
[lines 106-130](https://gitlab.com/recalbox/recalbox/-/blob/10.1.1/projects/frontend/es-app/src/bios/Bios.cpp#L106-130)). The platform YAML carries them as
`required` and, when the attribute is written, `hash_match_mandatory`.
| File | mandatory | hashMatchMandatory | Recalbox | verify.py |
@@ -130,7 +139,7 @@ Recalbox shows RED for a mandatory entry with `hashMatchMandatory`.
When a platform entry has a `zipped_file` field, the expected MD5 is not the hash of the
ZIP container but of a specific ROM file inside the ZIP. `verify.py` replicates Batocera's
`checkInsideZip()`:
[`checkInsideZip()`](https://github.com/batocera-linux/batocera.linux/blob/batocera-43.1/package/batocera/core/batocera-scripts/scripts/batocera-systems#L994):
1. Open the ZIP.
2. Find the inner file by name (case-insensitive via `casefold()`).
@@ -141,7 +150,7 @@ If the inner file is not found inside the ZIP, the status is UNTESTED with a rea
### RomM verification
**Source**: `backend/models/firmware.py`, `Firmware.verify_file_hashes`
**Source**: RomM 5.4.0 [`backend/models/firmware.py:58-76`](https://github.com/rommapp/romm/blob/5.4.0/backend/models/firmware.py#L58-L76), `Firmware.verify_file_hashes`
RomM reads the file's bytes (`verification_mode: md5`) but does not compare one
digest. Its platform YAML carries `hash_rule: size_and_any_hash`: the file's
@@ -157,7 +166,7 @@ not a single digest gets a new `hash_rule` value, never a new mode.
### ROCKNIX verification
**Source**: `rocknix-systems`, function `checkBios`
**Source**: ROCKNIX 20261001 [`rocknix-systems:137-197`](https://github.com/ROCKNIX/distribution/blob/20261001/projects/ROCKNIX/packages/rocknix/sources/scripts/rocknix-systems#L137-L197), function `checkBios`
ROCKNIX derives its BIOS checker from Batocera's, so the logic has the same
shape: `md5sum()` on the file, `checkInsideZip()` for archive entries, and an
@@ -167,8 +176,9 @@ platform declares is mandatory in its own data, so the platform YAML marks all
### KNULLI, AmberELEC and EmuELEC verification
**Source**: `knulli-systems` (KNULLI) and `batocera-systems` (AmberELEC,
EmuELEC), function `checkBios`
**Source**: function `checkBios` in [`knulli-systems:867-928`](https://github.com/knulli-cfw/knulli-linux/blob/20260511/package/system/knulli-scripts/scripts/knulli-systems#L867-L928)
(KNULLI 20260511), and in `batocera-systems` for
[AmberELEC](https://github.com/AmberELEC/AmberELEC/blob/a21975bfb1a3af68f66e07a931b994b523e1e6e2/packages/amberelec/sources/scripts/batocera-systems#L583-L644) and [EmuELEC 4.8](https://github.com/EmuELEC/EmuELEC/blob/v4.8/packages/sx05re/emuelec/bin/batocera/batocera-systems#L817-L834)
All three keep Batocera's `systems` dict and its checker, run by their
EmulationStation's BIOS screen.
@@ -205,6 +215,8 @@ URL and install themselves, so they are not part of the pack.
**Platforms**: BizHawk
**Source**: BizHawk 2.11.1 [`FirmwareDatabase.cs`](https://github.com/TASEmulators/BizHawk/blob/2.11.1/src/BizHawk.Emulation.Common/Database/FirmwareDatabase.cs)
BizHawk firmware entries use SHA1 as the primary hash. `verify.py` computes SHA1
via `compute_hashes()` and compares case-insensitively.
@@ -437,152 +449,8 @@ dump with that CRC32 too (`bios/Dragon/Dragon/d64_1.rom`), but its MD5 is
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
## Next steps
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
This section and the two after it are about this repository's own tools, run
from a clone. `scripts/verify.py` checks the collection in `bios/` against each
platform, never your BIOS folder: for that, use the installer's `--check`
([When a game does not start](troubleshooting.md)).
`verify.py` reports `UNTESTED` for a file of the collection that was hashed
and does not match what the platform declares. The line gives the reason:
```
UNTESTED (required): nintendo-ds/dsifirmware.bin: declared hash contradicted by the local file
```
The system page on the site lists every known version of the file with its
expected MD5 and SHA1.
### Existence-mode platforms never report UNTESTED
On RetroArch, Lakka and RetroPie, the platform check only asks whether the file
is there, so the only outcomes are OK and MISSING. `verify.py` adds the emulator
ground truth from the profiles and flags a `DISCREPANCY` when a file passes the
platform check but fails the emulator's own size or hash validation.
### The .variants/ directory
When multiple versions of the same BIOS exist (different revisions, regions, or
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.
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
A generated pack doesn't contain all the files you expected.
### Severity levels
`verify.py` assigns a severity to each issue, counted under `severity_counts`
in its `--json` output. Not all missing files are equally important:
| Severity | Meaning | Action needed |
|----------|---------|---------------|
| CRITICAL | Required file missing on an MD5 or SHA1 platform | Must fix. Core won't function. |
| WARNING | Optional file missing on an MD5 or SHA1 platform, hash mismatch (UNTESTED) on any hash platform, or a required file missing on an existence platform | Core works but with reduced functionality, or runs on content nobody verified. |
| INFO | Optional file missing on an existence-only platform, or a missing file the core covers with an HLE fallback | Core works fine, BIOS improves accuracy. |
| OK | File present and verified | No action needed. |
The full mapping, including how `hle_fallback` overrides the platform mode, is
in [severity matrix](#severity-matrix).
Focus on CRITICAL issues first. WARNING files improve the experience but aren't
strictly necessary. INFO files are nice to have.
### Large files (release assets)
Files like PS3UPDAT.PUP, PSVUPDAT.PUP, and Switch firmware are too large for the
git repository. They are stored as GitHub release assets under the `large-files`
release and downloaded at build time.
If a pack build fails to include these, check your network connection. In offline
mode (`--offline`), large files are only included if already cached locally in
`.cache/large/`.
### Data directories
Some cores need entire directory trees rather than individual files (e.g. Dolphin's
`Sys/` directory, PPSSPP's `assets/`). These are fetched by `refresh_data_dirs.py`
from upstream repositories.
In offline mode, data directories are only included if already cached in `data/`.
Run `python scripts/refresh_data_dirs.py` to fetch them.
## verify.py reports errors
How to read and interpret `verify.py` output.
### Status codes
| Status | Meaning |
|--------|---------|
| `OK` | File present, hash matches (or existence check passed) |
| `UNTESTED` | File present, hash not confirmed against the expected value |
| `MISSING` | File not found in the repository |
| `DISCREPANCY` | The platform check passes, an emulator's own check fails |
### Reading the output
The first line counts the platform's files and names its check. Under it come
the entries that need attention, one per line as `STATUS (required|optional):
system/file`, followed by a reason where there is one, then the counts of the
files the emulator cores add. From `python scripts/verify.py --platform retrodeck`:
```
RetroDECK: 2007/2008 OK, 1 untested [md5]
UNTESTED (required): nintendo-ds/dsifirmware.bin: declared hash contradicted by the local file
DISCREPANCY: nintendo-snes/sgb2.boot.rom: RetroDECK says OK but supersnes9x says size mismatch: got 524288, accepted [256]
supersnes9x [size]
Core files: 1495 in pack, 0 required missing, 1 optional missing
```
`--verbose` also lists the passing entries that an emulator validates, with
the check and the source lines behind it:
```
Recalbox: 351/351 OK [md5]
OK (required): macintosh/MacII.ROM
minivmac validates size=262144 [minivmac/cfg/CNFGRAPI.h:32, minivmac/src/OSGLUERETRO.c:781]
```
### Cross-reference section
After per-file results, `verify.py` prints a cross-reference report. This lists
files that emulator cores need but that the platform YAML doesn't declare. These
files are still included in packs automatically, but the report helps identify
gaps in platform coverage data.
The cross-reference uses `resolve_platform_cores()` to determine which emulator
profiles are relevant for each platform, then checks whether each profile's files
appear in the platform config.
### Filtering output
```bash
# By platform
python scripts/verify.py --platform batocera
# By emulator core
python scripts/verify.py --emulator beetle_psx
# By system
python scripts/verify.py --system sony-playstation
# By hardware target
python scripts/verify.py --platform retroarch --target switch
# JSON for scripted processing: the entries that need attention
python scripts/verify.py --platform retroarch --json
# every entry, passing ones included, with its ground truth
python scripts/verify.py --platform retroarch --json --verbose
```
- [Reading this project's own reports](reading-reports.md): `verify.py` output,
status codes and severity levels
- [What the packs do not hold](../gaps.md)
+5 -6
View File
@@ -1,7 +1,6 @@
---
level: start
order: 10
nav_title: What BIOS files are
---
# What is a BIOS?
@@ -18,8 +17,8 @@ a copy of the BIOS. That copy is a file: a **BIOS file**.
## How it works
1. You pick a game in your game menu.
2. The menu starts the emulator.
1. You pick a game in your setup's menu.
2. The setup starts the emulator.
3. The emulator opens the BIOS file in your **BIOS folder**.
4. The game starts.
@@ -57,10 +56,10 @@ then glitch or do not start. The real file works best, so we include it.
## Is it legal?
Laws differ by country. [Read the project's position](faq.md#is-this-legal).
Laws differ by country. [Is it legal?](legal.md)
## Next steps
:::tip[Next]
- [Get your files](../which-pack.md)
- [Words used on this site](glossary.md)
:::