fix: keep the cache usable when a path is both

This commit is contained in:
Abdessamad Derraz committed 2026-08-10 19:10:26 +02:00
1 parent 1ac569b98e
commit 5330ed1950
5 files changed
+33 -13

No files matched your search

+6 -6
View File
@@ -16,14 +16,14 @@ systems:
# Original code from https://codeberg.org/iyzsong/gam4980, based on the
# BA4988 BBK simulator by Wuyun. Uses a 6502-based CPU with banked ROM access.
#
# ROM loading (src/libretro.c:692-760, sys_init):
# ROM loading (libretro.c:692-760, sys_init):
# Opens romdir/8.BIN and reads 0x200000 bytes (2 MB) into sys.rom_8 (font ROM).
# Opens romdir/E.BIN and reads 0x200000 bytes (2 MB) into sys.rom_e (OS ROM).
# The upstream has error handling (error_msg + RETRO_ENVIRONMENT_SHUTDOWN on
# missing files). The fork (ThisBoringWorld) removed these checks -- crashes
# on missing files.
#
# Memory map (src/libretro.c:109-110, 300-305):
# Memory map (libretro.c:109-110, 300-305):
# 0x800000-0x9FFFFF rom_8 (font ROM, 8.BIN)
# 0xE00000-0xFFFFFF rom_e (OS ROM, E.BIN)
#
@@ -42,19 +42,19 @@ files:
required: true
system: bbk-longman-4980
note: "Font ROM (2 MB). Loaded at 0x800000."
source_ref: "src/libretro.c:716-718"
source_ref: "libretro.c:716-718"
- name: "gam4980/E.BIN"
size: 2097152
required: true
system: bbk-longman-4980
note: "OS ROM (2 MB). Loaded at 0xE00000."
source_ref: "src/libretro.c:720-722"
source_ref: "libretro.c:720-722"
platform_details:
bios_mapping:
target: "0x800000-0x9FFFFF (font), 0xE00000-0xFFFFFF (OS) in banked address space"
source_ref: "src/libretro.c:109-110, 300-305"
source_ref: "libretro.c:109-110, 300-305"
note: |
sys.rom_8 and sys.rom_e are flat 2 MB arrays. The CPU accesses them
through bank-switched memory (PA() macro resolves virtual to physical
@@ -62,7 +62,7 @@ platform_details:
the banking system.
load_path:
source_ref: "src/libretro.c:1173-1175"
source_ref: "libretro.c:1173-1175"
note: |
retro_init() builds the path as {system_directory}/gam4980/ and
passes it to sys_init(). Files must be named exactly 8.BIN and
+2 -2
View File
@@ -31,7 +31,7 @@ files:
aliases: [ROM.01, ROM.03, APPLE2GS.ROM, APPLE2GS.ROM2, xgs.rom, XGS.ROM, Rom03gd, 342-0077-b]
required: true
description: "Apple IIGS system ROM"
source_ref: "config.c:131,403-406,1092-1149"
source_ref: "gsplus/src/config.c:131,403-406,1092-1149"
note: "Accepted sizes: 32768 (Apple //e), 131072 (ROM 01), 262144 (ROM 03)"
validation: [size]
@@ -42,5 +42,5 @@ files:
size: 256
description: "Disk II controller PROM (slot 6)"
validation: [size]
source_ref: "config.c:414-415,1168-1220"
source_ref: "gsplus/src/config.c:414-415,1168-1220"
note: "Built-in PROM generated from XOR diffs against main ROM"
+3 -3
View File
@@ -475,7 +475,7 @@ files:
md5: 57af4ae21d4b705c2991d98ed5c1f7b8
crc32: f833d117
note: "C64 BASIC V2 ROM (DTV copy). Embedded in core."
source_ref: "vice/data/C64DTV/"
source_ref: "vice/data/C64DTV/basic-901226-01.bin"
- name: "vice/C64DTV/chargen-901225-01.bin"
system: commodore-c64dtv
@@ -487,7 +487,7 @@ files:
md5: 12a4202f5331d45af846af6c58fba946
crc32: ec4272ee
note: "C64 Character Generator (DTV copy). Embedded in core."
source_ref: "vice/data/C64DTV/"
source_ref: "vice/data/C64DTV/chargen-901225-01.bin"
- name: "vice/C64DTV/kernal-901227-03.bin"
system: commodore-c64dtv
@@ -499,7 +499,7 @@ files:
md5: 39065497630802346bce17963f13c092
crc32: dbe3e7c7
note: "C64 Kernal Rev 3 (DTV copy). Embedded in core."
source_ref: "vice/data/C64DTV/"
source_ref: "vice/data/C64DTV/kernal-901227-03.bin"
# -------------------------------------------------------
# VIC-20 ROMs (vice_xvic)
+11 -2
View File
@@ -213,8 +213,17 @@ def cache_path(cache_dir: str, repo: Repo, sha: str, path: str) -> Path:
def write_cache(target: Path, text: str) -> None:
"""Atomic write: unique scratch in the target directory, then replace."""
target.parent.mkdir(parents=True, exist_ok=True)
"""Atomic write: unique scratch in the target directory, then replace.
A profile can cite both a directory and files inside it, and the first
citation caches `vice/data/C64DTV` as a file, which then blocks the
directory the second one needs. The cache is derived data, so a collision
skips the write rather than failing the read.
"""
try:
target.parent.mkdir(parents=True, exist_ok=True)
except (FileExistsError, NotADirectoryError):
return
fd, scratch = tempfile.mkstemp(dir=str(target.parent), suffix=".part")
try:
with os.fdopen(fd, "w", encoding="utf-8") as fh:
+11
View File
@@ -309,6 +309,17 @@ class TestCache(unittest.TestCase):
self.assertEqual([p.name for p in siblings], ["f.txt"])
class TestCacheCollision(unittest.TestCase):
def test_a_file_where_a_directory_is_needed_skips_the_write(self):
# A profile citing both a directory and files inside it caches the
# directory as a file first; that must not break the files.
with tempfile.TemporaryDirectory() as root:
base = Path(root)
(base / "C64DTV").write_text("", encoding="utf-8")
upstream.write_cache(base / "C64DTV" / "basic.bin", "data")
self.assertTrue((base / "C64DTV").is_file())
class TestRevisions(unittest.TestCase):
def setUp(self):
self.tmp = tempfile.TemporaryDirectory()