reloj en assembler

Para cualquier plataforma ATARI, computadores o consolas.
lagarto
novice
novice
Mensajes: 15
Registrado: Lun Nov 25, 2013 12:20 pm
Reputación: 0

reloj en assembler

Mensaje por lagarto »

Hola a todos. Tengo un problema con respecto a crear un reloj en gr.0,el cual marque la hora,min y seg.independientemente de lo que se este haciendo.Recuerdo que cuando la dirección 20 marcaba 60,era porque había pasado un segundo,y lo tiraba a la pantalla. Así hasta llegar a 60 seg,lo cual significaba que había pasado un minuto,y cuando pasaban 60 min.,sumaba una hora mas(todo esto lo tiraba a la pantalla).
Lo lamentable,es que he intentado hacerlo en assembler,y no me resulta. He tratado de hacerlo en básic con rutinas en lenguaje de maquina pero....nada.
Alguien podría echarme una mano?

Arte
Lagarto
Avatar de Usuario
vitoco
expert
expert
Mensajes: 869
Registrado: Mié Nov 08, 2006 7:25 pm
Reputación: 5
Contactar:

Re: reloj en assembler

Mensaje por vitoco »

Si lo que quieres es hacer un reloj que muestre la hora en pantalla (digamos en un vértice de la pantalla) independientemente de si estás programando, viendo lo que tienen tus diskettes con el DOS o lo que sea, lo que necesitas es assembler puro, nada de basic entremedio (salvo posiblemente para inicializar el cuento y poner el reloj a la hora).

Lo que tienes que hacer es constuir una VBI (Vertical Blank Interrupt), es decir, una interrupción en pantalla que administre ese relojito. ¿Y como sería? Así a la rápida se me ocurre que deberías definir 4 contadores en memoria, 3 de ellos en BCD (con aritmética decimal) para la hora, minutos y segundos y otro para el contador de jiffies (el número de refrescos de pantalla), que coincidentemente son 60 en un segundo!!! En el fondo, cada 60 jiffies hay que incrementar el contador de segundos, cada 60 de esos los de minutos, etc. Para desplegar el número correspondiente a cada segmento de la hora, debes tomar el contador y separar los nibbles (los 4 bits más y los 4 menos significativos del byte), y usarlos en cada uno de los dígitos en decimal (sumándole alguna constante para que se visualice correctamente). Yo cacho al vuelo que todo ese programa assembler cabe, por ejemplo, en la página 6. Para habilitarlo como una VBI, basta llenar unos vectores apuntando a la rutina y habilitarla.

Para que sepas, el contador en la dirección 20 se modifica con una routina interna de la misma forma que expliqué arriba, por lo que no es nada tan rebuscado. El único problema es que algunas rutinas del SO deshabilitan temporalmente las VBI, por lo que tu reloj sin duda se atrasará.

Ojalá te alcancen los ciclos de reloj para que la VBI haga todo lo que corresponda para mantener la hora visible. Si no es así, puedes delegar parte de la pega a las DLI (Display List Interrupts).

Me hiciste recordar mi reloj romano digital :-D
Avatar de Usuario
Suppawer
hard player
hard player
Mensajes: 285
Registrado: Mar Dic 12, 2006 6:33 pm
Reputación: 3

Re: reloj en assembler

Mensaje por Suppawer »

Lagarto, ¿te refieres a algo como esto?:
Descargar
Última edición por Suppawer el Lun Mar 03, 2014 4:52 pm, editado 1 vez en total.
Avatar de Usuario
vitoco
expert
expert
Mensajes: 869
Registrado: Mié Nov 08, 2006 7:25 pm
Reputación: 5
Contactar:

Re: reloj en assembler

Mensaje por vitoco »

Suppawer escribió:Lagarto, ¿te refieres a algo como esto, pero hecho en assembler?:
Descargar
Suppawer: ¿de dónde sacaste ese programa?

Éste es el listado del programa:
► Mostrar Spoiler
Es curioso... la rutina en assembler fue programada para ser usada en página 6, pero la parte en BASIC la instala en RAMTOP (de una forma dañina), moviendo la pantalla en GR.0 una página más abajo. Hasta donde recuerdo, eso no es seguro, ya que hacer un nuevo GR.0 en el programa después de instalar la rutina puede borrar parte de esa área reservada, matando el código assembler metido ahí.

