# CD32 Native-Akiko — Broad-Compat Release

Experimental MiSTer Minimig-AGA fork that implements native CD32 Akiko CD-DMA
instead of the IDEFix97 / CD32-Emulator workaround. The previous releases
(`mvp` → `saves` → `fastpush`) drove Cannon Fodder end-to-end on real
hardware. **This release widens the bridge to a much broader CD32 fleet**:
13 of 14 sampled CD32 titles now reach their title screens via a single MGL
launcher, including titles that previously hit BIOS retry storms or post-TOC
hangs.

NVRAM save persistence and the 2.4× faster `UIO_SECTOR_RD` push path from the
fastpush release are unchanged and on by default.

## What's new vs. the fast-push release

### Audio + OOB PLAY DATA refusal (the big one)

Several titles (Chuck Rock 2, HeroQuest 2, Microcosm, Lemmings) issued
`PLAY DATA` against LBAs that lie inside an audio track, in pre-gap, or
past lead-out. The legacy bridge replied with `CDS_ERROR`, which the CD32
BIOS treats as transient and retries forever — manifesting as a garbage-CMD
storm post-splash with the title locked at a black screen.

Fixed in `cmd_play_msf`: the bridge now classifies the requested LBA against
the parsed TOC. If it falls in an audio range, in pre-gap (re-classified to
the next track), or past lead-out, the bridge replies `CDS_PLAYEND` instead
of `CDS_ERROR`. `CDS_PLAYEND` is the "you reached the end of playable data"
status — the BIOS accepts it and moves on, breaking the retry loop.

WinUAE booted these same `.cue` files cleanly, which was the tell that this
was a bridge defect, not a content issue.

### Unmount-then-reset CHD leak fix

`ide_open(0, "")` (the eject path) used to leave `drive->chd_f` allocated
and forced `drive->cd = 1` for placeholder-mount compatibility, so
`cd_is_mounted()` kept returning true after an eject. Result: after
unmounting, the next reset would re-boot the prior disc instead of booting
clean.

`ide.cpp` now calls `cdrom_close_chd` and clears
`akiko_cd32_set_cd_path("")` in the eject path so the slot is genuinely
empty.

### TOC `MAX_POINTS` 16 → 32

Fire & Ice has 23 CDDA tracks. The 16-entry TOC parser silently truncated
the last seven, after which the BIOS hung post-scan-TOC waiting on tracks
that never landed. Bumped to 32. Was originally misdiagnosed as needing
M6-scope CDDA work — it was a one-line fix.

### Negative-LBA PBX feed: skip-push like WinUAE

CD32 BIOS occasionally requests pre-gap PLAY DATA at negative LBAs. The
bridge used to push zero sectors there, which the BIOS treated as data
errors and retried in a loop. WinUAE skip-pushes (no sector posted, no
error replied) until the read crosses into a valid LBA. Matched.

A diagnostic `printf("%u", lba)` was hiding the bug too — `-6` was logging
as `4294967290`. Fixed.

### Phase 33-E: boot-with-no-CD then mount works

Launching the no-CD MGL and then mounting a CHD via OSD now reaches the
cold-boot Akiko auto-init path via a deferred `minimig_reset()`. Hot-swaps
during gameplay still go through the WinUAE-style `mediachange` push.
Useful for testing CHDs without rebuilding a per-title CFG/MGL pair.

## Compatibility (sampled fleet)

Tested 2026-05-08 against 14 CD32 titles by mounting their CHDs through the
included MGLs and confirming title-screen reach. Discs were stock dumps
from the standard CD32 release set.

| Title | Boots | Notes |
|---|---|---|
| Cannon Fodder (1993, Virgin) | OK | M5 baseline; intro → HEROES menu |
| Alien Breed: Special Edition | OK | |
| Beavers | OK | |
| Brian the Lion (BSS / Brutal Sports Football) | OK | |
| Chuck Rock | OK | |
| Chuck Rock 2 | OK | Required audio+PLAY DATA fix |
| Defender of the Crown II (DotC) | OK | |
| Fire & Ice | OK | Required TOC cap 16→32 |
| Frontier: Elite II | OK | |
| HeroQuest 2 | OK | Required audio+PLAY DATA fix |
| Jim Power | OK | |
| Lemmings | OK | Required audio+PLAY DATA fix |
| Lost Vikings | OK | |
| Microcosm (US + EU) | OK | Required audio+PLAY DATA fix |
| Simon the Sorcerer | OK | |
| Theme Park (1995 EU, Mindscape) | OK | |
| Theme Park (1994 M4, Bullfrog) | **No** | Content issue: installer disc, no `s/` dir on root. Not a bridge bug — WinUAE with a real CD32 Kickstart fails the same way. Use the 1995 EU disc. |
| Trivial Pursuit | OK | |

The MGL/CFG launchers for all of the above ship in this release. Drop in
your own CHD path (offset 0x418 in the .cfg) for any title not listed and
it should "just work" if its disc layout is similar to the tested set.

## Files

| File | Path on MiSTer | Purpose |
|---|---|---|
| `MiSTer` | `/media/fat/MiSTer` | Patched Main_MiSTer userspace (Akiko bridge + canonical SD-block NVR + UIO_SECTOR_RD fast push + audio/PLAY DATA refusal + unmount cleanup) |
| `Minimig.rbf` | `/media/fat/_Test/Minimig.rbf` | Patched Minimig-AGA core (NATIVE_CD32=1, hps_io VDNUM=2 BLKSZ=3, akiko sector slot 1) |
| `*-CD32MVP.cfg` | `/media/fat/config/<name>.cfg` | Per-title launch config (binds CHD + Kickstart) |
| `*-CD32MVP.mgl` | `/media/fat/_Computer/<name>.mgl` | Per-title launcher entry |
| `CD32-NoCD-MVP.cfg` / `.mgl` | as above | No-CD test launcher (Kickstart only; mount CHD via OSD) |

