summaryrefslogtreecommitdiff
path: root/lib/archi.c
diff options
context:
space:
mode:
Diffstat (limited to 'lib/archi.c')
-rw-r--r--lib/archi.c349
1 files changed, 349 insertions, 0 deletions
diff --git a/lib/archi.c b/lib/archi.c
new file mode 100644
index 0000000..cb8bb4a
--- /dev/null
+++ b/lib/archi.c
@@ -0,0 +1,349 @@
+#include <stdio.h>
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#else
+#define _(x) x
+#endif
+
+#include "alu.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");
+}
+