OVH Cloud OVH Cloud

Emulation et cycle d'horloge

13 réponses
Avatar
pthfndr
Bonjour à tous,



Je veux émuler un Z80 à 5 MHz.
Chaque cycle d'horloge vaut donc 1/5*10**6 seconde soit 0.2
microseconde.
Si je fais "émuler" mon émulateur sans controle , la vitesse équivaut à
un processeur tournant à 20 MHZ ( je cherche l'exactitude en temps, à
disons 10 %
près).
La question est donc de stopper l'émulateur (par un wait ?) le temps
d'un cycle d'horloge (0.2 us) mais en y retranchant la durée qu'a déjà
consommé l'émulation de l'instruction.
Peut-on générer sous windows des durées si courtes (2/10 de us) ?
Je vois cela comme ça :


temps_fin_instruction_en_us = temps_actuel_en_us + temps_de_cycle_en_us
for(;;)
{
while (temps_actuel_en_us < temps_fin_instruction_en_us)
{
;
}
temps_fin_instruction_en_us += temps_de_cycle_en_us ;
traitement du l'instruction simulée
...
}

Mais on doit pouvoir, au lieu du while{;} faire un wait() ou suspend()
et redémarrer le process par un timer, non ?

Merci pour vos conseils et expertises en matière d'émulations et de
temps réel.


Pthfndr.

10 réponses

1 2
Avatar
François Müller
Bonjour

"pthfndr" escribió en el mensaje
news:
| Je veux émuler un Z80 à 5 MHz.

Amusant

| Peut-on générer sous windows des durées si courtes (2/10 de us) ?

Pas à ma connaissance. Sur ces résolutions, on rentre dans le temps réel, et
Windows n'est clairement pas fait pour cela (je ne dit pas que c'est
impossible, mais ...)

F.
Avatar
Olivier
as tu essaye sleep(tontemps);

--
Cordialement ,
Sarda Olivier

Site Web:
http://membres.lycos.fr/osarda
Avatar
Dominique Baldo
Olivier nous disait
as tu essaye sleep(tontemps);



avec tontemps en micro seconde? t'es fou dans ta tête? le scheduler
descend pas sous les 5 ou 10 *milli* secondes
Avatar
François Müller
"Olivier" escribió en el mensaje
news:3f567282$0$1139
| as tu essaye sleep(tontemps);

On *lit* la question avant de répondre ...

F.
Avatar
François Müller
Bonjour

"pthfndr" escribió en el mensaje
news:
| Je veux émuler un Z80 à 5 MHz.

| Peut-on générer sous windows des durées si courtes (2/10 de us) ?

Bon j'ai regardé de plus prés, et, il y a bien qq chose (je ne savais même
pas) :

A défaut de générer des durées ainsi, regarde ces 2 fonctions (simplissime
en plus ;-):

QueryPerformanceFrequency
QueryPerformanceCounter

Elle doivent te pernmetre d'aprocher ce que tu veux faire (sur ma machine
j'obtient une frequenec de résolution de 2393930000).

Un bout de code de demo (je viens de torcher cela en 1').
Si je comprend bien bien ce qu'affiche le bout de code (des diff de temps
trés faible considérant la fréquence), on obtient effectivement des
résolutions très très fines :

DWORD erc;

LARGE_INTEGER li_freq;
LARGE_INTEGER li_count [100];
erc = QueryPerformanceFrequency(&li_freq);
if(erc)
{
for(long i = 0; i < 100; ++i)
{
erc = QueryPerformanceCounter(&li_count[i]);
if(erc == 0)
break;
}
}

F.
Avatar
Plotark
> La question est donc de stopper l'émulateur (par un wait ?) le temps
d'un cycle d'horloge (0.2 us) mais en y retranchant la durée qu'a déjà



Salut,

