Karoshi MSX Community

Desarrollo MSX => Desarrollo (Español/Spanish) => Mensaje iniciado por: e_sedes en 11 de Mayo de 2006, 01:25:40 am



Título: leer el joystick
Publicado por: e_sedes en 11 de Mayo de 2006, 01:25:40 am
Estoy intentando leer el joystick sin usar el GTSTCK, y lo que hago es leer el registro 14 del PSG con RDPSG. Pero siempre me da la lectura del segundo puerto, aunque ponga a 0 el bit 6 del reg. 15. Alguna alma caritativa me puede dar una pista de como hacer?... ???

Las pruebas las hago en emulador, llamando desde BASIC a la rutinilla con un USR y leyendo lo que me da.

gracias. un saludo.


Título: Re: leer el joystick
Publicado por: jltursan en 11 de Mayo de 2006, 09:32:24 am
¡Uf!, ¡como nos estamos pasando últimamente con la BIOS!. No lo he hecho nunca; pero así a bote pronto igual sería una buena echarle un vistazo a la propia rutina de la BIOS, no debe de ser nada complicada.


Título: Re: leer el joystick
Publicado por: e_sedes en 11 de Mayo de 2006, 10:13:11 am
Es que la manera en que te da la lectura el GTSTCK es un coñazo. Yo solo quiero una forma simple de leer cada interruptor del joystick por separado. Me da cierto reparo mandar cosas al reg. 15, por si meto el zueco y achicharro algo  :-\, ...
Si hubiera o hubiese alguna dirección en RAM donde el sistema guardase el byte que lee de cada joystick sería fantabuloso. Pero no se si hay de eso.

un saludo.


Título: Re: leer el joystick
Publicado por: Jon_Cortazar en 11 de Mayo de 2006, 10:22:18 am
Pero, ¿que es lo que no te mola de GTSTCK?. ¡Pero si es ultra cómoda  :o!. (Misa no entiende tusa :D)


Título: Re: leer el joystick
Publicado por: pitpan en 11 de Mayo de 2006, 06:32:50 pm
Pues a ese mismo problema me enfrenté yo. Y otra mucha gente, a juzgar por los problemas que ha tenido la lectura del joystick en algunos de los juegos de la última MSXdev'05.

Mi consejo es que uses la rutina de la BIOS o que la repliques, de forma simplificada, dentro de tu propio código. La lectura de joysticks tiene un problema de sincronización grande, ya que distintas máquinas requieren de distintos retardos. Por ello, la BIOS es una muy buena opción. No se necesita MÁS velocidad. Lo suyo es leer el joystick - como mucho - en cada v-blank una vez (una lectura por frame). Sólo se me ocurriría leerlo continuamente para el control de una pistola óptica, por ejemplo. Así tuve que hacerlo en su momento.

En cuanto al problema que dices, me topé con él durante el desarrollo del DUCK HUNT, que necesitaba realizar una lectura muy rápida de los bits de estado del PSG correspondientes al joystick. Mi diagnóstico es el siguiente: en cada interrupción v-blank, cuando el control pasa a la BIOS, en algún punto de ésta se reinicia el bit de selección. Me imagino que está relacionado con alguna de las rutinas de sistema, que lee sucesivamente ambos joysticks y por eso acaba apuntando al puerto 2.

Pero que me puedo estar equivocando, así que si alguien sabe algo más (hint: Dioniso), que lo comente aquí.


Título: Re: leer el joystick
Publicado por: e_sedes en 11 de Mayo de 2006, 11:29:55 pm
Lo que no me gusta de GTSTCK es el formato en que te entrega la lectura. No buscaba velocidad, sino ver si se podía leer de una manera más simple. Le he estado echando un vistazo al código desensamblado a ver que hacía y si dejaba la lectura directa por algún lado, pero creo que va a ser mejor no liarse demasiado. Usaré la rutina de la BIOS y listo.

P.D.: me mola esto de "aprofundarse" en el ensamblador... :D


