motor AGD para V9958 modo gráfico G4 para HD6309

jltursan
Mensajes: 5619
Registrado: 20 Sep 2011 13:59
Ubicación: Madrid
Agradecido : 990 veces
Agradecimiento recibido: 2040 veces
Contactar:

Re: motor AGD para V9958 modo gráfico G4 para HD6309

Mensajepor jltursan » 09 Abr 2021 19:05

Último mensaje de la página anterior:

La verdad es que el hecho de que esté ligado a una NMI es una faena. ¿Es un imponderable cuando se trata de periféricos en el Dragon, están siempre ligados a la NMI o es una decisión de diseño de la tarjeta V9958?

Avatar de Usuario
pser1
Mensajes: 4094
Registrado: 08 Dic 2012 18:34
Agradecido : 1352 veces
Agradecimiento recibido: 1118 veces

Re: motor AGD para V9958 modo gráfico G4 para HD6309

Mensajepor pser1 » 09 Abr 2021 20:28

jltursan escribió:La verdad es que el hecho de que esté ligado a una NMI es una faena. ¿Es un imponderable cuando se trata de periféricos en el Dragon, están siempre ligados a la NMI o es una decisión de diseño de la tarjeta V9958?

Yo diría que los periféricos de Dragon suelen estar ligados a un IRQ. De hecho las PIAs que es donde puedes conectar hardware externo
pueden generar una interrupción que es reconocida como un IRQ (cualquiera de ellas), sabes cual ha sido leyendo los registros de las PIAs
La excepción es la unidad de disco. Dragon Data decidió que la lectura de disco (byte a byte de un sector) se sincronizara con un FIRQ que
guarda pocos registros en el stack a diferencia del IRQ (que es usado por el CoCo), cuando se llega al final de un sector se genera un NMI
que se usa para salir del bucle de lectura/grabación
El diseñador de la placa original WORDPAK2 (Luis Felipe Antoniosi) conectó la interrupción del V9958 a la patilla NMI de CoCo-Dragón y así sigue
siendo en la nueva versión de John Whitworth ...
La única pega es que al ser NMI no hay forma de bloquearlo mas que solicitando esta acción al V9958
Y la rutina de servicio de la interrupción debe si o si leer S#0 para borrar el flag de interrupción y así permitir la llegada de la siguiente ...

Ya revisaré este tema, ha sucedido una vez de 50 y no estaba jugando, sino saltando pantallas demasiado rápido seguramente.
La rutina GetSlot ya está implementada, ahora me faltan algunos retoques para ajustar todas las rutinas. Hay código repetido en
algunas partes antiguas que ahora se podría unificar con FreeSlot y GarbCol
saludos
pere

jltursan
Mensajes: 5619
Registrado: 20 Sep 2011 13:59
Ubicación: Madrid
Agradecido : 990 veces
Agradecimiento recibido: 2040 veces
Contactar:

Re: motor AGD para V9958 modo gráfico G4 para HD6309

Mensajepor jltursan » 10 Abr 2021 09:55

