Skip to content

Update atari800 core from 3.1.0 to 5.2.0#123

Open
WizzardSK wants to merge 7 commits intolibretro:masterfrom
WizzardSK:update-atari800-5.2.0
Open

Update atari800 core from 3.1.0 to 5.2.0#123
WizzardSK wants to merge 7 commits intolibretro:masterfrom
WizzardSK:update-atari800-5.2.0

Conversation

@WizzardSK
Copy link
Copy Markdown

@WizzardSK WizzardSK commented Mar 19, 2026

Summary

  • Replace atari800/src/ with standalone atari800 5.2.0 source (from 3.1.0)
  • Re-apply all libretro-specific patches (state save, sound, input, UI, config)
  • Fix crash when TV mode changes before sound initialization (guard POKEYSND_Init against Sound_out.freq==0)

Changes

  • New files: cartridge_info.c/h, file_export.c/h, altirra_5200_charset.c, codecs/, libatari800/, pokeyrec.c/h
  • Removed: emuos.c/h (replaced by EMUOS_ALTIRRA), sndsave.c/h
  • Config: PACKAGE_VERSION 3.1.0 → 5.2.0, added EMUOS_ALTIRRA=1

Replace atari800/src with standalone atari800 5.2.0 source and re-apply
all libretro-specific patches:

- State save/load via memory stream (Retro_SaveAtariState/ReadAtariState)
- Per-subsystem Retro_*_StateSave/StateRead functions
- ROM directory search (retro_system_directory)
- Config file handling (legacy_configuration_file)
- co_switch in Atari800_Sync for libretro coroutine model
- Analog joystick (Atari_POT) and digital 5200 sensitivity
- Stereo sound defaults and POKEYSND_stereo_enabled
- UI menu cleanup (remove screenshot/monitor/exit items)
- CRC-based cart hash detection in AFILE_DetectFileType
- path_mkdir for libretro directory creation

Build system changes:
- Add cartridge_info.c, file_export.c, altirra_5200_charset.c
- Remove emuos.c (replaced by EMUOS_ALTIRRA define), sndsave.c

Config changes:
- PACKAGE_VERSION: 3.1.0 → 5.2.0
- Add EMUOS_ALTIRRA=1 for built-in AltirraOS ROMs

Bug fix:
- Guard POKEYSND_Init in Atari800_SetTVMode against Sound_out.freq==0
  to prevent crash when TV mode changes before sound is initialized
@warmenhoven
Copy link
Copy Markdown

https://git.libretro.com/libretro/libretro-atari800/-/pipelines/64699

Looks like most failures are related to termios.h

termios.h is missing on Windows and transitively broken on devkitPro
platforms (PSP, Vita, 3DS, GC/Wii, Wii U, Switch) where it pulls in a
nonexistent sys/termios.h. monitor.c includes it only when
HAVE_TERMIOS_H is defined, so skip the define on those targets.
@WizzardSK
Copy link
Copy Markdown
Author

Thanks for the pointer! Fixed in 1d7a65flibretro/config.h was defining HAVE_TERMIOS_H unconditionally. Now guarded against Windows and devkitPro targets (PSP, Vita, 3DS, GC/Wii, Wii U, Switch) where termios.h is either missing or transitively pulls in a nonexistent sys/termios.h.

@KamiLordus
Copy link
Copy Markdown

I don't think .a52 files for the Atari 5200 system work. They don't boot. At least on Win 11.

@warmenhoven
Copy link
Copy Markdown

Only one remaining build failure for WiiU missing nanosleep

https://git.libretro.com/libretro/libretro-atari800/-/jobs/1295954

devkitPPC's libc declares nanosleep() in <time.h> but doesn't provide
the symbol at link time, causing the WiiU build to fail. Fall back to
usleep() like VITA/PSP/PS3 do.
@WizzardSK
Copy link
Copy Markdown
Author