## Building the CD32 ROM (1MB combined)

The CD32 needs a 1MB ROM image consisting of the standard Amiga Kickstart 3.1
(512KB) followed by the CD32 extended ROM (512KB). It is normally distributed
as two separate 512KB files which must be concatenated into a single 1MB file.

File names vary by source but commonly look like `kick40060.CD32` (the 512KB
Kickstart) and `kick40060.E` (the 512KB extended ROM). Other common names
include `391330-01.U6A` + `391330-01.U6B` halves, etc. Make sure you know
which two files you have. **Order matters: Kickstart first, extended ROM
second.**

**Windows (cmd.exe):**

```
copy /b kick40060.CD32 + kick40060.E cd32.rom
```

**Windows (PowerShell):**

```powershell
[System.IO.File]::WriteAllBytes('cd32.rom', [System.IO.File]::ReadAllBytes('kick40060.CD32') + [System.IO.File]::ReadAllBytes('kick40060.E'))
```

**Linux / macOS (bash/zsh):**

```bash
cat kick40060.CD32 kick40060.E > cd32.rom
```

After concatenation, verify the size is exactly 1048576 bytes (1MB):

- Linux / macOS: `wc -c cd32.rom`
- Windows PowerShell: `(Get-Item cd32.rom).Length`

The native-Akiko core takes natural-byte-order ROMs (no byte-swap).

Place the resulting `cd32.rom` somewhere on the SD card or USB and update
the kickstart path in each `.cfg` file (offset 0x00C as a NUL-terminated
relative path) to point to it.

## Prerequisites

- MiSTer SD card with a CD32 Kickstart ROM at the path encoded in the
  bundled .cfg files (currently `/media/usb0/Games/Amiga/roms/Caldor/cd32_swapped.rom`).
- Per-title CHDs at the paths encoded in each .cfg (offset 0x418).
  The shipped CFGs assume `/media/usb0/Games/Amiga/CHD/<title>.chd`.

Adjust paths in the `.cfg` files if your layout differs.

## Install

1. Back up your existing `/media/fat/MiSTer` and any `/media/fat/Minimig*.rbf`.
2. Copy `MiSTer` to `/media/fat/MiSTer`, `chmod +x` it.
3. Copy `Minimig.rbf` to `/media/fat/_Test/Minimig.rbf` (or replace the
   production `Minimig_<date>.rbf` if you want it to be the default).
4. Copy the `.cfg` files to `/media/fat/config/`.
5. Copy the `.mgl` files to `/media/fat/_Computer/`.
6. Reboot MiSTer (`killall MiSTer` works; no supervisor on this device).

The fast push path is on by default. To revert to the slow path for
diagnostic A/B comparison without rebuilding, restart MiSTer with
`AKIKO_SLOW_PUSH=1` in its environment.

## Test

- **Boot a title**: from MiSTer menu, navigate to Computer → `<Title>-CD32MVP`.
  The title should boot to its main menu / title screen.
- **No-CD mount path**: launch `CD32-NoCD-MVP`, then mount any CD32 CHD
  via OSD. The deferred `minimig_reset()` triggers the cold-boot Akiko
  init and the disc plays from a clean state.
- **Save in-game** (titles that support NVR — CF is the verified one):
  complete a mission or use the in-game save dialog. The akiko log will
  show `[akiko] NVR dirty observed at t=...`.
- **Commit on OSD-open**: open the OSD any time after a save. The log
  will show `[akiko] NVR flush: OSD opened with dirty pending` followed
  immediately by `[akiko] NVR saved 1024 bytes to /media/fat/saves/Minimig/cd32-<hash>.nvr`.
- **Reload across reset**: power-cycle or reset MiSTer. On next boot of
  the same CHD, `[akiko] NVR loaded 1024 bytes from .../cd32-<hash>.nvr
  (verify OK)` confirms the byte-for-byte load.
- **Verify the fast path is on**: after launch, check
  `cat /tmp/akiko_dbg.log` for a `sec_req timing N=256` line. Push average
  should be ≈ 950 µs/sector. If you see ≈ 2300 µs/sector you're on the
  slow path (check the env).

## Save layout

- One file per CHD: `/media/fat/saves/Minimig/cd32-<16hex>.nvr` (1024 bytes,
  byte-format compatible with WinUAE's `cd32.nvr`).
- The 16-hex suffix is the FNV-1a-64 hash of the CHD basename, so renaming
  a CHD will start a fresh save slot. Keep the basename stable.
- Saves are byte-format compatible with WinUAE: copy a `cd32-<hash>.nvr`
  over WinUAE's `cd32.nvr` and the title will load the save in WinUAE,
  and vice versa.

## Known issues

- emu PLL setup slack is -0.662 ns. Real-hardware tests pass.
- chd_read latency variability has been observed (10s vs 2 min mission
  loads on the same content). Suspected USB-SATA bridge link power
  management on some SSD enclosures, not a bridge issue. Tracked
  separately.
- Cannon Fodder intro music can sometimes play 30+ seconds before
  graphics appear. Cosmetic, not blocking. Suspected CHD-IO-bound and
  intermittent.
- Theme Park (1994 Bullfrog M4 / installer disc) does not boot — the disc
  has no `s/` directory, so any CD32 Kickstart fails the dosboot. Use the
  1995 EU release instead.