Caramba, que pena, es una herencia en el diseño. No sé, una IRQ estándar quizá habría sido mucho más práctica :-(

La única solución que se me ocurre para "organizar" un poco el funcionamiento es tratar de identificar todas las operaciones que necesiten asegurarse que no salte una interrupción y procurar por todos los medios que se ejecuten inmediatamente después a la interrupción; tienes un frame completo hasta que llegue la siguiente. Eso juraría que ya me lo has comentado; pero habría que asegurarse. ¿Has probado el truco de cambiar el color del borde al empezar las grandes rutinas?, eso te da una idea estupenda de por donde anda el programa y cuento cuesta cada cosa.

Y respecto a la rutina de la interrupción, si no consumes la interrupción no llega la siguiente; pero al salir de la rutina acabarías consumiéndola en algún momento, el problema es que ya se haría sin control y salvo que tuviese la ejecución perfectamente medida, ya no tendría la certeza de que se produce a intervalos regulares.

Avatar de Usuario
pser1
Mensajes: 4094
Registrado: 08 Dic 2012 18:34
Agradecido : 1352 veces
Agradecimiento recibido: 1118 veces

Re: motor AGD para V9958 modo gráfico G4 para HD6309

Mensajepor pser1 » 10 Abr 2021 22:44

@jltursan,
he estado pensando en este tema de las interrupciones.
Si realmente el problema que he detectado solo pude ser debido a que en alguna ocasión, una interrupción se genera antes de finalizar
la operación de deshabilitación de interrupciones por el método de solicitárselo al V9958, entonces cabe una posibilidad de 'emular' las
instrucciones di, ei del Z80 ...
La posible solución pasaría por hacer que la rutina de servicio al NMI disponga de un conmutador que le permita leer el status o bien
saltarse esta operación. Como la solicitud de interrupción son instrucciones normales del 6809 que no pueden ser 'rotos' por una
interrupción, el proceso seguirá tras atender la interrupción recibida y deshabilitará las interrupciones a partir de este momento.
Si llegara alguna interrupción entre DisVdpInt y EnaVdpInt (deshabiltar y habilitar), la rutina de servicio saltará la lectura de S#0 pero
nos dejará una variable a 1 para indicar que ha habido una interrupción que no ha podido ser 'limpiada'.
Entonces, la rutina que habilita interrupciones puede consultar esta variable y, en su caso, lee ella misma el S#0 ...
Reconozco que la explicación puede resultar enrevesada así que adjunto el código en dos partes: Di,EI y NewNMI
A ver que te parece la idea ... Cualquier observación al respecto será bien recibida -drinks
saludos
pere

Código: Seleccionar todo

flgSRead      equ   $42                  ; flag to know if Int Status (S#0) has been read
                                       ; will be reset to zero at the beginning
; - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
DisVdpInt   pshs   a                     ; save register A
            lda   #$20                  ; get a 'BRA' opcode
            sta   >NMISwitch            ; modify switch in NewNMI to SKIP S#0 process (disable INT)
            puls   a,pc                  ; restore register and return
; - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
EnaVdpInt   pshs   a                     ; save registers A
            tst   <flgSRead            ; is there an INT not yet aknowledged?
            beq   EnaVdpL01            ; no, skip section
            ldd   #$008f               ; ask for S#0 to R#15
            sta   PCONF                  ; send status register number
            nop                        ; waste some cycles
            stb   PCONF                  ; send register number to port #1
            nop                        ; waste some cycles
            lda   PCONF                  ; read port #1 to clean interrupt flag
            clr   <flgSRead            ; reset flag to Status ALREADY read
EnaVdpL01   lda   #$21                   ; get a 'BRN' opcode
            sta   >NMISwitch            ; modify switch in NewNMI to ALLOW S#0 process (enable INT)
            puls   a,pc                  ; restore register and return

Código: Seleccionar todo

NewNMI      lda   #1                     ; set flag
            sta   <flgSRead            ; to Status NOT YET read
NMISwitch   brn   NMINoVdp               ; self modifiable code to skip (or not) VDP S#0 process
            ldx   #PDATA               ; point to VDP port #0
            ldd   #$008f               ; ask for S#0 to R#15
            sta   1,x                  ; send status register number
            nop                        ; waste some cycles
            stb   1,x                  ; send register number to port #1
            nop                        ; waste some cycles
            lda   1,x                  ; read port #1 to clean flag
            clr   <flgSRead            ; reset flag to Status ALREADY read
NMINoVdp      inc   >TIMER               ; increment timer high byte
      IF (YFLAG || EFLAG)            ; if Music or Effects are enabled
            lbsr   PsgrOut               ; send the registers to the YM-2149
         IF YFLAG                     ; if Music enabled
            lbsr   Music_Play            ; play a music frame
         ENDIF
         IF EFLAG                     ; if effects enabled
            lbsr   Sfx_Play               ; play a sound frame
         ENDIF
      ENDIF
NewNMIEx      rti                        ; return from interrupt

Avatar de Usuario
pser1
Mensajes: 4094
Registrado: 08 Dic 2012 18:34
Agradecido : 1352 veces
Agradecimiento recibido: 1118 veces

Re: motor AGD para V9958 modo gráfico G4 para HD6309

Mensajepor pser1 » 10 Abr 2021 22:57

@jltursan,
si este truco o una variante del mismo te parece correcto, entonces pasaría a hacer una relación de los puntos en los que mi motor
llama a la rutina de deshabilitación de interrupciones para decidir cuales son imprescindibles y cuales son innecesarias ...
Lo ideal sería poder simplificar de forma que DisVdpInt no requiera el pshs a y puls a de entrada y salida, con lo cual se aceleraría
un montón su velocidad de ejecución ...
saludos
pere

Avatar de Usuario
pser1
Mensajes: 4094
Registrado: 08 Dic 2012 18:34
Agradecido : 1352 veces
Agradecimiento recibido: 1118 veces

Re: motor AGD para V9958 modo gráfico G4 para HD6309

Mensajepor pser1 » 10 Abr 2021 23:46

esta es la lista de llamadas a la subrutina para deshabilitar interrupciones
saludos
pere

Llamadas a DisVdpInt (deshabilitar Interrupciones)
--------------------------------------------------
RstRt:RstRt0 antes de lbsr DRoom/IniShr/RBloc
RstRt:RpBlc0 antes de lbsr LoadObj/LoadSprt
DBpx2:Mod0 antes de lbsr DisVdpSpr ( deshabilitar sprites ¿Lo requiere? )
DBox0 antes de lbsr PChr0 -> DoHMMC
DBoxf antes de lbsr PChr0 -> DoHMMC

DoLmmm antes de lbsr WaitVDP ( ¿Lo requiere? )
SpriteInk antes de lbsr SetVdpWrit y enviar datos al puerto #1
Sprite16C antes de lbsr SetVdpWrit y enviar datos al puerto #1
DisSprite antes de lbsr SetVdpWrit y enviar datos al puerto #1
DSpr antes de UpdImage/SprSame

Cls antes de DisVdpSpr y DoHMMV ( ¿Lo requieren? )
SetBorder antes de enviar datos al puerto #1
ReDraw antes de UpdVdpLay (enviar tiles a pantalla -> DoHMMM)
ReDrawM (redibujar ventana menu/inve) antes de DoHMMM
ClW antes de DisVdpSpr y DoHMMV ( ¿Lo requieren? )

DMsg3 antes de BChar/PChar -> DoHMMC
AChar antes de BChar/PChar -> DoHMMC
ScrlyP03 antes de DoHMMM
DelObjNC antes de DoHMMM
DropOb antes de ShwObj -> DoHMMM

DoBlink antes de DoLmmm

jltursan
Mensajes: 5619
Registrado: 20 Sep 2011 13:59
Ubicación: Madrid
Agradecido : 990 veces
Agradecimiento recibido: 2040 veces
Contactar:

Re: motor AGD para V9958 modo gráfico G4 para HD6309

Mensajepor jltursan » 12 Abr 2021 19:55

Pues veamos, se deshabilitan interrupciones:

- Siempre que se escribe un registro (la secuencia "enviar dato" - "enviar registro + 128"). Nota: por eso se muerde la cola el mecanismo que empleabas, porque precisamente para escribir en un registro ya deben estar deshabilitadas las interrupciones
- Siempre que se programe una dirección de escritura o lectura (los SetVdpWrit y SetVdpRead que tienes)
- Al inicializar el registro R#17 (el de indirección) en un comando del VDP. El resto de escrituras a la secuencia de registros parece que está protegida ya que el puntero parece no verse afectado. En los plot0 y plot1 que te pasé, como no empleo R#17 tengo que tener deshabilitadas las interrupciones hasta escribir el último valor a registro.

Y ya está...:-)

Avatar de Usuario
pser1
Mensajes: 4094
Registrado: 08 Dic 2012 18:34
Agradecido : 1352 veces
Agradecimiento recibido: 1118 veces

Re: motor AGD para V9958 modo gráfico G4 para HD6309

Mensajepor pser1 » 12 Abr 2021 20:32

jltursan escribió:Pues veamos, se deshabilitan interrupciones:
- Siempre que se escribe un registro (la secuencia "enviar dato" - "enviar registro + 128"). Nota: por eso se muerde la cola el mecanismo que empleabas, porque precisamente para escribir en un registro ya deben estar deshabilitadas las interrupciones
- Siempre que se programe una dirección de escritura o lectura (los SetVdpWrit y SetVdpRead que tienes)
- Al inicializar el registro R#17 (el de indirección) en un comando del VDP. El resto de escrituras a la secuencia de registros parece que está protegida ya que el puntero parece no verse afectado. En los plot0 y plot1 que te pasé, como no empleo R#17 tengo que tener deshabilitadas las interrupciones hasta escribir el último valor a registro.
Y ya está...:-)
De acuerdo, muchas gracias -drinks
A ver si puedo dedicarme a esto un rato después ...
Voy a marcar en la lista de rutinas que he indicado antes, aquellas que 'requieren' que se deshabiliten las interrupciones.
Si tenemos en cuenta el procedimiento que quiero aplicar para *NO* deshabilitar las interrupciones del V9958 *nunca* ya que
pretendo dejar que siempre se produzcan, pero la lectura del S#0 para permitir la siguiente, se hará dentro de la rutina de servicio
de la interrupción si ha sido habilitadas, en caso contrario será la rutina que vuelve a habilitarlas quien limpiará el flag
Me da la impresión de que haciéndolo así no debería preocuparme por posibles colisiones ya que no existe ningún proceso tan largo
como para que lleguen dos interrupciones seguidas. Iría todo lentísimo si esto pasara
Obviamente las rutinas para deshabilitar y habilitar interrupciones seguirán siendo llamadas en los puntos que tu me has comentado
A ver que sale de todo esto, parece que al final se podrán 'gestionar' bien las NMI -thumbup
saludos
pere

