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]