En C il est aise de definir des structures.On utilisera donc un type de donnee
proche du type REGS (ceux qui connaissent un peu le C sur PC doivent connaitre cette
structure) pour definir la globalite des registres.Par exemple:
typedef register_68000 |
{ |
int D0,D1,D2,D3,D4,D5,D6,D7; // registres de donnes |
int A0,A1,A2,A3,A4,A5,A6,A7; // registres d'adresse |
int flag; // registre flag |
int PC; // programm counter |
int USP,SSP; // registres de piles (! idem A7) |
} register_68000; |
Generalement l'instruction se presente sous la forme
Opcode (8 bits 16 bits,32 bits....) | Operande1 | Operande2 | .... | Opcode suivant |
if (OPCODE=code1) {... traiteemnt de l'opcode code1} |
else if (OPCODE=code2) {.. traitement de l'opcode code2} |
... |
else {... traitement du dernier opcode ...} |
if (opcode&0x8) | |||
{if (opcode&0x4) | |||
{ if (opcode&0x2) | |||
{if (opcode&0x1){...traite opcode 0xF} | |||
else {traite opcode 0xE}} | |||
else | |||
{if (opcode&0x1){...traite opcode 0xD} | |||
else {traite opcode 0xC}}} | |||
else | |||
{ if (opcode&0x2) | |||
{if (opcode&0x1){...traite opcode 0xB} | |||
else {traite opcode 0xA}} | |||
else | |||
{if (opcode&0x1){...traite opcode 0x9} | |||
else {traite opcode 0x8}}}} | |||
else | |||
{if (opcode&0x4) | |||
{ if (opcode&0x2) | |||
{if (opcode&0x1){...traite opcode 0x7} | |||
else {traite opcode 0x6}} | |||
else | |||
{if (opcode&0x1){...traite opcode 0x5} | |||
else {traite opcode 0x4}}} | |||
else | |||
{ if (opcode&0x2) | |||
{if (opcode&0x1){...traite opcode 0x3} | |||
else {traite opcode 0x2}} | |||
else | |||
{if (opcode&0x1){...traite opcode 0x1} | |||
else {traite opcode 0x0}}}} |
Le nombre d'operandes depend de l'opcode.
Neanmoins il faut extraire les opcodes et placer le PC apres la derniere opcode extraite !!!
On utilise POPERANDE, pour cela !!!
On ecrit en memoire les resultats et on modifie les flags !!!
tous les pointeur PC,Adresse etc... sont relatifs au CPU emul , mais pas a la machine
qui effectue l'emulation. On peut utiliser plusieurs methodes pour reprensenter la memoire
de la machine.
On distinguera le cas ou la machine a peu de RAM (64k) comme le CPC 464 et
l'utilise de maniere lineaire.
A ce moment la,ont peut utiliser un tableau lineaire de memoire, comme
char* memoireCPC464=(char*)malloc(65536);
Sinon on utilise une structure complexe: Ondivise la memoire en section ou pages, par exemple
sur amiga on pourra diviser la memoire en plusieurs tableaux: ChipMem,SlowMem,Customchips,CIAs
FastMem,... que l'on stockera separement.
Puis au sein de l'emulateur on retournera pour une adresse memoire de la machine emulee
un pointeur sur une case memoire reelle de la memoire de la machine qui emule.Par exemple:
void* memory_mapping(int mem_emule); |
... |
*((short*)memory_mapping(0xdff180))=0xFFF; |