Título: Re: leer el joystick
Publicado por: pitpan en 12 de Mayo de 2006, 08:55:23 am
Podrías reconvertir el original sin muchos problemas para su tratamiento más sencillo:

LD A,1
CALL GTSTCK
LD HL,TABLA_JOYSTICK
LD C,A
LD B,0
ADD HL,BC
LD A,[HL]
...

TABLA_JOYSTICK:
db 0000b,0001b,0101b,0100b,0110b,0010b,1010b,1000b,1001b

De esta forma tendrás en el acumulador el campo siguiente:

bit 4 ---  bit 3 --- bit 2 --- bit 1
IZQ.      DER.     ABAJO  ARRIBA

Es una solución. El código es un poco chungo, especialmente el desplazamiento.

A ver qué tal.


Título: Re: leer el joystick
Publicado por: SapphiRe en 12 de Mayo de 2006, 10:33:53 am
Podrías reconvertir el original sin muchos problemas para su tratamiento más sencillo:

LD A,1
CALL GTSTCK
LD HL,TABLA_JOYSTICK
LD C,A
LD B,0
ADD HL,BC
LD A,[HL]
...

TABLA_JOYSTICK:
db 0000b,0001b,0101b,0100b,0110b,0010b,1010b,1000b,1001b

De esta forma tendrás en el acumulador el campo siguiente:

bit 4 ---  bit 3 --- bit 2 --- bit 1
IZQ.      DER.     ABAJO  ARRIBA

Es una solución. El código es un poco chungo, especialmente el desplazamiento.

A ver qué tal.

Sería mejor

Código:
LD A,1
CALL GTSTCK
LD HL,TABLA_JOYSTICK
ADD A,L
JP NC,@@NOCARRY
INC H
@@NOCARRY:
LD L,A
LD A,[HL]

Aunque eso no evita el problema principal, que es que una configuración 1111 le daría 0 y sería indistinguible de una 0000 o una 1100.


Título: Re: leer el joystick
Publicado por: e_sedes en 12 de Mayo de 2006, 10:35:29 am
Si, algo así es lo que tenía pensado hacer. Es lo que hace la BIOS pero al reves. Eso y alguna ideilla más saqué de de revisar el código de GTSTCK.
Gracias.

Ya digo, esto del asm es más vicioso que los sudokus esos... ;D


Título: Re: leer el joystick
Publicado por: e_sedes en 12 de Mayo de 2006, 10:43:58 am
Citar
Sería mejor

Código:
LD A,1
CALL GTSTCK
LD HL,TABLA_JOYSTICK
ADD A,L
JP NC,@@NOCARRY
INC L
@@NOCARRY:
LD L,A
LD A,[HL]

Aunque eso no evita el problema principal, que es que una configuración 1111 le daría 0 y sería indistinguible de una 0000 o una 1100.

Hey, gracias. Para leer un joystick normal no creo se dé ese problema, pero está bien tener eso en cuenta para otras cosas.

un saludo.


Título: Re: leer el joystick
Publicado por: e_sedes en 12 de Mayo de 2006, 10:54:09 am
Sería mejor

Código:
LD A,1
CALL GTSTCK
LD HL,TABLA_JOYSTICK
ADD A,L
JP NC,@@NOCARRY
INC L
@@NOCARRY:
LD L,A
LD A,[HL]

Aunque eso no evita el problema principal, que es que una configuración 1111 le daría 0 y sería indistinguible de una 0000 o una 1100.

No habría que cambiar el INC L por INC H?


Título: Re: leer el joystick
Publicado por: jltursan en 12 de Mayo de 2006, 10:57:58 am
Citar
No habría que cambiar el INC L por INC H?

Sí  ;)


Título: Re: leer el joystick
Publicado por: SapphiRe en 12 de Mayo de 2006, 11:01:10 am
Citar
No habría que cambiar el INC L por INC H?

Sí, lapsus calami...  :-\ problemas de escribir deprisa


