La Place des Développeurs Interruptions sur MSX
ericb59
Membre non connecté
Conseiller Municipal
Reprise du message précédent
J'ai lu quelque part (je peux sans doute retrouver)que pour un bon fonctionnement la bonne pratique pour la routine appelée par le hook était:
1 - Push tout les registres
2 - Di
3 - notre code
4 - Ei
5 - pop tout les registreS
c'est pour cela que j'avais mis ces directictives
aoineko
Membre non connecté
Conseiller Municipal
Je pense que tu confonds les bonnes pratiques pour :
- Créer un code d'interruption ISR (interrupt service routine, comme celui qu'on peut placer en 38h) et qui doit sauver/restaurer le contexte du moment de son appel (donc l'intégralité des registres)
- Créer un hook appelé par un code d'interruption et dans ce cas, le contexte est déjà sauvé par l'ISR
L'ISR, c'est ce dont j'aurai besoin le jour ou je remplacerais le Bios par ma propre routine de gestion des interruptions (optimisée pour le jeu).
A priori, vu que Fusion-C utilise intensivement le Bios, ce n'est pas le genre de chose que tu souhaites faire.
Par contre, tu peux utiliser sans soucis les hook H.KEYI et H.TIMI avec comme seul et unique contrainte de sauver/restaurer AF dans le H.TIMI (si tu utilises le Bios).
H.TIMI peut contenir tous les codes à exécuter de façon régulière (musique, incrémentation de compteur gameplay, etc.).
H.KEYI peut contenir du code de gestion des autres interruptions (H-Blank, RS232, etc.).
Dans les deux cas, ces fonctions doivent être le plus courtes possibles (au moins sur la partie détection d'événements) sinon cela peut impacter les performances de ton programme.
D'après ce que j'ai lu, DI/EI n'ont aucun effet durant le code d'interruption. Les interruptions sont désactivés dans le CPU via un autre flag pour éviter les boucles infinis. C'est le RETI de l'ISR qui réactive les interruptions.
- Créer un code d'interruption ISR (interrupt service routine, comme celui qu'on peut placer en 38h) et qui doit sauver/restaurer le contexte du moment de son appel (donc l'intégralité des registres)
- Créer un hook appelé par un code d'interruption et dans ce cas, le contexte est déjà sauvé par l'ISR
L'ISR, c'est ce dont j'aurai besoin le jour ou je remplacerais le Bios par ma propre routine de gestion des interruptions (optimisée pour le jeu).
A priori, vu que Fusion-C utilise intensivement le Bios, ce n'est pas le genre de chose que tu souhaites faire.
Par contre, tu peux utiliser sans soucis les hook H.KEYI et H.TIMI avec comme seul et unique contrainte de sauver/restaurer AF dans le H.TIMI (si tu utilises le Bios).
H.TIMI peut contenir tous les codes à exécuter de façon régulière (musique, incrémentation de compteur gameplay, etc.).
H.KEYI peut contenir du code de gestion des autres interruptions (H-Blank, RS232, etc.).
Dans les deux cas, ces fonctions doivent être le plus courtes possibles (au moins sur la partie détection d'événements) sinon cela peut impacter les performances de ton programme.
D'après ce que j'ai lu, DI/EI n'ont aucun effet durant le code d'interruption. Les interruptions sont désactivés dans le CPU via un autre flag pour éviter les boucles infinis. C'est le RETI de l'ISR qui réactive les interruptions.
On est toujours ignorant avant de savoir.
ericb59
Membre non connecté
Conseiller Municipal
Citation :
Je pense que tu confonds les bonnes pratiques pour :
- Créer un code d'interruption ISR
- Créer un code d'interruption ISR
C'est possible.
Je vais essayer comme tu le dis.
ericb59 :
J'ai lu quelque part (je peux sans doute retrouver)
que pour un bon fonctionnement la bonne pratique pour la routine appelée par le hook était:
1 - Push tout les registres
2 - Di
3 - notre code
4 - Ei
5 - pop tout les registreS
c'est pour cela que j'avais mis ces directictives
que pour un bon fonctionnement la bonne pratique pour la routine appelée par le hook était:
1 - Push tout les registres
2 - Di
3 - notre code
4 - Ei
5 - pop tout les registreS
c'est pour cela que j'avais mis ces directictives
Non, le push/pop de tous les registres est inutile, puisqu'il est déjà exécuté par KEYINT dans le BIOS.
DI/EI aussi est inutile, car on est pendant une interruption, cela ne sert à rien de se protéger.
La seule bonne pratique en ce qui concerne les hooks, c'est de ne pas oublier que le hook est peut-être déjà utilisé par un autre programme. Par conséquent, ce qu'il est recommandé de faire, c'est :
1 - sauvegarder les octets du hook quelque part en RAM
2 - installer le JP vers sa propre routine à la place
3 - terminer sa propre routine avec un JP vers la sauvegarde du hook
Bien évidemment, dans le cas d'une ROM, cela ne sert à rien, et on peut purement et simplement placer sa dérivation dans le hook. Mais dans le cas de programmes fonctionnant sur disque, par exemple, ou sur un MSX assez bien accessoirisé, c'est nécessaire de le faire.
MSX1: Daewoo DPC-200 / Yamaha CX5M
MSX2: Sony HB-F9P
MSXVR
Vidéo: V9990 (GFX-9)
Audio: MSX-Music (FM-PAC) / MSX-Audio (Audiowave) / OPL4 (Monster Sound FM Blaster) / OPNB (Neotron)
aoineko :
C'est tout simple mais ça doit faire gagner pas mal de temps
C'est p'être pas forcement l'endroit pour en discuter, mais tu as gardé l'ISR par défaut de l'OS !?
Vu les prouesses que tu as fais avec ton Out-Run, j'aurai imaginé que tu étais sur un ISR custom.
Metalion :
Je me suis trompé, j'ai recopié sa routine optimisée pour le registre de statut toujours à 2 ... J'utilise aussi cette optimisation. Il suffit de mettre le registre de statut à 0 lors de l'appel à H.KEYI, et de le rétablir à 2 lors de l'appel à H.TIMI. De cette façon, le registre de statut est toujours à 2 pendant la frame.
C'est tout simple mais ça doit faire gagner pas mal de temps
C'est p'être pas forcement l'endroit pour en discuter, mais tu as gardé l'ISR par défaut de l'OS !?
Vu les prouesses que tu as fais avec ton Out-Run, j'aurai imaginé que tu étais sur un ISR custom.
Je reprends ton message ici, car effectivement, il ne vaut mieux pas polluer l'autre sujet.
Oui, j'ai gardé l'ISR par défaut. De toutes façons, il n'est pas très long dans son exécution, et j'ai contourné son défaut principal (le registre de statut). Tant qu'on utilise qu'une interruption VBLANK, ce n'est pas très grave. Par contre, si on utilise les interruptions HBLANK, là le timing devient critique, et il vaut probablement mieux écrire son propre ISR.
MSX1: Daewoo DPC-200 / Yamaha CX5M
MSX2: Sony HB-F9P
MSXVR
Vidéo: V9990 (GFX-9)
Audio: MSX-Music (FM-PAC) / MSX-Audio (Audiowave) / OPL4 (Monster Sound FM Blaster) / OPNB (Neotron)
aoineko
Membre non connecté
Conseiller Municipal
J'ai remarqué que l'accès aux lignes du clavier via le PPI est assez lent.
Même s'il ne le fait qu'un v-blank sur 2, je trouve que c'est un gros gâchis que l'ISR par défaut le fasse sur les 10 lignes alors qu'on a généralement pas besoin de plus d'une ou deux.
Surtout pour nos projets respectifs qui dure plusieurs frames et n'ont donc aucun intérêt à avoir un refresh des inputs aussi rapide.
Même s'il ne le fait qu'un v-blank sur 2, je trouve que c'est un gros gâchis que l'ISR par défaut le fasse sur les 10 lignes alors qu'on a généralement pas besoin de plus d'une ou deux.
Surtout pour nos projets respectifs qui dure plusieurs frames et n'ont donc aucun intérêt à avoir un refresh des inputs aussi rapide.
On est toujours ignorant avant de savoir.
aoineko
Membre non connecté
Conseiller Municipal
Est-ce que quelqu'un sait ce qu'il se passe si 2 interruptions arrivent en "même temps". Si j'ai bien compris, il y a un système au niveau du z80 pour "proteger" une interruption en cours jusqu'au prochain reti, donc j'imagine que dans ce cas, la 2e est juste ignoré ? Il ne me semble pas que le MSX ait un buffer pour stocker ces interruptions et les exécuter plus tard quand le z80 est disponible.
Ça doit être peu probable mais je me demande ce qu'il se passe si 2 interruptions arrivent exactement au même moment (genre une interruption du RS232 qui arriverait en même temps que celle du VDP).
Il y a aussi un cas particulier que j'aimerai comprendre : avec le VDP du MSX 2, si le registre d'interruption horizontal est mis sur la dernière ligne affichée, les interruptions v-blank et h-blank sont censés avoir lieu en même temps. Comment est-ce géré ? Une seule des 2 interruptions est générée ? Une seule interruption, mais avec les 2 registres de statut initialisés ? 2 interruptions ?
Ça doit être peu probable mais je me demande ce qu'il se passe si 2 interruptions arrivent exactement au même moment (genre une interruption du RS232 qui arriverait en même temps que celle du VDP).
Il y a aussi un cas particulier que j'aimerai comprendre : avec le VDP du MSX 2, si le registre d'interruption horizontal est mis sur la dernière ligne affichée, les interruptions v-blank et h-blank sont censés avoir lieu en même temps. Comment est-ce géré ? Une seule des 2 interruptions est générée ? Une seule interruption, mais avec les 2 registres de statut initialisés ? 2 interruptions ?
On est toujours ignorant avant de savoir.
aoineko
Membre non connecté
Conseiller Municipal
Alors, de ce que j'ai compris :
- 2 interruptions peuvent bien avoir lieu au même moment / au même cycle (même si c'est statistiquement très peu probable). Dans ce cas, je ne sais pas ce qu'il se passe.
- Cela ne peut pas arriver avec le VDP du MSX2 puisqu'un hblank (début de ligne) et un vblank (fin de la dernière ligne) ne peuvent pas arriver en même temps.
- J'ai appris que si le CPU rate une interruption (car il est occupé à gérer la précédente) la "trace" de cette interruption est conservé pour qu'elle soit exécuté quand le CPU est à nouveau dispo. Je suis assez étonné de ça et curieux de comprendre comment ça marche au niveau électronique.
- L'intruction reti permet de prévenir un périphérique que son interruption a eu lieu. Non utilisé par les périphériques MSX ?
Voilà. Comme souvent, j'ai eu des réponses... qui me font poser d'autres questions.
- 2 interruptions peuvent bien avoir lieu au même moment / au même cycle (même si c'est statistiquement très peu probable). Dans ce cas, je ne sais pas ce qu'il se passe.
- Cela ne peut pas arriver avec le VDP du MSX2 puisqu'un hblank (début de ligne) et un vblank (fin de la dernière ligne) ne peuvent pas arriver en même temps.
- J'ai appris que si le CPU rate une interruption (car il est occupé à gérer la précédente) la "trace" de cette interruption est conservé pour qu'elle soit exécuté quand le CPU est à nouveau dispo. Je suis assez étonné de ça et curieux de comprendre comment ça marche au niveau électronique.
- L'intruction reti permet de prévenir un périphérique que son interruption a eu lieu. Non utilisé par les périphériques MSX ?
Voilà. Comme souvent, j'ai eu des réponses... qui me font poser d'autres questions.
On est toujours ignorant avant de savoir.
aoineko :
- J'ai appris que si le CPU rate une interruption (car il est occupé à gérer la précédente) la "trace" de cette interruption est conservé pour qu'elle soit exécuté quand le CPU est à nouveau dispo. Je suis assez étonné de ça et curieux de comprendre comment ça marche au niveau électronique.
L'électronique du Z80 n'est pas mon fort, mais d'après ce que je comprends, le signal sur l'entrée INT du processeur reste "high" tant que l'interruption en cours n'a pas été traitée.
aoineko :
- L'intruction reti permet de prévenir un périphérique que son interruption a eu lieu. Non utilisé par les périphériques MSX ?
Les MSX utilisent le mode 1 des interruptions du Z80. C'est à dire que toutes les interruptions sont gérées par le même appel en 38h. Mais le périphérique qui a généré cette interruption est inconnu. C'est à la routine en 38h d'aller frapper à la porte de tous les périphériques pour demander si c'est eux qui ont généré l'interruption. Je ne vois donc pas comment reti pourrait prévenir le périphérique.
Personnellement, je n'utilise jamais cette instruction, et la routine du BIOS en 38h non plus, d'ailleurs.
Elle se termine par un simple ei/ret. Edité par Metalion Le 17/06/2022 à 08h17
MSX1: Daewoo DPC-200 / Yamaha CX5M
MSX2: Sony HB-F9P
MSXVR
Vidéo: V9990 (GFX-9)
Audio: MSX-Music (FM-PAC) / MSX-Audio (Audiowave) / OPL4 (Monster Sound FM Blaster) / OPNB (Neotron)
aoineko
Membre non connecté
Conseiller Municipal
Je crois que j'ai le fin mot de l'histoire. Le VDP set le signal IRQ au moment d'une interruption vblank ou hblank (sur MSX2) et maintien le signal à l'infini (il ne réagit pas à l'instruction reti). C'est la lecture (manuelle) des valeurs des registres S#0 et S#1 du VDP qui déclenche la fin de l'interruption.
On est toujours ignorant avant de savoir.
TurboSEB
Membre non connecté
Conseiller Municipal
C'est un peu comme si le VDP et le PPI servaient de "temporisateur" au Z80 pour ne pas le surchargé en interruptions , le VDP ayant ses propres piles en VRAM...
Ou j'ai rien compris Edité par TurboSEB Le 18/06/2022 à 10h55
Ou j'ai rien compris Edité par TurboSEB Le 18/06/2022 à 10h55
MSX 1&2 + Moniteurs+divers (environ 0.70Tonnes)
aoineko
Membre non connecté
Conseiller Municipal
Quelqu'un pourrait me traduire ce que ça veux dire ?
C'est pour le V9990. J'ai compris que quand le bit est a 1, cela génère une interruption (saut en 0038h).
Est-ce bien ça ?
(je comprends toujours pas les low et high par rapport aux valeurs des bits)
Code TEXT :
IECE Command end interrupt enable control 1 : INT0 terminal becomes low level when CE flag of P#6 is "1". 0 : INT0 terminal does not change according to CE flag.
C'est pour le V9990. J'ai compris que quand le bit est a 1, cela génère une interruption (saut en 0038h).
Est-ce bien ça ?
(je comprends toujours pas les low et high par rapport aux valeurs des bits)
On est toujours ignorant avant de savoir.
le flag de p#6 il faut que je regarde la doc du v9990
si on simplifie
Low level c'est 0V -> bit à 0
High level c'est 5V ->bit à 1
mais en électronique pure le Low Level est compris entre 2valeurs ainsi que le High Level
et ça dépend des puces employées TTL ou CMOS
si on simplifie
Low level c'est 0V -> bit à 0
High level c'est 5V ->bit à 1
mais en électronique pure le Low Level est compris entre 2valeurs ainsi que le High Level
et ça dépend des puces employées TTL ou CMOS
Répondre
Vous n'êtes pas autorisé à écrire dans cette catégorie