diff options
Diffstat (limited to 'lib/simulator.c')
-rw-r--r-- | lib/simulator.c | 351 |
1 files changed, 351 insertions, 0 deletions
diff --git a/lib/simulator.c b/lib/simulator.c new file mode 100644 index 0000000..ac1dae4 --- /dev/null +++ b/lib/simulator.c @@ -0,0 +1,351 @@ +#include <stdio.h> + +#ifdef HAVE_CONFIG_H +#include "config.h" +#else +#define _(x) x +#endif + +#include "alu.h" +#include "simulator.h" +#include "interne.h" +#include "registre.h" +#include "memoire.h" +#include "fpu.h" + + + + +// a modifier : Adresse switch 0 c faux +// CALL RET ??? +// verifier le reste + +// initialisation de la MP avec un malloc +// fermeture du prog et free +// catch du ctrl-c + +Uint32 LireInstruction(void) +{ + return (LD(LireRegistrePC())); +} + +void IncrementeCompteurOrdinal(void) +{ + EcrireRegistrePC(AdditionNonSigne(LireRegistrePC(), 1)); +} + +Uint32 Adresse(Uint32 u, Uint32 instruction) +{ + switch (champ(u, 2)) { + case 0: + return (LireRegistre(Champ3(instruction))); /* directement registre A CORRIGER */ + case 1: + IncrementeCompteurOrdinal(); + return (LireInstruction()); + case 2: + return (LireRegistre(Champ3(instruction))); /* Adresse dans registre */ + case 3: + IncrementeCompteurOrdinal(); + return (LireRegistre(Champ3(instruction)) + LireInstruction()); /* Adresse dans registre + decalage de nouvelle instruction */ + default: /* Il exige une loge... */ + return (0); + } +} + +void Initialisation(void) +{ + int i; + + Reset(&Err_Mem); + Reset(&Err_Reg); + for (i = 0; i < TAILLE_MEMOIRE; i++) + Reset(&memoire_principale[i]); + EcrireRegistrePP(ADD_PP); +} + +void Decode(Uint32 instruction) +{ + Uint32 champ_registre_resultat, val1, val2, resultat; + + if (Opcode(instruction) & 0x80) { + fpu(Opcode(instruction)); + } else { + switch (Opcode(instruction)) { + case (0 || 1 || 2 || 3 || 4 || 5):{ + /* ALU */ + champ_registre_resultat = Champ1(instruction); /* Champ du registre dans lequel va etre stocké le résultat */ + val1 = LireRegistre(Champ2(instruction)); /* Premier entier qui va etre utilisé dans l'opération */ + if (ValeurBit(Extension(instruction), 0) == 0) + val2 = LireRegistre(Champ3(instruction)); /* Deuxième entier, stocké dans un registre, qui va etre utilisé dans l'opération */ + else { + IncrementeCompteurOrdinal(); + val2 = LireInstruction(); /* Deuxième entier, stocké après l'instruction, qui va etre utilisé dans l'opération */ + } + if (ValeurBit(Extension(instruction), 1) == 0) /* Teste si l'opération est signée ou pas */ + switch (Opcode(instruction)) { + case 0: + resultat = AdditionNonSigne(val1, val2); + break; + case 1: + resultat = SoustractionNonSigne(val1, val2); + break; + case 2: + resultat = MultiplicationNonSigne(val1, val2); + break; + case 3: + resultat = DivisionNonSigne(val1, val2); + break; + case 4: + resultat = AND(val1, val2); + break; + case 5: + resultat = OR(val1, val2); + break; + case 6: + resultat = SHL(val1); + break; + case 7: + resultat = SHR(val1); + break; + } else + switch (Opcode(instruction)) { + case 0: + resultat = AdditionSigne(val1, val2); + break; + case 1: + resultat = SoustractionSigne(val1, val2); + break; + case 2: + resultat = MultiplicationSigne(val1, val2); + break; + case 3: + resultat = DivisionSigne(val1, val2); + break; + case 4: + resultat = AND(val1, val2); + break; + case 5: + resultat = OR(val1, val2); + break; + case 6: + resultat = SHL(val1); + break; + case 7: + resultat = SHR(val1); + break; + } + EcrireRegistre(champ_registre_resultat, resultat); /* On écrit le résultat dans le registre de sortie */ + break; + } + case 8:{ /* MOV <=> il exige une loge en losange ou la sauje jonche les sieges */ + if (ValeurBit(Extension(instruction), 4) == 1) /* MOV conditionnel */ + if (ValeurBit(Extension(instruction), 5) == 0) /* Test normal */ + switch (champ(Extension(instruction) >> 2, 4)) { /* teste les bits 2 et 3 */ + case 0: + if (Overflow() == 1) + goto fin; + case 1: + if (Zero() == 1) + goto fin; + case 2: + if (Sign() == 1) + goto fin; + case 3: + if (Parity() == 1) + goto fin; + } else /* Negation du test */ + switch (champ(Extension(instruction) >> 2, 4)) { /* teste les bits 2 et 3 */ + case 0: + if (Overflow() == 0) + goto fin; + case 1: + if (Zero() == 0) + goto fin; + case 2: + if (Sign() == 0) + goto fin; + case 3: + if (Parity() == 0) + goto fin; + } + /* Pas de MOV conditionnel */ + if (ValeurBit(Extension(instruction), 1) == 0) /* Mov arg1 arg2 */ + if (ValeurBit(Extension(instruction), 0) == 0) /* arg2 = reg */ + EcrireRegistre(Champ1(instruction), LireRegistre(Champ2(instruction))); + else /* arg2 = imm32 */ if (champ(Champ2(instruction), 4) == 0) + EcrireRegistre(Champ1(instruction), + Adresse(Champ2(instruction), instruction)); + else + EcrireRegistre(Champ1(instruction), + LD(Adresse(Champ2(instruction), instruction))); + else /* Mov arg2 arg1 */ if (ValeurBit(Extension(instruction), 0) == 0) /* arg2 = reg */ + EcrireRegistre(Champ2(instruction), LireRegistre(Champ1(instruction))); + else /* arg1 = imm32 */ if (champ(Champ2(instruction), 4) == 0) + ST(Adresse(Champ2(instruction), instruction), + LireRegistre(Champ1(instruction))); + else + ST(Adresse(Champ2(instruction), instruction), + LireRegistre(Champ1(instruction))); + fin: + break; + } + case 9:{ /* NOP */ + /* Instruction nulle */ + break; + } + case 10: /* J */ + case 11:{ + int test1, test2; + + switch (champ(Extension(instruction), 4)) { + case 0: + test1 = LireRegistre(Champ1(instruction)) == LireRegistre(Champ2(instruction)); + break; + case 1: + test1 = LireRegistre(Champ1(instruction)) != LireRegistre(Champ2(instruction)); + break; + case 2: + test1 = LireRegistre(Champ1(instruction)) < LireRegistre(Champ2(instruction)); + break; + case 3: + test1 = LireRegistre(Champ1(instruction)) <= LireRegistre(Champ2(instruction)); + break; + } + switch (champ(Extension(instruction) >> 2, 4)) { + case 0: + test2 = Overflow(); + break; + case 1: + test2 = Zero(); + break; + case 2: + test2 = Sign(); + break; + case 3: + test2 = Parity(); + break; + } + switch (champ(Extension(instruction) >> 4, 4)) { + case 0: + test1 = test1; + break; + case 1: + test1 = test1 || test2; + break; + case 2: + test1 = test1 && !test2; + break; + case 3: + test1 = test1 || !test2; + break; + } + if (test1) { + IncrementeCompteurOrdinal(); + if (Opcode(instruction) == 10) + EcrireRegistrePC(LireInstruction()); + else + EcrireRegistrePC(AdditionNonSigne(LireRegistrePC(), LireInstruction())); + } + break; + } + case (12): /* JMP *//* Kris Kross */ + case (13): + if (ValeurBit(Extension(instruction), 0) == 0) { + ; /* RET */ + } else if (ValeurBit(Extension(instruction), 1) == 0) ; /* JMP */ + else; /* CALL */ + + break; + case 14:{ /* PUSH */ + Uint32 val; /* valeur qui va etre stockée */ + + EcrireRegistrePP(SoustractionNonSigne(LireRegistrePP(), 1)); /* On pointe sur un emplacement vide */ + if (ValeurBit(Extension(instruction), 0) == 0) + val = LireRegistre(Champ1(instruction)); + else { + IncrementeCompteurOrdinal(); + val = LireInstruction(); + } + ST(LireRegistrePP(), val); + break; + } + case 15:{ /* POP */ + EcrireRegistre(Champ1(instruction), LireRegistrePP()); + EcrireRegistrePP(AdditionNonSigne(LireRegistrePP(), 1)); + break; + } + case 127:{ /* HALT-RESET */ + if (ValeurBit(Extension(instruction), 0)) + getc(stdin); /* Halt */ + else + Initialisation(); /* Reset */ + break; + } + default:{ + printf("soja"); + } + } + } +} +void Traitement(void) +{ + Uint32 instruction; + + while (!0) { + instruction = LireInstruction(); + Decode(instruction); + IncrementeCompteurOrdinal(); + } +} + +void Debogueur(void) // transformer en affiche reg +{ + int i,j; + +/* gotoxy(1, 1); + printf("Etat des registres classiques Etat des registres"); + gotoxy(1, 2); + printf(" speciaux "); + gotoxy(1, 11); + printf(" Instruction a decoder"); + gotoxy(1, 14); + printf(" Prochaine instruction"); + for (i = 1; i <= 16; i++) { + gotoxy(1, i + 2); + printf("r%2d:%9d", i - 1, registre[i - 1]); + } + for (i = 17; i <= 32; i++) { + gotoxy(17, i - 16 + 2); + printf("r%2d:%9d", i - 1, registre[i - 1]); + } + gotoxy(40, 4); + printf("Rg :%9d", LireRegistreRG()); + gotoxy(40, 5); + printf("Rd :%9d", LireRegistreRD()); + gotoxy(40, 6); + printf("PC :%9d", LireRegistrePC()); + gotoxy(40, 7); + printf("Flag :%9d", LireRegistreFLAG()); + gotoxy(40, 12); + printf(" %9d", LireInstruction()); + registre[REG_PC]++; + gotoxy(40, 15); + printf(" %9d", LireInstruction()); + registre[REG_PC]--; + getc(stdin); +*/ + for (i=0; i<=3; i++) { + for (j=1; j<=8;j++) { + printf(" R%02d ", (i*8+j)); + } + printf("\n"); + for (j=1; j<=8;j++) { + printf("%08lX ", (registre[i*8+j-1])); + } + printf("\n"); + + } + printf("Rg: %08lX | Rd: %08lX | Flag: %08lX | PC: %08lX\n", LireRegistreRG(), LireRegistreRD(), LireRegistreFLAG(),registre[REG_PC]); + printf("\n"); +} + |