Karoshi MSX Community
05 de Julio de 2021, 03:36:18 pm *
Bienvenido(a), Visitante. Por favor, ingresa o regístrate.

Ingresar con nombre de usuario, contraseña y duración de la sesión
Noticias:
 
   Inicio   Ayuda Buscar Ingresar Registrarse  
Páginas: 1 [2] 3
  Imprimir  
Autor Tema: Rincón del novato en ASM  (Leído 17017 veces)
0 Usuarios y 1 Visitante están viendo este tema.
theNestruo
Karoshi Lover
***
Mensajes: 236


Email
« Respuesta #15 : 25 de Mayo de 2012, 05:12:09 pm »

Al final no he podido resistirme y he abandonado el LDIRVM... pero es que la diferencia de tiempos es salvaje, en especial a 60Hz que se come prácticamente todo el frame él solito Sad

He aislado la parte del scroll infinito para compartirla con vosotros (aunque, sinceramente, no sé si estoy reinventando la rueda :-P).

Podeis hacer scroll hacia los lados, hacia arriba y en diagonal (hacia abajo no porque el juego que estoy haciendo no lo neceista y simplemente lo quité). Con espacio pulsado hace el volcado con OTIR (implementación basada en C-BIOS) y sin él utiliza LDIRVM. El borde azul es transferencia RAM->VRAM, el borde rojo el pintado de la parte nueva de la pantalla (en el ejemplo, caracteres aleatorios) y el borde verde es libre.
Como vereis, LDIRVM a 60Hz prácticamente se come todo el frame Sad En el código del juego, que se mira qué caracteres tiene que poner en función de un mapa de tiles, el scroll diagonal se pasaba de tiempo y por eso acabé con el OTIR.
Por contra, ¡OTIR a 50Hz no se sale del VBlank! ¡Es genial! Lo malo es que a 60Hz sí. Tengo que desenrollar ese bucle, pero como el número de bytes a transferir no es fijo aún no he aprendido a hacerlo (creo que tengo que hacer un código automodificable con un JR). También estoy usando números de puertos VDP "fijos" y eso tampoco me gusta.

Otra opción que probé en su momento fue mover el buffer con LDIR/LDDR y volcar con OUTIs. Era algo más rápido que la solución LDIRVM y facilitaba mucho el saber dónde pintar del buffer, que con el offset es un poco coñazo Smiley

En fin... probadlo si os interesa. Y cualquier sugerencia es bienvenida :-D
En línea

theNestruo."Old BASIC programmers never die; they GOSUB but never RETURN."
cybernoid
Karoshi Maniac
****
Mensajes: 368



WWW
« Respuesta #16 : 27 de Mayo de 2012, 07:04:39 pm »

Hola,

Creo que es incompatible con MSX2, lo he estado probando con blueMSX y con openMSX con configuración de MSX2 y no funciona.
En línea
Mortimer
Karoshi Lover
***
Mensajes: 216


WWW
« Respuesta #17 : 27 de Mayo de 2012, 09:25:19 pm »

Pues es cierto que se cuelga en MSX2... (En MSX1 sí funciona, en emulador y en máquina real).  Algo le pasa que llega a HALT con la CPU con las interrupciones deshabilitadas, y echando un vistazo al código sólo veo un EI pero dentro de una rutina...
En línea
theNestruo
Karoshi Lover
***
Mensajes: 236


Email
« Respuesta #18 : 27 de Mayo de 2012, 09:25:41 pm »

@cybernoid:
Pues tienes toda la razón; en MSX-2 no tira. He tenido que meter la pata al quitar el resto de código del juego, porque éste sí que funciona. :S

@Mortimer:
No me ha dado tiempo a mirar nada (de hecho, estaba contestando cuando has escrto tú) pero precisamente la parte que tiene el DI/EI sustituye a un call SETWRT... que estaba pensando en recuperar para despreocuparme de los números de puerto.

Muchas gracias por el aviso; ya os contaré si consigo arreglarlo!
« Última modificación: 27 de Mayo de 2012, 09:32:55 pm por theNestruo » En línea