Pourquoi ne pas faire des batchs. Par exemple tu executes n instructions
le plus vite possible et apres tu attends n*0.2us. C'est pas possible?
Sinon je crois me souvenir que sur le gameboy qui utilise un Z80 il
fallait 4 cycles d'horloge pour executer une instruction. Je ne sais pas
si c'etait le cas du vrai Z80 puisque le GameBoy utilisait une version
modifiee si je me souviens bien.

Plotark
Avatar
Michaël Cortex
pthfndr wrote:
Mais on doit pouvoir, au lieu du while{;} faire un wait() ou suspend()
et redémarrer le process par un timer, non ?



Si tu fais un while (); comme ça, tu vas prendre 100% du CPU... Il faudrait
passer par une fonction comme sleep (...) ou Query... ocmme le dit François.
Je ne connais pas assez bien ce domaine-là...
--
<=- Michaël "Cortex" Monerau -=>
Avatar
adebaene
pthfndr wrote in message news:...
Bonjour à tous,


Bonjour.

Je veux émuler un Z80 à 5 MHz.


Est-ce bien nécesaire de simuler sa *vitesse* ? Enfin bon, pourqoi
pas...

Chaque cycle d'horloge vaut donc 1/5*10**6 seconde soit 0.2
microseconde.
Si je fais "émuler" mon émulateur sans controle , la vitesse équivaut à
un processeur tournant à 20 MHZ ( je cherche l'exactitude en temps, à
disons 10 %
près).
La question est donc de stopper l'émulateur (par un wait ?) le temps
d'un cycle d'horloge (0.2 us) mais en y retranchant la durée qu'a déjà
consommé l'émulation de l'instruction.
Peut-on générer sous windows des durées si courtes (2/10 de us) ?



Je vois cela comme ça :


temps_fin_instruction_en_us = temps_actuel_en_us + temps_de_cycle_en_us
for(;;)
{
while (temps_actuel_en_us < temps_fin_instruction_en_us)
{
;
}
temps_fin_instruction_en_us += temps_de_cycle_en_us ;
traitement du l'instruction simulée
...
}

Mais on doit pouvoir, au lieu du while{;} faire un wait() ou suspend()
et redémarrer le process par un timer, non ?


Non, ta méthode est la seule *éventuellement* utilisable : Windows ne
fournit aucun timer avec une résolution et une précision suffisante.
Inutile de dire que cette façon de faire (attente active) est très
moche. Voir QueryPerformanceCounter pour avoir un timer suffisamment
précis.

De plus, tu dois aussi être conscient que ton émulateur sera préempté
comme tous les autres threads par le système, ce qui mettra ton
compteur dans les choux d'une valeur à peu près multiple du
"time-slice" de Windows, soit 10 ms. La seule façon de contourner ce
problème (monter très haut la priorité du thread de ton émulateur) est
une très mauvaise idée pour des durées importantes (plus de quelques
ms) car cela remet en cause la stabilité de l'OS (ton thread bouffant
tout le temps processeur et ne laissant pas le temps aux processus
essentiels de Windows - cache manager et autres - le temps de
s'exécuter).

Bref, ca me semble très difficilement réalisable sous Windows qui n'a
jamais eu la prétention d'être un système temps réel.

Arnaud
MVP - VC
Avatar
pthfndr
Bonsoir,

Merci à tous, en particulier François Müller et Arnaux Debaene.
Pour ce dernier, je désire simuler à vitesse réelle, d'où la question.
Je vais essayer avec le code de François, et je vous fais un retour
d'expérience.
Pour la préemptivité, un Z80 à 5 MHz, même émulé, ne doit pas consommé
beaucoup,
aussi j'espère que le reste du temps sera suffisant pour les taches
systèmes de
Windows.
Sinon, MS-dos et Linux seront les solutions.

Merci encore à tous.

Pthfndr.
Avatar
Arnaud Debaene
pthfndr wrote:
Pour la préemptivité, un Z80 à 5 MHz, même émulé, ne doit pas consommé
beaucoup,



Le problème, c'est que quand tu est préempté, c'est par tranche d'au moins
10 ms (le "time slice" de Windows).

Arnaud
1 2