[EMULATION AMSTRAD CPC] AMSpiriT - work in Progress

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

Modérateurs : Carl, Papy.G, fneck

Lone
Messages : 15
Inscription : 26 nov. 2020 09:53

Re: [EMULATION AMSTRAD CPC] AMSpiriT - work in Progress

Message par Lone »

Je te laisse faire tes choix :)

Il est peut être, par ailleurs, plus sain de commencer par l'approche logique (octet par octet) avant de passer au flux de bit, plus proche du matériel (et donc, moins sujet a des "bricolages"). Ton expérience sera d'ailleurs intéressante. (Mais bon courage quand même !)
Dmanu78
Messages : 177
Inscription : 20 juin 2020 14:28
Localisation : Yvelines

Re: [EMULATION AMSTRAD CPC] AMSpiriT - work in Progress

Message par Dmanu78 »

Merci pour tes encouragements, je vais en avoir besoin...
Dans l'esprit c'est un peu comme le codage en "T-State" ou en "NOP" mais appliqué au contrôleur de drive cette fois. Dans ce cas je privilégie l'octet car le FDC transmets un flux d'octets au CPU et non de bits. ça me semble plus logique mais au fil de mes connaissances sur le FDC, peut être que je changerai d'avis. Il est vrai que tu as plusieurs coups d'avance sur moi ... :D

En attendant, c'est laborieux...

Image
OK, cette protection est encore un peu plus forte que moi...pour l'instant :D

Bon, en vérité quelques protections commencent à passer mais je ne vous cacherais pas que le débogage de l'émulation du FDC reste assez fastidieux, même en approche "octets". Je sens que ça va me prendre un peu de temps avant de fiabiliser totalement la lecture des disques non "standards"... :?

Allez, au boulot maintenant :D
Lone
Messages : 15
Inscription : 26 nov. 2020 09:53

Re: [EMULATION AMSTRAD CPC] AMSpiriT - work in Progress

Message par Lone »

Méfie toi tout de même de l'approche octet : Si le FDC envoie effectivement des octets au CPC, le fonctionnement interne est vraiment basé sur un flux de bits... (détection des synchro, etc).

En tout cas, n'hésite pas si tu as des questions, j'ai encore quelques souvenirs !
Avatar de l’utilisateur
ThomasR
Messages : 14
Inscription : 16 janv. 2019 09:02

Re: [EMULATION AMSTRAD CPC] AMSpiriT - work in Progress

Message par ThomasR »

Dmanu78 a écrit : 22 sept. 2021 21:57 @ThomasR, merci pour le compliment. :)

oh oui, c'est faisable. L'objectif à terme est que l'émulateur puisse lire à minima tous les fichiers DSK. Il arrive déjà à lire des fichiers DSK formatés en double face et 80 pistes.

C'est plus compliqué avec les pistes protégées (protections GAP ...) mais j'y travaille :)

( ... )
https://www.cpc-power.com/cpcarchives/i ... es&num=180

ça avance lentement mais surement :)
Hello, Dmanu!

Is it okay to write in English?

Here are some screenshots of playing a BasiCode game from this
BASICODE.ZIP
rename to .DSK
(380.25 Kio) Téléchargé 12 fois
disc with your emulator. Nice to see that my USB joystick is recognised.
OthelloC.png
OthelloC.png (80.28 Kio) Consulté 710 fois
I still like your work very much!
Today I have two questions:
How can I use the second side of the disc image?
Is there an option to change the emulation speed?

Greets, Thomas
Dmanu78
Messages : 177
Inscription : 20 juin 2020 14:28
Localisation : Yvelines

Re: [EMULATION AMSTRAD CPC] AMSpiriT - work in Progress

Message par Dmanu78 »

Hello ThomasR,

Thanks for your interest in this emulator.
It's nice to see that some people use it for testing :)

To answer your 2 questions (only 2 ? :wink: ) :
1. Indeed, I haven't implemented this feature (yet). I can't read the second side of a single DSK file for the moment. For my tests, I always used 2 files to read the A and B sides of a disk. I will implement this feature in a future version. Thanks for this remark :)
2. What processor are you using? In the screenshots, I see that the emulation speed is 1.7 Mhz instead of 4 Mhz..... This is low. The emulator needs a lot of resources and old processors are rather disadvantaged. For the moment I don't plan to change the emulation speed because it doesn't make sense (the CPC is built for a speed of 4 Mhz and any change has an impact on the screen, the sound, the keyboard responsiveness...).
Instead I will try to optimize my code. The goal is to get a stable 4Mhz emulation on a large number of processor models.

