Karoshi MSX Community
05 de Julio de 2021, 07:03:13 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
  Imprimir  
Autor Tema: Ayuda con un par de ideas  (Leído 7347 veces)
0 Usuarios y 1 Visitante están viendo este tema.
Jos'b
Karoshi Maniac
****
Mensajes: 262


« : 26 de Mayo de 2007, 10:35:35 am »

Quiero conseguir las siguientes rutinas:

Rutina 1.
Crea un una rutina que produzca un retardo, pero que sea controlable en segundos o fracciones

Rutina 2.
Hacer volcado RAM a VRAM, pero que se ejecute cada cierto tiempo. Por ejemplo que se vuelquen los sprites en una tanda, en otra se vuelquen los gráficos, etc. Al estilo de lo que hizo viejo en el Malaika.

En definitiva, lo que quiero saber es como parchear (no sé si se dice así) la memoria para que cada vez que salte una interrupcion se ejecute mi propio codigo. He estado mirando el código del ejemplo que viene en el Caruso, pero no doy de sí para entenderlo bien.

Asi, si no es mucho pedir, explicarmelo como si fuera para torpes.
Y gracias al alma caritativa que me ayude
En línea
jltursan
Karoshi Forum's Guru
*******
Mensajes: 1516


¿Que es lo que has aprendido hoy?


WWW Email
« Respuesta #1 : 26 de Mayo de 2007, 01:01:54 pm »

Citar
Rutina 1.
Crea un una rutina que produzca un retardo, pero que sea controlable en segundos o fracciones

La más sencilla es esta:

Código:
ld a,[TIMETICKS] ; TIMETICKS = numero de interrupciones a esperar
ld b,a   
@@WAIT:          halt
                djnz @@WAIT

Si TIMETICKS vale 50/60 está rutina esperará 1 segundo según la máquina funcione a una frecuencia o a la otra respectivamente. A partir de aquí es fácil adaptarla para que espere el tiempo que tu quieras ;-)

Citar
Rutina 2.
Hacer volcado RAM a VRAM, pero que se ejecute cada cierto tiempo. Por ejemplo que se vuelquen los sprites en una tanda, en otra se vuelquen los gráficos, etc. Al estilo de lo que hizo viejo en el Malaika.

Independientemente del volcado a VRAM tu necesitas instalar tu propio gestor de interrupciones; para ello puedes encontrar diversos ejemplos en la sección de snippets:

Utilizando IM1 y el hook $FD9F: Interlaced SC1 with 64 columns
Utilizando IM2: Interlaced SC1 with 64 columns (IM2 example)
Utilizando IM1 y el hook $FD9A: FD9APATCH

Espero que alguno te proporcione la información que necesitas
« Última modificación: 28 de Mayo de 2007, 09:58:01 am por jltursan » En línea

Doom dee doom dee doom
Jos'b
Karoshi Maniac
****
Mensajes: 262


« Respuesta #2 : 26 de Mayo de 2007, 05:42:23 pm »

Gracias por la rutina de tiempo, me viene de perlas.


Respecto a otra toquiero seguir preguntando. En el código de Sap, viene esto

FD9APATCHON:     ; --- PARCHEO DE LA INTERRUPCION ---
                ld      hl,FD9APATCHCODE                ; Direccion del codigo del path
                ld      [$FD9C],hl                             ; Puesta en FD9C
                ld      hl,$C3F1                                ; HL = Pop AF; JP xxxx
                ld      [$FD9A],hl                            ; Puesto en FD9A
                ret                                               ; Volvemos


pues vale, ya he cogido que lo que hace es almacenar en FD9Ch la dirección de mi codigo, pero...

esto que es lo que es
ld      hl,$C3F1                                ; HL = Pop AF; JP xxxx
ld      [$FD9A],hl                            ; Puesto en FD9A
vamos que no sé esto que es. No sé si soy claro Grin

Y otra pregunta, en el código sustituyente, osea mi propio código, ¿ hay que tener en cuenta  algo fuera de lo normal ? o me limito a escribir mi codigo y ya esta. Lo digo por si esto de parchear las interrupciones tiene algún efecto secundario.

Y otra pregunta más. Como haceis para repartir el trabajo, poneís un contador y en función del mismo vais realizando una tarea u otra. Por ejemplo, reservo un byte de ram, y cada vez que se llame al código, voy incrementado su valor y en función de este mismo valor hago en cada llamada una tarea diferente.Lo siento pero no me se explicar mejor. Grin