Título: Re: leer el joystick
Publicado por: pitpan en 12 de Mayo de 2006, 12:23:55 pm
Sap: aceptamos barco, pero no sé en qué te basas para decir que es mejor.  ;D

La rutina que tú propones ocupa 15 bytes y la original sólo 13 (salvo error u omisión en mis cálculos mentales). Además, la solución es más lenta al tener saltos y ser más larga (más bytes que leer).
Si cambias el JP C,... por JR C,... ahorras 1 byte pero la ejecución se penaliza un poco más.

Por mi parte, prefiero hacer todo lo que puedo sin iterar/saltar.



Título: Re: leer el joystick
Publicado por: e_sedes en 12 de Mayo de 2006, 12:31:19 pm
Bien, pues mirando el código de GTSTCK vi que para tomar el resultado de la tabla al final hace algo así como:
Código:
LD HL,$1233
AND $0F
LD E,A
LD D,0
ADD HL,DE
LD A,[HL]
RET

A la salida resulta que ya tienes en E la lectura del joystick. Y sin los problemas de que sean datos no soportados por el sistema normal. Lo he probado en todas las configuraciones de BIOS del BlueMSX (menos CBios) y va perfectamente. ¿Creeis que puede dar problemas de compatibilidad con alguna máquina? ¿Será fiable?... ???

Si vale lo flipo yo solo ;D


Título: Re: leer el joystick
Publicado por: SapphiRe en 12 de Mayo de 2006, 01:21:09 pm
Sap: aceptamos barco, pero no sé en qué te basas para decir que es mejor.  ;D

La rutina que tú propones ocupa 15 bytes y la original sólo 13 (salvo error u omisión en mis cálculos mentales). Además, la solución es más lenta al tener saltos y ser más larga (más bytes que leer).
Si cambias el JP C,... por JR C,... ahorras 1 byte pero la ejecución se penaliza un poco más.

Por mi parte, prefiero hacer todo lo que puedo sin iterar/saltar.

Me baso en lo siguiente:

Código:
LD C,A (4 ciclos)
LD B,0 (7 ciclos)
ADD HL,BC (11 ciclos)

Luego esa rutina cuesta 22 ciclos SIEMPRE.

Código:
ADD A,L (4 ciclos)
JP NC,@@NOCARRY (10 ciclos)
INC H (4 ciclos)
@@NOCARRY:
LD L,A (4 ciclos)

Que cuesta 22 ciclos EN EL PEOR DE LOS CASOS y 18 en el mejor.

Por lo tanto en un uso cotidiano esa rutina en media es más rápida.

Saludos
--
SapphiRe




Título: Re: leer el joystick
Publicado por: SapphiRe en 12 de Mayo de 2006, 03:14:47 pm
AVISO: contenido matemático

Aún podemos afinar más el análisis. Si realmente cada instrucción lleva asociado un ciclo extra por refresco de memoria tendríamos:

La solución con suma de 16 bits = 25 ciclos (22 + 3 instrucciones)

La solución con el salto =

21 ciclos (18 ciclos + 3 instrucciones) en el caso mejor.
26 ciclos (22 ciclos + 4 instrucciones) en el caso peor.

  En este caso el caso peor supondría un ciclo extra con respecto a la solución con suma de 16 bits, pero sólo sucedería si A+L activa el flag de acarreo. Para ello habría que calcular cual es la probabilidad de que A+L active el flag de acarreo, hagámoslo:

  Supongamos que la probabilidad de que un registro tome un valor cualquiera entre 0 y 255 es uniforme, de tal forma que la probabilidad de que A = V sea 1/256 (de igual manera la probabilidad de que L = W es 1/256). Supongamos, además, que los valores que tomen A y L son totalmente independientes, por lo que la probabilidad de que A = V y L = W es 1/65536 (el producto de ambas probabilidades).

  Ahora viene lo farragoso: calcular la probabilidad de que A+L active el flag de acarreo, es decir: conocer todos los valores V y W que sumados sean 256 o más. Vayamos paso a paso:

