Buenas,
le he estado dando vueltas al tema de los patrones para los modos bitmap del
MSX2 (y 2+). Creo que he encontrado una solución.
He escrito un artículo con la teoría. Aún tengo que pulir la parte hardware,
pero creo que la implementación no sería difícil.
Echale un vistazo a ver que os parece y qué pegas le veis.
Salu2,
IvI
----------
Modo de patrones para V9938/58
------------------------------
1.- Introducción
2.- Desarrollo
3.- Análisis hardware
4.- Pros y contras: Incompatibilidades
5.- Método alternativo
1.- Introduccion:
El VDP de los MSX 2 y 2+ carece de modo patrones en los nuevos modos bitmap.
El principal problema para emular un modo de patrones por software, es que hay
que hacer múltiples "copias" a vídeo (de vídeo a vídeo). Es un método poco
rápido
y limitado por el tiempo de refresco de pantalla, además de hacer que la CPU
trabaje casi en exclusiva para el chip de vídeo.
Pero, si el VDP es capaz de redibujar la pantalla 50 (o 60) veces por segundo,
quiere decir que en realidad el chip sí es lo suficientemente rápido como para
mostrar unas 64K en cada interrupcion.
Entonces, ¿por qué no se suministró un modo de patrones para los nuevos modos
bitmap? Recordemos otra evolución del chip, el incluido en las consolas SEGA
Master System, que sí incluye un modo bitmap con patrones.
Si nos fijamos en cómo funcionan otros modos de patrones, como el modo
gráfico 2 (SCREEN 2 en MSX), nos daremos cuenta de que la pantalla está
compuesta
por un montón de patrones que son mostrados según la tabla de patrones, es
decir,
al contrario que los modos bitmap, donde la pantalla se muestra recorriendo
linealmente la memoria de vídeo, sin saltos, en el modo patrones lo que se hace
es variar la dirección de lectura de memoria para cada grupo de 8x8 puntos.
Esto quiere decir que la tabla de patrones actúa como una tabla de punteros.
Ya que los punteros de los patrones son de 8 bits, se pueden conseguir un máximo
de 256 patrones diferentes. El resto de bits del bus de direcciones actúan de 2
maneras: por un lado unos bits son un puntero interno para los atributos
(colores)
de cada fila de cada patrón y, los otros bits, apuntan al grupo de 256 patrones.
De ésta manera, se pueden conseguir 3 grupos de 256 patrones. Suficientes para
llenar una pantalla de screen 2 (256x192)
Pero, si los modos bitmap carecen de modo patrones, ¿sería posible variar con
circuitería externa, el acceso del VDP a VRAM para hacer que dibuje lo que
queramos
para cada punto?
Una posible solución sería, aprovechando el redibujado de la pantalla, sustituir
el bus de direcciones que atacan a la VRAM, por punteros a los patrones, esto
es,
hacer que el chip de vídeo dibuje la pantalla en cada área de 8x8 con la zona
de memoria indicada por el mapa de patrones, en lugar del tradicional redibujado
lineal.
2.- Desarrollo:
Para hacer un modo fácil y a la vez potente de patrones, tomemos el modo gráfico
de 256 colores (screen 8). Este modo es ideal, ya que cada punto está
representado
por 1 byte, lo que facilita enormemente las cuentas. Además, los nuevos modos
del
chip V9958 tienen un mapa de memoria similar.
Para hacer que el modo patrones funcione sin interferir al resto de funciones
gráficas
(sprites), se desplazará el área de trabajo de los sprites al segundo banco de
64K.
De ésta manera, se puede usar el bit A16 como "interruptor" para conectar o
desconectar el modo de patrones.
Recordar que el VDP trabaja con una ventana de 256x256 puntos en este modo, por
eso
la tabla de patrones resultante será de 32x32 (1024 bytes).
Gracias a que la dirección de comienzo del bitmap siempre es 0 y el ancho y
alto no
varían, no es difícil calcular qué patrón está redibujando VDP en cada momento.
Se
establece una relación entre la dirección VRAM y el patron a dibujar.
EL VDP dibuja la pantalla del siguiente modo (obviando dibujado de sprites):
- Bus de direcciones a 0
- Lectura de VRAM
- Muestra el punto (8 bits)
- Incrementa bus direcciones en uno (puntero lectura)
- Repite bucle de lectura
- Los puntos se dibujan de izquierda a derecha, siguiendo la línea de
raster.
- Si dibujando llega al fin de linea, salta a la siguiente linea de
raster.
- Entre las líneas no hay saltos:
el primer byte de una línea es justo el siguiente al último de la
anterior.
Si se intercepta el bus de direcciones, se puede hacer que en vez de apuntar al
punto
siguiente, el bus apunte al punto que corresponda según la tabla de patrones.
Lógicamente, el dibujado de pantalla se complica cuando hay sprites que mostrar,
pero eso no es problema si la zona de trabajo de los sprites se desplaza a las
64K
superiores. Esto permite que, activando el bit A16, se desconecte el modo de
patrones
y se muestren los sprites normalmente. Este efecto permitiría usar la segunda
página
de la manera convencional.
En el funcionamiento normal del VDP, las direcciones de los puntos van asociadas
al refresco de pantalla, esto es, al mismo tiempo que el raster dibuja la
pantalla
de izquierda a derecha, se incrementa el bus de direcciones desde cero en
adelante.
Los puntos (o bytes) están colocados contíguos de izquierda a derecha y las
líneas
contíguas de arriba a abajo. Esto es un mapa de memoria plano.
El inconveniente de usar este sistema de memoria y un modo de patrones, es que
para
redefinir un patrón habría que recalcular (cada 8 puntos), la direccion de VRAM
a la
que escribir. Para solucionarlo habrá que redirigir las líneas de direcciones
para
que todos los bytes del patrón sean contíguos en memoria.
El problema de usar una memoria no lineal es que el VDP sigue refrescando la
pantalla
de la manera tradicional (de izquierda a derecha y de arriba a abajo) e
incrementando
el bus de direcciones de uno en uno para cada punto (en screen 8).
Si queremos que el VDP coloque cada byte en su sitio, tendremos que hacer que
"salte"
por la memoria, controlando el byte que lee para cada punto. Esto se consigue
con unos
cuantos cruces en las líneas de dirección.
La ventaja de usar este sistema es que para calcular la dirección donde está
almacenado
un determinado patrón, basta multiplicar su número por 64 (8x8=64). Además,
basta con
64 OUTs o un OTIR para redefinir un patrón completo
*** Correspondencia entre direccion de refresco (raster) y direccion de punto
de patrón.
Calcular las coordenadas del patron al que pertence un punto (coordenadas de
punto):
Considerando el raster (refresco), las coordenadas de un punto en modo
256 colores
coinciden con el byte alto y el byte bajo de la direccion VRAM del
punto. Se puede
decir que el byte alto es la coordenada vertical (Y) y el bajo es la
horizontal (X).
Para saber a qué posicion en la tabla de patrones (32x32), pertence un
punto del
raster, basta aplicar la siguiente fórmula:
posicion = (Y/8)*32+(X/8)
esto es, despreciar los 3 bits bajos, (rotar a izquierda) y recolocar
los bits como sigue:
X=A7 A6 A5 A4 A3 A2 A1 A0
Y=A15 A14 A13 A12 A11 A10 A9 A8 -> coordenadas del punto =
direccion VRAM
XY=A15 A14 A13 A12 A11 A7 A6 A5 A4 A3 ->posicion tabla patrones
= 10 bits = 1024 bytes
El valor leído de la tabla (P0-P7), nos dá el número de patrón
correspondiente
a la posición del patrón en pantalla.
Para calcular la dirección a aplicar al bus de direcciones,
reconstruiríamos el bus
de direcciones de la siguiente manera:
RAM=P7 P6 P5 P4 A11 A10 A9 A8 P3 P2 P1 P0 A3 A2 A1 A0 (siendo
P0-P3=X, P4-P7=Y)
Pero con esto seguiríamos teniendo el problema de la memoria lineal.
Los bytes de
cada patrón no estarían contíguos.
Con el modelo de patrones de bytes contíguos, para calcular dónde está
almacenado
cada patrón, basta tomar el byte leído de la tabla y multiplicarlo por
64 (que es
el tamaño en bytes de cada patrón). A dicho valor habrá que añadirle
los bits de
dirección para que el VDP se desplace por el patrón mientras el raster
refresca la
pantalla.
El valor resultante sería algo así:
A15 A14 P7 P6 P5 P4 P3 P2 P1 P0 A10 A9 A8 A2 A1 A0
Esta es la explicación de esta colocación de los bits:
- Las líneas A0-A2, hacen que se muestren los 8 bytes del
patrón en el
refresco horizontal
- Las líneas A8-A10 hacen que el raster salte, cada 8 bytes, al
siguiente
patrón.
- P0-P7 hacen que el bus de direcciones apunte al comienzo de
cada
patrón, según el valor leído de la tabla (en saltos de 64
bytes).
- Ya que el rango de patrones va de 0 a 255, A14 y A15 actúan a
modo de
selectores de banco (cuarto de pantalla).
*** Comparación entre el modelo de memoria tradicional y el modelo de patrones
(de bytes contiguos)
Usando el modelo de memoria original,
los bytes (puntos) de cada patron, estarían dispuestos de la siguiente
manera:
VRAM+0 -> 12345678 -> comienzo primer patrón
VRAM+256 -> 12345678
VRAM+512 -> 12345678
VRAM+768 -> 12345678
VRAM+1024 -> 12345678
VRAM+1280 -> 12345678
VRAM+1536 -> 12345678
VRAM+1792 -> 12345678 -> fin primer patrón
VRAM+0+8 -> 12345678 -> comienzo segundo patrón
VRAM+256+8-> 12345678 -> etc. ...
o lo que es lo mismo:
VRAM+256x0 -> 12345678 -> comienzo primer patrón
VRAM+256x1 -> 12345678
VRAM+256x2 -> 12345678
VRAM+256x3 -> 12345678
VRAM+256x4 -> 12345678
VRAM+256x5 -> 12345678
VRAM+256x6 -> 12345678
VRAM+256x7 -> 12345678 -> fin primer patrón
VRAM+256x0+8 -> 12345678 -> comienzo segundo patrón
VRAM+256x1+8 -> 12345678 -> etc. ...
Usando el modelo de patrones (de bytes contiguos),
los bytes (puntos) de cada patron, estarían dispuestos de la siguiente
manera:
VRAM+0 -> 12345678 -> comienzo primer patrón
VRAM+8 -> 12345678
VRAM+16 -> 12345678
VRAM+24 -> 12345678
VRAM+32 -> 12345678
VRAM+40 -> 12345678
VRAM+48 -> 12345678
VRAM+56 -> 12345678 -> fin primer patrón
VRAM+64 -> 12345678 -> comienzo segundo patrón
VRAM+72-> 12345678 -> etc. ...
o lo que es lo mismo:
VRAM+8x0 -> 12345678 -> comienzo primer patrón
VRAM+8x1 -> 12345678
VRAM+8x2 -> 12345678
VRAM+8x3 -> 12345678
VRAM+8x4 -> 12345678
VRAM+8x5 -> 12345678
VRAM+8x6 -> 12345678
VRAM+8x7 -> 12345678 -> fin primer patrón
VRAM+8x0+64 -> 12345678 -> comienzo segundo patrón
VRAM+8x1+64 -> 12345678 -> etc. ...
4.- Pros y contras: Incompatibilidades
* Manejo se sprites: Comprobar el funcionamiento con los diferentes modos de
sprite
* Posibilidad de conexión desconexión del modo patrones (por compatibilidad)
* ¿Posibilidad de scroll horizontal? ¿Vertical?
* ¿Compatibilidad con comandos acelaradores VDP?
5.- Método alternativo
Modificar las líneas de direcciones de VRAM en el momento de ESCRITURA en vez
de lectura,
para que no se perdiera la compatibilidad con los comandos y el scroll.
Para implementarlo, habría que aplicar al bus de direcciones los mismos cambios
que
en el método de lectura.
El problema vendría cuando se quisiera escribir en una dirección de la VRAM
concreta:
Si el número de patrón para una posición no es el original, al hacer la
conversión de
direcciones se escribiría en el patrón mostrado en ese momento, no en la
dirección
real a la que queremos escribir, es decir:
Imaginar que en la tabla de patrones, hemos seleccionado en la posición
X=1, Y=0, el
número de patrón 2 (en vez de el número 1) para mostrar en esa posición
el patrón 2.
cuando vayamos a escribir en la VRAM correspondiente al patrón 1, por
la conversión
de direcciones, estaríamos escribiendo realmente al patrón 2 (que es el
seleccionado
para que se muestre).
Otro incoveniente sería que, modificando la tabla de patrones, no se
modificaría lo que
el VDP muestra en pantalla, si no sólo cuando se escribe en ella.
ESTE MÉTODO NO SERÍA ADECUADO.
[Se han eliminado los trozos de este mensaje que no contenían texto]