From 499ede4e8601e4bd07633afe637cdbd9cb9e4cbe Mon Sep 17 00:00:00 2001 From: WizzardSK <42868978+WizzardSK@users.noreply.github.com> Date: Sun, 12 Jul 2026 16:20:31 +0200 Subject: [PATCH 1/2] core options: group the flat option list into v2 categories The option list had grown long and mostly uncategorized (24 options in the flat root plus a stray reference to a non-existent "5200" category). Distribute every option across the v2 categorized menu so the list reads at a glance: - System: Atari model, OS/BASIC ROMs, RAM expansions (Mosaic/Axlon/ MapRAM), XEP80, R-Time 8, stereo POKEY, legacy config file - Video / Input: unchanged, plus Joystick Autofire and the 5200 analog center moved into Input (the latter also fixes its dangling "5200" category_key) - Media (new): SIO acceleration, cassette boot, slow binary loading, cartridge autodetect, host P:/R: device redirection - On-Screen Display (new): speed %, disk/tape activity, sector/block counter, 1200XL LEDs Data-only change to option_defs_us category keys + option_cats_us; no behaviour change. Builds clean; RetroArch registers it via SET_CORE_OPTIONS_V2_INTL with no errors. --- libretro/libretro_core_options.h | 67 +++++++++++++++++++------------- 1 file changed, 41 insertions(+), 26 deletions(-) diff --git a/libretro/libretro_core_options.h b/libretro/libretro_core_options.h index 90d6054..62e8059 100644 --- a/libretro/libretro_core_options.h +++ b/libretro/libretro_core_options.h @@ -397,6 +397,11 @@ extern "C" { } struct retro_core_option_v2_category option_cats_us[] = { + { + "system", + "System", + "Emulated machine and hardware: Atari system model, OS and BASIC ROMs, RAM expansions, and add-on hardware. Most take effect after a restart." + }, { "video", "Video", @@ -407,6 +412,16 @@ struct retro_core_option_v2_category option_cats_us[] = { "Input", "Configure 5200 Digital and Analog Joystick sensitivity and Analog deadzone. Activate Swap, Dual Joysticks or Joy 2B+. Activate Paddle mode and set Paddle speed. Set retroarch keyboard type." }, + { + "media", + "Media", + "Disk, tape and cartridge loading behaviour: SIO acceleration, cassette boot, binary-load speed, cartridge autodetect, and host P:/R: device redirection." + }, + { + "osd", + "On-Screen Display", + "On-screen indicators drawn over the emulation: emulation speed, disk/tape activity, sector/block counter, and 1200XL LEDs." + }, { NULL, NULL, NULL }, }; @@ -805,7 +820,7 @@ struct retro_core_option_v2_definition option_defs_us[] = { NULL, "Select system emulated. Atari 5200 for Atari 5200 console games. 400/800 (OS B) for <48K games or ones that require OS/B. 800XL (64K) works for most content. 130XE (128K), Modern XL/XE(320K Compy Shop), Modern XL/XE(576K), Modern XL/XE(1088K) for content that needs more than 64K. Atari XE Game System for the Atari XE Game System or XEGS console games.", NULL, - NULL, + "system", { { "400/800 (OS B)", "Atari 400/800 (OS B)" }, { "800XL (64K)", "Atari 800XL (64K)" }, @@ -825,7 +840,7 @@ struct retro_core_option_v2_definition option_defs_us[] = { NULL, "Enable for content that needs Atari BASIC in order to run. A proper ROM file (ATARIBAS.ROM) is needed.", NULL, - NULL, + "system", { { "disabled", NULL }, { "enabled", NULL }, @@ -839,7 +854,7 @@ struct retro_core_option_v2_definition option_defs_us[] = { NULL, "Select the operating-system ROM revision used by the Atari 400/800. 'Auto' picks a revision automatically. 'AltirraOS' uses the bundled open-source replacement ROM (no original ROM required). Other revisions require the matching ROM file in the system directory.", NULL, - NULL, + "system", { { "auto", "Auto" }, { "Rev. A NTSC", NULL }, @@ -856,7 +871,7 @@ struct retro_core_option_v2_definition option_defs_us[] = { NULL, "Select the operating-system ROM revision used by the Atari XL/XE/XEGS. 'Auto' picks a revision automatically. 'AltirraOS' uses the bundled open-source replacement ROM (no original ROM required). Other revisions require the matching ROM file in the system directory.", NULL, - NULL, + "system", { { "auto", "Auto" }, { "AA00 Rev. 10", NULL }, @@ -881,7 +896,7 @@ struct retro_core_option_v2_definition option_defs_us[] = { NULL, "Select the BIOS ROM revision used by the Atari 5200. 'Auto' picks a revision automatically. 'AltirraOS' uses the bundled open-source replacement ROM (no original ROM required). Other revisions require the matching ROM file in the system directory.", NULL, - NULL, + "system", { { "auto", "Auto" }, { "Original", NULL }, @@ -897,7 +912,7 @@ struct retro_core_option_v2_definition option_defs_us[] = { NULL, "Select the Atari BASIC ROM revision. 'Auto' picks a revision automatically. 'Altirra BASIC' uses the bundled open-source replacement (no original ROM required). Other revisions require the matching ROM file in the system directory.", NULL, - NULL, + "system", { { "auto", "Auto" }, { "Rev. A", NULL }, @@ -914,7 +929,7 @@ struct retro_core_option_v2_definition option_defs_us[] = { NULL, "Emulate the Mosaic RAM expansion (Atari 400/800 only). Adds RAM-select boards mapped at $4000-$7FFF. Mutually exclusive with the Axlon expansion.", NULL, - NULL, + "system", { { "disabled", NULL }, { "16 KB", "16 KB (1 board)" }, @@ -930,7 +945,7 @@ struct retro_core_option_v2_definition option_defs_us[] = { NULL, "Emulate the Axlon 128K-compatible bank-switched RAM expansion (Atari 400/800 only). Mutually exclusive with the Mosaic expansion.", NULL, - NULL, + "system", { { "disabled", NULL }, { "128 KB", NULL }, @@ -949,7 +964,7 @@ struct retro_core_option_v2_definition option_defs_us[] = { NULL, "The real Axlon board mirrored its bank-select register at $0FC0-$0FFF; some compatibles did not. Enable for full Axlon compatibility.", NULL, - NULL, + "system", { { "disabled", NULL }, { "enabled", NULL }, @@ -963,7 +978,7 @@ struct retro_core_option_v2_definition option_defs_us[] = { NULL, "Enable MapRAM RAM-under-ROM mapping (Atari XL/XE only), mirroring the OS ROM into RAM for a small speed-up used by some enhanced systems.", NULL, - NULL, + "system", { { "disabled", NULL }, { "enabled", NULL }, @@ -977,7 +992,7 @@ struct retro_core_option_v2_definition option_defs_us[] = { NULL, "Autofire mode for all joystick ports. Fire: autofire while the fire button is held. Always: continuous autofire without holding the button.", NULL, - NULL, + "input", { { "disabled", NULL }, { "fire", "While fire held" }, @@ -992,7 +1007,7 @@ struct retro_core_option_v2_definition option_defs_us[] = { NULL, "Overlay the emulation speed as a percentage on screen.", NULL, - NULL, + "osd", { { "disabled", NULL }, { "enabled", NULL }, @@ -1006,7 +1021,7 @@ struct retro_core_option_v2_definition option_defs_us[] = { NULL, "Overlay a disk-drive / tape activity indicator on screen.", NULL, - NULL, + "osd", { { "disabled", NULL }, { "enabled", NULL }, @@ -1020,7 +1035,7 @@ struct retro_core_option_v2_definition option_defs_us[] = { NULL, "Overlay the current disk sector / tape block number on screen.", NULL, - NULL, + "osd", { { "disabled", NULL }, { "enabled", NULL }, @@ -1034,7 +1049,7 @@ struct retro_core_option_v2_definition option_defs_us[] = { NULL, "Overlay the two 1200XL keyboard LEDs on screen (Atari 1200XL only).", NULL, - NULL, + "osd", { { "disabled", NULL }, { "enabled", NULL }, @@ -1048,7 +1063,7 @@ struct retro_core_option_v2_definition option_defs_us[] = { NULL, "Emulate the XEP80 80-column display interface on the chosen joystick port. Requires the XEP80 charset ROM.", NULL, - NULL, + "system", { { "disabled", NULL }, { "port 1", "Port 1" }, @@ -1063,7 +1078,7 @@ struct retro_core_option_v2_definition option_defs_us[] = { NULL, "Emulate the ICD R-Time 8 real-time clock cartridge.", NULL, - NULL, + "system", { { "disabled", NULL }, { "enabled", NULL }, @@ -1077,7 +1092,7 @@ struct retro_core_option_v2_definition option_defs_us[] = { NULL, "Enable the P: printer device SIO patch.", NULL, - NULL, + "media", { { "disabled", NULL }, { "enabled", NULL }, @@ -1091,7 +1106,7 @@ struct retro_core_option_v2_definition option_defs_us[] = { NULL, "Enable the R: serial device SIO patch (Atari 850 emulation / Coder's Cable).", NULL, - NULL, + "media", { { "disabled", NULL }, { "enabled", NULL }, @@ -1105,7 +1120,7 @@ struct retro_core_option_v2_definition option_defs_us[] = { NULL, "Load DOS binary (.xex) files at the slower, more accurate original speed instead of instantly.", NULL, - NULL, + "media", { { "disabled", NULL }, { "enabled", NULL }, @@ -1119,7 +1134,7 @@ struct retro_core_option_v2_definition option_defs_us[] = { NULL, "This enables ALL SIO acceleration. Enabled improves loading speed for Disk and Cassette images. Disable only for protected disk (.ATX) and protected cassette images. Reboot required if change made while loading a cassette image.", NULL, - NULL, + "media", { { "disabled", NULL }, { "enabled", NULL }, @@ -1133,7 +1148,7 @@ struct retro_core_option_v2_definition option_defs_us[] = { NULL, "Forces emulated system to boot from autoboot cassette images by holding down the \"START\" key on boot.", NULL, - NULL, + "media", { { "disabled", NULL }, { "enabled", NULL }, @@ -1147,7 +1162,7 @@ struct retro_core_option_v2_definition option_defs_us[] = { NULL, "Emulates the Atari Stereo Sound Mod (second POKEY chip at $D210-$D21F on 800/XL/XE). Stock 800/XL/XE has only one POKEY -- leave this disabled for authentic behavior. Some games (Bounty Bob Strikes Back, Road Race) use POKEY register mirroring tricks that lock up or lose audio when stereo is enabled. The Atari 5200 always uses mono regardless of this setting.", NULL, - NULL, + "system", { { "disabled", NULL }, { "enabled", NULL }, @@ -1161,7 +1176,7 @@ struct retro_core_option_v2_definition option_defs_us[] = { NULL, "If the Atari800 legacy configuration file, .atari800.cfg, is found, it will be loaded, and if not found, a new will be created.", NULL, - NULL, + "system", { { "disabled", NULL }, { "enabled", NULL }, @@ -1176,7 +1191,7 @@ struct retro_core_option_v2_definition option_defs_us[] = { NULL, "Emulator will auto detect Atari cartridge based on checksum. (requires good ROM dumps).", NULL, - NULL, + "media", { { "disabled", NULL }, { "enabled", NULL }, @@ -1191,7 +1206,7 @@ struct retro_core_option_v2_definition option_defs_us[] = { NULL, "Set the value for emulated analog joystick or paddle center. Use this to properly center player for some games like Kaboom, Starwars or Super Breakout. Default is 114", NULL, - "5200", + "input", { { "80", NULL }, { "82", NULL }, From 59f498d823574076d70cc1d5ed1c74fbc5a4fbeb Mon Sep 17 00:00:00 2001 From: WizzardSK <42868978+WizzardSK@users.noreply.github.com> Date: Sun, 12 Jul 2026 20:38:03 +0200 Subject: [PATCH 2/2] cassette: reboot boot tapes on reset instead of dropping to self-test A machine-language boot tape loaded fine the first time but would not reload on Reset -- the machine came up on the green self-test screen instead. Cause: the cassette boot handshake in gtia.c consumes CASSETTE_hold_start once the tape boots (`CASSETTE_hold_start = CASSETTE_hold_start_on_reboot`), and hold_start_on_reboot defaulted to 0. So after the first boot hold_start was 0, and retro_reset's cold-start no longer held START, so the (rewound) tape never booted and the machine fell through to self-test. Set CASSETTE_hold_start_on_reboot alongside CASSETTE_hold_start from the "Cassette boot" core option: enabled -> 1 (hold_start survives the boot and every subsequent reset re-boots the tape), disabled -> 0 (unchanged; BASIC/CLOAD tapes still come up at the prompt for manual loading, so the recent reset fix for those is preserved). --- libretro/libretro-core.c | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/libretro/libretro-core.c b/libretro/libretro-core.c index faa7c35..c21166a 100644 --- a/libretro/libretro-core.c +++ b/libretro/libretro-core.c @@ -232,6 +232,7 @@ extern int CASSETTE_Insert(const char* filename); extern void CASSETTE_Remove(void); extern void CASSETTE_Seek(unsigned int position); extern int CASSETTE_hold_start; +extern int CASSETTE_hold_start_on_reboot; //extern int SIO_RotateDisks(void); @@ -1100,10 +1101,19 @@ static void update_variables(void) if (strcmp(var.value, "enabled") == 0) { CASSETTE_hold_start = 1; + /* Persist the START-held state across reboots: the cassette boot + * handshake (gtia.c) consumes CASSETTE_hold_start into + * CASSETTE_hold_start_on_reboot once the tape boots. With this at 0 + * (the default), a boot tape loads the first time but a subsequent + * reset cold-starts without holding START -> the machine drops to + * the self-test screen instead of reloading. Keeping it at 1 makes + * every reset re-boot the (rewound) tape. */ + CASSETTE_hold_start_on_reboot = 1; } else if (strcmp(var.value, "disabled") == 0) { CASSETTE_hold_start = 0; + CASSETTE_hold_start_on_reboot = 0; } if (!libretro_runloop_active)