Pushed 69e3f38#undef HAVE_NANOSLEEP for WiiU so Util_sleep() falls back to usleep() (same approach as VITA/PSP/PS3). devkitPPC declares nanosleep in <time.h> but doesn't provide the symbol at link time.

@KamiLordus
Copy link
Copy Markdown

KamiLordus commented Apr 23, 2026

@WizzardSK Have you tested the Atari 5200 ROMs?
After testing new build on Windows 11, the .a52 and .bin files have a black screen.
Could you check if it works for you?

@WizzardSK
Copy link
Copy Markdown
Author

WizzardSK commented Apr 23, 2026

Yes, I have tested Atari 5200 games yesterday on Linux and I also having black screen.
I only tested Atari 800 games before, so we need further testing.

edit: I think I found the bug. Tomorrow I will try to do the fix.

The 3.1.0 -> 5.2.0 core update dropped the libretro-specific patch in
atari800/src/cartridge.c (commit 1ac0cbc, 2017) that CRC-autodetected
5200 cart types. Without it, raw .a52/.bin images of common sizes (16K,
32K, 64K, 128K, 256K, 512K) match multiple entries in CARTRIDGES[] and
fall into CARTRIDGE_UNKNOWN, which triggers UI_SelectCartType() during
boot -> black screen.

Re-implement the autodetect in the libretro layer (no change to
atari800/src/):
- carts_hash: new get_5200_cart_atari800_type(crc, size) resolving the
  internal a5200_* category (plus size-based fallback for unlisted
  .a52 files) to CARTRIDGE_5200_* enums.
- libretro-core: compute CRC for .a52 too, store the resolved type in
  autorun5200CartType.
- cmdline: for A5200_CART, invoke atari800 with
  '-5200 -cart-type <N> -cart <file>' so CARTRIDGE_Initialise() preserves
  the commandline-specified type when auto-detect returns UNKNOWN.
@WizzardSK
Copy link
Copy Markdown
Author

Fix for Atari 5200 black screen regression introduced by this PR (commit bc35963).

Bug

Replacing atari800/src/ wholesale dropped the libretro-specific patch in cartridge.c from 2017 (commit 1ac0cbc, "autodetect a52 cart type"), which used atari5200_hash.h CRCs to force the right CARTRIDGE_5200_* type. Without it, raw .a52/.bin images of common sizes (16K, 32K, 64K, 128K, 256K, 512K) match multiple entries in CARTRIDGES[] — so CARTRIDGE_ReadImage() returns CARTRIDGE_UNKNOWN, Atari800_Initialise() falls into UI_SelectCartType() (atari.c:904), and the first-boot libretro UI can't answer → black screen. Matches the long-standing upstream report #79.

Fix (no change to atari800/src/)

  • libretro/carts_hash.{c,h} — new get_5200_cart_atari800_type(crc, size) maps internal a5200_* categories (+ size-based fallback for unlisted .a52) to CARTRIDGE_5200_* enums.
  • libretro/libretro-core.c — compute CRC for .a52 too, store the resolved type in autorun5200CartType.
  • libretro/cmdline.c — for autorunCartridge == A5200_CART, invoke atari800 with -5200 -cart-type <N> -cart <file> instead of the positional prg <file>. CARTRIDGE_Initialise() then preserves the commandline-specified type (see InitInsert() at cartridge.c:1856) even when CARTRIDGE_ReadImage() returns UNKNOWN.

Test

5200 Menu (USA) (Proto).a52 (8 KB → CARTRIDGE_5200_8) boots cleanly and shows the Atari 5200 splash screen in RetroArch (180-frame --max-frames-ss screenshot confirms). Before: black screen.

Upstream atari800 5.2.0 knows only CARTRIDGE_5200_40 (fixed 8K at image
offset 0x8000). The TOSEC dump of Bounty Bob Strikes Back (5200) CRC32
0x7873c6dd has the fixed 8K at image offset 0 and the two banked 16K
regions shifted by +0x2000. Running it through CARTRIDGE_5200_40
produced garbage at the reset vector -> CIM at $0007 and the Atari800
crash monitor.