Avatar de Usuario
pser1
Mensajes: 4094
Registrado: 08 Dic 2012 18:34
Agradecido : 1352 veces
Agradecimiento recibido: 1118 veces

Re: motor AGD para V9958 modo gráfico G4 para HD6309

Mensajepor pser1 » 12 Abr 2021 21:40

jltursan escribió:Pues veamos, se deshabilitan interrupciones:
- Siempre que se escribe un registro (la secuencia "enviar dato" - "enviar registro + 128"). Nota: por eso se muerde la cola el mecanismo que empleabas, porque precisamente para escribir en un registro ya deben estar deshabilitadas las interrupciones
En todas partes donde se envían datos y luego el número de registro se llama previamente a DisVdpInt, por lo que no es posible que
sean interrumpidas. La otra posibilidad que tu apuntaste era el hecho de que para deshabiltar las interrupciones estoy enviando
un valor al registro R#1 y esta secuencia de envío de valor-registro *SI* puede ser interrumpida por una interrupción cuando todavía no
se ha ejecutado la segunda parte que envia el num de registro
- Siempre que se programe una dirección de escritura o lectura (los SetVdpWrit y SetVdpRead que tienes)
esto también se hace sistemáticamente
- Al inicializar el registro R#17 (el de indirección) en un comando del VDP. El resto de escrituras a la secuencia de registros parece que está protegida ya que el puntero parece no verse afectado. En los plot0 y plot1 que te pasé, como no empleo R#17 tengo que tener deshabilitadas las interrupciones hasta escribir el último valor a registro.
Aquí estoy de acuerdo con hacerlo antes de enviar al R#17 el primer registro de parámetros, como luego los bytes se envían en secuencia pero al port #3, esto garantizaría que no pueden ser interrumpidos, pero el comando HMMMC que va enviando bytes de RAM a la VRAM lo hace via port#1 y me temo que esta parte si podría ser interrumpida ...
saludos
pere