No sé que hará exactamente el código en assembler, ya que no lo he desensamblado aún (no tengo emulador en este PC), y ya no recerdo el significado de las instrucciones escritas en decimal (apenas recuerdo la 104 y la 96).

Creo que lagarto debe explicar un poco más qué es lo que ya ha intentado para ver cómo ayudarlo...
Avatar de Usuario
Suppawer
hard player
hard player
Mensajes: 285
Registrado: Mar Dic 12, 2006 6:33 pm
Reputación: 3

Re: reloj en assembler

Mensaje por Suppawer »

vitoco escribió:Suppawer: ¿de dónde sacaste ese programa?
Mmmm, creo que fue hace aaaños en el PigWa FTP
vitoco escribió:Me hiciste recordar mi reloj romano digital
A mi mente viene el "Caesar's Clock":
Descargar
lagarto
novice
novice
Mensajes: 15
Registrado: Lun Nov 25, 2013 12:20 pm
Reputación: 0

Re: reloj en assembler

Mensaje por lagarto »

vitoco escribió:Si lo que quieres es hacer un reloj que muestre la hora en pantalla (digamos en un vértice de la pantalla) independientemente de si estás programando, viendo lo que tienen tus diskettes con el DOS o lo que sea, lo que necesitas es assembler puro, nada de basic entremedio (salvo posiblemente para inicializar el cuento y poner el reloj a la hora).

Lo que tienes que hacer es constuir una VBI (Vertical Blank Interrupt), es decir, una interrupción en pantalla que administre ese relojito. ¿Y como sería? Así a la rápida se me ocurre que deberías definir 4 contadores en memoria, 3 de ellos en BCD (con aritmética decimal) para la hora, minutos y segundos y otro para el contador de jiffies (el número de refrescos de pantalla), que coincidentemente son 60 en un segundo!!! En el fondo, cada 60 jiffies hay que incrementar el contador de segundos, cada 60 de esos los de minutos, etc. Para desplegar el número correspondiente a cada segmento de la hora, debes tomar el contador y separar los nibbles (los 4 bits más y los 4 menos significativos del byte), y usarlos en cada uno de los dígitos en decimal (sumándole alguna constante para que se visualice correctamente). Yo cacho al vuelo que todo ese programa assembler cabe, por ejemplo, en la página 6. Para habilitarlo como una VBI, basta llenar unos vectores apuntando a la rutina y habilitarla.

Para que sepas, el contador en la dirección 20 se modifica con una routina interna de la misma forma que expliqué arriba, por lo que no es nada tan rebuscado. El único problema es que algunas rutinas del SO deshabilitan temporalmente las VBI, por lo que tu reloj sin duda se atrasará.

Ojalá te alcancen los ciclos de reloj para que la VBI haga todo lo que corresponda para mantener la hora visible. Si no es así, puedes delegar parte de la pega a las DLI (Display List Interrupts).

Me hiciste recordar mi reloj romano digital :-D

Vitoco,gracias x la ayuda. Hay algo en que me equivoque al plantear la rutina del reloj:no andaba siempre,aunque estuvieras en DOS,o cargando un juego,o cosas así.Solamente andaba en gr.0,en la esquina superior derecha,chequeaba los puros segundos,cuando la dirección 20 llegaba a 60. De ahi sacaba los minutos y las horas.
Pero mientras el reloj andaba,podía hacer cualquier cosa en básic(mover el cursor,imprimir en pantalla,hacer un programa,etc) y el reloj seguía andando.

Porfa,si tienes algúna idea seria súper bienvenida x mi parte.

Atte.
Lagarto.
Avatar de Usuario
fcatrin
hard player
hard player
Mensajes: 470
Registrado: Jue Abr 10, 2008 2:45 pm
Reputación: 5
Ubicación: Quilpué, Chile
Contactar:

Re: reloj en assembler

Mensaje por fcatrin »

