### Snooping

#### De que se trata

Snooping es una funcionalidad de WHDLoad que realiza la validación y registro de los accesos a los registros Custom y de la CIA. Si Snoop esta activo todos los accesos inválidos crearán una Falla de Acceso y el programa instalado terminará. WHDLoad mostrará un diálogo explicando la razón de la falla.

#### Registros Custom

Todos los accesos de lectura y escrituro a los registros custom son verificados. Los accesos inválidos son:

- accesos a registros no existentes
- accesos de lectura a registros de Solo Escritura
- accesos de escritura a registros de Solo Lectura
- accesos a registros Early Read
- accesos de escritura de byte (excepto `bltcon0l` y `aud*vol+1`)

Los registros Strobe pueden ser leídos o escritos. El conjunto de registros Custom válidos puede variar entre OCS (Old ChipSet - A500, A1000, viejas A2000), ECS (Enhanced ChipSet - A600, nuevas A2000, A3000) y AGA (Advanced Graphics - A1200, A4000). Esto es útil especialmente para localizar errores en programas viejos causados por accesos no definidos a los nuevos registros AGA.

#### Registros CIA

En los registros CIA solamente se verifican los accesos para escritura. Esto significa que los accesos para lectura a registros inexistentes en el área de memoria $bfd000...$bfefff no serán detectados. Para todos los accesos de escritura el valor escrito será guardado internamente por WHDLoad. Para algunos registros CIA existen verificaciones especiales dependiendo del valor escrito:

dirección | registro | verificación
--- | --- | ---
$bfe001 | ciaa.ciapra | está prohibido configurar el bit Overlay #0
$bfe201 | ciaa.ciaddra | los bits #6-7 pueden tener cualquier valor (utilizado por el joypad), los bits mas bajos deben ser %000011
$bfe801 | ciaa.ciatodlow | los accesos de lectura-escritura (por ej. bchg) no están permitidos si el bit ALARM está configurado en ciaa.ciacrb (solo se verifica en el 68060)
$bfe901 | ciaa.ciatodmid
$bfea01 | ciaa.ciatodhi
$bfed01 | ciaa.ciaicr | los accesos de lectura-escritura (por ej. bchg) no están permitidos (solo se verifica en el 68060)
$bfd100 | ciab.ciaprb | los bits para MOTOR #7, SELECT #3-6 y STEP #0 no deben ser borrados, los otros bits pueden ser cambiados; con ello cualquier acceso a las controladoras de discos floppy drives será detectado
$bfd200 | ciab.ciaddra | el valor escrito debe ser %11000000
$bfd300 | ciab.ciaddrb | el valor escrito debe ser %11111111
$bfd800 | ciab.ciatodlow | los accesos de lectura-escritura (por ej. bchg) no están permitidos si el bit ALARM está configurado en ciab.ciacrb (solo se verifica en el 68060)
$bfd900 | ciab.ciatodmid
$bfda00 | ciab.ciatodhi
$bfdd00 | ciab.ciaicr | los accesos de lectura-escritura (por ej. bchg) no están permitidos (solo se verifica en el 68060)

#### Como trabaja

Si Snoop esta activado, WHDLoad marca las direcciones de los registros Custom y CIA como inválidas/protegido-contra-escritura en el árbol de traducción de la MMU. Debido a esto, cada acceso a un registro Custom o CIA ocasionará una excepción de Falla de Acceso. El gestor de excepciones dentro de WHDLoad manejará esta excepción. Primero controlará si el acceso es válido. Si el acceso es inválido el programa será terminado. Si el acceso es válido y es una operación de lectura será emulado y la ejecución del programa continuara. Si es una operación de escritura WHDLoad adicionalmente guardara los valores escritos en un espacio de almacenamiento interno.
Debido a la sobrecarga de la excepción y la secuencia de emulación la ejecución del programa se enlentecera. Cuando dependerá del tipo de CPU, el tipo de Memoria Chip (16/32 bits) y el alineamiento del Puntero de Pila si la Memoria Chip es de 32 bits (Palabras Largas alineadas o no). También diferirá por el tipo de acceso (Byte/Palabra/Palabra Larga, Lectura/Escritura). En el 68030 la Escritura será mas rápida que la Lectura (debido a que durante las lecturas el entorno de pila es de 92 bytes, y en escrituras 32 bytes), en el 68060 las Lecturas serán mas rápidas debido a que la emulación para las Escrituras es mas compleja.

#### Modo Snoop Rápido (Fast Snoop)

La opción Snoop/S activa el modo de snoop rápido. Los accesos de lectura no serán comprobados. No se realizan controles especiales. Este modo solo será útil para obtener el contenido de los registros Custom, por ej. para salvar una pantalla usando SP.

