Durante la imagen, el ARM solo puede adelantarse unos ciclos al 6507. Entre dos inyecciones dispone del tiempo que tarda el 6507 en ejecutar la anterior: tras una escritura, un ciclo; tras un WSYNC, el resto de la línea. Si llega tarde, el 6507 lee el último byte que vio en esa dirección, que en un kernel repetitivo a veces es la misma instrucción y «funciona por suerte». De ahí las reglas: nada de cálculos en el kernel (todo se precalcula en una caché que solo se rehace si cambian la sala, el modo o la ventana), las divisiones entre 3 son multiplicaciones y cada espera va ya calculada.
El kernel
Planificar 23 escrituras en 76 ciclos y dejar el resto para el overblank.
El ARM va un ciclo por delante
Una línea como lista de eventos
En FRANJA+ y COMPLETO cada línea es una lista de eventos: qué registro se escribe, con qué dato y en qué ciclo acaba la escritura. Cada escritura tiene una ventana válida, calculada con tiempos medidos en Stella (un RESP que acaba en el ciclo c deja el objeto en x = 3c − 63; un gráfico escrito en el ciclo c se ve desde x ≈ 3c − 68). Un planificador coloca primero las de ventana más estrecha y, si no caben, vuelve atrás. Reglas: entre dos eventos hay 0 ciclos libres o al menos 2, y el jmp cuenta como una escritura más.
No se planifica en cada línea. En FRANJA+ la tabla se resuelve una vez al arrancar y el kernel la reproduce. En COMPLETO, las parejas de líneas del damero (una A y una B, para cada campo y tipo de fila) las resuelve una herramienta fuera de la ROM, porque en el ARM costaban segundos. Una línea de COMPLETO lleva los HMOVE, tres RESP0 (uno en el ciclo 76 y dos a media línea), ocho GRP, la muestra de AUDV0 y el jmp.
Los colores de la sala, el fondo y la tinta de los jugadores, no van en cada línea: se ponen una sola vez antes de ella, sin bus stuffing, y valen para los dos campos. En el marcador solo cambian donde empieza cada tramo. Antes el campo 1 los reescribía en cada línea con bus stuffing, y en algunas teles PAL aparecían rayas de color. Solo sigue por línea el recuadro rojo de la hora.
Líneas de 76 ciclos sin WSYNC
La sala entera se emite en un solo bucle: la espera de fin de línea se suma a la del primer evento de la siguiente, y las líneas duran exactamente 76 ciclos sin WSYNC. Una línea «de cebado» apaga VBLANK con una escritura que acaba en el ciclo 76, de modo que la primera línea visible empieza ya en el ciclo 0. Eso bajó el hueco entre líneas de 93 a unas 29 instrucciones del ARM. Hoy el peor hueco del kernel está en el damero de COMPLETO: 36 instrucciones en un ciclo del 6507, unos 43 MIPS. FRANJA, FRANJA+ y DOBLE sí esperan con WSYNC entre líneas.
El algoritmo del pintor
El TIA no dibuja a Guillermo ni a los monjes: los compone el ARM en el bitmap de 128 × 160, como el original. Se ordenan los personajes de atrás adelante; antes de cada uno se pintan las baldosas aún sin pintar que no estén más cerca que él; al final, las que falten, por delante de todo. Así Guillermo pasa por detrás de columnas y arcos. El motor reproduce al píxel las 94 salas del Spectrum (reducidas) y 19 escenas con personajes.
El overblank, en cuatro tiempos
En cada overblank va como mucho una tarea pesada. Mientras alguien habla, la lógica sigue el ritmo del original: un tick cada 6 frames a 50 Hz, uno cada 7,2 a 60. Cuando nadie habla, el original corre sin esperar, y el demake también: cada tick empieza en cuanto el anterior está dibujado, uno cada 6,9 frames de media a 60 Hz, para que el personaje que sigue la cámara no avance a saltos. Ese es el ritmo nominal, el que da el interruptor de dificultad derecho en la posición que tiene al encender la consola. El Spectrum, en la práctica, no llegaba a él: andando da 6,5 ticks por segundo y no los 8,3 de su espera de 6 frames. Por eso, en la otra posición, cada tick dura un 28 % más: el ritmo lento que recuerda quien jugó al original. Al mover el interruptor, el marcador lo dice durante unos dos segundos, por encima de las frases de los monjes: «RITMO RAPIDO» o «RITMO LENTO», y en FRANJA, que tiene menos sitio, «RAPIDO» o «LENTO». Cada tick se reparte en cuatro partes: objetos, puertas y Guillermo; Adso; monjes 2 y 3; monjes 4 y 5 y el final. Una sala nueva se construye por trozos, interpretando los «programas de bloque» del original (6 bloques por overblank; una sala tiene 21 de media), y se dibuja en dos franjas. La sala nueva aparece unos 6 frames después del cambio, y mientras tanto la lógica espera, como en el original.
| Tarea | Antes | Ahora (instrucciones del ARM) |
|---|---|---|
| Construir una sala | 260 000 en un overblank | 98 000 como máximo por overblank |
| Preparar las líneas (COMPLETO) | 85 000 | 42 000 |
| Sintetizar el sonido de un frame | 29 000 | 9 000 – 13 000 |
| Preparar el marcador | 13 000 | 2 900 de media |