Currently, I'm working mainly on the disk controller emulation with significant progress (thanks to Lone's hints).
A new (beta) version should be available soon. :wink:
Avatar de l’utilisateur
ThomasR
Messages : 14
Inscription : 16 janv. 2019 09:02

Re: [EMULATION AMSTRAD CPC] AMSpiriT - work in Progress

Message par ThomasR »

Dmanu78 a écrit : 07 nov. 2021 23:38(...)
What processor are you using? In the screenshots, I see that the emulation speed is 1.7 Mhz instead of 4 Mhz..... (...) A new (beta) version should be available soon. :wink:
Hello Dmanu!

Yes, my machine is a little bit slow😴😉: "only" 4 x 1500 MHz of Logical CPU Config, an AMD A4-5000 APU. I like logical games more than ego shooters or other action games, so this is enough for me.

I will be glad to see Your next version.

Best regards,

Thomas
Dmanu78
Messages : 177
Inscription : 20 juin 2020 14:28
Localisation : Yvelines

Re: [EMULATION AMSTRAD CPC] AMSpiriT - work in Progress

Message par Dmanu78 »

Thanks for the information.
Humm, it seems that my emulator doesn't like old AMD processors...it’s not the first time I have this remark. it is faster with Intel processors. I don't have any explanation for this at the moment. I didn't find any options in Visual Studio to optimize the code for AMD processor...
Dmanu78
Messages : 177
Inscription : 20 juin 2020 14:28
Localisation : Yvelines

Re: [EMULATION AMSTRAD CPC] AMSpiriT - work in Progress

Message par Dmanu78 »

Après quelques semaines de durs labeurs, me revoilà de retour avec une nouvelle version de l'émulateur. Le plus gros du travail a porté sur l'amélioration de l'émulation du Floppy Disk Controler (FDC), mais il y a aussi des petits changements et des améliorations qui ne se remarquent pas forcément au premier abord.

Un gros boulot de fond a donc été fait sur l'émulation du FDC afin de pouvoir lire correctement, et sans patch particuliers je précise, les disquettes au formatages atypiques utilisées dans certaines protections. Le travail n'est pas terminé, j'ai encore des fichiers disquettes qui ne passent pas mais c'est bien mieux qu'avant. Cela m'a permis en outre d'optimiser et de nettoyer le code source qui en avait bien besoin.

Je remercie @Lone qui m'a bien aiguillé sur les pistes à prendre. Je confirme le bien fondé de transformer le format DSK en format "Disquette" qui permet, une fois la conversion maitrisée, de bien comprendre le fonctionnement des protections.

Par ailleurs, il y a une anecdote intéressante à raconter. J'ai longtemps été embêté par une protection bien tordue qui consistait à lire un secteur avec une taille déclarée bien supérieure à sa taille réelle. Lors de la lecture de ce secteur, ce sont en fait 3 secteurs tronqués qui sont lus consécutivement (avec des informations normalement non lisibles : ID Adress Mark, octets de synchro...) et en plein milieu de la partie DATA du 3eme secteur se trouvait comme par hasard le CRC adéquat, permettant de terminer la lecture de ce "secteur" sans erreur.
Afin de reproduire une émulation du FDC la plus fidèle possible, il me fallait donc pouvoir calculer à la volée le CRC pour pouvoir la comparer à la valeur lue. Plus facile à dire qu'à faire, j'ai passé pas mal de temps à chercher sur internet à décortiquer les Datasheets pour connaitre la formule utilisée ans le FDC NEc PD765A, sans grand succès.
A défaut, je me suis dis que je ne risquais pas grand chose à utiliser le même algorithme que celui utilisé en ROM du CPC pour calculer le CRC lors d'une lecture d'une cassette. J'essaie ... et ça ne matche pas, sans grande surprise. En désespoir de cause, je jette quand même un coup d’œil sur le code source de "SugarBox", l'émulateur de @Lone et ...quelle ne fut pas ma surprise de voir l'algorithme utilisé était bien semblable à celui que j'utilisais. En fait, mon erreur était de ne pas intégrer dans le calcul du CRC les champs "ID" qui précédent la partie "Data". La lecture de ce petit bout de code de @Lone m'a donc permis de gagner un temps précieux au final..et m'a permis de passer la protection avec succès, sans artifice :)
Il est surprenant de voir que le calcul du CRC utilisé en soft pour vérifier l'intégrité des données "cassette" est identique à celui utilisé en hard dans le FDC pour vérifier l'intégrité des données "disquette". ça devait être un standard à l'époque. :?

