1. Présentation
1.1. L'idée
1.2. La démarche
1.3. Historique

2. Version Allegro
2.1. Fonctionnalités
2.2. Les touches
2.3. Utilisation
2.4. Captures d'écran
2.5. Téléchargement

3. Version Juce
3.1. Fonctionnalités
3.2. Captures d'écran
3.3. Téléchargement

4. Version DS
4.1. Fonctionnalités
4.2. Téléchargement

5. Quelques snapshots

6. Informations
6.1. Outils utilisés
6.2. Sites utiles
6.3. Documentation

Emulateur ZX Spectrum 48K


1. Présentation
1.1. L'idée

Encore un nième émulateur de ZX Spectrum ?
Pourquoi s'acharner à en réécrire un alors qu'il en existe des dizaines ?

L'idée ici n'est pas uniquement d'en fournir un avec toujours plus de fonctionnalités, mais plutôt d'évaluer la difficulté de réalisation, les connaissances nécessaires à la fois sur la machine elle-même et sur la façon de le programmer.

A la question, pourquoi le "ZX Spectrum", je repondrai simplement qu'il s'agit d'une machine qui a marquée toute une génération et que c'est une machine que j'affectionne tout particulièrement.
En effet, le ZX Spectrum, grand frère du ZX 81 était pourvu de couleurs, de son et disposait de milliers de programmes.
Au jour d'aujourd'hui, il me reste deux ZX Spectrum, mais hélas plus en état de marche.

1.2. La démarche
L'envie de réécrire un émulateur de ZX Spectrum m'est venue après avoir découvert la bibliothèque Allegro. Cette bibliothèque, multi-plateformes (DOS/Windows/Unix ...), est simple à utiliser, bien documentée et possède toutes les fonctions nécessaires à la gestion du graphisme, du son, des entrées sorties, et ce, de manière completement transparente de l'OS utilisé.

Les seules connaissances du ZX Spectrum qu'il me reste sont plutôt vagnes.
Je me souviens de quelques mots-clefs du Basic, de la façon dont la mémoire écran est organisée et de la structure materiélle de la machine.

Commencons.

Première étape
Vérifier que l'on possède tous les outils nécessaires. En l'occurence, un g++, Allegro correctement installé (sous entendu qui fonctionne) et sa documentation, un bon éditeur (XEmacs par exemple ...).

Deuxième étape
Plutôt que de réécrire un simulateur de code Z80 (au coeur du ZX Spectrum), j'ai préféré trouver des sources et les adapter à mon besoin.
Ca n'a rien de compliqué mais c'est terriblement long. Compte-tenu du fait que le Z80 possède plus de 200 instructions, ça fait déjà pas mal de code à taper et à tester.

A titre d'information, j'ai ecrit il y a fort longtemps un simulateur de code 8085, dans le but de mettre au point d'une part, du code assembleur 8085 et d'autre part, de simuler la partie électronique composée de 8255, 8279 ... J'ai fini le simulateur de 8085 mais avec le temps,  j'ai perdu de vue le projet global.

J'ai donc commence par nettoyer le code, l'adapter, le simplifier, le transformer en C++ et le compiler (sans savoir par avance s'il marcherait ou non).

Troisième étape
Ce n'est pas tout d'avoir une classe C++ d'un Z80, il faut le reste autour.
J'ai donc créé les classes ZXSpectrum (la machine), ZXIO (gestion des acces IO In et Out), ZXULA (gestion de l'affichage, du son et du clavier) et ZXMemory (Gestion des accès mémoire).

Le programme instancie les classes, charge le fichier de ROM du ZX Spectrum dans l'objet ZXMemory, affiche une petite fenêtre, et ... c'est tout.
Ensuite, j'ai ajouté deux méthodes appelées séquentiellement (dans un while (1), l'une pour exécuter quelques pas de Z80 et l'autre lire le contenu de mémoire aux adresses correspondants à la zone de mémoire vidéo.
Et la, miracle de l'informatique moderne, j'ai vu apparaître le message "(c) 1982 Sinclair Research Ltd" en bas de la fenêtre. D'accord, la chaîne était écrite à l'envers, en noir sur fond blanc (l'implémentation de la gestion des couleurs n'est venue que le lendemain).

Après cet essai concluant, montrant que le Z80 simulé semblait exécuter des instructions correctes, j'ai ajouté la gestion du clavier.
De manière périodique, je venais écrire quelques bits dans l'objet ZXIO à des adresses connues comme étant les adresses scannées par le Z80 pour la gestion du clavier.
Il ne s'est rien passé. En fait, dans la ROM désassemblée, un commentaire explique que le clavier n'est scanné (les ports IO associés) que lorsque le Z80 reçoit une interruption.
Je procède donc à quelques modifications : j'exécute quelques pas de Z80, je lis le clavier PC pour remplir quelques bits de la zone ZXIO, je simule une interruption Z80 et ... ça marche !

