Atariware Wiki: Sección 2 - Como usar el reloj interno del Atari

https://www.atariware.cl/wiki     Versión: 6 (31.10.2020 01:24)

Sección 2 - Como usar el reloj interno del Atari

https://www.atariware.cl/archivos/compu-util1/reloj.png

¿Has escrito un programa en donde desees un tiempo de espera específico entre un proceso y otro?, para leer un mensaje, por ejemplo.

¿Cómo lo hiciste?

Posiblemente como lo hacemos la mayoría de nosotros: usando un ciclo FOR/NEXT.

El ejemplo típico de rutina de espera que te mostramos a continuación, demora aproximadamente tres segundos en ser ejecutado.

Compruébalo por ti mismo. Escribe y corre este pequeñito programa, y mide el tiempo que demora en aparecer el mensaje «Fin del ciclo».
10 PRINT "COMIENZA EL CICLO"
20 FOR K=1 TO 1000 
30 NEXT K
40 PRINT "FIN DEL CICLO"	

Hasta aquí se vé maravilloso. Una solución sencilla y eficiente. Pero ¿qué sucede cuando incorporas esta rutina en tus programas? Si lo haces, encontrarás que los tres segundos se transforman en cinco, seis y hasta diez segundos.

¿Porqué ocurre esto?

La razón es que los ciclos FOR/NEXT demoran mayor tiempo en ser ejecutados, en la medida que se suman líneas al programa.

Pero hay un modo de hacer rutinas de espera con duraciones precisas e independientes de la longitud del programa.

Te contamos el secreto: USAR LAS DIRECCIONES 18, 19 Y 20 DE LA MEMORIA DE TU COMPUTADOR ATARI, que en sí constituyen un reloj por su modo peculiar de funcionamiento.

Este reloj avanza igual que el odómetro de un automóvil. En el tablero del auto existen 5 ruedas dentadas, ubicadas una al lado de la otra. Cada ruedecita contiene los dígitos del 0 al ? y cada vez que el auto recorre un kilómetro, la rueda del extremo derecho avanza un número. Cuando ha avanzado 10, es decir desde el 1 al 9 y ha vuelto a 0, su vecina inmediata de la izquierda avanzará un número y el tablero mostrará la cifra 10. Así sucesivamente hasta que la segunda rueda vuelva a cero, la tercera avance un número y el tablero muestre la cifra 100.

En el computador es lo mismo, pero cada posición contará hasta 255 para que la siguiente avance en una unidad.
El registro número veinte cuenta 60 números por segundo hasta llegar a 255. En ese momento, el registro 19 se incrementa en uno Y el 20 comienza a contar desde cero nuevamente. Cuando el registro 19 llega a 255, incrementa en uno al registro 18 y recomienza el ciclo.

Si colocas el valor cero en los tres registros mencionados (usando la función POKE), demorará alrededor de 1092 segundos (más de 8 minutos) en aparecer un uno en el registro 18. Un sencillo cálculo te mostrará que deberías esperar más de 77 horas para que el registro 18 alcance el valor 255, Más adelante encontrarás una tabla que te mostrará los tiempos que demoran los tres registros en alcanzar diferentes valores que te damos a modo de ejemplo.

Bueno, volviendo a neutro pequeño programa de espera, ahora podemos reescribirlo de un modo algo diferente. Veamos:
10 PRINT "COMIENZA EL CICLO"
20 IF PEEK(20) < 180 THEN 20 
30 PRINT "FIN DEL CICLO"	

Esta rutina demorará tres segundos en ser ejecutada, independientemente de cuan largo pueda ser tu programa.

Incluimos aquí tres programas que te muestran un uso mucho más funcional de este reloj.

Escribe el Programa 1, sin incluir las sentencias REM. Es decir, escribirlo a partir de la línea 120, ya que así funcionará mejor. Si de todos modos deseas incluirlas para mayor claridad en usos futuros, agrega la instrucción:
5 GOTO 120	

para que el computador no pierda tiempo pasando por los comentarios (instrucciones REM), las cuales si bien es cierto no se ejecutan ni inciden en el funcionamiento del programa, de todos modos deben ser «traducidas» por el interprete Basic, toda vez que la ejecución del programa pasa por esas líneas. Esto ocasionará una demora adicional, que no está considerada en el tiempo de demora estimado para la ejecución.

Este programa te dirá el tiempo transcurrido desde que pulses RETURN (después de escribir RUN), hasta una segunda presión de la tecla RETURN. Fíjate que si presionas una tecla diferente de RETURN, el programa retrocederá hasta la línea 40.

El programa te mostrará varios conceptos útiles.

Primero: el computador está esperando una entrada específica, la tecla RETURN (ATASCII 155), en este caso.

Segundo: la línea 60 lee los contenidos (PEEK) de los registros 18, 19 y 20.

Tercero: La línea 70 contiene una fórmula para convertir a segundos la información de las direcciones 18, 19 y 20. El número 4.267 proviene de dividir 256 por 60 (256 = valores de 0 a 255 que toman los registros; 60 = incrementos por segundo en cada registros).

Cuarto: las líneas 80 a 100 convierten a minutos y segundos el número total de segundos.

El Programa 2 es mas útil aún. Es una prueba de matemáticas con tiempo máximo de 8.5 segundos para responder.

La línea 140 se usa para verificar si se ha presionado alguna tecla. Si ninguna lo ha sido, el programa retrocede a la línea 120 y verifica el tiempo transcurrido. Una vez que se presiona una tecla, el computador obtiene el código ATASCI1 correspondiente y lo guarda en la variable Al.

En las lineas 160 y 170, Al es convertida al CHR$ correspondiente y colocada en el lugar apropiado en la variable RES$. Si Al es igual a 155 (código ATASCII para la tecla RETURN) el programa salta a la linea 220, donde el valor de RES$ es colocado en la variable RES.

Como muestra final, te entregamos el Programa 3, que también es una prueba de matemáticas.

En este caso se da tiempo ilimitado para responder y el programa combina elementos de los programas 1 y 2.

Este dispositivo de medición de tiempo puede ser útil ya sea para colocar tiempos limite, medir tiempos de respuesta, o hacer competencias entre los usuarios y se puede aplicar tanto en programa educacionales como en programas de juegos. Una vez que te familiarices con él, podrás adoptarlo para ser usado en tus propios programas.

Tabla 1 «Ejemplos de Tiempos»
Registro 20Registro 19Registro 18Min. Seg.
60000:01
60100:05
0200:08
100200:10
0300:12
100400:18
211401:00

Tabla 2 «Ejemplos de Tiempos»
Registro 20Registro 19Registro 18Min. Seg.
422802:00
845604:00
17611208:00
0255018:08
060240:40
0016291:17
001001820:35
001552730:52
002554642:29

Programa 1 «reloj Atari»
10 REM * RELOJ INTERNO DEL ATARI *
20 OPEN #1,4,0,"K:"
30 FOR K=18 TO 20:POKE K,0:NEXT K 
40 GET #1,T:IF T=155 THEN 60 
50 GOTO 40
60 A=PEEK(20):B=PEEK(19):C=PEEK(18) 
70 SEG=INT(4.267*256*C)+(B*4.267)+(A/60)
80 MIN=INT(SEG/60)
90 M=MIN*60 
100 SEG=SEG-M
110 PRINT MIN;" MINUTOS ";SEG;" SEGUNDOS"	

Programa 2 «prueba de matemáticas»
10 REM ESTA ES UNA PRUEBA DE MATEMATICAS 
20 REM CON TIEMPO LIMITE DE RESPUESTA 
30 REM LOS TIEMPOS DADOS PUEDEN SER 
40 REM CAMBIADOS SI MODIFICAS LA LINEA 130 
50 REM SI COLOCAS A=1 PERMITE 4 1/4 SEGUNDOS
60 REM SI COLOCAS A=2 PERMITE 8 1/2 SEGUNDOS
70 REM SI COLOCAS A=3 PERMITE 12 3/4 SEGUNDOS,ETC
80 OPEN #1,4,0,"K:":DIM RES$(10)
90 PRINT:P1=INT(RND(0)*20):P2=INT(RND(0)*20):X=1 
100 PRINT P1;" + ";P2;" = ";
110 FOR K=18 TO 20:POKE K,0:NEXT K 
120 A=PEEK(19):B=PEEK(20)
130 IF A=2 THEN 180:REM 8 1/2 SEGUNDOS 
140 IF PEEK(764)=255 THEN 120 
150 GET #1,A1:IF A1=155 THEN 220 
160 RES$(X,X) = CHR$(A1)
170 PRINT RES$(X,X);:X=X+1:GOTO 120 
180 PRINT: PRINT "SE TERMINO EL TIEMPO"
190 PRINT "LA RESPUESTA ES ";P1+P2 
200 FOR W=1 TO 400:NEXT W
210 RES$=" ":GOTO 90 
220 RES=VAL(RES$):PRINT 
230 IF RES=P1+P2 THEN PRINT: PRINT "CORRECTO":GOTO 200
240 PRINT: PRINT "LO SIENTO. EQUIVOCADO.": PRINT:GOTO 190	

Programa 3 «prueba de matemáticas 2»
10 REM PRUEBA DE MATEMATICAS 
20 REM VERSION 2
30 REM ESTE PROGRAMA COMBINA ELEMENTOS
40 REM DE LOS PROGRAMAS 1 Y 2
50 REM ES UNA PRUEBA DE MATEMATICAS
60 REM QUE TE DICE CUANTO TIEMPO DEMORASTE
70 REM EN DAR TU RESPUESTA
80 OPEN #1,4,0,"K:":DIM RES$(10)
90 PRINT:P1=INT(RND(0)*20):P2=INT(RND(0)*20):X=1
100 PRINT P1;" + "; P2;" = ";
110 FOR K=18 TO 20:POKE K,0:NEXT K 
120 IF PEEK(764)=255 THEN 120 
130 GET #1,A1: IF A1=155 THEN 190 
140 RES$(X,X)=CHR$(A1)
150 PRINT RES$(X,X);: X=X+1:GOTO 120 
160 PRINT " LA RESPUESTA ES ";P1+P2
170 FOR W=1 TO 1000:NEXT W 
180 RES$=" ":GOTO 90 
190 A=PEEK(20):B=PEEK(19):C=PEEK(18) 
200 RES=VAL(RES$):PRINT 
210 IF RES=P1+P2 THEN PRINT: PRINT "CORRECTO":GOTO 230
220 PRINT: PRINT "LO SIENTO. EQUIVOCADO."
230 SEG=INT(4.267*256*C)+(B*4.267)+(A/60)
240 MIN=INT(SEG/60)
250 M=MIN*60 
260 SEG=SEG-M 
270 IF MIN<>0 THEN 290 
280 PRINT "DEMORASTE ";SEG;" SEGUNDOS":GOTO 170
290 PRINT "DEMORASTE ";MIN;" SEGUNDOS"
300 GOTO 170