En épilogue, petite déception, le jeu en question est bien nul (HIGH EPIDEMY).. tous ces efforts pour ça :D

Outre le volet FDC, j'ai apportés des petites corrections par ci, par là : un bug de lecture du clavier corrigé (mauvaise émulation du AY), un problème aléatoire de rendu graphique lors du changement de taille de la fenêtre de l'émulateur.

Par ailleurs je me suis penché sur l'optimisation de mon code pour voir comment améliorer le rendu sur les vieux processeurs AMD notamment. Il n'y a pas trop de miracle à attendre de ce côté là mais à cette occasion, je me suis aperçu d'un comportement étrange des fonctions "TIMER" utilisés par les API Windows.
On peut programmer leur valeur en milliseconde, avec une valeur minimale de 1, (soit 1 ms). Jusqu'à présent je ne m'étais pas occupé de vérifier la fiabilité de leur chrono, je m'en servais juste pour appeler la routine de scan des touches claviers toutes les 10 ms. Suite à un comportement étrange dans l'émulation du joystick (saccades à l'écran), je me suis aperçu en fait que ces fonctions ne sont pas très fiable et qu'en pratique, les timers sous Windows ont une période minimale de 15-16ms et non pas 1 ms... Bref, j'ai abandonné les timers pour scanner l'état des touches du clavier..
Par contre, comme les timers font gagner beaucoup de ressources CPU, j'ai intégrer une option pour rafraichir l'écran (50 hz) via un appel à la routine via un timer. La régularité de l'affichage est moins précis mais ça fait gagner 10 à 15% de ressource CPU d'après mes essais. Pour les vieux processeurs, c'est mieux que rien. Cette option est désormais présente dans le menu de configuration.

Par ailleurs, côté amélioration, le plein écran est désormais disponible (touche F12), on peut changer de type de moniteur ou de CRTC sans reboot de l'émulateur, pour @ThomasR, une option a été ajoutée pour lire la face B d'un fichier DSK "double face" ;) et ..cerise sur le gâteau, l'émulateur tourne aussi sous Windows 11 aussi puisque j'ai fait la migration de mon PC ce mois-ci.

Cette nouvelle version toute chaude sortie du four (v0.465b) est disponible en téléchargement en première page ). Pour l'instant je laisse les versions précédentes, s'il y a des régressions qui apparaissent...Les administrateurs ne m'en voudront pas trop ;)

N'hésitez pas à me faire des retours, c'est comme cela qu'il s'améliorera dans le temps ;)
Dernière modification par Dmanu78 le 28 nov. 2021 14:11, modifié 1 fois.
Avatar de l’utilisateur
Silou78
Messages : 288
Inscription : 11 févr. 2017 14:54
Localisation : Yvelines (78)

Re: [EMULATION AMSTRAD CPC] AMSpiriT - work in Progress

Message par Silou78 »