Avatar de Usuario
pser1
Mensajes: 4094
Registrado: 08 Dic 2012 18:34
Agradecido : 1352 veces
Agradecimiento recibido: 1118 veces

Re: motor AGD para V9958 modo gráfico G4 para HD6309

Mensajepor pser1 » 12 Abr 2021 22:01

acabo de revisar la lista de puntos en los que se llama a la rutina para deshabilitar las interrupciones, y en todos ellos existe código
que envia un valor a un registro por lo menos una vez así que *todos* van a permanecer.
De momento no voy a unificar cosas que se hacen en mas de un sitio, me limitaré a modificar las rutinas DisVpdInt y EnaVdpInt para que
la primera *NO* envíe datos al V9958 y se limite a modificar la rutina NewNMI para que las interrupciones se salten el código que lee
el S#0 pero indicará que ha habido una interrupción en una variable (flag) siendo la rutina que habilita las interrupciones la encargada
de leer S#0 si hay alguna interrupción pendiente.
Creo que esto debería bastar para erradicar definitivamente este tipo de problemas, o eso espero -thumbup
saludos
pere

Avatar de Usuario
invacuo
Mensajes: 401
Registrado: 13 Oct 2020 19:47
Agradecido : 149 veces
Agradecimiento recibido: 145 veces