-Si A = 0, la suma será como mucho 255, luego la probabilidad de activación del flag (en adelante PAF) es 0.
-Si A = 1, para L = 255 la suma será 256, luego PAF = 1/65536 (sólo un par de valores activan el flag).
-Si A = 2, para L = 254 ó L = 255 la suma será superior a 255, luego PAF = 2/65536 (así que ya tenemos 3 pares de valores)
...

  Si continuamos para todos los valores de A (0..255) podremos sacar como conclusión que la probabilidad de que un par de valores concretos sumen más que 256 es

Sumatorio en A perteneciente a {0..255}. ( A / 65536 )

que es igual a

( Sumatorio en A perteneciente a {0..255}. ( A )  ) / 65536

  Ahora recordemos las clases de matemáticas cuando nos enseñaban a sumar una serie de números consecutivos (nota histórica: al parecer la idea se le ocurrió a Gauss cuando tenía 5 añitos): el primero más el último multiplicado por el número de términos y dividido por dos. Por lo tanto:

( Sumatorio en A perteneciente a {0..255}. ( A )  ) = ( ( 0 + 255 ) * 256 ) / 2 = 32640

  Así pues la probabilidad de que la suma de dos bytes cualesquiera active el flag de acarreo es

32640/65536 = 0'4980...

  Algo menos de la mitad. Y la probabilidad de que la suma no active el flag de acarreo (con lo que nos saltaríamos la instrucción INC H) es:

32896/65536 = 0'5019...

  Un poquito más de la mitad. Así que es más probable (por poco) que la suma de dos bytes cualesquiera no active el flag de acarreo. Por lo tanto el coste en media de la rutina con el salto es:

21 * ( 32896 / 65536 ) + 26 * ( 32640 / 65536 ) = 23'49 ciclos

un ciclo y medio menor que los 25 ciclos que cuesta siempre la otra rutina.

  Si es una rutina crítica que se vaya a usar a menudo un ciclo y medio siempre es importante ;D ;D

Saludos
--
SapphiRe


Título: Re: leer el joystick
Publicado por: jltursan en 12 de Mayo de 2006, 05:12:23 pm
Citar
Sap: aceptamos barco, pero no sé en qué te basas para decir que es mejor.

Joer Robsy, ¿a quien se le ocurre decirle a un matemático que en que se basa para afirmar algo?. Si es que los hay inconscientes. ;D

Hoy me acostaré pronto, que se me ha levantado un dolor de cabeza... scrms:)

Citar
¿Creeis que puede dar problemas de compatibilidad con alguna máquina? ¿Será fiable?...

Este siempre es un tema peliagudo. Yo no me fiaría, depués de todo sigo sin ver las ventajas de usar un método u otro; pero desde luego, si haces un programilla que permita testearlo yo me ofrezco para probarlo en los modelos que tengo, 1 de cada generación.


Título: Re: leer el joystick
Publicado por: SapphiRe en 12 de Mayo de 2006, 06:25:04 pm
  Aún más...  ;D ;D ;D esto se me ha ocurrido en el coche mientras venía hacia casa, ¡¡para que luego digan que los atascos en la M30 por culpa de las obras son inútiles!!

  Esta rutina está limitada a valores de A entre 0 y 8, por lo que la probabilidad de activar el flag de acarreo es

( Sumatorio en A perteneciente a {0..8} ( A ) ) / 65536 = 36/65536 = 0'0005491...

  Es decir, en este caso concreto la probabilidad de que la tabla se coloque en una posición que haga que la rutina con el salto sea menos eficiente es inferior al 0'1%, por lo que la velocidad en media de la rutina será mucho más cercana a los 21 ciclos del caso mejor que a los 26 del caso peor, ganando aproximadamente 4 ciclos de reloj.

Citar
Sap: aceptamos barco, pero no sé en qué te basas para decir que es mejor.

Joer Robsy, ¿a quien se le ocurre decirle a un matemático que en que se basa para afirmar algo?. Si es que los hay inconscientes. ;D

