Winape est un très bon émulateur de CPC sous Windows. Mais
il possède en plus quelques fonctions intéressantes comme… un assembleur !
En effet, ce logiciel permet d’écrire simplement des programmes en assembleur,
puis de les compiler (c’est à dire les transformer en code machine
compréhensible par le microprocesseur) directement en mémoire. Et, ô
magie !, ils sont ensuite exécutables par un simple CALL sous l’écran
BASIC (voir ci-dessous).
On peut trouver cet émulateur, dans sa version 2.0a6,
directement à la source :
http://winape.emuunlim.com/download/WinAPE20A6.zip
Mais attention, pour bénéficier du clavier AZERTY et des
caractères français sous l’écran BASIC, il faut en plus la ROM française.
Toutefois l’assembleur s’utilise normalement, c’est à dire avec le clavier PC.
L’assembleur de Winape est directement accessible avec la
touche F6 (du clavier PC, pas du CPC). Une fenêtre apparaît alors, avec la
gestion de fichier pour les sauvegardes, l’édition de texte, la compilation
puis l’aide.
L’assembleur de WINAPE est compatible MAXAM 1.5 (un célèbre
assembleur CPC). Il en possède donc les directives de compilation.
Les directives de compilation sont des instructions propre
au compilateur. Ici ce sont celles de MAXAM, donc attention :
TOUS LES PROGRAMMES ECRITS EN ASSEMBLEUR POUR LE CPC NE
FONCTIONNERONT PAS FORCEMMENT SOUS WINAPE SANS UNE CERTAINE ADAPTATION .
Ceci peut se vérifier notamment avec la notation hexadécimale.
Sous WINAPE/MAXAM, elle est notée par exemple &FF ou #FF pour le nombre
hexadécimal FF (255 en décimal). Mais certains programmes ont utilisé la
notation 0FFh, avec un 0 devant et un h derrière donc. Ces programmes doivent
alors être adaptés pour tourner sous WINAPE.
Toutefois, les directives sont généralement cohérentes d’un
compilateur à un autre et les exemples que celui là sont peu nombreux.
Cette instruction, contrairement à ce que certains pensent,
ne sert pas à définir l’adresse de début du programme compilé, mais l’adresse
de la prochaine instruction compilée. En effet, rien n’empêche de l’utiliser
plusieurs fois au court d’un programme (pour fixer l’adresse de fonctions par
exemple).
ORG &4000
DB &FF
Une fois compilé, le programme placera l’octet &FF à
l’adresse mémoire &4000. Voir ci-dessous pour l’instruction DB. Autre
exemple :
DEBUT EQU &4000
ORG DEBUT
DB &FF
La directive EQU permettant de remplacer un nombre par une
expression, on aura toujours notre octet &FF placé à l’adresse &4000.
Et enfin :
FONCTION1 EQU &4000
FONCTION2 EQU &4002
ORG FONCTION1
DB &FF
ORG
FONCTION2
DB &FF
Place &FF aux adresse &4000 et &4002. Il n’y
aura rien en &4001, mais le programme aura bien une longueur de 3 octets quand
même.
Il existe aussi la directive :
ORG <expression
1>,<expression 2>
Permet de stocker le programme à l’adresse indiquée par
<expression 2>, mais de l’exécuter à l’adresse indiquée par
<expression 1>. Le programme pourra ensuite être sauvegardé à partir de
la 2ème adresse, mais le programme aura quand même été compilé avec
la 1ère adresse comme référence. Cette astuce, inutile aujourd’hui
avec WINAPE, permettait de charger MAXAM en mémoire CPC sans occuper
l’emplacement réel du programme compilé.
Permet de limiter la taille d’un programme (pour qu’il
n’écrase pas la zone suivante par exemple). Si le programme dépasse, le
compilateur indique une erreur.
LIMIT 100
Le programme ne pourra pas dépasser 100 octets.
Permettent (CODE) ou ne permettent pas (NOCODE) de compiler
le code suivant l’expression. Ceci peut servir à occulter certaines parties du
programme qui seraient fausses ou incomplètes, mais en permettant de tester le
reste.
Le compilateur s’arrête quand il rencontre cette expression.
Les nombres sont notés de la manière suivante :
Décimal : 255
Hexadécimal : &FF ou #FF (préférez toutefois
&FF)
Binaire : %11111111
Les caractères : ‘a’ ou ‘’a’’. Dans ce cas pour ‘’ on
utilisera les apostrophes (‘ ‘’ ‘) et pour les apostrophes on utilisera les
guillemets (‘’ ‘ ‘’).
Les phrases : ‘’CPC6128’’, entre guillemets donc.
Les opérateurs arithmétiques : +,-,*,/,MOD (Comme en
basic)
Les opérateurs logiques (à ne pas confondre avec les
mnémoniques Z80) : AND, OR, XOR
Permet de pointer un endroit dans le programme, pour pouvoir
y faire des sauts ou pour récupérer des données.
ORG &4000
Ld hl,DATA
Ld a,(hl)
…
DATA DB &FF
Quelque soit l’emplacement de DATA dans le programme, hl
sera chargé avec son adresse. Puis l’accumulateur A sera chargé avec le contenu
de cette adresse, soit &FF.
jp SAUT
…
SAUT ld a,(hl)
L’instruction jp saute à l’adresse indiquée par SAUT.
Cette directive entrevue plus haut, permet de remplacer un
nombre par une expression.
DATA EQU &4000
Ld hl,DATA
Hl contiendra le nombre hexadécimal &4000
Comme nous l’avons vu avec la directive DB, il est possible
de réserver un emplacement mémoire dans le programme, pour y placer des données
prédéfinies ou non
DB (define BYTE) : Permet de remplir la
mémoire avec des octets
DATA DB &FF, ‘a’, 0,
‘’COUCOU’’
À l’emplacement mémoire DATA, DB a permis le stockage du
nombre &FF, puis du nombre représenté par le code ascii de ‘a’, puis le
nombre 0, puis des nombres représentés par les codes ascii de la chaîne
‘’COUCOU’’.
Cette directive peut aussi être remplacée par les
expressions BYTE, TEXT,
DEFB et DEFM, moins utilisées cependant.
DW (define
WORD): Permet de
remplir la mémoire avec des “mots” binaires, c’est à dire des nombres de 16
bits.
DATA DW &4000,
15200, %1001110100001111
Attention,
chaque donnée prenant 2 octets, il faudra incrémenter de 2 le registre servant
d’indexage pour aller les chercher en mémoire.
Cette
expression peut aussi être remplacée par DEFW ou WORD, moins utilisés
cependant.
DS
(define string) : Permet de réserver un bloc mémoire.
DATA DS 10
Réserve 10
octets à partir de l’adresse de DATA
DATA DS 10,&FF
Réserve 10
octets et les initialise tous à &FF. On aura alors 10 &FF à partir de
l’adresse de DATA.
Il est possible d’assembler un programme en fonction d’une
condition ou d’un numéro de version.
CPC464 EQU 0
CPC664 EQU 0
CPC6128 EQU 1
IF CPC464
Bloc programme pour le
CPC464
ELSE : IF CPC664
Bloc
programme pour le CPC664
ELSE
Bloc
programme pour le CPC6128
ENDIF
ENDIF
En fait, l’expression après le IF est considérée comme un
nombre de 16 bits. La condition est vraie s’il est strictement positif
(&0001 à &7FFF), et fausse sinon (&0000 ou &8000 à &FFFF).
Pour mieux s’y retrouver quand on écrit un programme, il est
préférable de bien le commenter. C’est encore plus vrai si quelqu’un doit passer
derrière pour relire. Les commentaires ne sont jamais compilés, on peut donc en
mettre tant qu’on veut sans que ça augmente la taille du programme. Ils sont
indiqués par un point virgule :
ORG &4000
; ******************************
; * Mon
programme à moi *
; ******************************
ld hl,DATA ;
HL pointe les données
…
On va donc dans l’assembleur et on tape le programme
suivant :
; Programme permettant l’affichage d’une phrase
ORG
&4000
LD
HL,TEXTE ;HL pointe le début de
phrase
BOUCLE LD A,
(HL) ;A <- caractère pointé pas HL.
OR A ;A <- A OU A (détection de 0)
RET Z ;retour de programme si A = 0
CALL &BB5A ;vecteur d’affichage d’un caractère
INC HL ;HL pointe le caractère suivant
JR BOUCLE ;revient à BOUCLE
TEXTE DB "AMSTRAD CPC",0
Ce programme commence par faire pointer HL sur le début de
la phrase étiquetée par TEXTE, soit le 1er A.
Puis on forme une boucle qui lira tous les caractères de la
phrase, jusqu’à ce que le nombre 0 soit détecté (celui qui se trouve après
l’expression ‘’AMSTRAD CPC’’). Pour cela, on place le caractère courant dans A,
puis on fait un masque OU avec lui même. Sachant que les codes ASCII contenus
dans la phrase sont forcément différents de 0, ils contiennent donc au moins un
1 binaire. Ce qui fait que le OU entraînera alors la mise à 0 du flag Z (1 si
détection de 0). L’instruction RET Z permet de terminer le programme si Z = 1, donc tous les
caractères seront lus. Le vecteur &BB5A permet ensuite d’afficher le
caractère contenu dans A, donc avec la boucle il affichera toute la phrase. HL
est ensuite incrémenté pour pointer le caractère suivant. Et on reboucle avec
le JR BOUCLE.
On fait CTRL + F9, ce qui compile le programme en mémoire (à
l’adresse &4000 donc).
On revient ensuite sous BASIC, et on tape :
CALL &4000
Et ô joie, la phrase ‘’AMSTRAD CPC’’ s’affiche sur notre bel
écran bleu, magique non ? Sachant que le programme compilé fait &17
octets, soient 23 octets en décimal, on peut le sauvegarder sur disquette de la
manière suivante :
SAVE
‘’texte.bin’’,b,&4000,23
Vous pourrez ensuite le reprendre en faisant :
10 MEMORY &3FFF
20 LOAD
“texte.bin”,&4000
30 CALL &4000
RUN
La ligne 10 limite la taille réservée au basic juste en
dessous du programme à charger. La ligne 20 charge le programme binaire à
l’adresse &4000, puisque c’est à cette adresse qu’il a été compilé. Et la ligne
30 appelle ce programme.
Attention : un programme compilé à une
certaine adresse doit ensuite être relogé et exécuté à cette adresse. En effet,
l’assembleur s’est basé par rapport à celle-ci pour faire tous ses calculs
d’étiquettes. Si vous changez l’adresse, vous risquez donc un super plantage.