### Snooping

#### Co to jest?

Snooping to jedna z cech WHDLoad, która dokonuje sprawdzania i odnotowuje dostępy do rejestrów CIA oraz rejestrów własnych. Jeśli opcja Snoop jest aktywna, wszystkie nieprawidłowe i błędne próby dostępu wygenerują błąd dostępu i przerwanie pracy uruchamianego programu. WHDLoad wyświetli komunikat wyjaśniający powód niepowodzenia.

#### Rejestry własne

Wszystkie próby zapisu i odczytu rejestrów są weryfikowane. Niedozwolone działania to:

- dostępy do nieistniejących rejestrów,
- odczyt z rejestrów oznaczonych jako przeznaczone "tylko do zapisu" (Write Only),
- zapis do rejestrów oznaczonych jako przeznaczone "tylko do odczytu" (Read Only),
- dostępy do rejestrów wczesnego odczytu (Early Read),
- dostępy typu "byte write" (za wyjątkiem `bltcon0l` i `aud*vol+1`).

Rejestry "Strobe" mogą być odczytywane i zapisywane. Zestaw sprawdzonych rejestrów własnych może się różnić w zależności od układów graficznych: OCS (Old ChipSet - A500, A1000, stara A2000), ECS (Enhanced ChipSet - A600, nowa A2000, A3000) i AGA (Advanced Graphics - A1200, A4000). Jest to użyteczne zwłaszcza przy wychwytywaniu błędów w starych programach.

#### Rejestry CIA

Podczas prób dostępu do rejestrów CIA tylko próby zapisu są weryfikowane. Oznacza to, że próby odczytu nieistniejących rejestrów w obszarze pamięcie $bfd000...$bfefff nie zostaną wykryte. Dla wszystkich prób zapisu, zapisywane wartości będą przechowywane wewnętrznie przez WHDLoad. Dla niektórych rejestrów CIA są dokonywane szczególne sprawdzenia w zależności od wpisywanej wartości:

addres | rejestr | sprawdzenie
--- | --- | ---
$bfe001 | ciaa.ciapra | ustawienie bitu Overlay #0 jest zabronione
$bfe201 | ciaa.ciaddra | bity #6-7 mogą posiadać dowolną wartość (używane przez joypady), niższe bity muszą być ustawione na %000011
$bfe801 | ciaa.ciatodlow | dostępy odczytu-zapisu-zmiany (na przykład bchg) są niedozwolone w przypadku ustawienia bitu ALARM w ciaa.ciacrb (sprawdzane tylko na procesorze 68060)
$bfe901 | ciaa.ciatodmid
$bfea01 | ciaa.ciatodhi
$bfed01 | ciaa.ciaicr | dostępy odczytu-zapisu-zmiany (na przykład bchg) są niedozwolone (sprawdzane tylko na procesorze 68060)
$bfd100 | ciab.ciaprb | bity dla MOTOR #7, SELECT #3-6 i STEP #0 nie mogą być kasowane, pozostałe bity mogą być zmieniane; dzięki temu każda próba dostępu do stacji dysków zostanie wykryta
$bfd200 | ciab.ciaddra | dopuszczalna zapisywana wartość to %11000000
$bfd300 | ciab.ciaddrb | dopuszczalna zapisywana wartość to %11111111
$bfd800 | ciab.ciatodlow | dostępy odczytu-zapisu-zmiany (na przykład bchg) są niedozwolone w przypadku ustawienia bitu ALARM w ciaa.ciacrb (sprawdzane tylko na procesorze 68060)
$bfd900 | ciab.ciatodmid
$bfda00 | ciab.ciatodhi
$bfdd00 | ciab.ciaicr | dostępy odczytu-zapisu-zmiany (na przykład bchg) są niedozwolone (sprawdzane tylko na procesorze 68060)

#### Jak to działa?

Jeżeli opcja "Snoop" jest włączona, WHDLoad zaznacza w drzewie translacji MMU adresy rejestrów CIA i rejestrów własnych jako nieprawidłowe/zabezpieczone przed zapisem. Z tego powodu każdy dostęp do rejestrów własnych lub/i CIA generuje błąd dostępu. WHDLoad wówczas sprawdza, czy próba dostępu była prawidłowa. Jeżeli okaże się, że nie była, nastąpi przerwanie wykonywanego programu. Jeżeli próba dostępu jest prawidłowa i wystąpiła operacja odczytu, zostanie ona zaemulowana i będzie kontynuowane wykonywanie programu. Jeżeli wystąpiła operacja zapisu, WHDLoad odpowiednio dokonana zapisu wartości wewnętrznego schowka.
Zaznaczanie obszarów pamięci oraz emulacja pociągają za sobą zwolnienie wykonywania programu. Jak bardzo, to zależy od typu procesora oraz typu pamięci graficznej (16/32-bit), a także od ustawienia wskaźnika stosu. Zależne jest to również od typu dostępu (Bajt/Słowo/Długie Słowo, Zapis/Odczyt). Na 68030 zapis jest szybszy niż odczyt (gdyż odczyt stosu zajmuje 92 bajty, a zapis 32 bajty), na 68060 odczyt jest szybszy, ponieważ emulacja zapisu jest bardziej złożona.

#### Tryb "Fast Snoop"

Opcja Snoop/S uaktywnia szybki snooping. Dostępy odczytu nie będą sprawdzane. Również nie są prowadzone oznaczenia. Ten tryb może być przydatny w celu zdobycia zawartości rejestrów własnych, np. zapisania obrazka przy wykorzystaniu programu SP.