Y otra más. me daría tiempo entre llamada y llamada a volcar, por ejemplo, unos 500 bytes de RAM a VRAM.

Y ya esta de momento.
Sé que algunas preguntas ya estan más que contestadas en otros post, pero es que soy así, necesito respuestas personalizadas. y como sé que esto os lo sabeis de memoria... Grin y si no os importa contestarme pos lo agradezco.

Y para que veaís que soy agradecido os voy a hacer un poco la bola Grin

los de Karoshi sois fantasticos :god: :god:
los mejores msxeros del mundo  :god: :god:
que sería del MSX sin vosotros  :god: :god:

Bueno ya esta por hoy me voy a  cmptr:)




En línea
kabish
Karoshi Maniac
****
Mensajes: 470


caspaflims@hotmail.com
« Respuesta #3 : 27 de Mayo de 2007, 11:15:42 am »


Y otra pregunta más. Como haceis para repartir el trabajo, poneís un contador y en función del mismo vais realizando una tarea u otra. Por ejemplo, reservo un byte de ram, y cada vez que se llame al código, voy incrementado su valor y en función de este mismo valor hago en cada llamada una tarea diferente.Lo siento pero no me se explicar mejor. Grin


Sí, yo hago eso mismo, otra cosa es q haya maneras mejores de hacerlo. Roll Eyes
En línea
Jos'b
Karoshi Maniac
****
Mensajes: 262


« Respuesta #4 : 27 de Mayo de 2007, 07:06:31 pm »

Por eso lo pregunté, a mí desde luego no se me ocurre otra forma de hacerlo. Pero no sé, a lo mejor hay formas más sencillas.

Y respecto al resto de preguntas, he cogido la indirecta. Grin Buscaré por el foro a ver que encuentro Grin
En línea
jltursan
Karoshi Forum's Guru
*******
Mensajes: 1516


¿Que es lo que has aprendido hoy?


WWW Email
« Respuesta #5 : 28 de Mayo de 2007, 09:57:22 am »

Citar
Pero no sé, a lo mejor hay formas más sencillas

Eso ya dependerá de lo que quieras hacer; pero lo de tener una variable para distinguir entre un bloque y otro está perfecto Smiley

Citar
vamos que no sé esto que es. No sé si soy claro

Es que la rutina de Sapphire es la más especial de las que te puse como ejemplo. En esa rutina lo que se pretende es abortar por completo la ejecución del ISR oficial de la BIOS, el punto más temprano en el que podemos interceptar su ejecución es el que nos proporciona el hook $FD9A; hasta ahí bien, nosotros podemos instalar nuestra propia rutina de interrupciones donde queramos de igual manera que cuando usamos el $FD9F, el problema que tenemos es que al retornar de nuestra rutina no queremos que continue con el resto de la rutina oficial, para evitarlo lo primero que se hace es extraer de la pila la dirección de retorno a la BIOS y en ese momento ya podemos llamar a nuestro código, que por tanto va a ser lo único que se ejecute.
El código del ISR de este ejemplo lo único que hace es proporcionar una salida apropiada para la propia rutina de la BIOS, por eso únicamente consta de POPs.
Sapphire comenta todo eso (en inglish) en el propio ejemplo, la utilidad de esta rutina es la de hacer que manteniendo el modo IM1 de interrupciones, quede disponible para el programador el máximo tiempo de "frame". Es un perfecto ejemplo de "MSX extreme programming" :-D

De todas formas no se si es un buen ejemplo para que empieces por él... Roll Eyes
En línea

Doom dee doom dee doom
SapphiRe_MSX
Visitante
« Respuesta #6 : 28 de Mayo de 2007, 11:19:45 am »

Y otra pregunta más. Como haceis para repartir el trabajo, poneís un contador y en función del mismo vais realizando una tarea u otra. Por ejemplo, reservo un byte de ram, y cada vez que se llame al código, voy incrementado su valor y en función de este mismo valor hago en cada llamada una tarea diferente.Lo siento pero no me se explicar mejor. Grin

Eso es lo que hacía antes. Ahora el bucle de juego se basa en un autómata de estados finitos dirigido por eventos, de forma que en cada frame se deben realizar las acciones que están activadas según los eventos que han sido detectados en frames anteriores.

Lo cierto es que es muy cómodo a la hora de programar, porque te olvidas de todo si está bien hecho.
En línea
Jos'b
Karoshi Maniac
****
Mensajes: 262