Re: motor AGD para V9958 modo gráfico G4 para HD6309

Mensajepor invacuo » 12 Abr 2021 22:46

Se me escapa un poco de mis conocimientos, pero te estás dando un curro de mucho cuidado.

Avatar de Usuario
pser1
Mensajes: 4094
Registrado: 08 Dic 2012 18:34
Agradecido : 1352 veces
Agradecimiento recibido: 1118 veces

Re: motor AGD para V9958 modo gráfico G4 para HD6309

Mensajepor pser1 » 12 Abr 2021 23:37

invacuo escribió:Se me escapa un poco de mis conocimientos, pero te estás dando un curro de mucho cuidado.
jeje, me va la marcha, está claro -507
Ya he implementado el cambio de método para las rutinas que habilitan y deshabilitan las interrupciones, además de modificar la
rutina de servicio al NMI. Al segundo intento ha funcionado perfectamente -drinks
El primer intento ha sido para reirse, no ha pintado nada, solo LEVEL 1 y se ha bloqueado -banghead
El motivo era bastante evidente, como la rutina EnaVdpInt ya *NO* habilita las interrupciones sinó que permite que NewNMI lea el s#0,
y en la configuración del modo G4 estoy bloqueando las interrupciones ... no iba nada en absoluto. He tenido que activarlas una sola vez
y he elegido la parte del motor donde está la etiqueta Game.
Será cuestión de probarlo unos centenares de veces mas -507
Por cierto, he encontrado un error en el juego. Sucede en el nivel 11. Si subes los dos personajes por la izquierda de la pantalla
usando el sistema de ponerlos uno encima del otro y haciendo saltar hacia arriba al de debajo, cuando llegas arriba del todo,
ya no haría falta seguir, pero si te despistas y vuelves a darle hacia arriba al de debajo, el de encima queda*clavado* en el techo
y ya no hay forma de bajarlo y por tanto de terminar el nivel -banghead
Lo he probado en la versión de B/N para CoCo-Dragón y sucede exactamente lo mismo.
Tendré que mirar como diablos se mueve hacia arriba el jugador que está encima ya que el que 'salta' llamando a la rutina Jump
debería ser solamente el de debajo. No creo que sea problema del motor, pero nunca se sabe. En el peor de los casos se puede solucionar
en el script AGD, o eso pienso ahora
saludos
pere

Avatar de Usuario
pser1
Mensajes: 4094
Registrado: 08 Dic 2012 18:34
Agradecido : 1352 veces
Agradecimiento recibido: 1118 veces

Re: motor AGD para V9958 modo gráfico G4 para HD6309

Mensajepor pser1 » 12 Abr 2021 23:43

no he encontrado nada en el motor.
La rutina Hop para saltar, llamada por TABLEJUMP y la TFall para 'caer', llamada por TABLEFALL parecen correctas así que he editado el AGD
y he añadido un control a ambos jugadores para que en la pantalla 10 (nivel 11) su posición Y no pueda ser menor de 16 ya que el techo tiene
dos líneas de ladrillos, de 8 pixels cada una, de esta forma evitamos que hinquen la cabeza en el techo -507
Así me funciona y no se clava ya ninguno de los dos en el techo por lo que se puede finalizar el nivel perfectamente ...
saludos
pere

jltursan
Mensajes: 5619
Registrado: 20 Sep 2011 13:59
Ubicación: Madrid
Agradecido : 990 veces
Agradecimiento recibido: 2040 veces
Contactar:

Re: motor AGD para V9958 modo gráfico G4 para HD6309

Mensajepor jltursan » 13 Abr 2021 09:11

Son pequeños fallos en la lógica del juego, nada importante :-)

Avatar de Usuario
pser1
Mensajes: 4094
Registrado: 08 Dic 2012 18:34
Agradecido : 1352 veces
Agradecimiento recibido: 1118 veces

Re: motor AGD para V9958 modo gráfico G4 para HD6309

