Karoshi MSX Community

Desarrollo MSX => Desarrollo (Español/Spanish) => Mensaje iniciado por: Darth_Fistro en 01 de Febrero de 2006, 06:07:15 pm



Título: Transferencias a VRAM
Publicado por: Darth_Fistro en 01 de Febrero de 2006, 06:07:15 pm
Hello, mi duda es la siguiente. Siempre usando las funciones de la BIOS, LDIRVM y LDIRMV, si estoy trabajando con una porción de la pantalla, ¿es más rápido transferir sólo esos bytes, por ejemplo, 512, o la pantalla completa (los 768)? Por ahora no quiero dejar de usar la BIOS, y para lo que hago, no he llegado al límite  :)


Título: Re: Transferencias a VRAM
Publicado por: jltursan en 01 de Febrero de 2006, 07:02:27 pm
No he tomado medidas; pero en general cuantos menos bytes mejor, da igual que uses la BIOS o rutinas propias, además entre 512 y 768 hay un pico.
Ahora bien, si los bytes no están consecutivos y si muy troceados, entonces si que te penalizaría bastante usar la BIOS. De la BIOS lo más desastroso son los SETWRT y SETRD (no creo que nadie use WRTVRM y RDVRM); pero los LDIR no están nada mal para el que no quiere complicarse la vida.


Título: Re: Transferencias a VRAM
Publicado por: Jon_Cortazar en 01 de Febrero de 2006, 08:04:49 pm
Juanma, que se te ve el plumero!  :). Currate ese scroll solo de 512 caracteres y haz un bonito marcador de 256 en el tercer banco!  :D (o no era eso lo que querías hacer?)


Título: Re: Transferencias a VRAM
Publicado por: Darth_Fistro en 01 de Febrero de 2006, 11:02:51 pm
Jon, ¡eres más mal pensado que una tía!  ;D

Pues no, esta vez no, pero es que las rutinas que generan "movimiento" de caracteres por la pantalla (disparos, etc.) pasan por un bucle mogollónico que claro, cuantas menos posiciones de pantalla tenga que procesar, mejor (en un buffer en RAM de esa pantalla, claro, que si no...  ;)). Pero a la hora de pasarla a la VRAM, me surgía esa duda.

Y sí, tengo pendiente ese scroll...

Y los magníficos sprites software de José Luis...

Y tantas cosas...  :D

Por cierto, descargué de un especial de Microhobby un tutorial sobre sprites en el Spectrum, que pensé que igual se podrían traspasar al MSX para hacer aquellos típicos juegos "versionados", pero es MUY complicado, la verdad es que plantar un sprite software en pantalla y moverlo (sobre todo en horizontal, con rotaciones y tal) es una odisea. Además, para ganar velocidad, la rutina lo que hacía era ir restableciendo lo que el sprite iba borrando a medida que se movía, en lugar de tener que volcar la pantalla completa. Una alegría, vaya   :-\


Título: Re: Transferencias a VRAM
Publicado por: Darth_Fistro en 26 de Marzo de 2006, 12:23:35 am
Tengo en mis manos una msx-extra donde se da una rutina de transferencia rápida a base de outs y otras hierbas y el autor menciona que se tiene que prescindir de las interrupciones por no sé qué de la sincronización y bla, bla... ¿quiere esto decir que si uso algo fuera de las rutinas BIOS tendré que prescindir p.e. del Caruso?  :-\


Título: Re: Transferencias a VRAM
Publicado por: jltursan en 26 de Marzo de 2006, 03:15:35 pm
Esa es la parte más jodida del VDP, a ver si consigo explicarme... :P

El VDP tiene 2 puertos de acceso, el puerto de datos ($98) y el puerto de direcciones ($99). Normalmente todas las operaciones con el puerto de datos van precedidas de una inicialización previa mediante el puerto de direcciones, en la que se le indica a partir de que dirección de la VRAM se va a escribir o leer (vease SETWRT o SETRD). Pues bien, si examinamos cualquiera de estas dos rutinas, por ejemplo SETWRT, encontramos lo siguiente :

Código:
ld a,l
di
out ($99),a
ld a,h
and $3F
or $40
out ($99),a
ei
ret

Vemos que se han desactivado las interrupciones durante los dos accesos a dicho puerto. Esto es necesario hacerlo ya que cuando se le inicializa el puntero de escritura o lectura, se hace mediante dos accesos, primero se le pasa el LSB y luego el MSB (con determinados flags añadidos para indicar lectura o escritura).

El VDP al recibir el LSB, sabe que es la primera mitad de una dirección; así que pone un flag interno a 1 para indicar que está esperando la otra mitad y que el siguiente byte que le llegue va a ser su media naranja. Cuando el MSB llega, se construye la dirección completa y se pone ese flag interno a 0, la operación ha finalizado. El problema es que cualquier otra lectura del puerto de direcciones ($99) o cualquier acceso sobre el puerto de datos ($98) también ponen ese flag a 0, por lo que si entre el LSB y el MSB dejamos que se nos cuele cualquiera de estas dos operaciones, se fastidiará el "SETWRT" o el "SETRD", no se habrá construido correctamente el puntero a la VRAM y lo que conseguiremos es basura en pantalla.