vitoco escribió: Es curioso... la rutina en assembler fue programada para ser usada en página 6, pero la parte en BASIC la instala en RAMTOP (de una forma dañina), moviendo la pantalla en GR.0 una página más abajo. Hasta donde recuerdo, eso no es seguro, ya que hacer un nuevo GR.0 en el programa después de instalar la rutina puede borrar parte de esa área reservada, matando el código assembler metido ahí.
Eso no va a pasar porque al hacer el poke en RAMTOP (imagino que es 106) el OS sabe que no puede usar la zona que está arriba de eso, por lo tanto el GR0 se inicializará siempre más abajo hasta que apague el computador o vuelva a modificar RAMTOP.
Avatar de Usuario
fcatrin
hard player
hard player
Mensajes: 470
Registrado: Jue Abr 10, 2008 2:45 pm
Reputación: 5
Ubicación: Quilpué, Chile
Contactar:

Re: reloj en assembler

Mensaje por fcatrin »

Leyendo el código muy por encima hace cosas muy extrañas. La parte en basic asume que el código se puede poner en cualquier lado, pero en realidad sólo puede ser ubicado en la página 6 (1536). No sé si habrán tratado de ejecutarlo, pero si no funciona, el primer cambio es forzar a que PAGEADDR sea 6, y todo el código de RAMTOP ya es irrelevante.

Lo que se puede ver en la parte de asm - insisto, mirado sólo por encima a través de la misma data, no es exacto - es que ocupa los valores inicializados via basic para llevar la cuenta de las horas, minutos y segundos. Para funcionar en el VBI y considerando que se ejecutará 60 veces por segundo, inicializa el contador en 196 y lo incrementa, cuando llega a 0 sabe que tiene que modificar los valores de minutos y horas si corresponde. Finalmente en base al display list calcula la posición de la pantalla en donde debe poner el reloj, si no me equivoco lo hará en la parte superior derecha (caracter 30 de la primera linea)

Si funciona (modificando el PAGEADDR), bien. De otro modo "se puede hacer más simple"
Avatar de Usuario
vitoco
expert
expert
Mensajes: 869
Registrado: Mié Nov 08, 2006 7:25 pm
Reputación: 5
Contactar:

Re: reloj en assembler

Mensaje por vitoco »

fcatrin escribió:
vitoco escribió: Es curioso... la rutina en assembler fue programada para ser usada en página 6, pero la parte en BASIC la instala en RAMTOP (de una forma dañina), moviendo la pantalla en GR.0 una página más abajo. Hasta donde recuerdo, eso no es seguro, ya que hacer un nuevo GR.0 en el programa después de instalar la rutina puede borrar parte de esa área reservada, matando el código assembler metido ahí.
Eso no va a pasar porque al hacer el poke en RAMTOP (imagino que es 106) el OS sabe que no puede usar la zona que está arriba de eso, por lo tanto el GR0 se inicializará siempre más abajo hasta que apague el computador o vuelva a modificar RAMTOP.
La rutina de GRAPHICS 0 tiene un bug, y es que limpia la memoria en bloques de 1K (4 páginas), pero como una pantalla de texto tiene 40*24=960 bytes, y su inicio NO parte al comienzo de una página, borra 1024-960=64 bytes de memoria demás sobre el RAMTOP (que usualmente no hace daño porque en ese punto comienza la ROM). Lo mismo pasa con el CHR$(125) para limpiar pantalla y cuando la pantalla hace scroll, por lo que si uno quiere reservar memoria entre la ROM y la pantalla, hay que dejarse una página extra para irse a la segura, lo cual puede ser complicado por ser la RAM un recurso escaso. En el caso del reloj, se podría estar perdiendo el primer cuarto de página con la rutina en assembler. Mejor reservar memoria usando algún otro mecanismo.
Avatar de Usuario
fcatrin
hard player
hard player
Mensajes: 470
Registrado: Jue Abr 10, 2008 2:45 pm
Reputación: 5
Ubicación: Quilpué, Chile
Contactar:

Re: reloj en assembler

Mensaje por fcatrin »

Ohh buena! No conocía ese bug!!

Bueno, en todo caso como decía, esa rutina está escrita para la página 6 y no funcionará en RAMTOP
Avatar de Usuario
vitoco
expert
expert
Mensajes: 869
Registrado: Mié Nov 08, 2006 7:25 pm
Reputación: 5
Contactar:

Re: reloj en assembler

Mensaje por vitoco »

fcatrin escribió:Leyendo el código muy por encima hace cosas muy extrañas. La parte en basic asume que el código se puede poner en cualquier lado, pero en realidad sólo puede ser ubicado en la página 6 (1536). No sé si habrán tratado de ejecutarlo, pero si no funciona, el primer cambio es forzar a que PAGEADDR sea 6, y todo el código de RAMTOP ya es irrelevante.
También noté eso ;)

Aunque mirando muy por encima, para que funcione sobre RAMTOP, hay que cambiar las líneas 170 y 180, reemplazando el valor 6 de los POKE por la variable PAGE.
Avatar de Usuario
vitoco
expert
expert
Mensajes: 869
Registrado: Mié Nov 08, 2006 7:25 pm
Reputación: 5
Contactar:

Re: reloj en assembler

Mensaje por vitoco »

Hey, acabo de notar que el programa del reloj realmente reserva 2 páginas bajo RAMTOP, ya que resta 1 dos veces:

PAGE = PEEK(RAMTOP) - 1
POKE RAMTOP, PAGE - 1

Sólo usa la más cercana a la ROM, es decir, reserva memoria que no usa, pero el manejo de pantalla sí... está autoprotegiéndose XD
Avatar de Usuario
fcatrin
hard player
hard player
Mensajes: 470
Registrado: Jue Abr 10, 2008 2:45 pm
Reputación: 5
Ubicación: Quilpué, Chile
Contactar:

Re: reloj en assembler

Mensaje por fcatrin »

vitoco escribió:
fcatrin escribió:Leyendo el código muy por encima hace cosas muy extrañas. La parte en basic asume que el código se puede poner en cualquier lado, pero en realidad sólo puede ser ubicado en la página 6 (1536). No sé si habrán tratado de ejecutarlo, pero si no funciona, el primer cambio es forzar a que PAGEADDR sea 6, y todo el código de RAMTOP ya es irrelevante.
También noté eso ;)

Aunque mirando muy por encima, para que funcione sobre RAMTOP, hay que cambiar las líneas 170 y 180, reemplazando el valor 6 de los POKE por la variable PAGE.
Ni siquiera eso, hay que cambiar TODO el código.
Avatar de Usuario
fcatrin
hard player
hard player
Mensajes: 470
Registrado: Jue Abr 10, 2008 2:45 pm
Reputación: 5
Ubicación: Quilpué, Chile
Contactar:

Re: reloj en assembler

Mensaje por fcatrin »

vitoco escribió:Hey, acabo de notar que el programa del reloj realmente reserva 2 páginas bajo RAMTOP, ya que resta 1 dos veces:

PAGE = PEEK(RAMTOP) - 1
POKE RAMTOP, PAGE - 1

Sólo usa la más cercana a la ROM, es decir, reserva memoria que no usa, pero el manejo de pantalla sí... está autoprotegiéndose XD
Esa parte inicial del código me suena a reciclado de otro
Avatar de Usuario
vitoco
expert
expert
Mensajes: 869
Registrado: Mié Nov 08, 2006 7:25 pm
Reputación: 5
Contactar:

Re: reloj en assembler

Mensaje por vitoco »

fcatrin escribió:
vitoco escribió:Aunque mirando muy por encima, para que funcione sobre RAMTOP, hay que cambiar las líneas 170 y 180, reemplazando el valor 6 de los POKE por la variable PAGE.
Ni siquiera eso, hay que cambiar TODO el código.
No, creo que estoy equivocado... lo que hace en el FOR de la línea 150 es cambiar cualquier 6 que venga en la DATA por el valor de la página de destino. Lo que deben estar haciendo los POKEs de las líneas 170 y 180 es volver a 6 aquellos que no debieron cambiar. Creo que todo quedaría más claro si desensamblara el código assembler, pero ahora no tengo mis herramientas para ello, y me da japa hacerlo a mano, byte a byte usando mi torpedo color mostaza.
Última edición por vitoco el Mié Mar 05, 2014 9:09 am, editado 1 vez en total.
Responder