Snooping (ficcare il naso, curiosare)

### Snooping

#### Cos'è

Lo Snooping è una caratteristica di WHDLoad che controlla la validità ed esegue il log degli accessi ai registri Custom e CIA. Se Snoop è attivato, tutti gli accessi non validi causeranno un Access Fault, il programma installato verrà terminato e WHDLoad mostrerà un requester spiegando i motivi.

#### Registri custom

Tutti gli accessi in lettura e scrittura ai registri custom vengono verificati. Accessi non validi sono:

- accessi a registri non esistenti
- accessi in lettura a registri a sola scrittura
- accessi in scrittura a registri a sola lettura
- accessi a registri Early Read
- accessi in scrittura di dimensione di un byte (eccetto `bltcon0l` e `aud*vol+1`)

I registri Strobe possono essere sia letti che scritti. Il set di registri Custom validi può variare tra OCS (Old ChipSet - A500, A1000, vecchi A2000), ECS (Enhanced ChipSet - A600, nuovi A2000, A3000) e AGA (Advanced Graphics Architecture - A1200, A4000). Questo è utile specialmente per localizzare i bug nei vecchi programmi causati da accessi non definiti ai nuovi registri AGA.

#### Registri CIA

Solo gli accessi in scrittura sono verificati per i registri CIA. Questo significa che accessi in lettura a registri inesistenti nell'area di memoria $bfd000...$bfefff non saranno rilevati. Per tutti gli accessi in scrittura il nuovo valore viene salvato internamente da WHDLoad. Per alcuni dei registri CIA sono effettuati controlli aggiuntivi dipendenti dal valore scritto:

indirizzo | registro | controllo aggiuntivo
--- | --- | ---
$bfe001 | ciaa.ciapra | il settaggio dell'Overlay bit #0 non è permesso
$bfe201 | ciaa.ciaddra | i bit #6-7 possono assumere qualsiasi valore (sono utilizzati per il joypad), i bit inferiori devono essere %000011
$bfe801 | ciaa.ciatodlow | accessi read-modify-write (come bchg) non sono permessi se il bit ALARM è settato in ciaa.ciacrb (controllato solamente sul 68060)
$bfe901 | ciaa.ciatodmid
$bfea01 | ciaa.ciatodhi
$bfed01 | ciaa.ciaicr | accessi read-modify-write (come bchg) non sono permessi (controllato solamente sul 68060)
$bfd100 | ciab.ciaprb | i bit MOTOR #7, SELECT #3-6 e STEP #0 non devono essere azzerati, gli altri bit possono essere modificati; in questa maniera tutti gli accessi ai floppy drive saranno rilevati
$bfd200 | ciab.ciaddra | il valore scritto deve essere %11000000
$bfd300 | ciab.ciaddrb | il valore scritto deve essere %11111111
$bfd800 | ciab.ciatodlow | accessi read-modify-write (come bchg) non sono permessi se il bit ALARM è settato in ciaa.ciacrb (controllato solamente sul 68060)
$bfd900 | ciab.ciatodmid
$bfda00 | ciab.ciatodhi
$bfdd00 | ciab.ciaicr | accessi read-modify-write (come bchg) non sono permessi (controllato solamente sul 68060)

#### Come funziona

Se Snoop è abilitato, WHDLoad contrassegnerà gli indirizzi dei registri Custom e CIA come non validi/protetti da scrittura nella MMU translation tree. Per questo motivo, ogni accesso ad uno di questi registri risulterà in un Access Fault exception. L'exception handler in WHDLoad si prende cura di questa eccezione. Come prima cosa controllerà se l'accesso è valido. Se non lo è il programma sarà terminato. Se invece sarà valido e si tratta di una operazione di lettura, verrà emulato e l'esecuzione del programma procederà. Nel caso questa sia invece un'operazione di scrittura, WHDLoad salverà anche il valore scritto in un'area interna.
A causa dell'overhead dell'eccezione e della sequenza di emulazione, l'esecuzione del programma subirà un rallentamento. Quanto rallenterà dipende dal tipo di CPU, tipo di memoria Chip (16/32-bit) e l'allineamento dello Stackpointer se la memoria Chip è a 32-bit (allineata oppure no alla Longword). Dipende anche dal tipo di accesso (Byte/Word/Longword, Lettura/Scrittura). Nel 68030 la scrittura è più veloce della lettura (perché in lettura lo stackframe è di 92 byte contro i 32 in scrittura), nel 68060 è la lettura ad essere più veloce poiché l'emulazione della scrittura è più complessa.

#### Modalità Veloce di Snoop

L'opzione Snoop/S abilita lo snooping veloce. Gli accessi in lettura non saranno verificati. Nessuna verifica speciale verrà eseguita. Questa modalità può essere utile nel caso ci interessi solo ottenere il contenuto dei registri Custom, ad esempio per salvare un'immagine mediante l'utilizzo di SP.