« Respuesta #7 : 28 de Mayo de 2007, 05:30:41 pm »

Gracias JL, pero me temo de que no va a ser tan sencillo como pensaba. Dejame que estudie la jugada un poco y ya comentaré(o preguntaré) en este mismo hilo mi parecer.

La idea que tengo pensada, es la siguiente:

Este año quiero hacer que el juego haga volcados de la RAM a VRAM, vamos de RAM a pantalla controlables en tiempo. Quiero decir que cada x fracciones de segundo se vuelque los sprites, y que cada x fracciones de segundo se vuelquen los graficos, y para ello creo (y dime lo conrario si me equivoco) que solo se puede a traves del parcheo de interrupciones. Así que intento enterarme bien de como hay que hacerlo.

De todas formas intentaré comprender los ejemplos que me has dado y por supuesto sigo aceptando sugerencias y referencias bibliograficas facilmente descargables de internet. Si veo que me supera utilizaré la vieja tecnica de usar retardos con bucles Grin Grin Lo siento. Grin

Y otra pregunta más. Como haceis para repartir el trabajo, poneís un contador y en función del mismo vais realizando una tarea u otra. Por ejemplo, reservo un byte de ram, y cada vez que se llame al código, voy incrementado su valor y en función de este mismo valor hago en cada llamada una tarea diferente.Lo siento pero no me se explicar mejor. Grin

Eso es lo que hacía antes. Ahora el bucle de juego se basa en un autómata de estados finitos dirigido por eventos, de forma que en cada frame se deben realizar las acciones que están activadas según los eventos que han sido detectados en frames anteriores.

Lo cierto es que es muy cómodo a la hora de programar, porque te olvidas de todo si está bien hecho.


Respecto a los Automatas de estados finitos, conozco su teoría, ya se utiliza en los circuitos digitales con memoría, basícamente es crear un circuito cuya salida dependa de la variable de entrada y del propio estado de la máquina. Sin embargo no sé como se podría adaptar para de forma simple para un juego, eso si que es verdad que se escapa a mi nivel de CM. Creo que me quedaré con lo del contador  Grin Es un poco cutre pero funcional.

Bueno en definitiva dejadme que siga investigando  a ver como puedo hacer lo de la interrupciones, y sino dentro de poco volveré Grin a dar la brasa de nuevo.
En línea
SapphiRe_MSX
Visitante
« Respuesta #8 : 28 de Mayo de 2007, 05:38:23 pm »

Sin embargo no sé como se podría adaptar para de forma simple para un juego, eso si que es verdad que se escapa a mi nivel de CM.

No es tan difícil. Por ejemplo tengo una acción que es "Calcular Scroll" y otra que es "Volcar Scroll a VRAM". Cada una de ellas está controlada por un bit de un byte de estado que tiene cada jugador. En un principio el bit de "Calcular Scroll" está siempre activado (aunque no siempre va a estarlo cuando termine por completo el motor del juego), con lo que la rutina de cálculo del scroll se llama 60 veces por segundo (50 en pal, pero siempre diseño en NTSC, da menos problemas). Esta rutina actualiza el scroll cada cierto número de frames (con un "cutre contador") y cuando ha calculado el siguiente scroll, activa el bit de "Volcar Scroll a VRAM". Dado que el Scroll no va siempre a la misma velocidad, no puedo saber a priori qué acciones se van a realizar en cada frame, sólo lo se cuando se han completado todos los cálculos en el frame inmediatamente anterior.

El autómata tiene una serie de estados que se encargan de activar y desactivar los bits de todas las acciones (hay unas 4 ó 5 más), dependiendo del estado en el que se encuentra y de los eventos que han sucedido.

Saludos
--
Sph.
En línea
Jos'b
Karoshi Maniac
****
Mensajes: 262


« Respuesta #9 : 28 de Mayo de 2007, 08:11:32 pm »

Oye, pues es una idea interesante. yo diría que casi mejor que lo del contador, de esta forma llamando a la funcion, ella misma se encargaría de verificar los bits y realizar las acciones que correspondan en relacion a su estado (si me equivoco dimelo).

Me ha gustado mas que lo del contador. Cheesy

Respecto a lo de parchear las interrupciones, he pensado otra cosa. Voy a usar lo que ya se comento hace tiempo respecto al halt y hacer el volcado a VRAM justo despues. En una tanda imprimiré los Sprites y en la otra los graficos. Espero que no se haga muy lento. De todas formas sigo aceptando sugerencias.
En línea
kabish
Karoshi Maniac
****
Mensajes: 470


