### Snooping

#### Was ist Snooping?

Snooping ist die Fähigkeit von WHDLoad Zugriffe auf Custom- und Cia-Register zu validieren und zu protokollieren. Wenn Snoop aktiviert ist, führen alle ungültigen oder nicht erlaubten Zugriffe zu einem Access Fault und das installierte Programm wird beendet. WHDLoad zeigt dann einen Requester, der die Ursache benennt.

#### Custom-Register

Alle Lese- und Schreibzugriffe auf die Custom-Register werden geprüft. Unerlaubte Zugriffe sind:

- Zugriffe auf nicht existierende Register
- Lesezugriffe auf Nur-Schreib-Register
- Schreibzugriffe auf Nur-Lese-Register
- Zugriffe auf Early-Read-Register
- Byte-Schreibzugriffe (außer `bltcon0l` und `aud*vol+1`)

Strobe-Register können gelesen und geschrieben werden. Die Liste der erlaubten Custom-Register kann auf OCS (Old ChipSet - A500, A1000, alte A2000), ECS (Enhanced ChipSet - A600, neue A2000, A3000) und AGA (Advanced Graphics - A1200, A4000) eingestellt werden. Dies ist insbesondere sinnvoll um Fehler in alten Programmen zu lokalisieren, die durch Zugriffe auf neue AGA Register verursacht werden.

#### Cia-Register

Bei den Cia-Registern werden nur Schreibzugriffe geprüft. Das heist, dass Lesezugriffe auf nicht existierende Register in dem Speicherbereich $bfd000...$bfefff nicht entdeckt werden. Bei Schreibzugriffen wird der geschriebene Wert von WHDLoad intern gespeichert. Für einige Cia-Register werden spezielle Prüfungen anhand des geschriebenen Wertes durchgeführt:

Adresse | Register | Prüfung
--- | --- | ---
$bfe001 | ciaa.ciapra | Das Setzen des Overlay Bits #0 ist nicht erlaubt.
$bfe201 | ciaa.ciaddra | Die Bits #6-7 können einen beliebigen Wert haben (werden für Joypad Abfrage benutzt), die unteren Bits müssen %000011 sein.
$bfe801 | ciaa.ciatodlow | Read-Modify-Write Zugriffe (z.B. bchg) sind nicht erlaubt, wenn das ALARM Bit in ciaa.ciacrb gesetzt ist (wird nur auf 68060 geprüft).
$bfe901 | ciaa.ciatodmid
$bfea01 | ciaa.ciatodhi
$bfed01 | ciaa.ciaicr | Read-Modify-Write Zugriffe (z.B. bchg) sind nicht erlaubt (wird nur auf 68060 geprüft).
$bfd100 | ciab.ciaprb | Die Bits für MOTOR #7, SELECT #3-6 und STEP #0 müssen gesetzt sein, die anderen Bits sind beliebig; damit werden alle Zugriffe auf die Diskettenlaufwerke entdeckt.
$bfd200 | ciab.ciaddra | Der zu schreibende Wert muss %11000000 sein.
$bfd300 | ciab.ciaddrb | Der zu schreibende Wert muss %11111111 sein.
$bfd800 | ciab.ciatodlow | Read-Modify-Write Zugriffe (z.B. bchg) sind nicht erlaubt, wenn das ALARM Bit in ciab.ciacrb gesetzt ist (wird nur auf 68060 geprüft).
$bfd900 | ciab.ciatodmid
$bfda00 | ciab.ciatodhi
$bfdd00 | ciab.ciaicr | Read-Modify-Write Zugriffe (z.B. bchg) sind nicht erlaubt (wird nur auf 68060 geprüft).

#### Wie es funktioniert

Wenn Snoop eingeschalten ist, markiert WHDLoad den Bereich der Custom- und Cia-Register als ungültig/schreibgeschützt im MMU-Übersetzungsbaum. Dadurch verursacht jeder Zugriff auf solch eine Adresse eine Access Fault Exception. Der Exception-Handler in WHDLoad bearbeitet diese Exception. Zuerst überprüft er, ob die zugegriffene Adresse erlaubt ist. Wenn nicht wird das installierte Programm beendet. Wenn der Zugriff erlaubt ist und eine Leseoperation ist, wird der Zugriff emuliert und die normale Programmausführung fortgesetzt. Bei einer Schreiboperation speichert WHDLoad zusätzlich den geschriebenen Wert intern ab.
Wegen dem Zusatzaufwand für die Exception, die Überprüfung und die Emulation, verlangsamt sich die Ausführungsgeschwindigkeit des installierten Programmes. Wie intensiv diese Verlangsamung ist, hängt von dem Prozessor, dem Speichertyp (16/32-Bit) und der Stackpointer-Ausrichtung (LongWord aligned oder nicht) bei 32-Bit Speicher ab. Sie hängt auch von der Art des Zugriffes (Byte/Word/LongWord, Read/Write) ab. Auf dem 68030 sind Schreibzugriffe schneller als Lesezugriffe (da die Stackframegrößen unterschiedlich sind, Lesen 92 Byte, Schreiben 32 Byte). Auf dem 68060 sind Lesezugriffe schneller, weil die Emulation der Schreibzugriffe komplizierter ist.

#### Fast-Snoop Modus

Die Option Snoop/S schaltet den schnellen Snoop Modus ein. Lesezugriffe werden in diesem Modus nicht mehr validiert. Auch werden keine speziellen Überprüfungen mehr durchgeführt. Dieser Modus ist hilfreich, wenn es nur darauf ankommt den Inhalt der Custom- und Cia-Register zu erfahren, z.B. um ein Bild mittels SP zu extrahieren.

