[EmuZ-700/PAL] L'importance de compter en T-states par M-cycle !

Couvre tous les domaines de l'émulation logicielle ou de la virtualisation ainsi que les discussions sur les divers outils associés.

Modérateurs : Papy.G, fneck, Carl

Avatar de l’utilisateur
hlide
Messages : 3469
Inscription : 29 nov. 2017 10:23

[EmuZ-700/PAL] L'importance de compter en T-states par M-cycle !

Message par hlide »

Sur la base du source d'origine d'EmuZ-700 qui ne fait que de la vidéo NTSC, j'ai entrepris certains changements pour l'adapter à la vidéo PAL.

J'ai donc commencé à piquer des mesures en cycles CPU avec un analyseur logique (ce dernier permet de compter des impulsions dans une intervalle) branché sur un vrai MZ-700 :

Code : Tout sélectionner

LINE	: 227
	Genuine MZ-700starts its LINE here
	   |	
	   |			EmuZ-700 starts its LINE here
	   |				   |
	   v				   v
BLNK	: (1) 80			| (0) 147	-> TOTAL: 227
/HBLK	: (0) 99			| (1) 128	-> TOTAL: 227
/HSY	: (0) 32	| (1) 16	| (0) 179	-> TOTAL: 227
L'accès est condamné au CPU tant que le signal BLNK n'est pas à 1 via le signal /WAIT.

J'ai donc mis à jour le source à partir de ces informations. Donc du 91 cycles que j'avais calculé à partir du manuel, je me retrouve en fait avec 80 cycles maximum d'accès. Ah mais il y a un problème !? le programme 112.mzf qui dessine notre "Sailor Jupiter" fait du 81 cycles par ligne !

Il existe un programme appelé 'wt' qui permet de déterminer jusqu'à combien de cycles on peut écrire pendant le signal BLNK=1 :

- Exécuté sous le MZ-700 réel, l'image qu'il faut obtenir va jusqu'à 83 cycles :
(
IMG_20200712_190010.jpg
IMG_20200712_190010.jpg (244.66 Kio) Consulté 2683 fois
)

Sinon au-delà, on obtient une perturbation indiquant que le code de dessin ne peux plus dessiner par ligne de "rasterisation" :
(
IMG_20200712_190021.jpg
IMG_20200712_190021.jpg (210.69 Kio) Consulté 2683 fois
)

Et l'EmuZ-700 PAL ? 91 cycles !!!

Face à cette énigme, j'ai entrepris d'analyser comment ça se passe :

- sur un vrai MZ-700 :

Code : Tout sélectionner

  Bloqué sur le T2 du M-cycle #2 (MRD) tant que BLANK est 0 ---> cette instruction  a donc bien exécuté 7 cycles
  avant d'être bloquée. 80 + 11 (coût total du PUSH) - 7, ça donne... 84 comme limite à ne pas franchir ! 
    |
    v
[PUSH:11][PUSH:11][PUSH:11][PUSH:11][...:n-44][PUSH:11]
- sur EmuZ-700/PAL :

Code : Tout sélectionner

  BLANK est à 0 ---> Le premier PUSH est exécuté complètement et le /BUSREQ passe à 0
  pour que l'instruction suivante soit bloquée jusqu'à ce que BLNK devienne 1
    |
    |      Le deuxième est maintenant bloqué : 80 + 11 (1er PUSH) + 1, soit... 92 comme limite à ne pas franchir !
    |        |
    v        v
[PUSH:11][PUSH:11][PUSH:11][PUSH:11][...:n-44][PUSH:11]
Premier constat, le choix d'émuler avec le /BUSREQ à 0 au lieu du /WAIT à 0 ne représente pas la réalité. Deuxième constat, l'émulateur calcule ces cycles par coût total d'un instruction. Donc pas étonnant que le résultat ne soit pas là et que le /BUSREQ a semblé être la rustine de circonstance.

Effectivement un programme qui affiche continuellement un certain nombre de fois avec LDIR au lieu de PUSH donné 11 secondes au lieu des 16 secondes attendues à cause de ce choix d'émulation.

J'ai galéré pour trouver un fichier exploitable programmatiquement et "générer" des tableau de cumul de T-state par M-cycle faisant accès à de la mémoire (insertion de /WAIT states potentiels sur le T2 du M-cycle de type M1R, MRD ou MWR). Avec ces tableaux, je peux obtenir plus finement les cycles CPU pour calculer le nombre de cycle /WAIT qui faut pour que l'instruction reprenne à l'instant où BLNK repasse à 1.

Et bingo ! EmuZ-700/PAL me fait bien 83 avec 'wt' (PUSH) et ~16 secondes avec le programme de test à base de LDIR comme le vrai MZ-700.

A noter que le cas d'une instruction exécutée dans la VRAM est maintenant bloquée plus finement aussi (premier opcode passe, le second ne passe pas --> pas le même nombre de cycles /WAIT que si ça avait été le premier opcode qui bloquait).

Conclusion : émuler avec des cycles par instruction ne suffit pas pour une bonne émulation de la partie hard extérieure au CPU, compter les T-states entre le M-cycles d'une instruction peut être crucial dans certain cas.
Répondre