caspaflims@hotmail.com
« Respuesta #10 : 28 de Mayo de 2007, 11:04:27 pm »


El autómata tiene una serie de estados que se encargan de activar y desactivar los bits de todas las acciones (hay unas 4 ó 5 más), dependiendo del estado en el que se encuentra y de los eventos que han sucedido.


Pues yo habia pensado hacer lo mismo para un juego q estoy haciendo. Ya q tengo una serie de eventos los cuales algunos son excluyentes y otros nacen de unos estados iniciales. Lo q pasa q mas cutre, claro. Cheesy

Buena idea, si señor.
En línea
SapphiRe_MSX
Visitante
« Respuesta #11 : 29 de Mayo de 2007, 10:40:03 am »

Oye, pues es una idea interesante. yo diría que casi mejor que lo del contador, de esta forma llamando a la funcion, ella misma se encargaría de verificar los bits y realizar las acciones que correspondan en relacion a su estado (si me equivoco dimelo).

No te equivocas, esa es la idea que utilizo.

Citar
Me ha gustado mas que lo del contador. Cheesy

Es más versátil.

Citar
Respecto a lo de parchear las interrupciones, he pensado otra cosa. Voy a usar lo que ya se comento hace tiempo respecto al halt y hacer el volcado a VRAM justo despues. En una tanda imprimiré los Sprites y en la otra los graficos. Espero que no se haga muy lento. De todas formas sigo aceptando sugerencias.

Vuelca los gráficos/sprites sólo cuando algo haya cambiado, con la idea del autómata es muy fácil hacerlo.

Saludos
--
Sph.
En línea
Jos'b
Karoshi Maniac
****
Mensajes: 262


« Respuesta #12 : 29 de Mayo de 2007, 06:12:34 pm »

Pues estoy aprovechando esta idea de los estados para modificar una rutina que tengo, pero como llevo toda la tarde dandole vuelta y no doy con la tecla, me gustaria que me confirmarais el efecto de las siguientes instrucciones

set 3,[memoria]  -> Pone a uno el bit 3 del contenido de la direccion memoria

res 3,[memoria] -> Pone a cero el idem

bit 3, [memoria] -> produce Z=0 si el bit 3 esta a uno y Z=1 si el bit 3 esta a cero

vamos que si hago esto

set 3,[memoria]
bit 3,[memoria]
call z,rutina

debería saltar a la rutina ¿verdad?

me vale un si o un no. Es para descartar errores.
En línea
SapphiRe_MSX
Visitante
« Respuesta #13 : 29 de Mayo de 2007, 06:50:38 pm »

Pues estoy aprovechando esta idea de los estados para modificar una rutina que tengo, pero como llevo toda la tarde dandole vuelta y no doy con la tecla, me gustaria que me confirmarais el efecto de las siguientes instrucciones

Veamos

Citar
set 3,[memoria]  -> Pone a uno el bit 3 del contenido de la direccion memoria

Correcto

Citar
res 3,[memoria] -> Pone a cero el idem

Correcto

Citar
bit 3, [memoria] -> produce Z=0 si el bit 3 esta a uno y Z=1 si el bit 3 esta a cero

Correcto

Citar
vamos que si hago esto

set 3,[memoria]
bit 3,[memoria]
call z,rutina

debería saltar a la rutina ¿verdad?

Incorrecto, el bit 3 está a uno, por lo tanto el flag z está a 0, o sea, no se activa. Si quieres saltar a la rutina deberías poner call nz,rutina

Citar
me vale un si o un no. Es para descartar errores.

Si lo llego a leer antes no hubiera escrito tanto... Grin Grin Grin Grin Grin
En línea
Jos'b
Karoshi Maniac
****
Mensajes: 262


« Respuesta #14 : 29 de Mayo de 2007, 07:32:25 pm »


Citar
me vale un si o un no. Es para descartar errores.

Si lo llego a leer antes no hubiera escrito tanto... Grin Grin Grin Grin Grin


 Grin


Bueno gracias por la aclaración, si soy sincero es la primera vez que uso las instrucciones de manipulación de bit y me he hecho un poco de lio Grin

Voy a probar mis nuevos conocimientos a ver que tal.
En línea
Páginas: [1] 2
  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!