Mensajepor pser1 » 13 Abr 2021 10:53

jltursan escribió:Son pequeños fallos en la lógica del juego, nada importante :-)

Exacto, un simple control de la posición 'Y' para ambos jugadores y ya no se produce el problema ...
Estoy añadiendo código al fichero AGD para que se muestre el número de vidas y una puntuación que me he sacado de la manga -507
Es curioso que estando LIVES declarado e inicializado a 9, luego no fuera utilizado, como si no estuviera acabado el juego!
saludos
pere

Avatar de Usuario
pser1
Mensajes: 4094
Registrado: 08 Dic 2012 18:34
Agradecido : 1352 veces
Agradecimiento recibido: 1118 veces

Re: motor AGD para V9958 modo gráfico G4 para HD6309

Mensajepor pser1 » 14 Abr 2021 16:07

buenas tardes,
ahora que ya tenía el BeanBrothers perfecto con sus sprites monocolor y los jugadores a cuatro colores, he aprovechado para añadir
la rutina GetSlot que reaprovecha slots dejados por sprites o imágenes que no se usan mas ... perfecto, sin problemas -drinks
Entonces he compilado con la ultimísma versión del motor a FOG95, LADDER, TSPEED y cuando los he probado, me he acongojado ...
Casi todos los sprites desaparecidos, sobre todo en el TestSpeed.
Para variar he empezado a dudar de las rutinas recién incorporadas y he ido compilando con versiones anteriores y siempre lo mismo.
De repente se me ha ocurrido que podría estar relacionado con los cambios en las rutinas SpriteInk y Sprite16C
Revisando el compilador C que genera el fichero en ASM, he visto que la rutina SpriteInk, recibe un parámetro que puede ser numérico
o una variable. Si es numérico, procedente de conversiones de Spectrum, lo convierto a color MSX2 y llamo a la rutina SpriteInk
pero si es una variable, al no poder convertir su valor me limito a llamar a SpriteInk.
Para poder vivir con estos dos tipos de parámetros, he creado dos entradas en SpriteInk, llamadas SpritInkS (spectrum) y SpritInkM (msx2)
Así el compilador llama la correcta según el tipo de parámetro recibido pasándolo además a través del pseudo-registro reg_B
De esta forma el script AGD no está obligado a usar una variable concreta para pasar el código de color
Recompilados los cuatro programas, ya funcionan todos correctamente -thumbup

Respecto al GetSlot y sus allegados FreeSlot / GarbCol he podido comprobar que incluso en BeanBrothers se dan casuísticas del tipo
dejar un slot con 3 frames que como tiene otro libre de 3 frames a continuación, se convierte en uno de 6 libres gracias a GarbCol
Cuando luego se llama a GetSlot, este puede reusar este slot mas grande para ubicar los frames de la nueva imagen ...
Además, las tablas de Atributos y Colores para sprites solamente utilizan 16 entradas, las mismas que tiene la tabla sprtab
Así que puedo decir que, de momento, parece que recupera bien las entradas no usadas y sin problemas visibles. Espero que dure -507
saludos
pere
Pd. Un dia mas de pruebas y a por las partículas!

Avatar de Usuario
pser1
Mensajes: 4094
Registrado: 08 Dic 2012 18:34
Agradecido : 1352 veces
Agradecimiento recibido: 1118 veces

Re: motor AGD para V9958 modo gráfico G4 para HD6309

Mensajepor pser1 » 14 Abr 2021 19:05

solo una observación referente a los cambios que introduje en control de las interrupciones.
La música y los efectos del DiamondGeezer (alias LADDER) funcionan perfectamente, luego el sistema es correcto -thumbup
Hasta ahora, sin problemas. Tengo los cuatro juegos en formato VDK montados en cuatro unidades del sistema Drivewire
lo cual me permite probar cualquiera de ellos de forma muy rápida.
Con el programa de pruebas TESTSPEED he podido verificar que tanto crear sprites como eliminarlos funciona correctamente
usando las funciones Spawn y DisSprite que llaman a las nuevas rutinas FreeSlot, GarbCol y GetSlot
saludos
pere


Volver a “Software MSX”

¿Quién está conectado?

Usuarios navegando por este Foro: No hay usuarios registrados visitando el Foro y 2 invitados