Así pues, entre dos accesos al puerto de direcciones no se puede hacer ninguna otra operación con el VDP. Claro, diremos; ¿pero para que he de desactivar las interrupciones?; pues para nada, no hace falta, basta con asegurarse que entre los accesos a $99 no se hace otra cosa con el VDP y que en tu interrupción al VDP ni olerlo.

En la BIOS es necesario ya que en cada interrupción se lee el registro de estado del VDP, lo que jodería inmediatamente cualquier operación con el VDP.

Vamos, que lo normal es que una rutina de reproducción de audio no toque para nada el VDP, por lo que es totalmente compatible con las rutinas de acceso rápidas al VDP. Y si por alguna desgraciada razón te ves obligado a desactivarlas; pues no pasa nada; pero procura hacerlo el menor tiempo posible. El reproductor seguirá sonando igual ya que sólo hay que proteger los accesos a $99, no a $98 (también hay problemas con los accesos rápidos a $98; pero esa es otra historia) ::)

Esto me sugiere una pregunta, ¿de igual manera que el EI se puede atrasar una instrucción, se podría adelantar el DI?, quedando algo así :

Código:
ld a,l
out ($99),a
di
ld a,h
and $3F
or $40
ei
out ($99),a
ret

¿Habría tiempo entre el OUT y el DI a que se colara alguna interrupción?

Ala, otro tocho infumable más para la colección  ;D


Título: Re: Transferencias a VRAM
Publicado por: Darth_Fistro en 26 de Marzo de 2006, 10:00:28 pm
Joder, me deja Ud. de piedra, como siempre :D

Vamos, que en principio no debo temer nada con el Caruso si cojo (con vuestro permiso) alguna de las rutinas memoria-vram-outs-a-punta-pala que se han publicado por aquí. He aprendido algo nuevo del VDP :)

Necesito MUCHA velocidad, ya lo sabe, jejejeje ;)


Título: Re: Transferencias a VRAM
Publicado por: jltursan en 26 de Marzo de 2006, 10:53:37 pm
Si; pero ojo con lo de la BIOS, que como supongo que la vas a seguir usando (¿o te vas a montar un peaso ROM de 48K? ;)) sí que vas a tener que proteger esos accesos con el DI/EI; ya que si se está ejecutando la interrupción que está en $38, siempre corres el riesgo de que te chafen la operación.


Título: Re: Transferencias a VRAM
Publicado por: Jon_Cortazar en 27 de Marzo de 2006, 10:15:17 am
Pedazo de comentario técnico, jl!. A sus pies!  :god:


Título: Re: Transferencias a VRAM
Publicado por: jltursan en 27 de Marzo de 2006, 04:02:20 pm
Lo que haga falta para conseguir... ¡la máxima velocidad!.  nnchks:)
Además Robsy tendrá que llevar todo esto a la práctica con su librería/BIOS optimizada; así que supongo que dentro de un tiempo esto va a ser un hervidero de ideas disparatadas y rutinas temerarias. :)


Título: Re: Transferencias a VRAM
Publicado por: Darth_Fistro en 27 de Marzo de 2006, 04:41:14 pm
Si; pero ojo con lo de la BIOS, que como supongo que la vas a seguir usando (¿o te vas a montar un peaso ROM de 48K? ;)) sí que vas a tener que proteger esos accesos con el DI/EI; ya que si se está ejecutando la interrupción que está en $38, siempre corres el riesgo de que te chafen la operación.

¿Cuál es esa interrupción?  ??? ya me estás dando canguelo ;D

Veo también que utilizáis el puerto 98 a destajo, pero ¿no está eso desaconsejado? Creo que en una de las revistas (ahora no las tengo a mano) venía un artículo diciendo que no era el mismo en todos los MSX y un método de acceso "seguro" (ya postearé el trozo de código en basic, creo que para hallar lo que el autor llamaba "puertos" o algo así).