theNestruo."Old BASIC programmers never die; they GOSUB but never RETURN."
e_sedes
Karoshi Maniac
****
Mensajes: 442



Email
« Respuesta #19 : 29 de Mayo de 2012, 07:54:39 pm »

Métele un EI antes del MAIN_LOOP. En la primera generación cuando llamas a INIT32 activa las interrupciones y por eso funciona, pero de la segunda pa'rriba me temo que no. Creo que ahí está el fallo.

Un saludo.
En línea

sempre fun un valente corredor
theNestruo
Karoshi Lover
***
Mensajes: 236


Email
« Respuesta #20 : 29 de Mayo de 2012, 08:24:04 pm »

Hola.

Estaba arreglandolo y cuando me he conectado para subir la nueva versión he visto tu respuesta, e_sedes. He visto que era antes de empezar el MAIN_LOOP, he puesto un call DISSCR y call ENASCR (un poco a ciegas, sin saber muy bien qué tenía que ver), y ha empezado a funcionar. Supongo que uno de los dos hace un EI dentro...
Ahora al menos ya sé el motivo de que no tirara; ¡muchas gracias!

Adjunto la nueva versión; está basada en FLDIRVM de SapphiRe del hilo de la rutina de transferencia "refinitiva", aunque no he sabido aplicar todo lo que tiene aquella (aprovechar el DEC B que hace internamente OUTI). Creo que si lo consiguiera y quitara los NOP entraría todo en el VBlank a 60Hz...
Pero bueno; de momento está arreglado lo de MSX2 y superior y aún con NOPs va bastante rápido Smiley

Por cierto, Mortimer, el MSX1 real en el que has probado es a 50Hz, ¿verdad?
En línea

theNestruo."Old BASIC programmers never die; they GOSUB but never RETURN."
Mortimer
Karoshi Lover
***
Mensajes: 216


WWW
« Respuesta #21 : 29 de Mayo de 2012, 09:55:45 pm »

Sí, lo probé con un Toshiba HX-20 a 50Hz...

Como comentas, sin los nops debería de entrar: un retrazo a 60Hz son 16060 ciclos, y cada OUTI son 17 ciclos, así que para volcar la tabla de nombres completa: 16060-(17*768)=3004 ciclos sobrantes. Si descuentas lo que consume el bios verás que muy justo, pero entra, pero apenas puedes hacer otra cosa que volcar a saco.



En línea
samsaga2
Karoshi Fan
**
Mensajes: 76


Email
« Respuesta #22 : 06 de Junio de 2012, 04:45:59 pm »

Ahora que comentais sobre 50Hz y 60Hz...

¿Si fuerzo a 50hz cambiando la vdp puedo tener algún problema? ¿Que no se vea en algún monitor o algo?
En línea
Mortimer
Karoshi Lover
***
Mensajes: 216


WWW
« Respuesta #23 : 06 de Junio de 2012, 10:39:02 pm »

Sí, dependiendo del monitor y del cable con el que esté conectado puede que la imagen empiece a saltar (En algunos monitores se dejan ajustar manualmente con un mando por detrás) o se vaya el color. Además, sólo puedes cambiar la frecuencia en MSX2 o superiores
En línea
theNestruo
Karoshi Lover
***
Mensajes: 236


Email
« Respuesta #24 : 28 de Junio de 2012, 08:55:20 pm »

Hola de nuevo!

¿Me podeis echar un cable con la instrucción DAA? O no sé usarla o no hace lo que yo creo que hace. He mirado los fuentes de Jumping y del Minesweeper (RKOS), pero no me aclaro.

El caso es que yo tengo una variable que, por ejemplo, vale 17 ($11) y quiero mostrar en pantalla eso, el 1 y el 7. Si DAA hace lo que yo creo...
  • $11 -> DAA -> $17 -> AND $0F -> ya tendría el 7
  • $11 -> DAA -> $17 -> AND $F0 -> RR RR RR RR -> ya tendría el 1
...pero si estais leyendo este post es, clarostá, porque no funciona así Sad

¡Muchas gracias de antemano!
En línea

theNestruo."Old BASIC programmers never die; they GOSUB but never RETURN."
pitpan
Karoshi Forum's Guru
*******
Mensajes: 1812