This was already handled in the 3.1.0 libretro fork via PR libretro#106
(CARTRIDGE_5200_40_ALT, slot 73), but was lost when the core was
replaced wholesale with upstream 5.2.0 in PR libretro#123. Re-add it at slot
104 (first unused slot in upstream 5.2.0 enum):

- atari800/src/cartridge_info.h: add CARTRIDGE_5200_40_ALT = 104.
- atari800/src/cartridge_info.c: add CARTRIDGES[104] entry (40 KB).
- atari800/src/cartridge.c: add ALT case to CartIsFor5200(), cold
  mapping in MapActiveCart(), and runtime bank-switch offsets in
  access_BountyBob1()/access_BountyBob2().
- libretro/carts_hash.c: map a5200_40_ALT -> CARTRIDGE_5200_40_ALT.
@WizzardSK
Copy link
Copy Markdown
Author

Follow-up fix: Bounty Bob Strikes Back! (5200) was crashing with CIM at $0007 (commit 3a6b4c5).

The TOSEC dump CRC32 `0x7873c6dd` has an alternative ROM layout: the fixed 8K block is at image offset 0 (mapped to $8000–$BFFF), with the two banked 16K regions shifted by +0x2000. Running it through the standard `CARTRIDGE_5200_40` (which expects the fixed 8K at image offset 0x8000) produces garbage at the reset vector → CIM → Atari800 crash monitor.

This was already handled in the 3.1.0 fork by PR #106 via a dedicated `CARTRIDGE_5200_40_ALT` cart type (slot 73 back then) with its own `MapActiveCart()` case and shifted offsets in the Bounty Bob bank-switch handlers. That custom cart type was lost when the core was replaced wholesale with upstream 5.2.0 in this PR.

