# CD32 Native-Akiko — Saves Release

Experimental MiSTer Minimig-AGA fork that implements native CD32 Akiko CD-DMA
instead of the IDEFix97 / CD32-Emulator workaround. Boots Cannon Fodder
(1993, Virgin) end-to-end on real MiSTer hardware via a single MGL launcher,
**with full NVRAM save persistence across reboots**.

## What's new vs. the MVP build

The previous `CD32-native-mvp` release wrote saves to disk in WinUAE-compatible
format but couldn't reload them on hardware (BRAM stayed at the .mif baseline,
the I²C-injection FSM never fired in the field). This build replaces that path
with the canonical MiSTer SD-block protocol that all the official cores use:

- **Per-game `cd32-<hash>.nvr` files** under `/media/fat/saves/Minimig/`,
  named by FNV-1a-64 hash of the CHD basename. Loading one game and then
  another doesn't clobber either save.
- **End-to-end save round-trip on hardware**. Mount a CHD → its NVR is
  loaded into the akiko EEPROM via `img_mounted` + `sd_buff_wr` &
  `sd_ack`. In-game writes set a dirty bit; userspace flushes to the same
  file path.
- **OSD-open-edge save trigger** (mirrors the arcade-core nvm_save
  pattern): if the NVR is dirty when you open the OSD, the save commits
  immediately (~10ms) instead of waiting for the 30-second throttle.
  Resetting the core or pulling power right after closing the OSD won't
  lose the save.
- **30-second debounce as a backup commit path**, for cases where the
  user never opens the OSD before resetting.

Both cfg/mgl filenames still carry the `MVP` suffix for continuity with
existing installs — they're internal launcher names, no functional impact.

## Files

| File | Path on MiSTer | Purpose |
|---|---|---|
| `MiSTer` | `/media/fat/MiSTer` | Patched Main_MiSTer userspace (Akiko bridge + canonical SD-block NVR path) |
| `Minimig.rbf` | `/media/fat/_Test/Minimig.rbf` | Patched Minimig-AGA core (NATIVE_CD32=1, hps_io VDNUM=1 BLKSZ=3) |
| `CannonFodder-CD32MVP.cfg` | `/media/fat/config/CannonFodder-CD32MVP.cfg` | CF launch config (binds CHD) |
| `CannonFodder-CD32MVP.mgl` | `/media/fat/_Computer/CannonFodder-CD32MVP.mgl` | CF launcher entry |
| `CD32-NoCD-MVP.cfg` | `/media/fat/config/CD32-NoCD-MVP.cfg` | No-CD test config (kickstart only) |
| `CD32-NoCD-MVP.mgl` | `/media/fat/_Computer/CD32-NoCD-MVP.mgl` | No-CD test launcher |

## 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 the `.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`).
- Cannon Fodder CHD at:
  `/media/usb0/Games/Amiga/CHD/Cannon Fodder (1993)(Virgin)[Amiga-CD32].chd`

Adjust paths in the `.cfg` files if your layout differs (kickstart at offset
0x00C as a NUL-terminated relative path; CHD path at offset 0x418).

## 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 two `.cfg` files to `/media/fat/config/`.
5. Copy the two `.mgl` files to `/media/fat/_Computer/`.
6. Reboot MiSTer (`killall MiSTer` works; no supervisor on this device).

## Test

- **Boot CF**: from MiSTer menu, navigate to Computer → CannonFodder-CD32MVP.
  Cannon Fodder should boot to the HEROES selection menu.
- **Save in-game**: complete a mission or use CF's 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, the NVR slot mounts and `[akiko] NVR loaded 1024 bytes
  from .../cd32-<hash>.nvr (verify OK)` confirms the byte-for-byte load.
  CF's save slot should appear in its load menu.

## 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 CF will load the save in
  WinUAE, and vice versa.

## Known issues

- emu PLL setup slack is -0.400 ns. Real-hardware tests pass; further
  reduction would require another targeted register-stage cut in the
  chipdma_arb / akiko boundary.
- Some users report MGL launches feel slower than the previous build at
  the "Loading Cannon Fodder" splash. Investigation ongoing — leading
  hypothesis is per-iteration UIO overhead from the canonical SD-block
  polling path now being active for Minimig.