« Respuesta #25 : 28 de Junio de 2012, 09:19:33 pm »

Pues no, no hace lo que crees... Grin

Con DAA consigues lo siguiente:

Tienes un número en formato BCD: 48h -> 48 en BCD
Y tienes otro número en formato BCD: 12h -> 12 en BCD
Los sumas con un ADD, y consigues, como es lógico, 5Ah, que no es un número BCD.

Ejecutas entonces DAA, y te da el resultado correcto, 60h, que en BCD es 60. Tachán!

Pero si quieres convertir base 2 a BCD, tendrás que programarlo tú.

Truco para hacerte la vida más fácil: DAA funciona correctamente con ADD, ADC y SBC, pero, contra toda lógica, no funciona bien con INC/DEC.
En línea
theNestruo
Karoshi Lover
***
Mensajes: 236


Email
« Respuesta #26 : 29 de Junio de 2012, 08:15:55 am »

Ya le podía dar yo vueltas al código...
Muchas gracias, pitpan; ya lo tengo funcionando ^_^
En línea

theNestruo."Old BASIC programmers never die; they GOSUB but never RETURN."
pitpan
Karoshi Forum's Guru
*******
Mensajes: 1812


« Respuesta #27 : 29 de Junio de 2012, 08:46:03 am »

Hice en su día un documento bastante completo sobre BCD, pero no he sido capaz de encontrarlo... Tenía todas las rutinas básicas para funcionar cómodamente con BCD, incluso para números de bastantes bytes. Si alguien lo tiene por ahí, que se anime a subirlo, por favor.

Me alegra saber que con la explicación rápida te has podido buscar la vida... En su día, cometí el mismo error al pensar que DAA podía con todo. Me estrellé contra la rutina mientras programaba mi emulador de menos de 2 KB del Space Invaders para 80286  Tongue
En línea
theNestruo
Karoshi Lover
***
Mensajes: 236


Email
« Respuesta #28 : 29 de Junio de 2012, 10:53:03 am »

Google + Wayback Machine FTW
En línea

theNestruo."Old BASIC programmers never die; they GOSUB but never RETURN."
theNestruo
Karoshi Lover
***
Mensajes: 236


Email
« Respuesta #29 : 06 de Octubre de 2012, 12:27:47 pm »

¡Buenas una vez más!

A ver si sabeis aclararme una cosa. Para uno de los estados del jugador (llamémoslo "pitufando" xDDD) tengo mucho código compartido entre las dos direcciones de la siguiente forma:
Código:
PITUFANDO_DCHA equ 9
PITUFANDO_IZQ equ 8


ACTUALIZA_PITUFAR:
; Aquí se llega con player_status = PITUFANDO_DCHA o PITUFANDO_IZQ
; ...montón de código común...
ld a, [player_status]
cp PITUFANDO_DCHA
jr z, @@ACTUALIZA_PITUFAR_DERECHA
; Izquierda
call CODIGO_ESPECIFICO_IZQUIERDA
jr @@CONTINUAR
@@ACTUALIZA_PITUFAR_DERECHA:
; Derecha
call CODIGO_ESPECIFICO_DERECHA
; jr @@CONTINUAR ; falls through
@@CONTINUAR:
; ...otro montón de código común...
ret

Ahora bien, para simplificar ese if...then...else he intentado lo siguiente:
Código:
; ...montón de código común...
ld a, [player_status]
cp PITUFANDO_DCHA
call z, CODIGO_ESPECIFICO_DERECHA
call nz, CODIGO_ESPECIFICO_IZQUIERDA
; ...otro montón de código común...

Pero lo que está en el call nz no se llama nunca Sad
¿Alguna idea de por qué no funciona? ¿Qué es lo que se me escapa?
En línea

theNestruo."Old BASIC programmers never die; they GOSUB but never RETURN."
Páginas: 1 [2] 3
  Imprimir  
 
Ir a:  

Impulsado por MySQL Impulsado por PHP Powered by SMF 1.1.21 | SMF © 2013, Simple Machines XHTML 1.0 válido! CSS válido!