Hola!
Tengo una pequeña duda técnica...
Cómo funciona el tema de las interrupciones en una determinada scanline?
A ver, una pequeña explicación:
El Z-80A del MSX puede ser interrumpido por el VDP. Cuando esto ocurre,
el Z-80A SE DETIENE y hace INTERNAMENTE un 'DI y CALL #0038' para atender la
interrupción. Por lo cual en la posición #0038 deberemos poner nuestro
código. Generalmente se pone un JP xxxx a nuestra rutina en la posición
#0038.
Pero, ¿cuando el VDP genera una interrupción?
El VDP puede generar dos tipos de interrupciones, la de vBlank y la Line
Interrupt.
La vBlank se produce cada vez que el VDP TERMINA de enviar UNA pantalla
al monitor. Lo que llamamos UN FRAME. Para que lo entiendas mejor, imagina
que tú eres el VDP y que el monitor es una hoja en blanco que has de
escribir. Empezarás a escribir desde la esquina superior izquierda y así
sucesivamente hasta llegar a la esquina inferior derecha, justo cuando
llegues al final pues provocarias la interrupcion de vBlank y comenzarías a
escribir en una nueva hoja en blanco... y así sucesivamente. Pues
exactamente esto hace el VDP.
Esta interrupción se genera 50 veces por segundo en modo PAL, y 60 en
modo NTSC, es como decir que la hoja de NTSC es más corta y hay que escribir
menos, por eso se genera más veces que la de PAL y la pantalla del MSX se
estira...
La Line Inter se genera cuando terminamos de escribir UNA LINEA de la
hoja. Imagina que le dices al VDP que te genere una Line Inter en la línea
70, pues siguiendo con nuestro ejemplo de la hoja, cuando TERMINASES de
escribir 70 lineas el VDP generaría la Line Inter.
El Z-80A SIEMPRE hace lo mismo, Detenerse y hacer DI y CALL #0038.
Siempre y cuando estemos en modo EI, si estamos en DI, el Z-80A ignora
cualquier interrupción.
Entonces, ¿como sabemos cual de las dos interrupciones se ha generado?
pues 'preguntandoselo' al VDP. El bit 7 del registro de estado 0 nos indica
que se trata de una vBlank si está a 1. Y el bit 0 del registro de estado 1
nos indica que se trata de una Line Inter si está a 1.
Es OBLIGATORIO leer estos registros para que el bit en cuestion se
resetee (se pone él solo a 0 al leerlo) si no se REPETIRIA la petición
en cuanto hagamos EI.
La line interrupt se puede generar tantas veces como queramos en un
mismo frame, siempre y cuando no revasemos la SIGUIENTE linea en la que
queremos provocarla.
Alguien me puede dar un esbozo del código?
Te paso un source que he hecho para que lo puedas ver, es 100%
compatible con COMPASS y DEVPAC.
Sobre este source pues está programado para trabajar DIRECTAMENTE con el
hardware del MSX, por lo cual CONGELA el DOS durante su ejecución y luego
restauro TODO lo que se modifica para ser totalmente trasparente al DOS.
El ejemplo que te adjunto corre bajo DOS/DOS2, por lo cual en la
posición #0038 el DOS ya tiene su JP a su servidor de interrupciones. Así
que lo que hago es sustituir el JP xxxx del DOS por el mio propio y al final
volverlo a dejar como estaba.
Al final, lo que quiero es tener dos paletas de colores (una para la
parte superior y otra para la parte inferior de la pantalla).
Pues justo esto hace este source, espero que te ayude.
Has de tener muy claro lo que es un frame y que todo lo que quieras
hacer ha de transcurrir dento de él, de lo contrario todo se desincroniza y
no funcionaría. En otras palabras, que todas las rutinas que corran dentro
de la interrupción han de tardar SIEMPRE menos de UN FRAME.
Por ejemplo, todos aquellos juegos que cuando los objetos se mueven lo
hacen 'como a trompicones' es porque el bucle principal corre como mínimo en
DOS frames. Sin envargo todos los objetos que se mueven suabes, sin ningún
'trompicón' ni anomalia es porque todo funciona dentro de UN mismo FRAME.
Aquí es donde está el que sabe programar mejor o peor en ensamblador!!!
Saludos!
Darth-007!
Rgbinter.asm
Description: Binary data
Rgbinter.com
Description: Binary data