Ensuite, tout c'est fait naturellement (ou presque).
J'ai ajouté la lecture de fichier snapshot (extension .SNA), la gestion de la couleur, quelques optimisations à 1 Euro et le tour était joué.

Si, une remarque tout de même. Bien que la simulation du son du spectrum n'était pas un de mes objectifs, j'ai voulu voir comment je pouvais le résoudre.
L'idée est de donner à une fonction d'Allegro, un buffer contenant les échantillons sonores à envoyer à la carte son.
L'exécution du Z80 simulé n'étant pas temps-reel (pour simplifier, toutes les 20ms on exécute 50000 cycles Z80, on rafraîchit le clavier, l'écran ...), lorsque le Z80 écrit sur le port "son" du ZX Spectrum, on stocke sa valeur ET la valeur du cycle courant du Z80, dans un buffer.
Dans ce cas, toutes les 20ms on a une poignée d'échantillons datés en cycles. Il suffit de remplir le STREAM (256 échantillons joués a 8KHz) en recalant les échantillons dans ce dernier.


1.3. Historique
06/08/2004
  • Optimisation du rafraîchissement de l'écran (blit)
  • Synchronisation par timer
11/08/04
  • Ajout de Pause/Unpause
  • Ajout de la sauvegarde de snapshot .SNA
  • Ajout de la modification de la mémoire
12/08/04
  • Capture d'écran
  • Réorganisation des touches de fonction et aide en ligne
  • Gestion de la couleur "Border"
  • Remapping de KEY_BACKSPACE, KEY_ENTER_PAD, KEY_UP ...
13/08/04
  • Sauvegarde rapide
  • Rechargement rapide
16/08/04
  • Ajout de dialogues pour Save/Load/Poke/Screen
  • Corrections de bugs pour la version Windows
  • Gestion du bit "Bright"
  • Ajout option fullscreen
  • Gestion du bit "Flash"
23/08/04
  • Gestion du son + ajout activation / désactivation du son
24/08/04
  • Ajout de dialogue pour l'aide en ligne
25/08/04
  • Gestion de l'émulation des interfaces joystick : Kempston, Cursor, Sinclair2 joystick
08/10/04
  • Ajout du mode deux joueurs
17/01/2007
  • Refonte complète en utilisant la bibliothèque graphique Juce
2. Version Allegro
2.1. Fonctionnalités

  • ZX Spectrum 48K
  • Chargement / Sauvegarde de Snapshots au format SNA
  • Pause
  • Poke memory
  • Captures d'écran aux formats PCX, BMP et TGA
  • Son
  • Emulation joysticks  Cursor,  Kempston, Sinclair 2
  • Aide en ligne
  • Affichage fenêtré 320x200 ou plein-écran
  • Mode deux joueurs (réseau)
2.2. Les touches
  • F1 : Aide en ligne
  • F2 : Sauvegarde d'un snapshot au format SNA.
  • F3 : Chargement d'un snapshot au format SNA.
  • F4 : Pause/Unpause. Suspend / Reprend l'exécution.
  • F5 : Modification de la mémoire. L'adresse doit être comprise entre 0 et 65535 et la valeur comprise entre 0 et 255.
  • F6 : Capture d'écran au format PCX, BMP et TGA. L'extension du nom de fichier détermine le format de l'image genérée.
  • F7 : Sauvegarde rapide. Le fichier est automatiquement nomme Quick.sna
  • F8 : Chargement rapide. Relit le fichier Quick.sna s'il existe.
  • F9 : Active / Désactive le son.
  • F10 : Change le type d'interface joystick et la façon dont certaines touches sont "remappées".
    No remapping for arrows.
    Arrows for Basic : Les flèches et la touche Backspace sont utilisables dans l'éditeur Basic.
    Arrows for Sinclair 2 interface Joystick 1 : Les flèches et la touche CTRL droite sont remappées pour le mode Sinclair Interface Joystick 1.
    Arrows for Sinclair 2 interface Joystick 2 : Les flèches et la touche CTRL droite sont remappées pour le mode Sinclair Interface Joystick 2.
    Arrows for Cursor interface : Les flèches et la touche CTRL droite sont remappées pour le mode Cursor Interface.
    Arrows for Kempston interface : Les flàches et la touche CTRL droite sont remappées pour le mode Kempston Interface.

  • F12 : Donne la main au deuxième joueur

Touches PC
Touches ZX Spectrum simulées
Mode Interface Joystick
0 - 9 du clavier et 0 - 9 du pavé numérique
0 à 9

a - z
a - z

SHIFT gauche
CAPS SHIFT

Enter du clavier et Enter du pavé numérique
ENTER

SHIFT droite
SYMBOL SHIFT

Backspace
Backspace
- Basic
Flèches
Déplacement




Flèches de déplacement
- Sinclair2 Interface Joystick 1
- Sinclair2 Interface Joystick 2
- Cursor Interface
- Kempston Interface

- Basic
Espace
Space

CTRL droite
Tir

- Sinclair2 Interface Joystick 1
- Sinclair2 Interface Joystick 2
- Cursor Interface
- Kempston Interface

2.3. Utilisation
AllSpec.exe [-fs] [<snapshot.sna>] [-master | -slave <host>]

Par défaut, l'émulation est lancée en mode fenêtré (320x200). L'option -fs permet de lancer l'émulation en mode plein-écran (320x200)

La ROM originale du spectrum doit être dans un fichier nommé spectrum.rom dans le même répertoire que l'exécutable.

En mode multi-joueurs, le premier joueur doit lancer l'émulateur avec l'option -master. Le titre de la fenêtre est "MASTER".
L'autre joueur doit lancer l'émulateur avec l'option -slave, suivie du nom de la machine distante. Le titre de la fenêtre est "SLAVE".

Joueur 1 : AllSpecMS.exe ChuckEgg.sna -master
Joueur 2 : AllSpecMS.exe ChuckEgg.sna -slave odeon

Lorsqu'un joueur (MASTER) veut donner la main, il presse la touche F12. Seul le MASTER peut donner la main. Le SLAVE n'a aucun contrôle sur l'exécution.

2.4. Captures d'écran


2.5. Téléchargement

Sources (Windows / Linux)
Version du 30/08/2004 : AllSpec-30-08.tar.gz
Version du 09/10/2004 (Multi-joueurs) : SpectrumMS.tar.gz

Binaire (Windows)
Version du 30/08/2004 : AllSpecW.zip
L'archive contient l'exécutable, la ROM et la DLL.
Pour installer, créer un répertoire puis dézipper l'archive (Winzip par exemple).

Binaire (Linux) : AllSpecL.tar.gz
L'archive contient l'exécutable, la ROM et la bibliothèque Allegro (liballeg.so.4.0)

Pour installer, faire :
tar xvfz AllSpecL.tar.gz
puis
export LD_LIBRARY_PATH=<le chemin où se trouve la bibliothèque
Allegro>:$LD_LIBRARY_PATH

3. Version Juce
3.1. Fonctionnalités

  • ZX Spectrum 48K
  • Chargement / Sauvegarde de Snapshots au format SNA
  • Pause
  • Poke memory
  • Captures d'écran au format JPG
  • Son
  • Emulation joysticks  Cursor,  Kempston, Sinclair 2
  • Affichage fenêtré 320x200
3.2. Captures d'écran




3.3. Téléchargement
Source Windows : JuceSpectrumSrc.zip
Binaire Windows : JuceSpectrumWinExe.zip

4. Version DS
4.1. Fonctionnalités
Cette application est mon premier développement de Homebrew sur DS.
Il s'agit ici du portage de l'émulateur Spectrum que j'ai réalisé pour Linux/Windows, que j'ai adapté pour la Nintendo DS.

Il a été réalisé avec les outils suivants :
  • devkitARM release 20
  • PAlib070717
  • Linker R4 DS


  • Emulation complète du ZX Spectrum 48K
  • Support des fichiers snapshots au format SNA
  • Gestion du son
  • Clavier virtuel géré au stylet
  • Browsing des fichiers SNA
  • Emulation des interfaces joystick : Sinclair 1&2, Cursor et Kempston
  • Configuration automatique des jeux
  • 50 FPS
  • Chargement possible d'une autre ROM
Pour plus d'informations, voir le fichier README dans le fichier tgz.

4.2. Téléchargement
Sources et Binaires Nintendo DS : SpectrumDS-08.04.2008.tgz

5. Quelques Snapshots au format SNA
C'est par ici ...

6. Informations
6.1. Outils utilisés
  • Z80Em Version 1.2 (04-09-1997) Marcel de Kogel 1996,1997 issu de xmess-0.2b4.1
  • g++ 3.2.3
  • Visual C++ 5.0 & 7.1
  • Allegro 4.0.3
  • Juce 1.39
6.2. Sites utiles

6.3. Documentation