viernes, 1 de julio de 2016

VOLCADO DEL BUFFER CON LA PILA (IV): RUTINA DE VOLCADO II







En esta entrada voy a explicar la subrutina VULVU.
Antes que nada, decir que es una "libre adaptación" de la que usa Mike Lamb en algunos de sus juegos, como Batman: The Movie o WEC Le Mans. Yo la uso en Knightmare 2 ZX.

En el .GIF de abajo puedes ver la forma en la que vuelco el buffer en la pantalla real. Va volcando las líneas de derecha a izquierda y primero vuelca un doce caracteres en horizontal y luego los otros doce.

Volcado del buffer en la pantalla real

Para la explicación, voy a tomar como base que volcamos desde la dirección 8004h del buffer a la 4090h de la pantalla real.

IX va a ser el puntero que lleva las direcciones del buffer, por ello lo cargamos con 8000h (inicio del buffer) + 4 que son los caracteres que dejamos de marco a la izquierda.
HL es el puntero de la pantalla real. Vamos a imprimir a partir del cuarto caracter vertical, dejando un marco de 4 caracteres a la izquierda: 4000h+80h+4=4084h. ¿Por qué lo cargamos con 4090h?, pues porque hay que sumarle 12 (0Ch). 4084h+0Ch=4090h. Ahora entenderás por qué.

 

Guardamos SP y lo cargamos con IX que es el inicio del buffer que queremos volcar (8004h).
Salvamos los registros. El que nos interesa es HL que lleva las direcciones de la pantalla real.
Cargamos 6 registros con las primeras 12 direcciones de la primera línea a volcar:

HL'=contenido de las direcciones 8004h,8005h
DE'=contenido de las direcciones 8006h,8007h
BC'=contenido de las direcciones 8008h,8009h
AF= contenido de las direcciones 800Ah,800Bh
DE= contenido de las direcciones 800Ch,800Dh
BC= contenido de las direcciones 800Eh,800Fh

Ahora cargamos SP con HL (SP=4090h) y hacemos PUSH con todos los registros que antes hemos cargado. Ya he comentado que al hacer POP, SP se incrementa, pero al hacer PUSH, primero se decrementa y luego se mete el dato en la dirección donde apunta SP. Por eso hay que sumarle 12 a HL. Al hacer PUSHes, éste se va decrementado. Así que los registros se "PUSHEAN" en orden inverso a como se "POPARON"

El valor de BC se mete en 408Fh,408Eh
El valor de DE se mete en 408Dh,408Ch
El valor de AF se mete en 408Bh,408Ah

En este momento incrementamos H para pasar a la siguiente línea de la pantalla (4190h)
y salvamos los registros.

El valor de BC' se mete en 4089h,4088h
El valor de DE' se mete en 4087h,4086h
El valor de HL' se mete en 4085h,4084h

Como puedes ver, cada byte se ha colocado en su sitio y de la forma como se ve en el .GIF.

Ahora tenemos que pasar a la siguiente línea del buffer, por lo que hay que incrementar el byte alto de IX. Hacer algo así como INC Ix. Este nemónico como tal no existe, pero si ponemos el valor DDh antes de INC H, el Z80 lo interpreta como INC Ix.

Esto lo hacemos cuatro veces para volcar las cuatro primeras líneas.
Después del último volcado miro a ver si hemos llegado a la cuarta línea, con lo que repetimos el proceso, o si hemos acabado con el caracter en curso. Para eso se hace BIT 2,H. Si el resultado es uno, significa que estamos en la línea 4, por lo que repite.

Hemos acabado de imprimir el primer rectángulo de 1 caracter de alto por 12 de ancho.
¿Qué valor tiene IX?: Partíamos de 8004h. Hemos incrementado Ix 8 veces, por lo que IX=8804h.
¿Qué valor queremos que tenga ahora? Queremos que apunte a la posición de inicio (8004h) más los doce caracteres que ya hemos metido, osea 8004h+0Ch=8010h.
La cuenta es sencilla. Restamos 8 a Ix y sumamos 0Ch a iX. Osea, le restamos (800h-0Ch).
Para HL la cuenta es la misma.



Ya podemos volcar los otros 12 caracteres.

¿Cuánto vale ahora IX? Empezó en 8010h y hemos incrementado Ix 8 veces. IX=8810h.
¿Cuánto queremos que valga? Pues queremos que se nos posicione en el siguiente caracter en vertical de donde empezó en un principio. Empezó en 8004h y queremos que valga 8024h.
Podemos restar 8 a Ix, restar 0Ch a iX y sumarle 20h. (800h-20h=7E0h.)
Basta con restar a IX (7E0h+0Ch). 8810h-(7E0h+0Ch)=8024h.

Ya tenemos volcado el primer rectángulo de 1 caracter de alto por 24 de ancho. HL e IX apuntan al inicio del segundo rectángulo... siempre que no se cambie de tercio. Este problema ya se solucinó en la anterior entrada.


Si he conseguido que entiendas esto, no te será muy complicado cambiar el tamaño del buffer que se vuelca. De todas formas he dejado preparada "alguna pista". Si queremos un buffer 4 caracteres más ancho, tenemos que volcar dos caracteres más por vuelta. Para eso hay que usar un registro doble más. Yo he elegido AF'. Si quitas los ";" delante de EX AF,AF' y de los PUSH AF y POP AF volcamos 4 datos más, por lo que el buffer volcado será de 28 caracteres de ancho. Pero recuerda darle a MITAN el valor de 14. Para centrar algo mejor el buffer puedes dar  a CHAR el valor de 2.
Si queremos menos caracteres verticales, tenemos que quitar VOLVUs de nuestra pila "artificial".

Como siempre te digo, experimenta, que es la mejor manera de entender las cosas.

La rutina de restablecimiento del fondo no tiene nada de especial.