Eso digo yo ;D ;D ;D ;D ;D Encima a un matemático que se dedica a la enseñanza del análisis de algoritmos... ::) ::)

Citar
Hoy me acostaré pronto, que se me ha levantado un dolor de cabeza... scrms:)

Exagerado... si en el fondo te has leído entera la discusión matemática y estás de acuerdo conmigo ;D ;D ;D


Título: Re: leer el joystick
Publicado por: WYZ en 13 de Mayo de 2006, 02:43:26 pm
Es lo que le suele pasar a los matemáticos... simplifica tio, simplifica!  ;D

Si no quieres usar BIOS (portar.doc)

Código:
R_JOY:  DI
LD A,$0F ;REG.15 PSG SELECCIONA JOYSTICK
OUT [$A0],A
IN A,[$A2] ;LEE DATO
AND 11011111B ;(PARA PUERTO 1) / AND 10101111B ;(PARA PUERTO 2)
OR 01001100B ;(IDEM)/ OR 00000011B (IDEM)
OUT [$A1],A

LD A,$0E  ;LEE REGISTRO 14
OUT [$A0],A
IN A,[$A2]

tendras en el reg. [A] este formato:

Código:
Bit #:  76  5    4   3210
        ||  |    |   ||||
Name:   10 TRG2 TRG1 RLDU

Que incluye los 2 pulsadores.

PS: Sapp, desde la demostración del teorema de Schwartz que no me se daban estos sudores frios.


Título: Re: leer el joystick
Publicado por: pitpan en 13 de Mayo de 2006, 03:44:12 pm
Pues ya veo que mejor me callo...

Siento el comentario, Sap: me has convencido de la bondad de los saltos frente a las sumas de 16 bits, que son las que vengo usando desde hace bastante. Por cierto, que ya tengo un asMSX con PHASE/DEPHASE y alguna que otra sorpresita. Ahora me falta implementar lo que más ilusión me hace:

.MEGAROM konamiSCC

.BANK 1 AT 4000h

...

.SELECT 2 AT 6000h

Me parece que la sintaxis es bastante clara. Es decir, se define que el formato de salida será un megaROM con un determinado mapeador, se define el programa contenido siempre en bancos (de 8 o 16 KB según el mapeador) y se tiene una rutina de selección de banco. Es la solución más sencilla a la que he llegado. Ya que aquí tenemos abundancia de mentes capaces, ¿se os ocurre otra forma mejor de hacerlo? ¿Alguna sintaxis más conveniente?


Título: Re: leer el joystick
Publicado por: WYZ en 13 de Mayo de 2006, 04:06:32 pm
Eduardo! buena noticia que sigas con el AsMSX.




Título: Re: leer el joystick
Publicado por: e_sedes en 13 de Mayo de 2006, 07:35:15 pm
Si no quieres usar BIOS (portar.doc)
Código:
R_JOY:  DI
LD A,$0F ;REG.15 PSG SELECCIONA JOYSTICK
OUT [$A0],A
IN A,[$A2] ;LEE DATO
AND 11011111B ;(PARA PUERTO 1) / AND 10101111B ;(PARA PUERTO 2)
OR 01001100B ;(IDEM)/ OR 00000011B (IDEM)
OUT [$A1],A

LD A,$0E  ;LEE REGISTRO 14
OUT [$A0],A
IN A,[$A2]

Eso es exactamente lo que hace la BIOS (por lo menos la que yo miré).

Citar
¿Creeis que puede dar problemas de compatibilidad con alguna máquina? ¿Será fiable?...

Este siempre es un tema peliagudo. Yo no me fiaría, depués de todo sigo sin ver las ventajas de usar un método u otro; pero desde luego, si haces un programilla que permita testearlo yo me ofrezco para probarlo en los modelos que tengo, 1 de cada generación.

