feat: read retrobat's saturn and atari builds

RetroBat installs its stable archives, so each config_reads entry is
read at the build the binary names: Hatari 2.4.1, hatariB 0.3,
Hatari2014 at ab55c3e from the buildbot, Kronos 2.7.0 and Ymir 0.3.3.
SSF ships PreviewVer R28 and YabaSanshiro 1.20.32 has no public
source: binary_sha256 names the file their address refs are read in.
The seven RetroBat records citing an option list now hold.
This commit is contained in:
Abdessamad Derraz committed 2026-11-11 11:57:12 +01:00
1 parent 01ca625378
commit b29500846b
11 files changed
+125 -4

No files matched your search

+8
View File
@@ -76,6 +76,14 @@ config_reads:
keys:
- key: "[ROM] szTosImageFileName"
source_ref: "upstream src/configuration.c:480, upstream src/tos.c:975-986"
- file: "*.cfg"
platforms: [retrobat]
revision: "4371dcd647fc85d31c0629400adaeaa4212040d9"
revision_from: "Hatari v2.4.1, compiled Aug 3 2022, in hatari.exe of RetroBat's stable hatari.7z (2026-04-04), the v2.4.1 tag"
source_ref: "upstream src/options.c:228-229, 1099-1108, upstream src/configuration.c:967-976, 1024"
keys:
- key: "[ROM] szTosImageFileName"
source_ref: "upstream src/configuration.c:413, 884, upstream src/tos.c:942-955"
notes: |
The main branch of libretro/hatari is the upstream Hatari tree at
+11
View File
@@ -22,6 +22,17 @@ systems:
- atari-tt
- atari-falcon
config_reads:
- file: "core options"
platforms: [retrobat]
revision: "ab55c3ed0e620c91e7f059a6d3fbef7acf9bfca8"
revision_from: "library_version 1.8 ab55c3e of hatari2014_libretro.dll from the libretro buildbot windows x86_64 nightly (2026-11-10), which RetroBat installs when its own repository has no copy"
source_ref: "source libretro/libretro.c:264-300, 372, 393-413, 437-440, 984-1001, 1418, source libretro/libretro_core_options.h:129-145"
keys:
- key: "hatari_tosimage"
source_ref: "source libretro/libretro.c:617, 639-649, 1612-1617, source src/main.c:913-917, source src/tos.c:575-590"
condition: "a value other than default is a file of system/hatari/tos ending in img (libretro/libretro.c:288-299)"
notes: |
Hatari 2014 is the libretro port of Hatari 1.8.0 (src/includes/version.h:16),
the July 2014 release, kept on the hitari2014-mercurial branch of
+11
View File
@@ -20,6 +20,17 @@ systems:
- atari-tt
- atari-falcon
config_reads:
- file: "core options"
platforms: [retrobat]
revision: "9c5ee608504d7e174dce99ac9237151863d78347"
revision_from: "library_version v0.3 9c5ee60 of hatarib_libretro.dll in RetroBat's stable cores/hatarib_libretro.dll.zip (2026-04-04), the 0.3 tag"
source_ref: "core/core.c:963-976, core/core_config.c:961-969, 985, 1286-1318, 1408-1413, hatari/src/main.c:898, 921-925, 1019"
keys:
- key: "hatarib_tos"
source_ref: "core/core_config.c:1082-1104, core/core_file.c:256-259, 763-769, hatari/src/tos.c:996-1056"
condition: "<tos.img> is offered only when system/tos.img exists, a hatarib/ value only for a file with an img, rom, bin or tos extension (core/core_config.c:1293-1318, core/core_file.c:707-716)"
notes: |
hatariB carries Hatari 2.6.1 in its hatari/ directory, every change
fenced by __LIBRETRO__ (DEVELOP.md:7-14, DEVELOP.md:44-48), and
+13
View File
@@ -20,6 +20,19 @@ systems:
- sega-saturn
- sega-stv
config_reads:
- file: "kronos.ini"
platforms: [retrobat]
revision: "6750417f3d6fef1b7be9adf52e707cc78aa41ee0"
revision_from: "Kronos 2.7.0 without a commit id in kronos.exe of RetroBat's stable kronos.7z, linked 2024-12-31: the last FCare/Kronos commit before that date, the cited files unchanged from aca9865c to the 2.7.0_official_release tag 58352d6d"
source_ref: "upstream yabause/src/port/qt/Settings.cpp:50-61, 95-103, upstream yabause/src/port/qt/Settings.h:25-26, upstream yabause/src/CMakeLists.txt:763, upstream yabause/src/port/qt/main.cpp:55-57"
keys:
- key: "[1.0] General\\EnableEmulatedBios"
source_ref: "upstream yabause/src/port/qt/YabauseThread.cpp:392-393"
- key: "[1.0] General\\Bios"
source_ref: "upstream yabause/src/port/qt/YabauseThread.cpp:394-395, upstream yabause/src/port/qt/VolatileSettings.cpp:20-27, upstream yabause/src/ctrl/src/yabause.c:497-509, 575-587, 626-630, upstream yabause/src/sys/memory/src/memory.c:1343-1346"
condition: "General\\EnableEmulatedBios false; an empty path runs the HLE BIOS, a path that fails to load stops init"
notes: |
Kronos is a Sega Saturn and ST-V arcade emulator by FCare, forked from
Yabause. Requires OpenGL 4.3 compute shaders.
+11
View File
@@ -21,6 +21,17 @@ systems:
- sega-stv
mode: standalone
config_reads:
- file: "SSF.ini"
platforms: [retrobat]
binary_sha256: "00f43e448592e5e8359eba7da4de5b3a16e6840ad8faf9cf182f738c4e25293a"
revision_from: "SSF PreviewVer R28 (string at 0x1a46634): the 32-bit SSF.exe of RetroBat's stable ssf.7z (2026-04-04), byte-identical to the one in SSF_PreviewVer_R28.zip of release tag PreviewVer"
source_ref: "SSF.exe 0x5b0b41-0x5b0b81, SSF.exe 0x5b9785, SSF.exe 0x5ac8cc-0x5ac8e2, SSF.exe 0x5ac94c, SSF.exe 0x5953d0, SSF.exe 0x5954c3-0x5954db, SSF.exe 0xb35e20"
keys:
- key: "[Peripheral] SaturnBIOS"
source_ref: "SSF.exe 0x52bc85-0x52bcd8, SSF.exe 0x5ac9e4, SSF.exe 0x5aab87-0x5aab93, SSF.exe 0x5b2905-0x5b2936, SSF.exe 0xb36022-0xb360cf"
condition: "[Program4] NoBIOS off (0 in the embedded template) and Ctrl not held at launch, in Saturn mode (no left Shift, no zip); an empty path or a read short of 0x80000 bytes boots without BIOS"
notes: |
Sega Saturn and ST-V emulator by Shima, closed source and distributed as a
binary. Two artifacts are read here and they describe the same emulator: the
+13
View File
@@ -39,6 +39,19 @@ data_root:
source_ref: "yabause/src/retro_arena/main.cpp:292-301"
note: "Created at startup. Holds backup.bin, keymapv2.json, the per-game settings files, save states and screenshots. No firmware is read from it."
config_reads:
- file: "yabause.ini"
platforms: [retrobat]
binary_sha256: "54f89ad3d45f078422616b794e9f7d400a37af0fbb00b31d3ba5a3b66516bf27"
revision_from: "yabasanshiro.exe of RetroBat's stable yabasanshiro.7z (2026-08-08), version 1.20.32 (0x141206de8), the yabasanshiro-1.20.32-3989ac release of 2026-07-31 whose source is not public"
source_ref: "yabasanshiro.exe 0x14001ae2c-0x14001ae58, yabasanshiro.exe 0x1400cea2c-0x1400cea33, yabasanshiro.exe 0x1400ce4d5-0x1400ce59e, yabasanshiro.exe 0x1400ce5a3-0x1400ce61f, yabasanshiro.exe 0x1400ce44a-0x1400ce496, yabasanshiro.exe 0x1400ce339-0x1400ce394"
keys:
- key: "[0.9.11] General\\EnableEmulatedBios"
source_ref: "yabasanshiro.exe 0x1400d248f-0x1400d2512"
- key: "[0.9.11] General\\Bios"
source_ref: "yabasanshiro.exe 0x1400d251b-0x1400d258c, yabasanshiro.exe 0x1400cf162-0x1400cf166, yabasanshiro.exe 0x14016d957-0x14016d98f, yabasanshiro.exe 0x14016f3ad-0x14016f4b4"
condition: "General\\EnableEmulatedBios false; an empty value runs the HLE BIOS (0x14016d997-0x14016d9f7), a file that does not open stops init"
notes: |
YabaSanshiro is a Sega Saturn emulator by devmiyax, forked from Yabause.
Requires OpenGL 3.3 or OpenGL ES 3.0.
+16
View File
@@ -42,6 +42,22 @@ data_root:
source_ref: "apps/ymir-sdl3/src/app/profile.cpp:29-34, apps/ymir-sdl3/src/app/app.cpp:342-437, apps/ymir-sdl3/CMakeLists.txt:647-648"
note: "Portable profile: the current directory, then the folder of the executable, when it holds Ymir.toml. The first launch asks between the two. -p names a folder, -u forces this one. Always this folder under Flatpak"
config_reads:
- file: "Ymir.toml"
platforms: [retrobat]
revision: "54fead6a0001d3e4b6741a8d095ee8342266c3dc"
revision_from: "version 0.3.3 of ymir-sdl3.exe in RetroBat's stable ymir.7z (2026-08-08), byte-identical to the v0.3.3 windows-x86_64-AVX2 release asset"
source_ref: "apps/ymir-sdl3/src/app/settings.hpp:40, apps/ymir-sdl3/src/app/app.cpp:340-359, 412, apps/ymir-sdl3/src/app/profile.cpp:36-62"
keys:
- key:
- "[System.IPL] Override"
- "[System.IPL] Path"
source_ref: "apps/ymir-sdl3/src/app/settings.cpp:1236-1240, 2805-2813, apps/ymir-sdl3/src/app/services/rom_service.cpp:109-114, apps/ymir-sdl3/src/util/rom_loader.cpp:9-22, apps/ymir-sdl3/src/app/app.cpp:451-462"
condition: "Override true and Path not empty: the path is opened without an existence check and must be 512 KiB"
- key: "[General.PathOverrides] IPLROMImages"
source_ref: "apps/ymir-sdl3/src/app/settings.cpp:1190-1197, apps/ymir-sdl3/src/app/profile.cpp:94-104, apps/ymir-sdl3/src/app/services/rom_service.cpp:67-73, 116-175, apps/ymir-sdl3/src/app/rom_manager.cpp:14-45"
condition: "Override false or Path empty: the folder is scanned recursively for 512 KiB files known by XXH128"
notes: |
Ymir is a Sega Saturn emulator by StrikerX3. The libretro port by
warmenhoven wraps the shared ymir-core library on the libretro branch of
+4 -2
View File
@@ -1165,12 +1165,14 @@
"type": "object",
"additionalProperties": false,
"required": ["file", "source_ref", "keys"],
"dependentRequired": {"revision": ["platforms", "revision_from"]},
"dependentRequired": {"revision": ["platforms", "revision_from"], "binary_sha256": ["platforms", "revision_from"]},
"not": {"required": ["revision", "binary_sha256"]},
"properties": {
"file": {"type": "string", "minLength": 1, "description": "The config as the code finds it: a name, a glob for any file a flag passes (*.uae), a path, the flag itself, \"command line\" or \"core options\""},
"platforms": {"type": "array", "items": {"type": "string"}, "minItems": 1, "uniqueItems": true, "description": "Registry slugs of the platforms shipping the build these refs are read at, each with a pin_build entry unless revision names the build"},
"revision": {"type": "string", "pattern": "^[0-9a-f]{40}$", "description": "The commit these refs are read at, for platforms installing a package no build file of theirs pins (RetroBat's stable archives, a Flathub app)"},
"revision_from": {"type": "string", "minLength": 1, "description": "Where revision was read: the version string of the shipped binary, the Flathub manifest commit"},
"binary_sha256": {"type": "string", "pattern": "^[0-9a-f]{64}$", "description": "The shipped binary these refs are read in, for a build whose source is not public (SSF, YabaSanshiro 1.20): its refs are virtual addresses of that file"},
"revision_from": {"type": "string", "minLength": 1, "description": "Where revision or binary_sha256 was read: the version string of the shipped binary, the Flathub manifest commit, the archive the binary comes from"},
"source_ref": {"type": "string", "minLength": 1},
"keys": {
"type": "array",
+4 -1
View File
@@ -1652,7 +1652,10 @@ def _check_build_refs(
results: list[dict] = []
for citation, read in deferred:
for platform in read.get("platforms") or []:
revision = str(read.get("revision") or "") or build_revision(profile, str(platform))
# A closed build is named by its binary: an address ref is
# skipped below, a source path cannot exist at a sha256.
revision = (str(read.get("revision") or read.get("binary_sha256") or "")
or build_revision(profile, str(platform)))
row = {"platform": str(platform), "revision": revision or "",
"ref": citation.ref, "field": citation.field}
if revision is None:
+1 -1
View File
@@ -147,7 +147,7 @@ def _config_reads_without_build(path: Path, document: object) -> list[str]:
for index, read in enumerate(document.get("config_reads") or []):
if not isinstance(read, dict):
continue
if read.get("revision"):
if read.get("revision") or read.get("binary_sha256"):
continue
for platform in read.get("platforms") or []:
if str(platform) not in builds:
+33
View File
@@ -261,6 +261,8 @@ class Invariants(unittest.TestCase):
), [])
pinned = [{**reads[0], "revision": "c" * 40, "revision_from": "the exe"}]
self.assertEqual(_config_reads_without_build(path, {"config_reads": pinned}), [])
closed = [{**reads[0], "binary_sha256": "d" * 64, "revision_from": "the archive"}]
self.assertEqual(_config_reads_without_build(path, {"config_reads": closed}), [])
class BuildRefs(unittest.TestCase):
@@ -299,6 +301,37 @@ class BuildRefs(unittest.TestCase):
self.assertNotIn(("b" * 40, "ROCKNIX x.patch"), asked)
def test_a_closed_build_is_read_in_its_binary(self) -> None:
"""An address ref is read in the binary binary_sha256 names, never
fetched; a source path cannot exist at a closed build."""
read = {
"file": "SSF.ini", "platforms": ["retrobat"], "binary_sha256": "e" * 64,
"revision_from": "the archive", "source_ref": "SSF.exe 0x10-0x20", "keys": [],
}
class View:
repo, field = "repo", "source"
class Citation:
def __init__(self, ref: str) -> None:
self.ref, self.field = ref, "c"
asked: list[str] = []
def fetch(_repo: str, _revision: str, path: str) -> list[str] | None:
asked.append(path)
return None
rows = _check_build_refs(
{"config_reads": [read]},
[(Citation("SSF.exe 0x10-0x20"), read), (Citation("src/a.c:3"), read)],
[View()], fetch,
)
self.assertEqual([r["status"] for r in rows], ["BUILD_OK", "BUILD_GONE"])
self.assertEqual({r["revision"] for r in rows}, {"e" * 64})
self.assertEqual(asked, ["src/a.c"])
class RepositoryRecords(unittest.TestCase):
"""The placement chains the audit of 2026-11-10 found moving files."""