#### Analizador de la CopperList

Desde la versión 13 de WHDLoad también la copperlist en si será comprobada. El analizador se activará durante las escrituras a los registros `coplc` si el DMA de copper esta activado, o cuando el programa instalado active el DMA de copper escribiendo el registro `dmacon`. El analizador seguirá la copperlist y validara todas las instrucciones Move aplicando las restricciones causadas por la opción Snoop (OCS/ECS/AGA). Las instrucciones Skip y Wait (excepto CEND) serán ignoradas. Cuando encuentre entradas inválidas el programa instalado terminara. El analizador sigue las ramificaciones (`copjmp`), detecta ciclos y comprueba hasta 16 sublistas. Los Move's en la copperlist serán salvados en el archivo interno de registros Custom que se vuelca al salir de WHDLoad. El analizador también no estará activo en el modo Snoop Rápido.

#### Comprobación de la Prioridad del Blitter

Cuando la opción ChkBltHog/S este activa WHDLoad comprobará que el programa instalado no active el bit `BltHog` bit escribiendo al registro `dmacon`. La Prioridad del Blitter puede causar problemas en algunas configuraciones de hardware en conjunto con grandes operaciones del blitter (donde se usen todos los canales).

#### Comprobación del Tamaño del Blitter

Cuando se activa la opción ChkBltSize/S WHDLoad comprobará que los trabajos del blitter no accedan memoria fuera del área BaseMem. En accesos de escritura a `bltsize` o `bltsizh` comprueba si el modo lineal esta activado en `bltcon1`. Si el modo lineal esta activado, cancelará el control de tamaño. En caso contrario WHDLoad calculara la primer y ultima palabra a acceder para cada canal activo de DMA. Si una dirección esta fuera del área BaseMem el programa será terminado con un cuadro de diálogo. El calculo esta diseñado para trabajar en todos los modos (ascendente/descendente, módulos positivos/negativos, módulos/punteros impares).
Recuerde que el modo de dibujo de líneas no será verificado y que todos los registros del blitter pueden ser escritos por el copper si `copcon` esta configurado.

#### Comprobación de la Espera del Blitter

Cuando la opción ChkBltWait/S esta activa WHDLoad usara un seguimiento de instrucciones para verificar que el programa instalado espera correctamente a que el blitter termine antes de lanzar otro trabajo de blitter. Usa una variable interna que representa el estado de trabajo del blitter. La variable es configurada cuando se produce un acceso de escritura a `bltsize` o `bltsizh` y desactivada cuando se realiza un acceso de lectura al registro `dmaconr`. En cada escritura a un registro del blitter el valor de la variable interna es comprobado, si demuestra un trabajo de blitter en ejecución el programa instalado será terminado y WHDLoad reportara el PC del ultimo trabajo de blitter arrancado conjuntamente con el acceso actual.
Hay dos cuellos de botella principales en esta funcionalidad. Primero, el uso de blitter a través del copper no se comprueba, y segundo, el uso de las interrupciones del blitter ocasionara que la rutina de comprobación reporte errores inexistentes.

#### El futuro

Esta planeado implementar funcionalidades tales como Congelado e Iconificado. Para las mismas, Snoop es un requisito necesario. Por lo tanto es recomendable que los autores de los instaladores comprueben sus instaladores con Snoop para asegurar la compatibilidad futura.

#### Requerimientos

Se requiere una MMU para la funcionalidad Snoop. WHDLoad también debe usar la MMU, por lo tanto MMU/S debe estar activo en máquinas con 68030.

#### Limitaciones

- 68020 + 68851
  - este hardware actualmente no esta soportado
- 68030
  - sin limitaciones conocidas
- 68040
  - este hardware actualmente no esta soportado
- 68060
  - instrucciones `movem` pueden acceder a un registro inválido sin ocasionar una excepción de Falla de Acceso, esto es posible debido a que solamente el primer acceso es comprobada contra validez del registro
  - `move <registro Cia/Custom>,sr` será ejecutado incorrectamente si intenta cambiar la porción supervisor del registro de estado, la porción de supervisor permanecerá sin cambios
  - cualquier `(ssp)+` o `-(ssp)` en conjunto con un acceso de escritura a un registro CIA o Custom no puede ser gestionado debido a problemas del entorno de pila, WHDLoad detectara tales accesos y terminara con un cuadro de diálogo apropiado
  - las instrucciones no deben acceder mas de un registro controlado por Snoop al mismo tiempo, esto significa que código como `move.b ($dff006),($bfd800)` no puede ser gestionado, si ocurre un código como este WHDLoad mostrara un diálogo de Falla de Acceso