Pues aunque solo sea por curiosidad, ahí va una chapucilla que prueba el joystick en el puerto 1. Si funciona en todas las máquinas se puede decir que GTSTCK a la salida entrega E así:
Código:
Bit #:  76543210
        ||||||||
Name:   0000RLDU
siendo 0-pulsado  1-no pulsado.

(p.d. me he desvirgado,este es el primer programa que hago en ensamblador... :-[ :D)


Título: Re: leer el joystick
Publicado por: SapphiRe en 13 de Mayo de 2006, 07:49:26 pm
Pues ya veo que mejor me callo...

Siento el comentario, Sap: me has convencido de la bondad de los saltos frente a las sumas de 16 bits, que son las que vengo usando desde hace bastante.

No hay nada que sentir, hombre. Yo también usaba las sumas de 16 bits hasta que JLTurSan me mostró esa simple rutinita. Como me picaba la curiosidad me dedqué a contar ciclos y ví que era más rápida en el caso mejor. Lo de hacer el cálculo del caso promedio ha sido bastante divertido, si es que las matemáticas se pueden aplicar a casi todo!!

Citar
Por cierto, que ya tengo un asMSX con PHASE/DEPHASE y alguna que otra sorpresita. Ahora me falta implementar lo que más ilusión me hace:

.MEGAROM konamiSCC

.BANK 1 AT 4000h

...

.SELECT 2 AT 6000h

Me parece que la sintaxis es bastante clara. Es decir, se define que el formato de salida será un megaROM con un determinado mapeador, se define el programa contenido siempre en bancos (de 8 o 16 KB según el mapeador) y se tiene una rutina de selección de banco. Es la solución más sencilla a la que he llegado. Ya que aquí tenemos abundancia de mentes capaces, ¿se os ocurre otra forma mejor de hacerlo? ¿Alguna sintaxis más conveniente?

Lo del SELECT lo encuentro un poco confuso, ¿qué quiere significar exactamente? ¿Que se selecciona el banco en esa posición (es decir, es una macro que hace el poke adecuado en la dirección adecuada) ? ¿Significa que a partir de ese momento se empezará a ensamblar en la posición 6000h ?

Además, sugiero que además de 4000h 6000h 8000h y a000h se pueda operar con PAGE0 PAGE1 PAGE2 y PAGE3, que no serían sino valores constantes. ¿Qué opinas?

En cuanto al nuevo asMSX es una noticia estupenda. ¿Será compatible con el anterior? :P :P


Título: Re: leer el joystick
Publicado por: msxnake en 13 de Mayo de 2006, 08:38:50 pm
 Joder Saphire ahora que viene la Declaración de la Renta que no se metan contigo, si los de Hacienda te estafan aunque sólo sea un céntimo de Euro... les vas a hacer papilla.
 Invertiste algo en sellos??


Título: Re: leer el joystick
Publicado por: jltursan en 15 de Mayo de 2006, 01:25:31 pm
Citar
Pues aunque solo sea por curiosidad, ahí va una chapucilla que prueba el joystick en el puerto 1. Si funciona en todas las máquinas se puede decir que GTSTCK a la salida entrega E así:

De momento en el Sony HB-75P funciona. El botón de disparo no lo has implementado supongo.
Luego continuo con las pruebas... :)


Título: Re: leer el joystick
Publicado por: e_sedes en 15 de Mayo de 2006, 01:50:27 pm
Citar
Pues aunque solo sea por curiosidad, ahí va una chapucilla que prueba el joystick en el puerto 1. Si funciona en todas las máquinas se puede decir que GTSTCK a la salida entrega E así:

De momento en el Sony HB-75P funciona. El botón de disparo no lo has implementado supongo.
Luego continuo con las pruebas... :)
Solo las direcciones. En el Philips VG-8020 también va. En la primera generación no creo que haya problema, me preocupa un poco más el resto, aunque pienso que tiene que funcionar. :)

un saludo.


Título: Re: leer el joystick
Publicado por: jltursan en 15 de Mayo de 2006, 04:25:57 pm
En el TR FS-A1ST también va. :)