Re-added at slot 104 (first unused slot in upstream 5.2.0's enum):

  • `atari800/src/cartridge_info.h` — `CARTRIDGE_5200_40_ALT = 104`
  • `atari800/src/cartridge_info.c` — `CARTRIDGES[104]` entry (40 KB)
  • `atari800/src/cartridge.c` — ALT case in `CartIsFor5200()`, cold mapping in `MapActiveCart()` (fixed 8K from image+0, banks from image+0x2000 and image+0x6000), runtime bank-switch offset handling in `access_BountyBob1()/access_BountyBob2()`
  • `libretro/carts_hash.c` — `a5200_40_ALT` now maps to `CARTRIDGE_5200_40_ALT` instead of `CARTRIDGE_5200_40`

Verified: `Bounty Bob Strikes Back! (USA).a52` boots to the title screen (Big Five Software copyright 1985) in RetroArch. Before: black screen on boot, then Atari computer crash monitor.

@KamiLordus
Copy link
Copy Markdown

@WizzardSK Unfortunately, all versions of this game still don't work properly:
Atari 5200 version (.a52, .bin files) - freezes in the menu
Atari 800 cartridge version (.car file) - freezes in the menu
Atari 800 tape version (.cas file) - no sound in the game

This is a problem that also occurred in 3.1. But in the standalone 5.2 version, the games work fine.

@KamiLordus
Copy link
Copy Markdown

KamiLordus commented Apr 25, 2026

After some research, I found information that the game uses some form of protection. This likely applies to the Atari 800 and Atari 5200 cartridge versions. I don't think the tape version has protection. The sound issue is likely caused by something else. I don't know if this will be useful (information from the Atariage forum):

" bounty bob uses custom banking scheme, developed for protecting atari 2600 games
repeated pia adresses - resulting in what you can observe here repeated pokey adresses - resulting in lazy birds and game unplayable at all if there is something more than single pokey on the bus if there was a vast amount of games that would use that banking scheme, or coding "standards" this would be noticed, and fixed, but there are none the other example i know of was road race, and i took care to make it playable when releasing u1mb board according to all available literature pokey address range is 0xd200-0xd20f, PIA is 0xd300-0xd303, remaining space is simply the result of address decoder being cheap, and there is no advantage of using remaining space for addressing these chips other than obscuring the code".

https://forums.atariage.com/topic/314050-bounty-bob-strikes-back-problem/#comments

Fixes the menu-freeze regression on Bounty Bob Strikes Back! reported by
@KamiLordus. The 3.1.0 fork's cartridge.c had an explicit
POKEYSND_stereo_enabled = FALSE for Bounty Bob ("game locks") that was
lost when the core was replaced with upstream 5.2.0 in 32cc3b2.

POKEY masks register addresses with 0x0F in mono and 0x1F in stereo
(pokey.c:188). Bounty Bob writes to mirrored POKEY addresses (e.g.
\$E810 on 5200, \$D210 on 800) expecting them to alias to \$E800/\$D200
on a single-POKEY system. With stereo enabled, bit 4 is decoded as
chip-select and those writes vanish into a nonexistent second chip,
leaving the game stuck in the title screen.

Real Atari 5200 has only one POKEY, so stereo is non-authentic for any
5200 cart -- force mono whenever the machine is set to MACHINE_5200.

For Atari 800 .car images, peek at the 4-byte big-endian type field in
the 16-byte CART header; if it's CARTRIDGE_BBSB_40 (18), force mono
before Sound_Initialise() runs.

Verified with Bounty Bob Strikes Back! (USA).a52 (CRC 0x7873c6dd):
attract-mode demo runs after the fix; previously the title screen was
static even after 2000 frames.

Not covered: .cas tape dumps of BBSB (no header to identify the game).
Stock Atari 800/XL/XE has a single POKEY chip. Stereo POKEY is the Atari
Stereo Sound Mod hardware addon (second POKEY at $D210-$D21F). Defaulting
to mono is more authentic and avoids breaking titles that rely on POKEY
register mirroring (Bounty Bob Strikes Back, Road Race) -- those games
write to addresses like $D210 expecting them to alias to $D200, but with
stereo enabled bit 4 is decoded as chip-select and the writes vanish into
a nonexistent second chip.

Adds atari800_pokey_stereo (disabled by default) to the core options.
The option is processed at the top of update_variables(), so the existing
5200 (always mono) and BBSB .car (always mono) overrides still apply on
top of it. To use stereo POKEY mod games, user toggles the option to
enabled and restarts.

Matches standalone atari800 behavior where stereo is a user-controllable
setting (-stereo / -nostereo cmdline, STEREO_POKEY config, or UI toggle)
rather than a forced default.
@WizzardSK
Copy link
Copy Markdown
Author

@KamiLordus Identified the root cause and pushed two follow-up commits.

Root cause

The 3.1.0 fork's cartridge.c had an explicit POKEYSND_stereo_enabled = FALSE for Bounty Bob with the comment "game locks" (PR #106). When this PR replaced atari800/src/ wholesale with upstream 5.2.0 (32cc3b2), that protection was lost.

POKEY masks register addresses with 0x0F in mono and 0x1F in stereo (pokey.c:188). Bounty Bob writes to mirrored POKEY addresses (e.g. $E810 on 5200, $D210 on 800) expecting them to alias to $E800/$D200 on a single-POKEY system. With stereo enabled, bit 4 is decoded as chip-select and those writes vanish into a nonexistent second chip — game locks in the title screen. This matches exactly the AtariAge forum description you linked.

Fixes (commits 01d80d3, d66c6a2)

  1. 5200 always mono — real Atari 5200 has only one POKEY, stereo is non-authentic for any 5200 cart
  2. .car BBSB_40 always mono — peek the 4-byte big-endian type field in the 16-byte CART header before Sound_Initialise()
  3. New atari800_pokey_stereo core option (default: disabled) — stock 800/XL/XE has a single POKEY, so default mono is most authentic and most compatible (BBSB, Road Race, etc.). Users who want to emulate the Atari Stereo Sound Mod toggle it on and restart. Matches standalone atari800 behavior where stereo is a -stereo/-nostereo cmdline / config / UI choice.

Verified

  • Bounty Bob Strikes Back! (USA).a52 (CRC 0x7873c6dd) — attract-mode demo runs after the fix; before, the title screen was static even after 2000 frames.
  • Synthesized BBSB .car triggers the header-peek path (BBSB_40 .car detected, forcing mono POKEY in libretro log).

Not addressed: .cas

I tested both .cas dumps you mentioned ((1985)(U.S. Gold)(PAL)(GB)[64K] CRC 30a923e4, (198x)(Aackosoft)(PAL)(NL)(en)[64K] CRC 874ab34c) headless and via Xvfb+xdotool: both crash with CIM $52 @ $6764 immediately on cold-boot, well before tape loading can begin. The crash reproduces with cassboot enabled/disabled, internalbasic enabled/disabled, on 800XL and 400/800 OS B, and is not affected by the POKEY stereo state. It's a separate regression in the cassette/SIO path of the 5.2.0 import, unrelated to POKEY mirroring — out of scope for this PR. Worth a separate issue if you can reproduce on Windows with the mono default.

@KamiLordus
Copy link
Copy Markdown

KamiLordus commented Apr 25, 2026

First of all, thanks a lot for your work on this.
Regarding tapes, you need to set them in the Atari800 core:
Video > Video Standard > PAL (if you leave NTSC - it will crash)
SIO Acceleration > OFF
Boot from casette > ON

With these settings, the tapes work (no crashes) in version 3a6b4c5 – except there's no sound. Although I don't rule out that the Linux version might be different.

For testing purposes, I'll include my versions of the tapes. If you can, please test them and then remove them. If that doesn't help, let's leave it as is.

@WizzardSK
Copy link
Copy Markdown
Author

@KamiLordus Did some more digging on the .cas audio question with both your tapes (PAL versions you uploaded). Tested on Linux with PAL + cassboot=ON, both with SIO acceleration ON (instant load) and OFF (real ~14 min cassette timing). Here's what I found:

Both .cas files load and run gameplay correctly, with full POKEY audio in-game (verified by recording the libretro audio output to a .wav and measuring RMS — clearly active output during gameplay, not silence).

Title screen comparison:

Variant Title-screen audio In-game audio
Bounty Bob Strikes Back! (USA).a52 (cart) full title music
Bounty Bob Strikes Back! (1985)(U.S. Gold)(PAL)(GB).cas typewriter SFX as letters scroll in, no melody
Bounty Bob Strikes Back! (198x)(Aackosoft)(PAL)(NL).cas typewriter SFX only

So the cart has proper title music and the European budget tape conversions don't — they reuse the simple typewriter "tick" SFX during the intro instead of a melodic theme. That's a property of those specific tape dumps (the conversions stripped the music to fit cassette memory layout), not a regression in this PR. I also cross-checked one of the tapes against standalone atari800 5.0.0 with -pal -boottape — same behavior, no title music there either.

If you're getting genuine silence in-game on Win11 (not just the missing title music), that's almost certainly a RetroArch audio driver / buffer issue rather than a core problem — the POKEY mono fix in d66c6a2 already addresses the underlying mirror-write issue that was breaking BBSB gameplay sound. Worth trying a different audio driver in RetroArch settings (WASAPI ↔ XAudio ↔ DirectSound) once a Win build with this PR's changes is available.

@KamiLordus
Copy link
Copy Markdown

@WizzardSK Very interesting. I usually use sio acceleration off, which often causes crashes for various games on tapes, but I always use the RA fast forward option. I wonder if that's the problem with the lack of sound.
I asked @warmenhoven to merge your latest commits into the WizzardSK repository.

Thanks a lot for checking the tapes and providing the information.

@KamiLordus
Copy link
Copy Markdown

KamiLordus commented Apr 26, 2026

Tested and hurray, all versions work without any problem. Great work WizzardSK!!!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants