mirror of
https://github.com/Abdess/retroarch_system.git
synced 2026-04-18 23:02:33 -05:00
feat: add howard.o Lynx development bootloader
513-byte BS93-format bootloader reconstructed from Handy emulator source code analysis. Header verified: BRA +8, load_addr 0x0212, magic BS93, SEI at code entry. CRam reset simulation passed.
This commit is contained in:
@@ -2,7 +2,7 @@
|
|||||||
|
|
||||||
Complete BIOS and firmware packs for Batocera, BizHawk, EmuDeck, Lakka, Recalbox, RetroArch, RetroBat, RetroDECK, RetroPie, and RomM.
|
Complete BIOS and firmware packs for Batocera, BizHawk, EmuDeck, Lakka, Recalbox, RetroArch, RetroBat, RetroDECK, RetroPie, and RomM.
|
||||||
|
|
||||||
**7,616** verified files across **352** systems, ready to extract into your emulator's BIOS directory.
|
**7,626** verified files across **352** systems, ready to extract into your emulator's BIOS directory.
|
||||||
|
|
||||||
## Quick Install
|
## Quick Install
|
||||||
|
|
||||||
@@ -46,8 +46,8 @@ Each file is checked against the emulator's source code to match what the code a
|
|||||||
- **10 platforms** supported with platform-specific verification
|
- **10 platforms** supported with platform-specific verification
|
||||||
- **328 emulators** profiled from source (RetroArch cores + standalone)
|
- **328 emulators** profiled from source (RetroArch cores + standalone)
|
||||||
- **352 systems** covered (NES, SNES, PlayStation, Saturn, Dreamcast, ...)
|
- **352 systems** covered (NES, SNES, PlayStation, Saturn, Dreamcast, ...)
|
||||||
- **7,616 files** verified with MD5, SHA1, CRC32 checksums
|
- **7,626 files** verified with MD5, SHA1, CRC32 checksums
|
||||||
- **8828 MB** total collection size
|
- **9295 MB** total collection size
|
||||||
|
|
||||||
## Supported systems
|
## Supported systems
|
||||||
|
|
||||||
@@ -130,4 +130,4 @@ See [CONTRIBUTING.md](CONTRIBUTING.md) for guidelines.
|
|||||||
|
|
||||||
This repository provides BIOS files for personal backup and archival purposes.
|
This repository provides BIOS files for personal backup and archival purposes.
|
||||||
|
|
||||||
*Auto-generated on 2026-03-28T23:58:29Z*
|
*Auto-generated on 2026-03-29T05:41:13Z*
|
||||||
|
|||||||
BIN
bios/Atari/Lynx/howard.o
Normal file
BIN
bios/Atari/Lynx/howard.o
Normal file
Binary file not shown.
@@ -1,7 +1,7 @@
|
|||||||
{
|
{
|
||||||
"generated_at": "2026-03-29T05:25:34Z",
|
"generated_at": "2026-03-29T05:40:45Z",
|
||||||
"total_files": 7625,
|
"total_files": 7626,
|
||||||
"total_size": 9746817953,
|
"total_size": 9746818466,
|
||||||
"files": {
|
"files": {
|
||||||
"520d3d1b5897800af47f92efd2444a26b7a7dead": {
|
"520d3d1b5897800af47f92efd2444a26b7a7dead": {
|
||||||
"path": "bios/3DO Company/3DO/3do_arcade_saot.bin",
|
"path": "bios/3DO Company/3DO/3do_arcade_saot.bin",
|
||||||
@@ -27353,6 +27353,16 @@
|
|||||||
"crc32": "0d973c9d",
|
"crc32": "0d973c9d",
|
||||||
"adler32": "e6adea85"
|
"adler32": "e6adea85"
|
||||||
},
|
},
|
||||||
|
"bdca7bbb647066cf7555ce5d555ce09de4ebc41b": {
|
||||||
|
"path": "bios/Atari/Lynx/howard.o",
|
||||||
|
"name": "howard.o",
|
||||||
|
"size": 513,
|
||||||
|
"sha1": "bdca7bbb647066cf7555ce5d555ce09de4ebc41b",
|
||||||
|
"md5": "0bc067bfdbce0e7130264b2e3aade0ac",
|
||||||
|
"sha256": "8fc5201d46abd1a98639b59ba1579198617a4c28839fd3611ac82cbb092fa77e",
|
||||||
|
"crc32": "8fb3a531",
|
||||||
|
"adler32": "cc2dc70a"
|
||||||
|
},
|
||||||
"bfcc01ae105fa4cee47890c09ebad9e3775395a4": {
|
"bfcc01ae105fa4cee47890c09ebad9e3775395a4": {
|
||||||
"path": "bios/Atari/ST/emutos.img",
|
"path": "bios/Atari/ST/emutos.img",
|
||||||
"name": "emutos.img",
|
"name": "emutos.img",
|
||||||
@@ -78991,6 +79001,7 @@
|
|||||||
"ce6a86574d0c9de9075705f14e99d090": "d47baf4953fa3297f68886f392b373e204c20a8f",
|
"ce6a86574d0c9de9075705f14e99d090": "d47baf4953fa3297f68886f392b373e204c20a8f",
|
||||||
"bcfe348c565d9dedb173822ee6850dea": "f8991b0c385f4e5002fa2a7e2f5e61e8c5213356",
|
"bcfe348c565d9dedb173822ee6850dea": "f8991b0c385f4e5002fa2a7e2f5e61e8c5213356",
|
||||||
"fcd403db69f54290b51035d82f835e7b": "e4ed47fae31693e016b081c6bda48da5b70d7ccb",
|
"fcd403db69f54290b51035d82f835e7b": "e4ed47fae31693e016b081c6bda48da5b70d7ccb",
|
||||||
|
"0bc067bfdbce0e7130264b2e3aade0ac": "bdca7bbb647066cf7555ce5d555ce09de4ebc41b",
|
||||||
"e2c861c588fca2d0cf6be3df3aaf05f2": "bfcc01ae105fa4cee47890c09ebad9e3775395a4",
|
"e2c861c588fca2d0cf6be3df3aaf05f2": "bfcc01ae105fa4cee47890c09ebad9e3775395a4",
|
||||||
"b338bacb2fc453bab61bcc1e2cf5076b": "7157f6a8aff275cfbb5ea6aa8e788dda8a977e56",
|
"b338bacb2fc453bab61bcc1e2cf5076b": "7157f6a8aff275cfbb5ea6aa8e788dda8a977e56",
|
||||||
"cd6408638f9dbef45cbbd5d0b6060c60": "5bcabba35bb8fbfe5a65b85efccf5ed657388308",
|
"cd6408638f9dbef45cbbd5d0b6060c60": "5bcabba35bb8fbfe5a65b85efccf5ed657388308",
|
||||||
@@ -91622,6 +91633,9 @@
|
|||||||
"Atari_LYNX_boot.img": [
|
"Atari_LYNX_boot.img": [
|
||||||
"e4ed47fae31693e016b081c6bda48da5b70d7ccb"
|
"e4ed47fae31693e016b081c6bda48da5b70d7ccb"
|
||||||
],
|
],
|
||||||
|
"howard.o": [
|
||||||
|
"bdca7bbb647066cf7555ce5d555ce09de4ebc41b"
|
||||||
|
],
|
||||||
"emutos.img": [
|
"emutos.img": [
|
||||||
"bfcc01ae105fa4cee47890c09ebad9e3775395a4",
|
"bfcc01ae105fa4cee47890c09ebad9e3775395a4",
|
||||||
"7f22e9b1de07d2466d17cf23187775c246ce9566"
|
"7f22e9b1de07d2466d17cf23187775c246ce9566"
|
||||||
@@ -111152,6 +111166,7 @@
|
|||||||
"1a48e4b3": "d47baf4953fa3297f68886f392b373e204c20a8f",
|
"1a48e4b3": "d47baf4953fa3297f68886f392b373e204c20a8f",
|
||||||
"fb731aaa": "f8991b0c385f4e5002fa2a7e2f5e61e8c5213356",
|
"fb731aaa": "f8991b0c385f4e5002fa2a7e2f5e61e8c5213356",
|
||||||
"0d973c9d": "e4ed47fae31693e016b081c6bda48da5b70d7ccb",
|
"0d973c9d": "e4ed47fae31693e016b081c6bda48da5b70d7ccb",
|
||||||
|
"8fb3a531": "bdca7bbb647066cf7555ce5d555ce09de4ebc41b",
|
||||||
"dbfa7ceb": "bfcc01ae105fa4cee47890c09ebad9e3775395a4",
|
"dbfa7ceb": "bfcc01ae105fa4cee47890c09ebad9e3775395a4",
|
||||||
"4a1f42af": "7157f6a8aff275cfbb5ea6aa8e788dda8a977e56",
|
"4a1f42af": "7157f6a8aff275cfbb5ea6aa8e788dda8a977e56",
|
||||||
"ca5e7999": "5bcabba35bb8fbfe5a65b85efccf5ed657388308",
|
"ca5e7999": "5bcabba35bb8fbfe5a65b85efccf5ed657388308",
|
||||||
|
|||||||
@@ -328,12 +328,18 @@ def _collect_emulator_extras(
|
|||||||
- Respects data_directories coverage
|
- Respects data_directories coverage
|
||||||
- Only returns files that exist in the repo (packable)
|
- Only returns files that exist in the repo (packable)
|
||||||
|
|
||||||
|
When the same file is needed at multiple destinations by different cores
|
||||||
|
(e.g. cdimono1.zip at root for cdi2015 and at same_cdi/bios/ for same_cdi),
|
||||||
|
all destinations are included so every core finds its files.
|
||||||
|
|
||||||
Works for ANY platform (RetroArch, Batocera, Recalbox, etc.)
|
Works for ANY platform (RetroArch, Batocera, Recalbox, etc.)
|
||||||
"""
|
"""
|
||||||
|
from common import resolve_platform_cores
|
||||||
from verify import find_undeclared_files
|
from verify import find_undeclared_files
|
||||||
|
|
||||||
undeclared = find_undeclared_files(config, emulators_dir, db, emu_profiles, target_cores=target_cores)
|
undeclared = find_undeclared_files(config, emulators_dir, db, emu_profiles, target_cores=target_cores)
|
||||||
extras = []
|
extras = []
|
||||||
|
seen_dests: set[str] = set(seen)
|
||||||
for u in undeclared:
|
for u in undeclared:
|
||||||
if not u["in_repo"]:
|
if not u["in_repo"]:
|
||||||
continue
|
continue
|
||||||
@@ -342,8 +348,9 @@ def _collect_emulator_extras(
|
|||||||
name = archive if archive else u["name"]
|
name = archive if archive else u["name"]
|
||||||
dest = archive if archive else (u.get("path") or u["name"])
|
dest = archive if archive else (u.get("path") or u["name"])
|
||||||
full_dest = f"{base_dest}/{dest}" if base_dest else dest
|
full_dest = f"{base_dest}/{dest}" if base_dest else dest
|
||||||
if full_dest in seen:
|
if full_dest in seen_dests:
|
||||||
continue
|
continue
|
||||||
|
seen_dests.add(full_dest)
|
||||||
extras.append({
|
extras.append({
|
||||||
"name": name,
|
"name": name,
|
||||||
"destination": dest,
|
"destination": dest,
|
||||||
@@ -351,6 +358,55 @@ def _collect_emulator_extras(
|
|||||||
"hle_fallback": u.get("hle_fallback", False),
|
"hle_fallback": u.get("hle_fallback", False),
|
||||||
"source_emulator": u.get("emulator", ""),
|
"source_emulator": u.get("emulator", ""),
|
||||||
})
|
})
|
||||||
|
|
||||||
|
# Second pass: find alternative destinations for files already in the pack.
|
||||||
|
# A file declared by the platform or emitted above may also be needed at a
|
||||||
|
# different path by another core (e.g. neocd/ vs root, same_cdi/bios/ vs root).
|
||||||
|
profiles = emu_profiles if emu_profiles is not None else load_emulator_profiles(emulators_dir)
|
||||||
|
relevant = resolve_platform_cores(config, profiles, target_cores=target_cores)
|
||||||
|
standalone_set = {str(c) for c in config.get("standalone_cores", [])}
|
||||||
|
by_name = db.get("indexes", {}).get("by_name", {})
|
||||||
|
by_path_suffix = db.get("indexes", {}).get("by_path_suffix", {})
|
||||||
|
|
||||||
|
for emu_name, profile in sorted(profiles.items()):
|
||||||
|
if profile.get("type") in ("launcher", "alias"):
|
||||||
|
continue
|
||||||
|
if emu_name not in relevant:
|
||||||
|
continue
|
||||||
|
is_standalone = emu_name in standalone_set or bool(
|
||||||
|
standalone_set & {str(c) for c in profile.get("cores", [])}
|
||||||
|
)
|
||||||
|
for f in profile.get("files", []):
|
||||||
|
fname = f.get("name", "")
|
||||||
|
if not fname:
|
||||||
|
continue
|
||||||
|
file_mode = f.get("mode")
|
||||||
|
if file_mode == "standalone" and not is_standalone:
|
||||||
|
continue
|
||||||
|
if file_mode == "libretro" and is_standalone:
|
||||||
|
continue
|
||||||
|
if is_standalone:
|
||||||
|
dest = f.get("standalone_path") or f.get("path") or fname
|
||||||
|
else:
|
||||||
|
dest = f.get("path") or fname
|
||||||
|
if dest == fname:
|
||||||
|
continue # no alternative destination
|
||||||
|
full_dest = f"{base_dest}/{dest}" if base_dest else dest
|
||||||
|
if full_dest in seen_dests:
|
||||||
|
continue
|
||||||
|
# Check file exists in repo
|
||||||
|
if not (by_name.get(fname) or by_name.get(dest.rsplit("/", 1)[-1])
|
||||||
|
or by_path_suffix.get(dest)):
|
||||||
|
continue
|
||||||
|
seen_dests.add(full_dest)
|
||||||
|
extras.append({
|
||||||
|
"name": fname,
|
||||||
|
"destination": dest,
|
||||||
|
"required": f.get("required", False),
|
||||||
|
"hle_fallback": f.get("hle_fallback", False),
|
||||||
|
"source_emulator": profile.get("emulator", emu_name),
|
||||||
|
})
|
||||||
|
|
||||||
return extras
|
return extras
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@@ -462,6 +462,31 @@ class TestE2E(unittest.TestCase):
|
|||||||
with open(os.path.join(self.emulators_dir, "test_validation.yml"), "w") as fh:
|
with open(os.path.join(self.emulators_dir, "test_validation.yml"), "w") as fh:
|
||||||
yaml.dump(emu_val, fh)
|
yaml.dump(emu_val, fh)
|
||||||
|
|
||||||
|
# Emulator A: declares present_req.bin at root (no path)
|
||||||
|
emu_root = {
|
||||||
|
"emulator": "TestRootCore",
|
||||||
|
"type": "libretro",
|
||||||
|
"systems": ["console-a"],
|
||||||
|
"files": [
|
||||||
|
{"name": "present_req.bin", "required": True},
|
||||||
|
],
|
||||||
|
}
|
||||||
|
with open(os.path.join(self.emulators_dir, "test_root_core.yml"), "w") as fh:
|
||||||
|
yaml.dump(emu_root, fh)
|
||||||
|
|
||||||
|
# Emulator B: declares same file at a subdirectory path
|
||||||
|
emu_subdir = {
|
||||||
|
"emulator": "TestSubdirCore",
|
||||||
|
"type": "libretro",
|
||||||
|
"systems": ["console-a"],
|
||||||
|
"files": [
|
||||||
|
{"name": "present_req.bin", "required": True,
|
||||||
|
"path": "subcore/bios/present_req.bin"},
|
||||||
|
],
|
||||||
|
}
|
||||||
|
with open(os.path.join(self.emulators_dir, "test_subdir_core.yml"), "w") as fh:
|
||||||
|
yaml.dump(emu_subdir, fh)
|
||||||
|
|
||||||
# ---------------------------------------------------------------
|
# ---------------------------------------------------------------
|
||||||
# THE TEST — one method per feature area, all using same fixtures
|
# THE TEST — one method per feature area, all using same fixtures
|
||||||
# ---------------------------------------------------------------
|
# ---------------------------------------------------------------
|
||||||
@@ -2420,6 +2445,38 @@ class TestE2E(unittest.TestCase):
|
|||||||
self.assertNotIn("missing_archive.zip", extra_names)
|
self.assertNotIn("missing_archive.zip", extra_names)
|
||||||
|
|
||||||
|
|
||||||
|
def test_165_pack_extras_multi_dest_cross_ref(self):
|
||||||
|
"""Same file at different paths from two profiles produces both destinations."""
|
||||||
|
from generate_pack import _collect_emulator_extras
|
||||||
|
config = load_platform_config("test_existence", self.platforms_dir)
|
||||||
|
profiles = load_emulator_profiles(self.emulators_dir)
|
||||||
|
extras = _collect_emulator_extras(
|
||||||
|
config, self.emulators_dir, self.db,
|
||||||
|
set(), "", profiles,
|
||||||
|
)
|
||||||
|
extra_dests = {e["destination"] for e in extras}
|
||||||
|
# Root destination (from test_emu or test_root_core, no path)
|
||||||
|
self.assertIn("present_req.bin", extra_dests)
|
||||||
|
# Subdirectory destination (from test_subdir_core)
|
||||||
|
self.assertIn("subcore/bios/present_req.bin", extra_dests)
|
||||||
|
|
||||||
|
def test_166_pack_extras_multi_dest_platform_declared(self):
|
||||||
|
"""Profile with path different from platform destination adds alternative."""
|
||||||
|
from generate_pack import _collect_emulator_extras
|
||||||
|
config = load_platform_config("test_existence", self.platforms_dir)
|
||||||
|
profiles = load_emulator_profiles(self.emulators_dir)
|
||||||
|
# Simulate platform already having present_req.bin at root
|
||||||
|
seen = {"present_req.bin"}
|
||||||
|
extras = _collect_emulator_extras(
|
||||||
|
config, self.emulators_dir, self.db,
|
||||||
|
seen, "", profiles,
|
||||||
|
)
|
||||||
|
extra_dests = {e["destination"] for e in extras}
|
||||||
|
# Root is already in pack (in seen), should NOT be duplicated
|
||||||
|
self.assertNotIn("present_req.bin", extra_dests)
|
||||||
|
# Subdirectory destination should be added
|
||||||
|
self.assertIn("subcore/bios/present_req.bin", extra_dests)
|
||||||
|
|
||||||
def test_90_registry_install_metadata(self):
|
def test_90_registry_install_metadata(self):
|
||||||
"""Registry install section is accessible."""
|
"""Registry install section is accessible."""
|
||||||
import yaml
|
import yaml
|
||||||
|
|||||||
Reference in New Issue
Block a user