#### Skaner copperlisty

Od WHDLoad w wersji 13 sprawdzana jest również copperlista. Skaner zostaje uaktywniony podczas zapisu do rejestrów `coplc` jeśli DMA coppera jest włączone lub wtedy, gdy zainstalowany program włącza DMA coppera poprzez zapis do rejestrów `dmacon`. Skaner podąża za copperlistą, sprawdza i ustawia wszystkie instrukcje Move zgodnie z restrykcjami opcji Snoop (OCS/ECS/AGA). Instrukcje Skip i Wait (za wyjątkiem CEND) są ignorowane. Gdy zostanie odnaleziona nieprawidłowa próba dostępu, zainstalowany program zostanie wyłączony. Skaner podąży za odgałęzieniami (`copjmp`), wykryje pętle i sprawdzi do 16 podlist. Instrukcje Move w copperliście zostaną zapisane do węwnętrznego pliku rejestru, który zostanie zapisany na dysk przy wyjściu z WHDLoad. Skaner jest nieaktywny w trybie "Fast Snoop".

#### Sprawdzanie priorytetu blittera

Gdy opcja "ChkBltHog/S" jest włączona, WHDLoad sprawdza, czy zainstalowany program nie włącza bitu `BltHog` poprzez zapis do rejestru `dmacon`. Priorytet blittera może powodować problemy na niektórych konfiguracjach w połączeniu z dużymi operacjami na blitterze (wykorzystanie wszystkich kanałów).

#### Sprawdzanie rozmiaru blittera

Gdy opcja "ChkBltSize/S" jest włączona, WHDLoad sprawdza, czy zadania blittera nie próbują przedostać się poza pamięć określoną w BaseMem. Podczas próby zapisu do `bltsize` lub `bltsizh` sprawdza, czy tryb linii jest włączony w `bltcon1`. Jeżeli jest włączony, zostanie zignorowane sprawdzanie rozmiaru. W przeciwnym razie WHDLoad wyliczy pierwsze i ostatnie słowo dla każego uaktywnionego kanału DMA. Jeżeli jeden adres znajduje się poza obszarem BaseMem, program zostanie wyłączony z odpowiednią informacją w oknie komunikatu. Obliczenia zostały zaprojektowany w taki sposób, aby współpracowały ze wszystkimi trybami (rosnący/malejący, pozytywny/negatywny, nieparzyste moduły/wskaźniki).
Pamiętaj, że tryb rysowania linii nie jest sprawdzany i wszystkie rejestry blittera mogą być zapisane do coppera jeśli bit `copcon` jest ustawiony.

#### Sprawdzanie oczekiwania blittera

Gdy opcja "ChkBltWait/S" jest włączona WHDLoad użyje instrukcji śledzenia, aby sprawdzić, czy zainstalowany program wykonuje poprawienie oczekiwanie na zakończenie wykonywania operacji blittera, zanim ten rozpocznie wykonywać kolejną. Wykorzystywana jest do tego wewnętrzna zmienna, która reprezentuje stan pracy blittera. Zmienna jest ustawiona, gdy dokonywany jest zapis do `bltsize` lub `bltsizh`. Zmienna jest czyszczona, gdy dokonywany jest odczyt z rejestru `dmaconr`. Przy każdorazowym zapisie do rejestru blittera sprawdzana jest wewnętrzna zmienna. Jeżeli wykazuje ona pracę blittera, wykonywanie zainstalowanego programu zostanie przerwane, a WHDLoad zgłosi PC ostatniej czynności wykonywanej przez blitter.
Istnieją dwa "wąskie gardła" tej opcji. Pierwsze to takie, że nie jest sprawdzane wykorzystanie blittera poprzez coppera, drugie - wykorzystanie przerwań blittera.

#### Przyszłość

Planuję dodanie funkcji podobnych do zamrażania (Freezing) i ikonifikacji (Iconifing) Zalecane jest, aby autorzy programów instalacyjnych sprawdzali swoje pliki .slave z opcją "Snoop", aby zapewnić sobie kompatybilność w przyszłości.

#### Wymagania

Dla opcji "Snoop" wymagane jest MMU. WHDLoad musi używać MMU, a z racji tej MMU/S musi być włączony na procesorach 68030.

#### Ograniczenia

- 68020 + 68851
  - Nie jest obsługiwany.
- 68030
  - Bez ograniczeń.
- 68040
  - Nie jest obecnie obsługiwany.
- 68060
  - Instrukcja `movem` może wywoływać dostępy do nieprawidłowych rejestrów bez wygenerowania błędu dostępu. Jest to możliwe gdyż tylko pierwsza próba dostępu jest sprawdzana.
  - Instrukcja `move <rejestr CIA/własny>,sr` jest wykonywana nieprawidłowo.
  - Jakakolwiek instrukcja `(ssp)+` lub `-(ssp)` w połączeniu z zapisem do rejestrów CIA lub rejestrów własnych nie może zostać wykonana z powodu problemów z ramką stosu. WHDLoad wykrywa takie próby dostępu i informuje o nich stosownym komunikatem.
  - Instukcje nie mogą odwoływać się do więcej niż jednego śledzonego rejestru w tym samym czasie. Oznacza to, że np. kod `move.b ($dff006),($bfd800)` nie może zostać wykonany. Jeżeli taki kod wystąpi w programie, WHDLoad pokaże komunikat o błędzie dostępu.