Ya os suplicaré por rutinas rápidas, pero antes tengo que terminar de experimentar con la bios a pelo, aunque ya me he dado cuenta de que aunque quite halts y demases, la cosa va igual de rápido, o sea que todo el cuello de botella está en el maldito volcado  :-[

¡Gracias de nuevo!


Título: Re: Transferencias a VRAM
Publicado por: jltursan en 27 de Marzo de 2006, 05:06:05 pm
En el MSX, el modo de interrupción estandar en el que se encuentra el Z80 es el IM1, es decir, que cuando toca, se llama al servicio de interrupción que tiene que residir forzosamente en la dirección $38. En esa dirección la BIOS tiene una rutina que hace la tira de cosas, como por ejemplo, leer ese maldito registro de estado del VDP, actualizar las variables que contienen los registros del VDP (que también joden lo suyo), incrementar el temporizador, leer la matriz de teclado, etc.

Si no cambias el modo de interrupciones (poniendo IM2, por ejemplo), no quitas la BIOS de enmedio y mantienenes las interrupciones activas, siempre se estará ejecutando todo esto a partir de la dirección $38. En esa rutina es donde tienes el gancho que habitualmente se usa para implementar tu propio servicio de interrupción, el $FD9F. Vamos, que no te creas que tu rutina es lo único que se ejecuta cada 50 veces (ó 60) por segundo, también hace otras muchas más cosas (de las cuales alguna seguro que te sobra :()

Citar
Veo también que utilizáis el puerto 98 a destajo, pero ¿no está eso desaconsejado?

Los puertos del VDP "reales" se encuentran en la BIOS en las direcciones $6 (puerto de direcciones) y $7 (puerto de datos), es posible que me haya equivocado, el que tenga un MSX a mano que haga un PEEK a esas direcciones y verá los valores (en el 99,99% de los casos, $99 y $98). Parece ser que sólo unos equipos brasileños que incorporaban una ampliación de algo, VDP o no se que, tenían puertos diferentes. Todos los MSX de todas las generaciones coinciden en que los puertos son el $98 y $99. Imaginate el follón que supondría el sacrificar toda esa velocidad por un par de modelos. Volviendo a Robsy, si está con su BIOS, supongo que lo primero que hará será leer los auténticos puertos y luego automodificar el codigo introduciendo esos valores en todas las rutinas que tenga en las que se usen. Es la única forma de hacer que el código sea 100% compatible y a la vez rápido. :-\

Tampoco se pueden hacer accesos a destajo al puerto $98. Como la memoria de video de los MSX1 puede ser algo lenta, es conveniente dejar algunos ciclos entre acceso y acceso (con 7 suele bastar); esa es la razón de porque el OTIR no funciona cuando transfieres muchos datos. En los MSX2 no pasa porque el acceso se hace a través de un buffer que se encarga de corregir esto. :)

Y recuerda que HALT sólo deberías emplear uno, al principio del volcado; si en un frame no te da tiempo, mal vamos  :P


Título: Re: Transferencias a VRAM
Publicado por: Darth_Fistro en 30 de Marzo de 2006, 03:03:47 pm
¿Es posible recuperar el topic del antiguo foro donde se expusieron varias rutinas de transferencia rápida a vram?

 :)


Título: Re: Transferencias a VRAM
Publicado por: pitpan en 30 de Marzo de 2006, 03:07:30 pm
Viejo_archivero es el que tiene el back-up, pero de momento puedes consultar el artículo al respecto en http://map.tni.nl


Título: Re: Transferencias a VRAM
Publicado por: Dioniso en 30 de Marzo de 2006, 04:06:08 pm
Código:
ld a,l
di
out ($99),a
ld a,h
and $3F
or $40
out ($99),a
ei
ret


Por cierto, se podría hacer un

Código:
ld a,l
di
out ($99),a
ld a,h
out ($99),a
ei
ret

con simplemente añadir $4000 a HL antes de llamar a la rutina, en fin, si queremos escribir en 6144 pues; LD HL,6144+$4000


Título: Re: Transferencias a VRAM
Publicado por: Darth_Fistro en 30 de Marzo de 2006, 04:22:56 pm
¡Gracias!  :)

Supongo que esa rutina es lo que corresponde a un VPOKE (perdonad mi ignorancia), ¿verdad? Ya he visto un post en MSX.org con un topic de Robsy sobre una rutina de volcado en bloque :) por lo que dijo José Luis, puedo quitar los di/ei ya que lo único que se ejecuta cada vblank es el Caruso, que no debería afectar.

Gracias también por lo del MAP. He visto una rutina de loops rápidos que también me van a venir al pelo (eso espero).

Bueno, a ver si se puede recuperar ese topic y gracias de nuevo :D


Título: Re: Transferencias a VRAM
Publicado por: jltursan en 31 de Marzo de 2006, 10:16:37 am
Citar
Supongo que esa rutina es lo que corresponde a un VPOKE

Más o menos, corresponde a un SETWRT, a continuación ya podrías volcar el dato a la VRAM.

Citar
puedo quitar los di/ei ya que lo único que se ejecuta cada vblank es el Caruso

Ojo con eso, para poder quitar los DI/EI tienes que tener mapeada en RAM la página 0 y haber implementado tu propia rutina de interrupción en $38. Si utilizas el gancho de $FD9F hay que mantener las interrupciones deshabilitadas haga lo que haga tu interrupción. También podrías cargarte la interrupción de la BIOS; pero eso ya es un poco más delicado y no me imagino todas las consecuencias que podría tener  :-\