diff options
| author | biouman <> | 2001-04-15 11:20:38 +0000 | 
|---|---|---|
| committer | biouman <> | 2001-04-15 11:20:38 +0000 | 
| commit | dcc24c3645b3878bf3454345dbcfdf7ef1a0ba10 (patch) | |
| tree | 1025dd726c5f75eed5e021a98acf97e6a785916f /lib/simulator.c | |
| parent | 9e44b6dca12c57022d66bd1fe7e9b50c3d741389 (diff) | |
*** empty log message ***
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");  +} + | 
