From 846640dd7c1526cdc7d413ab3beea4128351fa07 Mon Sep 17 00:00:00 2001 From: Abdessamad Derraz <3028866+Abdess@users.noreply.github.com> Date: Wed, 18 Mar 2026 17:37:01 +0100 Subject: [PATCH] feat: emulator mode field, archive ZX81 standalone ROMs emulator profiles support mode: standalone | libretro | both. cross_reference.py skips standalone-only files for libretro platforms. 81.yml: type standalone + libretro, upstream ref added, files listed with mode: standalone and source_refs to both codebases. bios/Sinclair/ZX 81/: zx81.rom (8K) and dkchr.rom (4K) archived. --- bios/Sinclair/ZX 81/dkchr.rom | Bin 0 -> 4096 bytes bios/Sinclair/ZX 81/zx81.rom | Bin 0 -> 8192 bytes database.json | 34 ++++++++++++++++-- emulators/81.yml | 66 +++++++++++++++------------------- scripts/cross_reference.py | 7 ++++ 5 files changed, 67 insertions(+), 40 deletions(-) create mode 100644 bios/Sinclair/ZX 81/dkchr.rom create mode 100644 bios/Sinclair/ZX 81/zx81.rom diff --git a/bios/Sinclair/ZX 81/dkchr.rom b/bios/Sinclair/ZX 81/dkchr.rom new file mode 100644 index 0000000000000000000000000000000000000000..289e5532a7b17d7adae8790acb8b24c74f7c4e37 GIT binary patch literal 4096 zcmds4U1%KF6+ZK$-I2W3j*T9MAf&0igvFS$7$QRY?RRR2zaQ@x}?JB!n2# z2R&?OcB%)rPgVOSNI-sAC@wB(AsC|$JMxBxzJ)@g2hnOF4;u)r7fM+Zt>)%CcUG>G zXG0)oqU4N|8w6oZQDaQ6-8Bbor9$7s;VdmuxHz* zsTC>->oLfF5XW&)DoI9Vu|l4=^0UR2I+ef-N~Gt;^xO;U72q-bA~3@fyjU59Ux;t! zL5SmgNW(GX`^bAgTVT}Pcy**>j-{ME&0nIeJ7EP8^3!$>aP1 zH@i5GSdeL!u`VO~zI`5|Pxb~FCPRJpokw!~*vZ*h3~z3JI!u4NN*!AMHQOgG+i!9o z((9{$*Cjt|T;E@KnXtcpdfjh;<$9jyVq>c>FZjSnOv7`C3a8D6X-e96RR{X7y;Z9b z8Dv<-^avZ+r!t?QEo2FNy7Kn&@-i^1L!YWZ)r?;EJfi2GKQp7Mkk{cDeAjbS%)^Ac z(*@8_uVH?`YMW)MUneAZ{xjZ01!3sbFc!$C}rpA~DWq?g01ICo&BPy%_ zvD9FU-NqtrQ2$W(5EpDF+hcv+uS5;M;rnps_@3uObG_#KwRO1n8lDIL5=(vWGRsHX zoKO`E1MyT<)n|Tf@#bO;_ONI<&cCsSl|cXc>hc0G{7F6b=4Jj@mobiM9_JuTY$uh6 zK!!o;^RN;hTfiF12MDVK{a+$poIeheJ&F^SNjUH*=N7p$Gw!W!LPjA?3kD_KTg*Wy zEekuHwEX4uMg!x_N*GpPr?I}?xSZF5XzR|Mtq5peh&YNY$KTrW9Sg-B^p=%c&fJ`1 zrJ>~vhmI9uT{zVSHAnZ#@jZi?3QM?|mF zvaD9;`0|mNl=*iSmRGMMK2{l45O>E{9nO#A7i8QFtGpN>{m7T39S@O(e!v$W%s4(W z02(cCcgEkR{B!MKK*=dGM#u5B(4Bee?hr{-hpzYfF3agZLr)k2iQ+r`9igd>N`==?nR(EIpf@S!(<9u-9)9p%$Q9Rt!y;r(%!8$RUtZmvI0 zMd(yt~B!*ocbYZ*;~X|r0!XVz+?&a=M%S4J=~0w%9{Ax{|Z9YM_gN==DE?;6V}Rlj1M z6tWK9T|yRMqOC1HXPUyx!SgKPuYw0;*Uer8m>3KZj&R!f(186UA(?U ze{-`Bvs4@(fATJRn#X;X@jv%P^#7bc-KWCD_=)ieT(s3odzY$2^=%tpo%3nrP>}0& z(?EhKm%~Nsajp!rUT4=?t;GexuS6$!bl4sQm}*v^-3fPc5)DzSC1NZW@0+>z7Rhdf`EAOdC(MwU5aJZWv(7)9 zO5j}chlCY>Gs&3wB8rueakegmxOr9GUx`6xPhw literal 0 HcmV?d00001 diff --git a/bios/Sinclair/ZX 81/zx81.rom b/bios/Sinclair/ZX 81/zx81.rom new file mode 100644 index 0000000000000000000000000000000000000000..557ddcbc979a79db44394690b26fd05ca89df1ba GIT binary patch literal 8192 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 aF7S`KYe5#!A?E`8D-BE). - ROM loading is in snap.c:487-512. The memory_load() function matches the - requested ROM filename against a compiled-in table and copies from embedded - byte arrays generated by xxd -i at build time (Makefile.libretro:519-522). - Only two ROMs are embedded: zx81.rom (the ZX81 8K BASIC ROM) and dkchr.rom - (dK'tronics character ROM). Any other ROM name logs an error and returns 0. + Original emulator supports ~15 machines (ZX80, ZX81, Jupiter ACE, TS1500, + Lambda, R470, TK85, ZX97LE, Spectrum variants). Libretro port hardcodes + MACHINEZX81 — only zx81.rom and dkchr.rom are embedded. - The core never calls RETRO_ENVIRONMENT_GET_SYSTEM_DIRECTORY, never opens - files from the filesystem for ROM data, and need_fullpath is set to false - (libretro.cpp:308). All ROM data is baked into the compiled .so/.dll. +files: + # mode: standalone = only needed when running as standalone emulator + # mode: libretro = only needed when running as libretro core + # mode: both (default if absent) = needed in both modes - No external BIOS or firmware files are needed. + # ref: 81-libretro/81/zx81/snap.c:37,489-496 — embedded as bin_ROM_zx81_rom + # ref: EightyOne/Source/zx81/snap.cpp:1219-1279 — open(cwd/ROM/zx81.rom) + - name: zx81.rom + system: sinclair-zx81 + required: true + mode: standalone + size: 8192 + note: "ZX81 8K BASIC ROM. Embedded in libretro core, external for standalone." + source_ref: "EightyOne/Source/zx81/snap.cpp:1264, 81-libretro/81/zx81/snap.c:489" -files: [] - -analysis: - embedded_roms: - zx81_rom: - variable: bin_ROM_zx81_rom - source_file: "bin/ROM/zx81.rom" - build_step: "xxd -i -> C array" - source_ref: "snap.c:489-498" - dkchr_rom: - variable: bin_ROM_dkchr_rom - source_file: "bin/ROM/dkchr.rom" - build_step: "xxd -i -> C array" - source_ref: "snap.c:499-508" - machine_roms: - notes: | - eo.c sets CurRom based on machine type. The libretro port forces - MACHINEZX81 (eo.c:39-41), so CurRom is always zx81.ROM81 which - defaults to "zx81.rom". Other machine ROMs (zx80, ace, ts1500, - lambda, zx97le, ringo470, tk85) are referenced but only zx81.rom - and dkchr.rom are embedded. Selecting other machines would log - "ROM not found" and load nothing. - filesystem_access: false - system_directory_used: false + # ref: 81-libretro/81/zx81/snap.c:38,499-508 — embedded as bin_ROM_dkchr_rom + - name: dkchr.rom + system: sinclair-zx81 + required: false + mode: standalone + size: 4096 + note: "dK'tronics character ROM. Embedded in libretro core." + source_ref: "81-libretro/81/zx81/snap.c:499" diff --git a/scripts/cross_reference.py b/scripts/cross_reference.py index ff0d5300..659d31aa 100644 --- a/scripts/cross_reference.py +++ b/scripts/cross_reference.py @@ -106,6 +106,13 @@ def cross_reference( if not fname: continue + # Skip standalone-only files when comparing against libretro + # platforms (RetroArch, Lakka, etc.). These files are embedded + # in the core and don't need to be in the platform pack. + file_mode = f.get("mode", "both") + if file_mode == "standalone": + continue + in_platform = fname in platform_names in_repo = _find_in_repo(fname, by_name, by_name_lower)