Cómo calcular el tiempo de un bucle en Z80

Sinclair QL, ZX81, +2, +3, 128K ...
Avatar de Usuario
Bubu
Amstrad PC 1640
Amstrad PC 1640
Mensajes: 525
Registrado: 04 Abr 2018, 23:10
Sistema Favorito: Spectrum 16Kb/48Kb
primer_sistema: Spectrum 16Kb/48Kb
consola_favorita: Atari 2600
Primera consola: Nintendo GameBoy
Gracias dadas: 12 veces
Gracias recibidas: 15 veces

Cómo calcular el tiempo de un bucle en Z80

Mensajepor Bubu » 05 Jun 2018, 19:44

¡Hola, torpedos!


Sus voy a plantear un poblema en Z80. Resulta que me gustaría hacer una subrutina que haga una pausa, aunque se sigan ejecutando las interrupciones IM2, y me gustaría saber cuánto tiempo (en segundos, o milisegundos, o lo que sea) estaría el pograma en pausa. Supongamos que esta es la rutina que hace la pausa:

Código: Seleccionar todo

ld bc, P
jajaja:
dec bc
ld a, b
or c
jr nz, jajaja
ret


Primera preguntita:
¿Cuánto tarda esta rutina en ejecutarse (en función de P) si no hubiera interrupciones?

Segunda preguntita:
Si activo las interrupciones IM2, y mi rutina de esa interrupción tarda p.ej. t(int), ¿cuánto tarda ahora esa rutina en ejecutarse? Creo que las interrupciones IM2 son llamadas cada 1/50 segundos, al menos aquí en las Españas.


¡Muchas gracias!
Si algo funciona... ¡¡NO LO TOQUES!! ¡¡NI DE COÑA!!

Avatar de Usuario
Namek
Amstrad PC 1640
Amstrad PC 1640
Mensajes: 635
Registrado: 11 Jul 2011, 13:13
Gracias dadas: 12 veces
Gracias recibidas: 30 veces

Re: Cómo calcular el tiempo de un bucle en Z80

Mensajepor Namek » 05 Jun 2018, 22:20

Teóricamente es fácil de calcular, solo tienes que buscar los t-estados que consume cada instrucción y sumarlas todas y luego multiplicar el total de la suma por el número de iteraciones del bucle. El resultado de ese calculo será el número de ciclos transcurridos y como sabemos que el Z80 del Spectrum funciona a aproximadamente 3,5 millones de ciclos por segundo, solo debemos realizar una simple regla de 3 para calcular el tiempo transcurrido.

Para calcular la diferencia con las interrupciones activas deberemos calcular los t-estados que consume la rutina de interrupciones y multiplicar ese calculo por 50 y sumarlo al calculo anterior.

Fácil verdad?

Avatar de Usuario
Uto
MSX Turbo R
MSX Turbo R
Mensajes: 435
Registrado: 28 Abr 2014, 15:50
Sistema Favorito: Spectrum 16Kb/48Kb
primer_sistema: Spectrum 16Kb/48Kb
consola_favorita: Nintendo SNES
Primera consola: TV Games/Pong Clone
Gracias dadas: 4 veces
Gracias recibidas: 14 veces

Re: Cómo calcular el tiempo de un bucle en Z80

Mensajepor Uto » 05 Jun 2018, 23:32

En esta página tienes la lista de T-States de cada instruccion.

http://map.grauw.nl/resources/z80instr.php

Ten en cuenta que el salto tarda unos t-states si se cumple la condición y otros diferentes cuando no se cumple. En la tabla por eso pone 12/7 en los JR NZ
http://www.ngpaws.com
Twitter: @uto_dev

Avatar de Usuario
Bubu
Amstrad PC 1640
Amstrad PC 1640
Mensajes: 525
Registrado: 04 Abr 2018, 23:10
Sistema Favorito: Spectrum 16Kb/48Kb
primer_sistema: Spectrum 16Kb/48Kb
consola_favorita: Atari 2600
Primera consola: Nintendo GameBoy
Gracias dadas: 12 veces
Gracias recibidas: 15 veces

Re: Cómo calcular el tiempo de un bucle en Z80

Mensajepor Bubu » 06 Jun 2018, 00:12

OK, pero, pero, peeeero, ¿1 T-estado es lo pispo que 1 ciclo?
Además, no entiendo el cálculo con las interrupciones, ¿multiplicar por 50 por qué?
Si algo funciona... ¡¡NO LO TOQUES!! ¡¡NI DE COÑA!!

Avatar de Usuario
Bubu
Amstrad PC 1640
Amstrad PC 1640
Mensajes: 525
Registrado: 04 Abr 2018, 23:10
Sistema Favorito: Spectrum 16Kb/48Kb
primer_sistema: Spectrum 16Kb/48Kb
consola_favorita: Atari 2600
Primera consola: Nintendo GameBoy
Gracias dadas: 12 veces
Gracias recibidas: 15 veces

Re: Cómo calcular el tiempo de un bucle en Z80

Mensajepor Bubu » 06 Jun 2018, 16:33

¡Jarl, torpedos! ¿La rutina esa tarda lo que tarden los t-estados de sus instrucciones? ¿La CPU no tarda un tiempo en tener que leer de la RAM la siguiente instrucción, o es que está incluida ya en esos t-estados?
Si algo funciona... ¡¡NO LO TOQUES!! ¡¡NI DE COÑA!!

Avatar de Usuario
jltursan
Amiga 2500
Amiga 2500
Mensajes: 3865
Registrado: 13 Oct 2006, 19:45
Sistema Favorito: MSX
primer_sistema: Dragon
Ubicación: Serracines, Madrid, España
Gracias dadas: 31 veces
Gracias recibidas: 69 veces
Contactar:

Re: Cómo calcular el tiempo de un bucle en Z80

Mensajepor jltursan » 06 Jun 2018, 20:09

Están incluidos, por eso si te fijas verás como las operaciones que se componen de dos bytes son más lentas siempre que las de uno, hay una lectura más de por medio. O por ejemplo, como en el caso de los MSX, hay un ciclo extra de lectura a añadir a las instrucciones de 1 byte y dos ciclos extra a las de 2 bytes.

Échale un ojo al capítulo 3 de esta presentación que es bastante legible ;-): https://www.slideshare.net/AceHigh1/z80-microprocessor-architecture

Avatar de Usuario
mcleod_ideafix
Amiga 2500
Amiga 2500
Mensajes: 5310
Registrado: 06 Oct 2009, 04:12
Sistema Favorito: Spectrum 16Kb/48Kb
primer_sistema: Spectrum 16Kb/48Kb
consola_favorita: Vectrex
Primera consola: TV Games/Pong Clone
Ubicación: Jerez de la Frontera
Gracias dadas: 12 veces
Gracias recibidas: 46 veces
Contactar:

Re: Cómo calcular el tiempo de un bucle en Z80

Mensajepor mcleod_ideafix » 07 Jun 2018, 13:00

Bubu escribió:¡Hola, torpedos!


Sus voy a plantear un poblema en Z80. Resulta que me gustaría hacer una subrutina que haga una pausa, aunque se sigan ejecutando las interrupciones IM2


Pues vamos a la raiz de tu problema. Aquí tienes una rutina que permite que se sigan ejecutando las interrupciones enmascarables, y que tarda N frames en ejecutarse (1 frame = 20 milisegundos)

Código: Seleccionar todo

ld bc,N
jp 1F3Dh


Esta no es más que la entrada de la ROM del comando PAUSE. Ojo, porque esta pausa se puede interrumpir de forma temprana si se pulsa una tecla. Si no quieres usar la ROM para nada, o no quieres que la pausa se interrumpa prematuramente por pulsar una tecla, aquí tienes otra:

Código: Seleccionar todo

  ld bc,N
espera:
  halt
  dec bc
  ld a,b
  or c
  jr nz,espera
  ret


En ambas rutinas, obviamente, las interrupciones tienen que estar habilitadas.
Recuerda: cada vez que se implementa un sistema clásico en FPGA, Dios mata a un purista

Avatar de Usuario
Bubu
Amstrad PC 1640
Amstrad PC 1640
Mensajes: 525
Registrado: 04 Abr 2018, 23:10
Sistema Favorito: Spectrum 16Kb/48Kb
primer_sistema: Spectrum 16Kb/48Kb
consola_favorita: Atari 2600
Primera consola: Nintendo GameBoy
Gracias dadas: 12 veces
Gracias recibidas: 15 veces

Re: Cómo calcular el tiempo de un bucle en Z80

Mensajepor Bubu » 07 Jun 2018, 14:00

OK, esa rutina es la que puse, pero no quiero poner el HALT, es decir, quiero que las interrupciones salten cuando tengan que saltar.
Así las cosas, decidme si es esto correcto:

Código: Seleccionar todo

ld bc, NN ---> 10 ciclos
espera:
dec bc ---> 6 ciclos
ld a, b ---> 4 ciclos
or c ---> 4 ciclos
jr nz, espera ---> 12 ciclos (considero que el 99% de las veces es "nz", pues bc es grande)
ret ---> 10 ciclos


Tendríamos pues 10 + 26*NN + 10 = 20 + 26*NN ciclos. ¿Corresto?
Última edición por Bubu el 07 Jun 2018, 17:27, editado 1 vez en total.
Si algo funciona... ¡¡NO LO TOQUES!! ¡¡NI DE COÑA!!

Avatar de Usuario
Namek
Amstrad PC 1640
Amstrad PC 1640
Mensajes: 635
Registrado: 11 Jul 2011, 13:13
Gracias dadas: 12 veces
Gracias recibidas: 30 veces

Re: Cómo calcular el tiempo de un bucle en Z80

Mensajepor Namek » 07 Jun 2018, 14:21

Bubu escribió:OK, esa rutina es la que puse, pero no quiero poner el HALT, es decir, quiero que las interrupciones salten cuando tengan que saltar.
Por usar HALT las interrupciones no van a dejar de saltar cuando tengan que saltar, HALT no obliga a que salte una interrupción, simplemente PARA el procesador hasta que la interrupción salta en el mismo momento que saltaría aunque el procesador no estuviera esperando.

Avatar de Usuario
Bubu
Amstrad PC 1640
Amstrad PC 1640
Mensajes: 525
Registrado: 04 Abr 2018, 23:10
Sistema Favorito: Spectrum 16Kb/48Kb
primer_sistema: Spectrum 16Kb/48Kb
consola_favorita: Atari 2600
Primera consola: Nintendo GameBoy
Gracias dadas: 12 veces
Gracias recibidas: 15 veces

Re: Cómo calcular el tiempo de un bucle en Z80

Mensajepor Bubu » 07 Jun 2018, 18:08

Ya, ya, quise decir que no me hacía falta sincronizar el bucle con las interrupciones, jiji.


Bueno, vamos que nos vamos. Sean:

c(p) los ciclos que lleva cada iteración del bucle de pausa
c(i) los ciclos que lleva cada interrupción
N el número de iteraciones que hace el bucle
f la frecuencia del Z80 (3,5E6)
50 el número de interrupciones por segundo (en USA y otros este número es 60)


Entóns, el tiempo que tarda la pausa si no hubiera interrupciones sería:

Código: Seleccionar todo


t(p) = N*c(p)/f



Durante ese tiempo, se habrá interrumpido el tema 50 veces cada segundo, es decir

Código: Seleccionar todo


Núm.int. = 50*N*c(p)/f




De este modo, el tiempo total que la CPU atiene a la interrupción será:

Código: Seleccionar todo


t(i) = (50*N*c(p)/f) * c(i)/f




Este tiempo hay que adicionarlo al tiempo que la CPU está en el bucle de pausa, así que el tiempo total es:

Código: Seleccionar todo


T = t(p) + t(i) = N*c(p)/f + (50*N*c(p)/f) * c(i)/f =

[N*c(p)/f]*(1 + 50*c(i)/f)




Y ahora vamos a usar el sentido común. ¿Acaso no es 50*c(i) << f? Téngase en cuén que f es 3 millones y medio, haría falta una rutina megatecnotrónica para que afectara en algo. Así que lo vamos a despreciar, y la fórmula se queda simplemente en su vertiente "sin interrupciones":

Código: Seleccionar todo


T = N*c(p)/f




Así las cosas, veamos cuánta N hace falta para generar 1 segundo de pausa:

Código: Seleccionar todo


1 = N * 26 / 3,5E6
N = 3,5E6 / 26 = 135000 aprox



Nos sale que hacen falta 135000 iteraciones para 1 segundo de pausa. Pero los registros de 16 bits dan para la mitad, ya que llegan hasta 65535 aprox. Así que podemos concluir con una regla muy básica y prástica:


1 registro de 16 bits da para medio segundo



Así que si alguien quiere una pausa de p.ej. 40 segundos, pues llámese 80 veces a la rutina de pausa.



¡¡¡YIIIHAAAA!!!
Si algo funciona... ¡¡NO LO TOQUES!! ¡¡NI DE COÑA!!


Volver a “Sinclair/Spectrum”

¿Quién está conectado?

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