#### Copper-Listen Scanner

Seit WHDLoad Version 13 werden auch die Inhalte von Copperlisten geprüft. Der Scanner wird aktiv bei Schreibzugriffen auf `coplc` wenn die Copper-DMA eingeschalten ist oder wenn das installierte Programm die Copper-DMA mit einem Schreibzugriff auf `dmacon` einschaltet. Der Scanner folgt den Copperlisten und prüft für jede Move Instruktion, ob die Restriktionen die durch die Snoop-Option (OCS/ECS/AGA) vorgegeben sind, eingehalten werden. Skip und Wait (außer CEND) Instruktionen werden ignoriert. Wenn ein nicht erlaubter Eintrag gefunden wird, wird das installierte Programm beendet. Der Scanner folgt Sprüngen (`copjmp`), entdeckt Schleifen und kann bis zu 16 Unterlisten untersuchen. Die Operanden der Move Instruktionen speichert WHDLoad in einer internen Tabelle. Der Scanner ist im Fast-Snoop Modus nicht aktiv.

#### Blitter Prioritäts Überprüfung

Wenn die Option ChkBltHog/S aktiv ist, überwacht WHDLoad das installierte Programm dahingehend, dass dieses das `BltHog` Bit mittels eines Schreibzugriffes auf das `dmacon` Register nicht einschaltet. Die Blitter-Priorität kann im Zusammenhang mit großen Blitteroperationen (alle Kanäle verwendet) Probleme auf einigen Hardwarekonfigurationen bereiten.

#### Blitter Größen Überprüfung

Wenn die Option ChkBltSize/S aktiv ist, prüft WHDLoad, dass keine Blitteroperationen gestartet werden, die Speicher außerhalb des BaseMem-Bereiches betreffen. Bei Schreibzugriffen auf `bltsize` oder `bltsizh` wird getestet ob der Linienmodus in `bltcon1` eingestellt ist. Wenn dies der Fall ist, wird keine Größenprüfung durchgeführt. Ansonsten berechnet WHDLoad für jeden benutzten DMA-Kanal das erste und letzte durch den Blitter zugegriffene Wort. Wenn eines von beiden außerhalb des BaseMem-Bereiches liegt wird das installierte Programm beendet und ein entsprechender Requester angezeigt. Die Berechnung ist so gestaltet, dass sämtliche Modi unterstützt werden (ascending/descending, positive/negative modulos, ungerade modulos/Zeiger).
Beachtet werden sollte, dass der Linienmodus nicht validiert wird und das alle Blitter-Register auch mit dem Copper beschrieben werden können wenn `copcon` entsprechend gesetzt ist.

#### Blitter Warte Überprüfung

Wenn die Option ChkBltWait/S aktiv ist, benutzt WHDLoad eine Art Instruktionenverfolgung um festzustellen, ob das installierte Programm korrekt auf das Ende von Blitteroperationen wartet bevor es neue Blitterjobs startet. Es wird dabei eine interne Variable verwendet, die den aktuellen Status des Blitters repräsentiert. Die Variable wird gesetzt, wenn ein Schreibzugriff auf `bltsize` oder `bltsizh` erfolgt und gelöscht bei einem Lesezugriff auf das `dmaconr` Register. Bei jedem Schreibzugriff auf ein Blitter-Register wird der Wert der internen Variable getestet. Wenn diese einen laufenden Blitter anzeigt, wird das installierte Programm terminiert und WHDLoad zeigt den PC der letzten gestarteten Blitteroperation zusammen mit den aktuellen Daten an.
Zwei wesentliche Sachen sind zu beachten! Erstens werden Blitteroperationen initiiert durch den Copper nicht geprüft und zweitens meldet die Funktion bei der Verwendung von Blitter-Interrupts Fehler, ohne dass dies wirklich Fehler sind.

#### Zukunft

Es ist geplant solche Dinge wie Einfrieren und Ikonifizieren später in WHDLoad zu implementieren. Für diese Funktionen ist Snoop eine Voraussetzung. Deshalb sollten Installautoren ihre Installs mit dem Snoop Modus testen, um eine zukünftige Kompatibilität ihrer Installs sicherzustellen.

#### Voraussetzungen

Eine MMU ist Voraussetzung für den Snoop Modus. Auch muss WHDLoad die MMU benutzen, damit verbunden, muss die Option MMU/S auf 68030 Systemen eingeschalten sein.

#### Einschränkungen

- 68020 + 68851
  - diese Hardware wird gegenwärtig nicht unterstützt
- 68030
  - keine bekannten Einschränkungen
- 68040
  - diese Hardware wird gegenwärtig nicht unterstützt
- 68060
  - `movem` Instruktionen können auf nicht erlaubte Register zugreifen, ohne das ein Access Fault ausgelöst wird; dies ist möglich da nur der erste Speicherzugriff überprüft wird
  - `move <Cia-/Custom-Register>,sr` wird fehlerhaft ausgeführt, wenn er versucht den Supervisor-Teil des Statusregisters zu verändern, der Supervisor-Teil bleibt immer unverändert
  - jeder `(ssp)+` oder `-(ssp)` in Verbindung mit einem Schreibzugriff auf ein Custom- oder Cia-Register kann nicht verarbeitet werden, WHDLoad entdeckt solche Zugriffe und terminiert mit einem entsprechenden Fehlerrequester
  - Instruktionen, die auf zwei Custom- oder Cia-Register zugreifen (z.B. `move.b ($dff006),($bfd800)`), können nicht verarbeitet werden, WHDLoad terminiert in solch einem Fall mit einem entsprechenden Requester