HispaMSX

Re: [hispamsx] patrones bitmap

2008-03-12 16:16:20

Pues las pegas las de siempre, que para implementarlo en un msx hay que
cortar pistas y hacer un guarreo que no veas, ademas de que para que lo
quieres si no hay software que lo use?


El mié, 12-03-2008 a las 13:16 +0100, mohai escribió:
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]




 


<Anterior en la conversación] Conversación actual [Siguiente en la conversación>
  • patrones bitmap, mohai
    • Re: [hispamsx] patrones bitmap, Rafael Vargas Coca <=