Bonsoir,
Concernant les timers sous Windows, pour une précision d'1ms ou moins, il ne faut pas utiliser les timers standard Windows (SetTimer, WM_TIMER), mais les timers multimedia (timeSetEvent, timeBeginPeriod).
Sinon, effectivement, on se retrouve plutôt avec une précision de 15ms (qui est l'intervalle de temps du scheduler multitâches de windows, du moins sous WinNT et WinXP pour des CPU multicoeurs selon mes souvenirs).
En espérant que ça te donne la clé pour améliorer les timers dans AMSpiriT :wink:
Sylvain
Les + malins et les + chanceux sont au sommet, les autres grenouillent.
La vie est un éternel combat contre soi-même.
Avatar de l’utilisateur
hlide
Messages : 2440
Inscription : 29 nov. 2017 10:23

Re: [EMULATION AMSTRAD CPC] AMSpiriT - work in Progress

Message par hlide »

Alors de souvenir, il y avait ça pour que la résolution en période des timers soit le plus petit possible (0.5 ms minimum dans la doc mais c'est sans doute plus tôt 1ms) :

Code : Tout sélectionner

    static ULONG    max_resolution;
    static ULONG    old_resolution;
    ULONG           dummy;

    ::NtQueryTimerResolution(&dummy, &max_resolution, &old_resolution);
    ::NtSetTimerResolution(max_resolution, TRUE, &dummy);
Mais attention, ça un un impact global. J'arrivais à avoir du 1 ms qui était confirmé avec l'outil NvPA (NVIDIA Platform Analyzer).

Pour mettre à 0,5 ms :

Code : Tout sélectionner

#include <windows.h>

extern "C" NTSYSAPI NTSTATUS NTAPI NtSetTimerResolution(ULONG DesiredResolution, BOOLEAN SetResolution, PULONG CurrentResolution);

...

ULONG currentRes;
BOOL successful = (STATUS_SUCCESS == NtSetTimerResolution(5000, TRUE, &currentRes));
successful sera vrai, si la résolution demandée est possible sur la machine.

Sinon, il y aurait ce code qui permettrait d'obtenir une fréquence "très" élevée de 1024 Hz (0,9766 ms) via un callback :

1) Mettre la résolution des timers à 0,9766 ms a priori (à vérifier car ce point n'est pas détaillé).

2) Utiliser KeSetTimer avec une période plus courte (0,9 ms ici) car si on utilise 0,9766 ms, on aura une alternance de période d'appel entre 0.9766 ms et 1.9532 ms (moitié de la fréquence) :

Code : Tout sélectionner

KTIMER        timer;
KDPC          dpc;
PVOID         context;
LARGE_INTEGER period_100ns = {-9000}; // relative time

void createTimer()
{
    KeInitializeDpc(&dpc, callback, context);
    KeInitializeTimerEx(&timer, SynchronizationTimer);
    KeSetTimer(timer, period_100ns, 0, &dpc);
}

VOID callback(PKDPC Dpc,
              PVOID DeferredContext,
              PVOID SystemArgument1,
              PVOID SystemArgument2)
{
    // On relance le callback 0,9 ms plus tard
    KeSetTimer(timer, period_100ns, 0, &dpc);
    
    // Fais ton truc ici
    ...
}
Dernière modification par hlide le 28 nov. 2021 02:08, modifié 1 fois.
Avatar de l’utilisateur
hlide
Messages : 2440
Inscription : 29 nov. 2017 10:23

Re: [EMULATION AMSTRAD CPC] AMSpiriT - work in Progress

Message par hlide »

timeBeginPeriod: "Prior to Windows 10, version 2004, this function affects a global Windows setting."

Intéressant, c'est ce que j'utilisais avant le ::NtSetTimerResolution.
Dmanu78
Messages : 177
Inscription : 20 juin 2020 14:28
Localisation : Yvelines

Re: [EMULATION AMSTRAD CPC] AMSpiriT - work in Progress

Message par Dmanu78 »

Je vous remercie pour vos remarques très intéressantes.
Pour être plus précis, j'utilise la fonction "CreateTimerQueueTimer" pour créer les timers. Cette fonction est recommandée en remplacement de "timeSetEvent" qui est obsolète, dixit la doc de Microsoft.

Mais apparemment depuis WIn10 v2004, on ne peut plus forcer les timing, impossible de descendre en dessous de 16ms.. Bug ?
https://social.technet.microsoft.com/Fo ... n-with-w10

Bon, je ferai avec en attendant :)

Sinon, je viens de mettre un ligne une nouvelle version (v0.466b) corrigeant un bug dans l'émulation du FDC (fonction Read Diagnostic) et un autre bug lorsque l'on modifie certains réglages dans le panneau de configuration.

Normalement, le prochain "gros" chantier d'évolution d'AMSpiriT sera d'intégrer le support de l'écriture sur les disquettes & cassettes. On va enfin pouvoir y sauvegarder nos créations... :)
Dernière modification par Dmanu78 le 28 nov. 2021 22:50, modifié 1 fois.
Lone
Messages : 15
Inscription : 26 nov. 2020 09:53

Re: [EMULATION AMSTRAD CPC] AMSpiriT - work in Progress

Message par Lone »

Hello, j'aime toujours autant tes comptes-rendus, techniques et détaillés.

Concernant le FDC, c'est effectivement un challenge de longue haleine pour tout prendre en compte.
A l'époque, je m'étais concocté une sorte de liste "de non régression" (avec un script permettant de valider que les dumps sont toujours ok).

Si tu es intéressé, je tâcherais de mettre le zip de ces dumps quelque part (pas ici, l'archive faisant dans les 25Mo).

Pour ce qui est de l'optimisation, tout dépend sans doute de ta conception. Pour ma part, j'ai fini par séparé la gestion du rendu des frame et du son sur un thread, ce qui a pas mal amélioré la vitesse globale (surtout sur les CPU modernes à plus de 2 coeurs !).
De même, le gros des lenteurs venait de l'émulation du moniteur. En modifiant cette gestion (en ne faisant un appel tous les 16 pixel plutôt que tous les pixels), j'ai pu passer de 50% de temps dans la routine à quelques %.

J'imagine que tu as passé un petit coup de profiler sur ton soft, mais si tu n'en a pas d'efficace, je ne saurais trop te conseiller de tester "Very Sleepy" (http://www.codersnotes.com/sleepy/ ) ou "Luke Stackwalker" (http://lukestackwalker.sourceforge.net/ dont le nom suffit à lui seul à le propulser au top !).
Avatar de l’utilisateur
ThomasR
Messages : 14
Inscription : 16 janv. 2019 09:02

Re: [EMULATION AMSTRAD CPC] AMSpiriT - work in Progress

Message par ThomasR »

Dmanu78 a écrit : 27 nov. 2021 20:56(..)pour @ThomasR, une option a été ajoutée pour lire la face B d'un fichier DSK "double face" ;) (...)
Hello Dmanu,

thank you very much - I will check it soon on my AMD-CPU-notebook and on the Intel-CPU-notebook I used before,

Best regards,

Thomas
Dmanu78
Messages : 177
Inscription : 20 juin 2020 14:28
Localisation : Yvelines

Re: [EMULATION AMSTRAD CPC] AMSpiriT - work in Progress

Message par Dmanu78 »

@lone.
Merci pour la proposition de cette liste de non régression. ça me sera très utile effectivement. Je ne teste que par échantillonnage "aléatoire" pour l'instant et je pense avoir encore pas mal de soft protégés non testés. On peut se MP si tu veux pour la suite :)

Effectivement, les API système (son, vidéo) sont très gourmands en ressource CPU et les mettre en Thread permet de libérer de précieuses ressources CPU dans la "boucle" principale de l'émulateur afin que celle-ci puisse tourner dans les timing imposés.
Mais d'un autre côté, après avoir passé l'émulateur au "profiler", je me suis aperçu que multiplier les Thread est contre-productif car les Thread en question saturent les "core" utilisés et au global le pourcentage d'utilisation du CPU est plus élevé...Sur un mono ou dual Core, ce n'est pas l'idéal je pense. Sur des processeurs modernes multicores, ça pose moins de problème. C'est pour cela que je laisse le choix maintenant. Selon les configurations, ça pourra aider.

Dans mon cas, seul le rafraichissement de l'affichage vidéo (à 50 frame/s) est désormais dans un thread dédié car celui-ci fait appel à des fonctions Direct2D assez gourmandes. La restitution sonore est directement gérée par l'API X-Audio2 qui, je pense, crée un thread dédié sans que je m'en occupe. Le scan des touches du clavier est désormais directement effectuée dans la boucle principale 100 fois/sec sans que cela est un impact perceptible sur les performances de l'émulateur. L'ensemble permet au final de contenir la consommation CPU, du moins sur un CPU moderne :) .

@ThomasR : It's a pleasure. Tell me the results of your tests :)

PS : J'en ai profité pour faire un nouvel "update" de l'émulateur. Il garde le même numéro (v0.466b) mais j'ai rajouté un petit plus ergonomique : des raccourcis clavier. (F1 pour mettre le jeu en pause / F5 pour charger un fichier DSK / F9 pour switcher l'émulateur joystick au clavier / F12 pour le mode plein écran). Je verrai en en rajouter selon vos préférences. ;)
Répondre