#### Copper List Scanner

Dalla versione 13 di WHDLoad anche le copperlist verranno controllate. Lo scanner verrà attivato nella scrittura dei registri `coplc` se il DMA del copper è abilitato, oppure quando il programma installato abilita il DMA scrivendo nel registro `dmacon`. Lo scanner controlla la copperlist validando tutte le istruzioni Move applicandone le restrizioni messe in atto dall'opzione Snoop (OCS/ECS/AGA). Le istruzioni Skip e Wait (eccetto CEND) saranno ignorate. Quando troverà valori non validi il programma installato sarà terminato. Lo scanner segue i branch (`copjmp`), scopre i loop e controlla fino a 16 subliste. Le Move nelle copperlist verranno salvate nel file interno dei registri Custom, e WHDLoad ne eseguirà il dump in uscita. Lo scanner non è attivo nella modalità Fast Snoop (Snoop Veloce).

#### Controllo Priorità Blitter

Quando l'opzione ChkBltHog/S è attivata, WHDLoad controllerà che il programma installato non abiliti il bit `BltHog` scrivendo nel registro `dmacon`. La Blitter Priority può causare problemi in alcune configurazioni hardware in concomitanza di grosse operazioni con il blitter (tutti i canali utilizzati).

#### Controllo Blitter Size

Quando l'opzione ChkBltSize/S è attivata WHDLoad controllerà che le operazione del blitter non accedano la memoria esterna all'area BaseMem. Nelle operazioni di scrittura di `bltsize` o `bltsizh` controllerà se sarà abilitata la line mode in `bltcon1`. Se la line mode è attiva annullerà il size check. Altrimenti WHDLoad calcolerà la prima e l'ultima word da accedere per ogni canale DMA attivato. Se un indirizzo è all'esterno dell'area BaseMem il programma sarà terminato con un requester. Il calcolo è progettato per funzionare con tutte le modalità (ascendente/discendente, modulo positivi/negativi, modulo/puntatori dispari).
Ricorda che la modalità di disegno linea (line drawing) non verrà verificata e tutti i registri del blitter possono essere scritti anche dal copper se `copcon` è impostato.

#### Controllo Blitter Wait

Quando l'opzione ChkBltWait/S è attiva, WHDLoad utilizzerà un tracciamento dell'istruzione per verificare che il programma installato attenda nel modo corretto che il blitter abbia finito il suo lavoro prima di fargliene cominciare uno nuovo. Viene utilizzata una variabile interna che rappresenta lo stato di funzionamento del blitter. La variabile viene impostata quando avviene un accesso in scrittura nei registri `bltsize` o `bltsizh` e azzerata quando viene acceduto il registro `dmaconr`. Ad ogni scrittura di un registro del blitter il valore della variabile interna viene controllato, e se indica che blitter sta già lavorando il programma installato viene terminato e WHDLoad ritornerà il PC dell'ultimo lavoro eseguito dal blitter e l'accesso attuale.
Ci sono due principali colli di bottiglia di questa peculiarità. Prima di tutto l'utilizzo del blitter tramite il copper non viene controllato, in secondo luogo l'utilizzo di interrupt del blitter farà riportare, dalla routine di controllo, degli errori senza effettiva necessità.

#### Futuro

E' pianificata l'implementazione di caratteristiche come il Freezing e l'Iconificazione. Snoop sarà essenziale per il loro funzionamento. Perciò raccomandiamo agli autori di installatori di controllarli con Snoop per assicurarne una futura compatibilità.

#### Requisiti di sistema

Lo Snoop richiede la presenza di una MMU. Anche WHDLoad deve utilizzare la MMU, perciò MMU/S deve essere abilitato nei sistemi con 68030.

#### Limitazioni

- 68020 + 68851
  - questo hardware non è attualmente supportato
- 68030
  - nessuna limitazione conosciuta
- 68040
  - questo hardware non è attualmente supportato
- 68060
  - l'istruzione `movem` potrebbe accedere ad un registro non valido senza causare un Access Fault exception, questo è possibile perché solo per il primo accesso verrà verificata la effettiva corrispondenza con un registro valido
  - `move <registri Cia/Custom>,sr` sarà eseguito in modo non corretto se tenterà di cambiare la porzione supervisore dello status register, infatti questa rimarrà inalterata
  - ogni `(ssp)+` o `-(ssp)` in concomitanza con un accesso in scrittura ad un registro CIA o Custom non può essere gestito a causa di problemi con lo stackframe, WHDLoad scoprirà questi accessi e terminerà con un appropriato requester
  - le istruzioni non devono accedere a più di un registro "snooped" contemporaneamente, questo significa che codice come `move.b ($dff006),($bfd800)` non può essere gestito, e se verrà eseguito WHDLoad aprirà un requester di Access Fault