When reversing games or hardware-banging software, you will frequently encounter direct accesses to `$DFF000` (Custom Chips), `$BFE001` (CIAA), and `$BFD000` (CIAB).
To make these readable in IDA:
1. Ensure the Amiga NDK headers are loaded (from Step 6).
2. Go to the `Structures` tab and ensure the `Custom` structure (from `hardware/custom.h`) is defined.
3. Jump to address `$DFF000` in the IDA view (you may need to create a dummy data segment at `$DFF000` if one doesn't exist).
4. Apply the `Custom` struct format to the data at `$DFF000` (using `Alt+Q`).
5. When you see an instruction like `MOVE.W D0, $096(A4)` where you know `A4` points to `$DFF000`, press `T` (Struct offset) to map it to the human-readable `dmacon` register.
> [!TIP]
> **Automating with IDAPython:** Instead of mapping structures manually, you can use the Python scripts included in this repository to bulk-define all custom chip and CIA registers specific to your target Amiga model.
> Simply load your binary in IDA 9.x, go to `File > Script file...` (or `Alt-F7`), and select the script. It will automatically create the `HW_CUSTOM`, `HW_CIAA`, and `HW_CIAB` segments, format the data types, and apply the physical register names. This makes hardware accesses immediately readable (e.g., `MOVE.W D0, $DFF096` becomes `MOVE.W D0, DMACON`). Using the correct chipset script ensures you quickly spot if an OCS game accidentally accesses an AGA-only register!
IDA Pro is primarily used for **static analysis** in standard Amiga workflows. Do not attempt to use IDA's Remote GDB debugger out-of-the-box, as standard WinUAE does not contain a GDB stub.
1. Use **IDA Pro** to build the map: label variables, identify routines, and find the target logic (e.g., the copy protection check).
2. Note the physical offset of the instruction in the binary (or its relative location to a known signature).
3. Run the software in **WinUAE**.
4. Press `Shift+F12` to drop into the **WinUAE native debugger**.
5. Set breakpoints (`f <address>`) based on your findings in IDA.
6. Step through the live hardware state natively in WinUAE, where all custom chip registers and DMA timings are perfectly emulated.
---
## Step 10: Patching Workflows
IDA's internal 68k assembler is notoriously finicky for generating inline patches directly in the database. If you need to neutralize a check (e.g., changing a `BNE` to `NOP`s):
1.**Live Testing:** In the WinUAE debugger, use the `a <address>` command to assemble new instructions live in memory, or `w <address> <value>` to write hex bytes directly. Test the patch live before committing it to disk.
2.**Permanent Patching:** Once the offset and replacement bytes are confirmed, use a dedicated hex editor (like HxD or ImHex) on the actual executable file on disk, or write a small Python patcher script to seek and write the bytes.
3.**Advanced Payload Patching:** For large patches that don't fit inline, use `vasm` to assemble a payload block, append it to a new HUNK or overwrite dead code, and redirect the execution flow via a `JMP`.
---
## Step 11: Decompilation Alternatives (Ghidra)
> [!WARNING]
> **Hex-Rays Does Not Support M68k.** The official Hex-Rays decompiler *does not* natively support the Motorola 68000 architecture. IDA Pro will provide world-class disassembly, debugging, and cross-referencing for Amiga binaries, but it **cannot** generate C pseudocode for them.
If C pseudocode generation is a strict requirement for your workflow, you must use **Ghidra**:
1. Ghidra officially supports the 68000 architecture for both disassembly and its integrated decompiler.
2. Use the **[ghidra-amiga](https://github.com/BartmanAbyss/ghidra-amiga)** plugin by BartmanAbyss, which provides a robust HUNK loader, Amiga custom chipset register mappings, and OS library base tracking specifically designed for the Ghidra decompiler engine.
When analyzing a binary compiled with GCC (often identified by a `.text` hunk or a `LINK A6` in the first function), the standard analysis workflow changes slightly:
**1. Handle `.text` as mixed code+data.** GCC embeds strings and jump tables directly in the code hunk. After auto-analysis:
- Search for `LEA xxx(PC), An` instructions (Edit → Find → by instruction mnemonic or IDAPython)
- For each, check if the target address contains ASCII bytes — if yes, press `A` to define as string
- Mark the string as `DATA` type so IDA doesn't try to disassemble it as code
**2. Function boundary detection without LINK.** IDA's auto-analysis finds most functions via call-graph tracing from the entry point. For stragglers:
- Every `BSR addr` / `JSR addr` target is a function entry — use `Create function` (P key) at those addresses
- Look for `MOVEM.L Dn/An, -(SP)` at addresses following a `RTS` — strong function-start indicator
- Use IDAPython to scan: `for ea in idautils.Heads(): if idc.print_insn_mnem(ea) == 'MOVEM.L': ...`
**3. Identify `main()` in stripped builds.** The libnix startup sequence is fixed: