Interrupciones enmascarables en el Z80

Si tienes alguna duda y crees que alguien podría resolverla, ponla aquí. || If you have any doubt about programming, post it here.

Moderador: CEZ

Responder
Avatar de Usuario
zogo
16 bits
16 bits
Mensajes: 278
Registrado: 05 Jun 2006 16:14
Ubicación: Alemania

Interrupciones enmascarables en el Z80

Mensaje por zogo »

Tengo la siguiente duda, que ocurre en el Z80 cuando utilizamos el modo IM1, y mientras se esta ejecutando el codigo de la ISR llega una nueva interrupcion. A mi entender deberia de ser ignorada, ya que el Z80 cuando acepta la primera interupcion pone los flags IFF1 y IFF2 a 0 ( equivalente a hacer un DI ). Pues mi sorpresa es que parece que no la ignora y el CPC se vuelve loco.

Esto viene a cuento porque para el betiled para la animacion del cursor, los efectos y la musica quiero controlarlos por interrupciones para saber con seguridad donde se ejectuta el codigo.
Para los que no lo sepan el CPC genera una interrupcion cada 1/300s. En la imagen de abajo podeis ver con diferentes colores las distintas interrupciones
Imagen



Bueno a ver si alguien puede echarme un cable.

S2
"Live every moment with a Smile, who knows what’s tomorrow".
"There are 10 kinds of people in the world,
those who understand binary and those that don't"

Avatar by Dad
Avatar de Usuario
Benway
Site Admin
Site Admin
Mensajes: 9241
Registrado: 24 Dic 2005 10:18
Ubicación: Madrid
Contactar:

Re: Interrupciones enmascarables en el Z80

Mensaje por Benway »

Pues no soy el más apropiado para contestarte (porque, como sabes, no tengo mucha idea de asm...) pero... yo juraría que el z80 inactiva las interrupciones cada vez que genera una... para evitar precisamente eso que cuentas.

Es por eso por lo que el código al que se llama ha de retornar con RETI / RETN , que se supone, es una especie de EI + RET en una sola instrucción.

Si miras el código de la interrupción IM1 en la ROM del Speccy, ves...

Código: Seleccionar todo


0038 MASK_INT:
     PUSH AF
     PUSH HL
     LD HL, (FRAMES)
     INC HL
     LD (FRAMES), HL
     LD A, H
     OR L
     JR NZ_KEY_INT
     INC (IY+64)

0048 KEY_INT:
     PUSH BC
     PUSH DE
     CALL KEYBOARD
     POP DE
     POP BC
     POP HL
     POP AF
     EI
     RET
Que, por cierto, acaba con EI + RET en lugar de RETI, que sería lo suyo, pero que así se ve más claramente aún...

Si en la práctica no te funciona así... siempre puedes poner un DI como primera instrucción en la interrupción :?
Un saludo.
Imagen - Imagen - Imagen
Avatar de Usuario
zogo
16 bits
16 bits
Mensajes: 278
Registrado: 05 Jun 2006 16:14
Ubicación: Alemania

Re: Interrupciones enmascarables en el Z80

Mensaje por zogo »

Muchas gracias Ben por tus comentarios. Lo del DI ya lo he probado y no va. Voy a seguir probando, a lo mejor el problema no es el CPC sino mi codigo ](*,)
"Live every moment with a Smile, who knows what’s tomorrow".
"There are 10 kinds of people in the world,
those who understand binary and those that don't"

Avatar by Dad
Avatar de Usuario
Guillian
32 bits
32 bits
Mensajes: 626
Registrado: 02 Ene 2005 02:40

Re: Interrupciones enmascarables en el Z80

Mensaje por Guillian »

zogo escribió:Tengo la siguiente duda, que ocurre en el Z80 cuando utilizamos el modo IM1, y mientras se esta ejecutando el codigo de la ISR llega una nueva interrupcion. A mi entender deberia de ser ignorada, ya que el Z80 cuando acepta la primera interupcion pone los flags IFF1 y IFF2 a 0 ( equivalente a hacer un DI ). Pues mi sorpresa es que parece que no la ignora y el CPC se vuelve loco.
En princio es como tú dices; no se atiende a una nueva interrupción hasta que terminas la actual y vuelves a activarlas con un EI.
Lo que pasa es que si se ha producido una nueva interrupción esta sigue pendiente de ser atendida, con lo que después del EI + RET volverá a ajecutarse la rutina de interrupción.
Desconozco el funcionamiento del CPC, pero lo normal es indicar al dispositivo que generó la interrupción que ésta ya ha sido atendida para que deje de "darnos la brasa". Prueba a hacer esto que te comento antes de volver a activar las interrupciones.
Avatar de Usuario
mcleod_ideafix
16 bits
16 bits
Mensajes: 85
Registrado: 05 Mar 2008 19:46
Ubicación: Sevilla
Contactar:

Re: Interrupciones enmascarables en el Z80

Mensaje por mcleod_ideafix »

En el momento en que se sirve una interrupción enmascarable se desactivan todas las interrupciones, es decir, ni siquiera hace falta hacer DI al principio de la rutina de gestión de interrupción.
Al acabar, se hace con la secuencia EI+RETI. No se atenderá una nueva interrupción hasta que no termine de ejecutarse RETI, para evitar overflow en la pila por culpa de llamadas anidadas de forma descontrolada.
El Z80A muestrea la línea INT entre la ejecución de dos instrucciones, pero sólo llama al gestor de interrupción si las interrupciones están permitidas. Si no es así, la interrupción se pierde, no se "guarda" para cuando estén habilitadas.
Si tu CPC se vuelve loco lo más probable es que sea por algo relacionado con no guardar todos los registros modificados, o bien que tu rutina tenga una duración cercana a los 1/300s que comentas, y no dé tiempo a que el resto del programa se ejecute, o estés usando una rutina que no permite reentrada.
No hay virginidad que aguante tres martinis.
Imagen
Responder