# ADSP-219x ROM Analyse Walkthrough

Dieses Dokument beschreibt den systematischen Prozess der Analyse eines ADSP-219x Binär-Dumps. Da wir mit einer 24-Bit Architektur auf einer 8-Bit-basierten Dateisystem-Welt arbeiten, ist der erste Schritt immer die Validierung des Formats.

## 1. Phase: Format-Validierung (Padded vs. Packed)

Ein ADSP-2191 Befehl ist **24 Bit (3 Bytes)** groß. In einem ROM-Dump liegen diese meist in einem von zwei Formaten vor:

*   **Packed (3-Byte):** `[B0][B1][B2] [B3][B4][B5] ...` (Keine Lücken)
*   **Padded (4-Byte):** `[00][B0][B1][B2] [00][B3][B4][B5] ...` (Oft bei 32-Bit EPROM-Builds)

### Woran erkenne ich das Format?
Suche nach dem **NOP** Opcode. 
*   Ein klassischer NOP (Type 30) ist `0x000000`. 
*   Ein Multifunktions-NOP (Type 1) ist `0xC00000`.

Wenn du alle 3 oder 4 Bytes lange Ketten von `00` findest, hast du wahrscheinlich das Alignment gefunden.

## 2. Phase: Den Einstiegspunkt finden (Vector Table)

Der ADSP-2191 startet nach einem Reset bei Adresse `0x0000` im Programm-Memory (PM). 
Die ersten Adressen sind die Interrupt-Vektoren (jeweils 8 oder 16 Words Platz).

**Typisches Muster am Anfang:**
```text
0x0000:  JUMP 0x0100   <-- Reset Vector
0x0008:  RTI           <-- Power Down Vector
0x0010:  RTI           <-- Kernel Interrupt
...
```

Wenn dein Disassembler am Anfang nur `UNKNOWN` auswirkt, ist meistens das Alignment (3 vs 4 Byte) oder die Endianness falsch. ADSP-219x ist standardmäßig **Big-Endian**.

## 3. Phase: Den Code "lesen" (Pattern Recognition)

### A. Register Initialisierung (Type 6/7)
DSP-Code beginnt fast immer damit, die DAGs (Data Address Generators) zu füttern.
*   `I0 = 0x2000` (Index-Register auf Start eines Buffers)
*   `M0 = 1`      (Modifier auf Schrittweite 1)
*   `L0 = 0`      (Circular Buffering aus)

**In deinem Disassembler:**
`AX0 = 0x1234` entspricht Opcode `0x4x....`. Das ist ein Type 6 Befehl.

### B. Die "Magic" des DSP: Multifunktions-Opcodes (Type 1)
Das ist der Kern des DSPs. In einem einzigen Takt passiert:
1.  Eine Berechnung (ALU/MAC)
2.  Ein Read aus dem DM (Data Memory)
3.  Ein Read aus dem PM (Program Memory)

**Beispiel:**
`MR + X * Y (SS), AX0 = DM(I0 += M0), AY0 = PM(I4 += M4)`

*   **Identifikation:** Opcodes die mit `0xC` bis `0xF` beginnen.
*   **Schlussfolgerung:** Das ist oft eine innere Schleife (z.B. ein FIR-Filter). Wenn du viele dieser Befehle hintereinander siehst, hast du den Signalverarbeitungs-Kernel gefunden.

## 4. Phase: Daten vs. Code im PM

Der ADSP-2191 hat eine Harvard-Architektur. Das Programm-Memory (PM) kann aber auch Daten enthalten (24-Bit breit). 
Dank des **Visible Instruction State (VIS)** kann der 2191 hocheffizient 24-Bit Koeffizienten aus dem PM laden, während er rechnet.

**Woran erkenne ich Daten im PM?**
Wenn der Disassembler sinnlose Befehle ausgibt (z.B. hunderte `UNKNOWN` oder seltsame Sprünge in ungültige Bereiche), handelt es sich wahrscheinlich um eine **Koeffizienten-Tabelle** (z.B. Sinus-Werte oder Filter-Taps).

## 5. Phase: Analyse-Workflow mit radare2

Wenn du den Dump in `iaito` oder `r2` lädst:

1.  **Bit-Breite:** Setze `e asm.bits = 24`.
2.  **Suchen:** Suche nach `000000` (NOPs), um Funktionsgrenzen zu finden.
3.  **Cross-References:** Suche nach `CALL` Befehlen (`0x11....`), um die Programmstruktur zu verstehen.
4.  **I/O Analyse:** Der ADSP-2191 steuert Peripherie über I/O-Register. Suche nach `IO(addr) = Dreg`. Adressen wie `0x00` bis `0x3F` sind oft System-Controller oder Sport (Serial Port) Konfiguration.

---
**Tipp:** Nutze das beiliegende Skript `analysis/analyze_rom.py`, um eine erste Statistik über die verwendeten Instruktionstypen zu erhalten. Das zeigt dir sofort, ob der Dump primär aus Logik (`JUMP`, `IF`) oder aus Mathe (`Compute`, `Multifunction`) besteht.
