[TUTO]-Base d'un trés simple Emulateur
Publié : lun. 27/déc./2010 16:49
Bonjour,
vous savez surement ce qu'est un émulateur, c'est un programme qui va convertir un code en provenance d'un micro d'ancienne génération, par exemple, et qui va lui redonner une nouvelle jeunesse
Ici il s'agit juste d'émuler du code et de le convertir pour le faire fonctionner sur nos machines actuelles.
Ceci n'est qu'une ébauche et il existe plusieurs façons de programmer un émulateur.
Ici je vais faire intervenir la fonction CallFunctionFast pour appeler des procédures.
Ici nous partons sur 5 opcodes, $01 (pour faire une addition), $02 (soustraction), $03 (multiplication), $04 (division) et $EA qui ne fait rien du tout.
Pour rappel, les opcodes ne sont que des octets mais qui, pour le processeur veulent dire quelque chose, et l'émulateur va les traduire...
Voici donc le code, commenté, on va juste prendre chaque octet dans la mémoire, incrémenter la position dans la mémoire, vérifier s'il correspond à un opcode connu et lancer la procédure qui lui est associée:
On peut rajouter autant de procédures que d'instructions (mais limité quand même à 255) - Si une procédure n'appelle qu'un seul argument, il suffit de faire un appel à la fonction GetMemory() qu'une seule fois, ou s'il n'y a pas d'argument, ne rien faire du tout (Code $EA) 
vous savez surement ce qu'est un émulateur, c'est un programme qui va convertir un code en provenance d'un micro d'ancienne génération, par exemple, et qui va lui redonner une nouvelle jeunesse

Ici il s'agit juste d'émuler du code et de le convertir pour le faire fonctionner sur nos machines actuelles.
Ceci n'est qu'une ébauche et il existe plusieurs façons de programmer un émulateur.
Ici je vais faire intervenir la fonction CallFunctionFast pour appeler des procédures.
Ici nous partons sur 5 opcodes, $01 (pour faire une addition), $02 (soustraction), $03 (multiplication), $04 (division) et $EA qui ne fait rien du tout.
Pour rappel, les opcodes ne sont que des octets mais qui, pour le processeur veulent dire quelque chose, et l'émulateur va les traduire...
Voici donc le code, commenté, on va juste prendre chaque octet dans la mémoire, incrémenter la position dans la mémoire, vérifier s'il correspond à un opcode connu et lancer la procédure qui lui est associée:
Code : Tout sélectionner
;VerySimpleEmulator
;Flaith-27.12.2010
;-Datasection
DataSection
_DS_Memory:
Data.u 34 ;Nombre de données
Data.a $00,$21,$30 ;$00 indique une addition de $21 et de $30
Data.a $00,$F0,$50 ;Additionne $F0 à $50
Data.a $01,$33,$45 ;$01 est une soustraction
Data.a $01,$F0,$53
Data.a $02,$33,$03 ;$02 est une multiplication
Data.a $03,$DE,$45 ;$03 est une division
Data.a $EA ;$EA = NOP ==> ne fait rien du tout
Data.a $EA
Data.a $EA
Data.a $00,$01,$01
Data.a $01,$01,$01
Data.a $02,$01,$01
Data.a $03,$01,$01
Data.a $FF ;Fin du programme
EndDataSection
;-Globals
Global Dim Instruction.i(255) ;Un entier car on conserve l'adresse de chaque procédure
Global Dim Memory.a($FFFF) ;On créé une mémoire de 65535 Octets
Global PC.i ;Program Counter : A quel endroit est notre opcode ? (index)
;-Procédures Internes
; Affiche en hexa
Procedure.s Hexa(__Value.a)
ProcedureReturn RSet(Hex(__Value,#PB_Ascii),2,"0")
EndProcedure
; Récupère un octet dans la mémoire incrémentée automatiquement
Procedure.a GetMemory()
PC + 1
ProcedureReturn Memory(PC)
EndProcedure
;-Procédures liées aux Opcodes
Procedure.a add()
Protected.a a,b
a = GetMemory()
b = GetMemory()
Debug "----Add $"+hexa(a)+" to $"+hexa(b)
ProcedureReturn a+b
EndProcedure
Procedure.a sub()
Protected.a a,b
a = GetMemory()
b = GetMemory()
Debug "----Sub $"+hexa(a)+" to $"+hexa(b)
ProcedureReturn a-b
EndProcedure
Procedure.a mul()
Protected.a a,b
a = GetMemory()
b = GetMemory()
Debug "----Mul $"+hexa(a)+" to $"+hexa(b)
ProcedureReturn a*b
EndProcedure
Procedure.a div()
Protected.a a,b
a = GetMemory()
b = GetMemory()
Debug "----Div $"+hexa(a)+" to $"+hexa(b)
ProcedureReturn a/b
EndProcedure
Procedure.a nop()
Debug "----Nop"
ProcedureReturn $EA
EndProcedure
;Liaison Tableau des instructions avec l'adresse de chaque procédure
Instruction($00) = @add()
Instruction($01) = @sub()
Instruction($02) = @mul()
Instruction($03) = @div()
Instruction($EA) = @nop()
;-Lecture des opcodes et insertion dans la mémoire
Restore _DS_Memory
Read.u longueur
For i = 0 To longueur-1
Read.a aValue
Memory(i) = aValue
Next i
; On commence à zéro
PC = 0
Opcode = Memory(PC)
;-Boucle principale
While Opcode <> $FF
;On appelle les procédures liées aux opcodes
Debug "$"+Hexa(CallFunctionFast(Instruction(Opcode)))
Opcode = GetMemory()
Wend
Debug "----End"
End
