@@ -0,0 +1,41 @@
#
# Makefile for the Linux simulator
#
########################################################

PROGRAM = Simulator

# Compilation Details
SHELL = /bin/sh
CC = cc
STDCFLAGS = -g -c -Wall
INCLUDES =
LIBRARIES =

${PROGRAM}: Simulator.o ComputerSystem.o MainMemory.o OperatingSystem.o Processor.o Buses.o Messages.o
$(CC) -o ${PROGRAM} Simulator.o ComputerSystem.o MainMemory.o OperatingSystem.o Processor.o Buses.o Messages.o $(LIBRARIES)

Simulator.o: Simulator.c Simulator.h
$(CC) $(STDCFLAGS) $(INCLUDES) Simulator.c

Messages.o: Messages.c Messages.h
$(CC) $(STDCFLAGS) $(INCLUDES) Messages.c

ComputerSystem.o: ComputerSystem.c ComputerSystem.h
$(CC) $(STDCFLAGS) $(INCLUDES) ComputerSystem.c

MainMemory.o: MainMemory.c MainMemory.h
$(CC) $(STDCFLAGS) $(INCLUDES) MainMemory.c

OperatingSystem.o: OperatingSystem.c OperatingSystem.h
$(CC) $(STDCFLAGS) $(INCLUDES) OperatingSystem.c

Processor.o: Processor.c Processor.h
$(CC) $(STDCFLAGS) $(INCLUDES) Processor.c


Buses.o: Buses.c Buses.h
$(CC) $(STDCFLAGS) $(INCLUDES) Buses.c

clean:
rm -f $(PROGRAM) *.o *~ core
@@ -0,0 +1,57 @@
#include "Messages.h"

#include <stdio.h>
#include <string.h>

#define MSGMAXIMUMLENGTH 132
#define MESSAGES_FILE "messages.txt"
#define NUMBEROFMSGS 64



int Messages_Load_Messages() {
char lineRead[MSGMAXIMUMLENGTH];
FILE *mf;
char *number, *text;
int msgNumber;
int lineNumber=0;;
int numberErrorMessages=0;
int rc;

mf=fopen(MESSAGES_FILE, "r");
if (mf==NULL) {
printf("Verbose messages unavailable\n");
return -1;
}

while (fgets(lineRead, MSGMAXIMUMLENGTH, mf) != NULL) {
lineNumber++;
number=strtok(lineRead,",");
rc=sscanf(number,"%d",&msgNumber);
if (rc==0){
printf("Illegal Message Number in line %d of file %s\n",lineNumber,MESSAGES_FILE);
continue;
}

text=strtok(NULL,"\n");
if (text==NULL){
printf("Illegal Message Format in line %d of file %s\n",lineNumber,MESSAGES_FILE);
continue;
}
strcpy(DebugMessages[numberErrorMessages].format,text);
DebugMessages[numberErrorMessages++].number=msgNumber;


}
fclose(mf);
return numberErrorMessages;
}

int Messages_Get_Pos(int number) {
int pos;

for (pos=0; DebugMessages[pos].number !=-1; pos++)
if (DebugMessages[pos].number==number) return pos;

return -1;
}
@@ -0,0 +1,17 @@
#ifndef MESSAGES_H
#define MESSAGES_H

#define NUMBEROFMSGS 64

typedef struct {
int number;
char format[60];
} DEBUG_MESSAGES;

DEBUG_MESSAGES DebugMessages[NUMBEROFMSGS];

int Messages_Get_Pos(int number);
int Messages_Load_Messages();

#endif

@@ -0,0 +1,68 @@
#include "OperatingSystem.h"
#include "MainMemory.h"
#include "Processor.h"
#include "Buses.h"
#include <stdio.h>
#include <string.h>
#include <ctype.h>
#include <stdlib.h>

// Function that processes the contents of the file named by the first argument
// in order to load it in main memory from the address given as the second
// argument
// IT IS NOT NECESSARY TO COMPLETELY UNDERSTAND THIS FUNCTION

int OperatingSystem_LoadProgram(FILE *programFile, int initialAddress) {

char lineRead[LINEMAXIMUMLENGTH];
char *token0, *token1, *token2;
int isComment=1;
int programSize;
MEMORYCELL data;

// Read the first number as the size of the program. Skip all comments.
while (isComment==1) {
if (fgets(lineRead, LINEMAXIMUMLENGTH, programFile) == NULL) {
return PROGRAMNOTVALID;
}
else
if (lineRead[0]!='/') { // Line IS NOT a comment
isComment=0;
programSize=atoi(strtok(lineRead," "));
if (programSize>MAINMEMORYSIZE)
return PROGRAMNOTVALID;
}
}

Processor_SetMAR(initialAddress);
while (fgets(lineRead, LINEMAXIMUMLENGTH, programFile) != NULL) {
// REMARK: if lineRead is greater than TAMANIOMAXIMOLINEA in number of characters, the program
// loading does not work
data.operationCode=' '; data.operand1=data.operand2=0;
token0=strtok(lineRead," ");
if ((token0!=NULL) && (token0[0]!='/')&& (token0[0]!='\n')) {
// I have an instruction with, at least, an operation code
data.operationCode=tolower(token0[0]);
token1=strtok(NULL," ");
if ((token1!=NULL) && (token1[0]!='/')) {
// I have an instruction with, at least, an operand
data.operand1=atoi(token1);
token2=strtok(NULL," ");
if ((token2!=NULL) && (token2[0]!='/')) {
// The read line is similar to 'sum 2 3 //coment'
// I have an instruction with two operands
data.operand2=atoi(token2);
}
}

Processor_SetMBR(&data);
// Send data to main memory using the system buses
Buses_write_DataBus_From_To(CPU, MAINMEMORY);
Buses_write_AddressBus_From_To(CPU, MAINMEMORY);
// Tell the main memory controller to write
MainMemory_writeMemory();
Processor_SetMAR(Processor_GetMAR()+1);
}
}
return SUCCESS;
}
@@ -0,0 +1,15 @@
#ifndef OPERATINGSYSTEM_H
#define OPERATINGSYSTEM_H

#include <stdio.h>

#define SUCCESS 1
#define PROGRAMDOESNOTEXIST -1
#define PROGRAMNOTVALID -2

#define LINEMAXIMUMLENGTH 150

// Functions prototypes
int OperatingSystem_LoadProgram(FILE *, int);

#endif
@@ -0,0 +1,167 @@
#include "Processor.h"
#include "ComputerSystem.h"
#include "Buses.h"
#include "MainMemory.h"
#include <stdio.h>
#include <string.h>
#include <stdlib.h>

// Local Functions prototypes
void Processor_FetchInstruction();
void Processor_DecodeAndExecuteInstruction();
void Processor_ManageInterrupts();


// Processor registers
int registerPC_CPU; // Program counter
int registerAccumulator_CPU; // Accumulator
MEMORYCELL registerIR_CPU; // Instruction register
unsigned int registerPSW_CPU; // Processor state word
int registerMAR_CPU; // Memory Address Register
MEMORYCELL registerMBR_CPU; // Memory Buffer Register

// Initialize processor registers
void Processor_InitializeRegisters(int regPC, int regAcum, unsigned int regPSW) {
registerPC_CPU=regPC;
registerAccumulator_CPU=regAcum;
registerPSW_CPU=regPSW;
}

// This is the instruction cycle loop (fetch, decoding, execution, etc.).
// The processor stops working when an POWEROFF signal is stored in its
// PSW register
void Processor_InstructionCycleLoop() {

while (registerPSW_CPU!=POWEROFF) {
Processor_FetchInstruction();
Processor_DecodeAndExecuteInstruction();
Processor_ManageInterrupts();
}
}

// Fetch an instruction from main memory and put it in the IR register
void Processor_FetchInstruction() {

// The instruction must be located at the memory address pointed by the PC register
registerMAR_CPU=registerPC_CPU;
// Send to the main memory controller the address in which the reading has to take place: use the address bus for this
Buses_write_AddressBus_From_To(CPU, MAINMEMORY);
// Tell the main memory controller to read
MainMemory_readMemory();
// All the read data is stored in the MBR register. Because it is an instruction
// we have to copy it to the IR register
memcpy((void *) (&registerIR_CPU), (void *) (&registerMBR_CPU), sizeof(MEMORYCELL));
// Show initial part of HARDWARE message with Operation Code and operands
ComputerSystem_DebugMessage(1, HARDWARE, registerIR_CPU.operationCode, registerIR_CPU.operand1, registerIR_CPU.operand2);

}

// Decode and execute the instruction in the IR register
void Processor_DecodeAndExecuteInstruction() {

switch (registerIR_CPU.operationCode) {

// Instruction ADD
case 'a': registerAccumulator_CPU= registerIR_CPU.operand1 + registerIR_CPU.operand2;
registerPC_CPU++;
break;

// Instruction SUB
case 's': registerAccumulator_CPU= registerIR_CPU.operand1 - registerIR_CPU.operand2;
registerPC_CPU++;
break;


// Instruction NOP
case 'n': registerPC_CPU++;
break;

// Instruction JUMP
case 'j': registerPC_CPU+= registerIR_CPU.operand1;
break;

// Instruction ZJUMP
case 'z': if (registerAccumulator_CPU==0)
registerPC_CPU+= registerIR_CPU.operand1;
else
registerPC_CPU++;
break;

// Instruction WRITE
case 'w': registerMBR_CPU.operationCode= registerMBR_CPU.operand1= registerMBR_CPU.operand2= registerAccumulator_CPU;
registerMAR_CPU=registerIR_CPU.operand1;
// Send to the main memory controller the data to be written: use the data bus for this
Buses_write_DataBus_From_To(CPU, MAINMEMORY);
// Send to the main memory controller the address in which the writing has to take place: use the address bus for this
Buses_write_AddressBus_From_To(CPU, MAINMEMORY);
// Tell the main memory controller to write
MainMemory_writeMemory();
registerPC_CPU++;
break;

// Instruction READ
case 'r': registerMAR_CPU=registerIR_CPU.operand1;
// Send to the main memory controller the address in which the reading has to take place: use the address bus for this
Buses_write_AddressBus_From_To(CPU, MAINMEMORY);
// Tell the main memory controller to read
MainMemory_readMemory();
// Copy the read data to the accumulator register
registerAccumulator_CPU= registerMBR_CPU.operand1;
registerPC_CPU++;
break;

// Instruction INC
case 'i': registerAccumulator_CPU+= registerIR_CPU.operand1;
registerPC_CPU++;
break;

// Instruction HALT
case 'h': registerPSW_CPU=POWEROFF;
break;

//Instruction MEMADD
case 'm': registerMAR_CPU=registerIR_CPU.operand1;
// Send to the main memory controller the address in which the reading has to take place: use the address bus for this
Buses_write_AddressBus_From_To(CPU, MAINMEMORY);
// Tell the main memory controller to read
MainMemory_readMemory();
//Perform the addition
registerAccumulator_CPU = registerIR_CPU.operand1 + registerIR_CPU.operand2;
registerPC_CPU++;
break;

// Unknown instruction
default : registerPC_CPU++;
break;
}
// Show final part of HARDWARE message with CPU registers
ComputerSystem_DebugMessage(3,HARDWARE,registerPC_CPU,registerAccumulator_CPU, registerPSW_CPU);
}

// Hardware interrup processing
// Our primitive processor DOES NOT SUPPORT interrupts
void Processor_ManageInterrupts() {

}

// Getter for the registerMAR_CPU
int Processor_GetMAR() {
return registerMAR_CPU;
}

// Setter for the registerMAR_CPU
void Processor_SetMAR(int data) {
registerMAR_CPU=data;
}

// pseudo-getter for the registerMBR_CPU
void Processor_GetMBR(MEMORYCELL *toRegister) {
memcpy((void*) toRegister, (void *) (&registerMBR_CPU), sizeof(MEMORYCELL));
}

// pseudo-setter for the registerMBR_CPU
void Processor_SetMBR(MEMORYCELL *fromRegister) {
memcpy((void*) (&registerMBR_CPU), (void *) fromRegister, sizeof(MEMORYCELL));
}


@@ -0,0 +1,18 @@
#ifndef PROCESSOR_H
#define PROCESSOR_H

#include "MainMemory.h"

#define POWEROFF 1

// Functions prototypes
void Processor_InitializeRegisters(int, int, unsigned int);
void Processor_InstructionCycleLoop();

// Buses needs to access MAR and MBR
int Processor_GetMAR();
void Processor_SetMAR(int);
void Processor_GetMBR(MEMORYCELL *);
void Processor_SetMBR(MEMORYCELL *);

#endif
BIN +30.5 KB V0/Simulator
Binary file not shown.
@@ -0,0 +1,24 @@
#include <stdio.h>
#include <stdlib.h>
#include "Simulator.h"
#include "ComputerSystem.h"


int main(int argc, char *argv[]) {

// Our Computer System is very primitive. It is monoprogrammed
// so it can only execute one program per simulation session.
// The program to be executed is specified in the function
// ComputerSystem_PowerOn()

if (argc != 2) {
printf("USE: Simulator <sections to be debugged>\n");
exit(-1);
}

// The simulation starts
ComputerSystem_PowerOn(argc, argv);
// The simulation ends
ComputerSystem_PowerOff();
return 0;
}
@@ -0,0 +1,14 @@
#ifndef SIMULATOR_H
#define SIMULATOR_H


// Overall constants

// Monoprogrammed system (a very primitive one)
#define MAXNUMPROCESSES 1

// Maximum number of user programs in command line (not used in this version)
#define MAXNUMUSERPROGRAMS 20


#endif
BIN +6.76 MB V0/core
Binary file not shown.
@@ -0,0 +1,3 @@
1,%c %d %d
3,(PC: @R%d@@, Accumulator: @R%d@@, PSW: @R%d@@)\n
4,(@REND of the simulation@@)\n
@@ -0,0 +1,7 @@
// Mi primer programa
55 // Tamanio del programa en posiciones de memoria
MEM ADD 10 0
INC -1
ZJUMP 2 // Si el registro acumulador==0, saltar dos posiciones de memoria hacia adelante
JUMP -2 // Saltar dos posiciones de memoria hacia atr�s
HALT
@@ -0,0 +1,32 @@
# 1 "MyAspect.c"
# 1 "<built-in>"
# 1 "<command-line>"
# 1 "/usr/include/stdc-predef.h" 1 3 4
# 1 "<command-line>" 2
# 1 "MyAspect.c"
# 1 "Clock.h" 1




void Clock_Update();
int Clock_GetTime();
# 2 "MyAspect.c" 2
# 1 "Asserts.h" 1
# 37 "Asserts.h"
int Asserts_LoadAsserts();
void Asserts_CheckAsserts();
# 3 "MyAspect.c" 2


before(): execution(void Processor_FetchInstruction()) {
Clock_Update();
}

after(): execution(void Processor_DecodeAndExecuteInstruction()){
Asserts_CheckAsserts();
}

before(): execution(void OperatingSystem_InterruptLogic(int)){
Clock_Update();
}
@@ -0,0 +1,79 @@

struct JoinPoint {
void** (*fp) (struct JoinPoint *);
void ** args;
int argsCount;
const char ** argsType;
void * (*arg)(int, struct JoinPoint *);
const char * (*argType)(int , struct JoinPoint *);
void ** retValue;
const char * retType;
const char * funcName ;
const char * targetName ;
const char * fileName ;
const char * kind ;
void * excep_return ;
};

struct __UTAC__EXCEPTION {
void * jumpbuf ;
unsigned long long int prtValue ;
int pops;
struct __UTAC__CFLOW_FUNC {
int (*func)(int,int) ;
int val ;
struct __UTAC__CFLOW_FUNC * next;
} * cflowfuncs;
};

extern void __utac__exception__cf_handler_set(void * exception, int (*cflow_func)(int, int), int val) ;
extern void __utac__exception__cf_handler_free(void * exception);
extern void __utac__exception__cf_handler_reset(void * exception) ;
extern void * __utac__error_stack_mgt(void * env , int mode, int count) ;

# 1 "MyAspect.c"
# 1 "<built-in>"
# 1 "<command-line>"
# 1 "/usr/include/stdc-predef.h" 1 3 4
# 1 "<command-line>" 2
# 1 "MyAspect.c"
# 5 "Clock.h" 1
void Clock_Update();
#line 6 "Clock.h"
int Clock_GetTime();
# 2 "MyAspect.c" 2
# 1 "Asserts.h" 1
# 37 "Asserts.h"
int Asserts_LoadAsserts();
#line 38 "Asserts.h"
void Asserts_CheckAsserts();
#line 5 "MyAspect.c"
inline void __utac_acc__Aspect__1(void) {



#line 6 "MyAspect.c"
Clock_Update(); }


#line 9 "MyAspect.c"
inline void __utac_acc__Aspect__2(void) {



#line 10 "MyAspect.c"
Asserts_CheckAsserts(); }


#line 13 "MyAspect.c"
inline void __utac_acc__Aspect__3(void) {



#line 14 "MyAspect.c"
Clock_Update(); }





@@ -0,0 +1,339 @@
#include "Asserts.h"
#include <string.h>
#include <stdio.h>
#include "MainMemory.h"
#include "Clock.h"
#include "ComputerSystemBase.h"
#include "MMU.h"

extern MEMORYCELL mainMemory[];
extern int registerPC_CPU; // Program counter
extern int registerAccumulator_CPU; // Accumulator
extern MEMORYCELL registerIR_CPU; // Instruction register
extern unsigned int registerPSW_CPU; // Processor state word
extern int registerMAR_CPU; // Memory Address Register
extern MEMORYCELL registerMBR_CPU; // Memory Buffer Register
extern int executingProcessID; // Executing process PID


char *elements[]={
"RMEM_OP",
"RMEM_O1",
"RMEM_O2",
"AMEM_OP",
"AMEM_O1",
"AMEM_O2",
"PC",
"ACC",
"IR_OP",
"IR_O1",
"IR_O2",
"PSW",
"MAR",
"MBR_OP",
"MBR_O1",
"MBR_O2",
"MMU_BS",
"MMU_LM",
"MMU_MAR",
"MMEM_MAR",
"MMBR_OP",
"MMBR_O1",
"MMBR_O2",
"XPID",
NULL};

struct assert {
int time;
int value;
char element[E_SIZE]; // Se almacenará lo arriba indicado o MEM si es un elemento de memoria (o RMEM y AMEM en su caso)
int address;
} asserts[MAX_ASSERTS];

extern int GEN_ASSERTS;

int elementNumber(char *cmp) {
int n=0;

while ((elements[n]!=NULL) && strcmp(cmp, elements[n]))
n++;

if (elements[n]==NULL) return -1;
else return n;

}

void strcmpSpaces(char *target, char *src, int nChars) {
int l, s, t;

l=strlen(src);
t=0;
for (s=0; (t<nChars-1) && (s<l); s++) {
if (src[s]!=' ') target[t++]=src[s];
}
target[t]=0;
}

int Asserts_LoadAsserts() {
// leer el fichero e ir almacenando en cada elemento lo que sea;
struct assert a;

char lineRead[MAXIMUMLENGTH];
FILE *mf;
char *time, *element, *value, *address;
char svalue[E_SIZE];


int lineNumber=0;;
int numberAsserts=0;
int rc;
int en;

mf=fopen(ASSERTS_FILE, "r");
if (mf==NULL) {
asserts[0].time=-1;
return -1;
}

while (fgets(lineRead,MAXIMUMLENGTH, mf) != NULL) {
lineNumber++;
// Leemos hasta 4 elementos por aserto
time=strtok(lineRead,",");
if (time==NULL){
printf("Illegal Assert in line %d of file %s\n",lineNumber,ASSERTS_FILE);
continue;
}

element=strtok(NULL,",");
if (element==NULL){
printf("Illegal Assert in line %d of file %s\n",lineNumber,ASSERTS_FILE);
continue;
}

value=strtok(NULL,",");
if (value==NULL){
printf("Illegal Assert in line %d of file %s\n",lineNumber,ASSERTS_FILE);
continue;
}
address=strtok(NULL,"\n");

//printf("-> %s, %s, %s, %s\n",time, element, value, address);

strcmpSpaces(a.element, element,E_SIZE);
if (strcmp(time,"*")) {
rc=sscanf(time,"%d",&a.time);
if (rc==0){
printf("Illegal time format in line %d of file %s\n",lineNumber,ASSERTS_FILE);
continue;
}
}
else a.time=-33; // All the instants of time.

//printf("-%s-\n",a.element);
// Si vamos a verificar un código de operación leemos un char (RMEM_OP, AMEM_OP,IR_OP, MBR_OP, MMBR_OP)
en=elementNumber(a.element);
if ((en==RMEM_OP) || (en==AMEM_OP) || (en==IR_OP) || (en==MBR_OP) || (en==MMBR_OP)) {
strcmpSpaces(svalue, value,E_SIZE);
rc=sscanf(svalue,"%c",(char *) &a.value);

}
else
rc=sscanf(value,"%d",&a.value);

if (rc==0){
printf("Illegal expected value format in line %d of file %s (%s)\n",lineNumber,ASSERTS_FILE,value);
continue;
}

// Si vamos a verificar una posición de memoria leemos la dirección (RMEM_OP, RMEM_O1, RMEM_O2, AMEM_OP, AMEM_O1, AMEM_O2)
en=elementNumber(a.element);
if ((en==RMEM_OP) || (en==RMEM_O1) || (en==RMEM_O2) || (en==AMEM_OP) || (en==AMEM_O1) || (en==AMEM_O2)) {
if (address==NULL){
printf("Illegal Assert in line %d of file %s\n",lineNumber,ASSERTS_FILE);
continue;
}
rc=sscanf(address,"%d",&a.address);
if (rc==0){
printf("Illegal address format in line %d of file %s\n",lineNumber,ASSERTS_FILE);
continue;
}
}
else a.address=0;

asserts[numberAsserts++]=a;
//printf("-> %d, %s, %d, %d\n",a.time, a.element, a.value, a.address);
}
fclose(mf);
asserts[numberAsserts].time=-1; // Para indicar el fin de los asertos
return numberAsserts;
}


void genAssertMsg(int time, char *ele, int realValue, int addr) {
int en;

printf("%d, %s",time, ele);
en=elementNumber(ele);

if ((en==RMEM_OP) || (en==AMEM_OP) || (en==IR_OP) || (en==MBR_OP))
printf(", %c",realValue);
else
printf(", %d", realValue);

if ((en==RMEM_OP) || (en==RMEM_O1) || (en==RMEM_O2) || (en==AMEM_OP) || (en==AMEM_O1) || (en==AMEM_O2))
printf(", %d", addr);

printf("\n");
}

void assertMsg(int time, char *ele, int expectedValue, int realValue, int addr) {
int en;

if (GEN_ASSERTS) {
genAssertMsg(time, ele, realValue,addr);
return;
}

// printf("Assert failed. Time: %d; Element: %s; ", time, ele);
ComputerSystem_DebugMessage(90,ERROR, time, ele);
en=elementNumber(ele);

if ((en==RMEM_OP) || (en==AMEM_OP) || (en==IR_OP) || (en==MBR_OP))
// printf("Expected: '%c'; Real: '%c'", expectedValue, realValue);
ComputerSystem_DebugMessage(91,ERROR, expectedValue, realValue);
else
// printf("Expected: %d; Real: %d", expectedValue, realValue);
ComputerSystem_DebugMessage(92,ERROR, expectedValue, realValue);

if ((en==RMEM_OP) || (en==RMEM_O1) || (en==RMEM_O2) || (en==AMEM_OP) || (en==AMEM_O1) || (en==AMEM_O2))
// printf("; Memory address: %d", addr);
ComputerSystem_DebugMessage(93,ERROR, addr);

// printf("\n");
ComputerSystem_DebugMessage(98, ERROR, "\n");
}


void Asserts_CheckAsserts(){
int na=0;
int op;
int globalCounter=Clock_GetTime();
MEMORYCELL data;

//printf("Checking asserts for time %d\n",globalCounter);

while (asserts[na].time!=-1) {

// if ((asserts[na].time==globalCounter) || (asserts[na].time==-33)) {
if ((asserts[na].time==globalCounter) || (asserts[na].time==-33)) {

op=elementNumber(asserts[na].element);
//printf("There is one assert for time %d: %d\n",globalCounter, op);
switch (op) {
case RMEM_OP:
if ((mainMemory[MMU_GetBase()+asserts[na].address].operationCode!=(char)asserts[na].value) || GEN_ASSERTS)
assertMsg(globalCounter,"RMEM_OP",asserts[na].value,mainMemory[MMU_GetBase()+asserts[na].address].operationCode,asserts[na].address);
break;
case RMEM_O1:
if ((mainMemory[MMU_GetBase()+asserts[na].address].operand1!=(char)asserts[na].value) || GEN_ASSERTS)
assertMsg(globalCounter,"RMEM_O1",asserts[na].value,mainMemory[MMU_GetBase()+asserts[na].address].operand1,asserts[na].address);
break;
case RMEM_O2:
if ((mainMemory[MMU_GetBase()+asserts[na].address].operand2!=(char)asserts[na].value) || GEN_ASSERTS)
assertMsg(globalCounter,"RMEM_O2",asserts[na].value,mainMemory[MMU_GetBase()+asserts[na].address].operand2,asserts[na].address);
break;
case AMEM_OP:
if ((mainMemory[asserts[na].address].operationCode!=(char)asserts[na].value) || GEN_ASSERTS)
assertMsg(globalCounter,"AMEM_OP",asserts[na].value,mainMemory[asserts[na].address].operationCode,asserts[na].address);
break;
case AMEM_O1:
if ((mainMemory[asserts[na].address].operand1!=asserts[na].value)|| GEN_ASSERTS)
assertMsg(globalCounter,"AMEM_01",asserts[na].value,mainMemory[asserts[na].address].operand1,asserts[na].address);
break;
case AMEM_O2:
if ((mainMemory[asserts[na].address].operand2!=asserts[na].value)|| GEN_ASSERTS)
assertMsg(globalCounter,"AMEM_02",asserts[na].value,mainMemory[asserts[na].address].operand2,asserts[na].address);
break;
case PC:
if ((registerPC_CPU!=asserts[na].value)|| GEN_ASSERTS)
assertMsg(globalCounter,"PC",asserts[na].value,registerPC_CPU,0);
break;
case ACC:
if ((registerAccumulator_CPU!=asserts[na].value)|| GEN_ASSERTS)
assertMsg(globalCounter,"ACC",asserts[na].value,registerAccumulator_CPU,0);
break;
case IR_OP:
if ((registerIR_CPU.operationCode!=(char) asserts[na].value)|| GEN_ASSERTS)
assertMsg(globalCounter,"IR_OP",asserts[na].value,registerIR_CPU.operationCode,0);
break;
case IR_O1:
if ((registerIR_CPU.operand1!= asserts[na].value)|| GEN_ASSERTS)
assertMsg(globalCounter,"IR_01",asserts[na].value,registerIR_CPU.operand1,0);
break;
case IR_O2:
if ((registerIR_CPU.operand2!=asserts[na].value)|| GEN_ASSERTS)
assertMsg(globalCounter,"IR_02",asserts[na].value,registerIR_CPU.operand2,0);
break;
case PSW:
if ((registerPSW_CPU!=asserts[na].value)|| GEN_ASSERTS)
assertMsg(globalCounter,"PSW",asserts[na].value,registerPSW_CPU,0);
break;
case MAR:
if ((registerMAR_CPU!=asserts[na].value)|| GEN_ASSERTS)
assertMsg(globalCounter,"MAR",asserts[na].value,registerMAR_CPU,0);
break;
case MBR_OP:
if ((registerMBR_CPU.operationCode!=(char) asserts[na].value)|| GEN_ASSERTS)
assertMsg(globalCounter,"MBR_OP",asserts[na].value,registerMBR_CPU.operationCode,0);
break;
case MBR_O1:
if ((registerMBR_CPU.operand1!= asserts[na].value)|| GEN_ASSERTS)
assertMsg(globalCounter,"MBR_O1",asserts[na].value,registerMBR_CPU.operand1,0);
break;
case MBR_O2:
if ((registerMBR_CPU.operand2!=asserts[na].value) || GEN_ASSERTS)
assertMsg(globalCounter,"MBR_02",asserts[na].value,registerMBR_CPU.operand2,0);
break;
case MMU_BS:
if ((MMU_GetBase()!=asserts[na].value) || GEN_ASSERTS)
assertMsg(globalCounter,"MMU_BS",asserts[na].value,MMU_GetBase(),0);
break;
case MMU_LM:
if ((MMU_GetLimit()!=asserts[na].value) || GEN_ASSERTS)
assertMsg(globalCounter,"MMU_LM",asserts[na].value,MMU_GetLimit(),0);
break;
case MMU_MAR:
if ((MMU_GetMAR()!=asserts[na].value) || GEN_ASSERTS)
assertMsg(globalCounter,"MMU_MAR",asserts[na].value,MMU_GetMAR(),0);
break;
case MMEM_MAR:
if ((MainMemory_GetMAR()!=asserts[na].value) || GEN_ASSERTS)
assertMsg(globalCounter,"MMEM_MAR",asserts[na].value,MainMemory_GetMAR(),0);
break;
case MMBR_OP:
MainMemory_GetMBR(&data);
if ((data.operationCode!=asserts[na].value) || GEN_ASSERTS)
assertMsg(globalCounter,"MMBR_OP",asserts[na].value,data.operationCode,0);
break;
case MMBR_O1:
MainMemory_GetMBR(&data);
if ((data.operand1!=asserts[na].value) || GEN_ASSERTS)
assertMsg(globalCounter,"MMBR_O1",asserts[na].value,data.operand1,0);
break;
case MMBR_O2:
MainMemory_GetMBR(&data);
if ((data.operand2!=asserts[na].value) || GEN_ASSERTS)
assertMsg(globalCounter,"MMBR_O2",asserts[na].value,data.operand2,0);
break;
case XPID:
if ((executingProcessID!=asserts[na].value) || GEN_ASSERTS)
assertMsg(globalCounter,"XPID",asserts[na].value,executingProcessID,0);
break;
default: ;

}
}
na++;

}
}
@@ -0,0 +1,39 @@
#ifndef CHECKASSERTS_H
#define CHECKASSERTS_H

#define MAX_ASSERTS 500
#define MAXIMUMLENGTH 64
#define ASSERTS_FILE "asserts"
#define E_SIZE 8



#define RMEM_OP 0
#define RMEM_O1 1
#define RMEM_O2 2
#define AMEM_OP 3
#define AMEM_O1 4
#define AMEM_O2 5
#define PC 6
#define ACC 7
#define IR_OP 8
#define IR_O1 9
#define IR_O2 10
#define PSW 11
#define MAR 12
#define MBR_OP 13
#define MBR_O1 14
#define MBR_O2 15
#define MMU_BS 16
#define MMU_LM 17
#define MMU_MAR 18
#define MMEM_MAR 19
#define MMBR_OP 20
#define MMBR_O1 21
#define MMBR_O2 22
#define XPID 23

// Functions prototypes
int Asserts_LoadAsserts();
void Asserts_CheckAsserts();
#endif
@@ -0,0 +1,71 @@
#include "Buses.h"
#include "MMU.h"
#include "Processor.h"
#include "MainMemory.h"
#include <string.h>
#include <stdlib.h>

// Function that simulates the delivery of an address by means of the address bus
// from a hardware component register to another hardware component register
int Buses_write_AddressBus_From_To(int fromRegister, int toRegister) {
int data;
switch (fromRegister) {
case MMU:
data=MMU_GetMAR();
break;
case CPU:
data=Processor_GetMAR();
break;
default:
return Bus_FAIL;
}

switch (toRegister) {
case MAINMEMORY:
if (fromRegister==MAINMEMORY)
return Bus_FAIL;
MainMemory_SetMAR(data);
break;
case MMU:
if (fromRegister==MMU)
return Bus_FAIL;
MMU_SetMAR(data);
break;
default:
return Bus_FAIL;
}
return Bus_SUCCESS;
}

// Function that simulates the delivery of memory word by means of the data bus
// from a hardware component register to another hardware component register
int Buses_write_DataBus_From_To(int fromRegister, int toRegister) {
MEMORYCELL data;
switch (fromRegister) {
case MAINMEMORY:
MainMemory_GetMBR(&data);
break;
case CPU:
Processor_GetMBR(&data);
break;
default:
return Bus_FAIL;
}

switch (toRegister) {
case MAINMEMORY:
if (fromRegister==MAINMEMORY)
return Bus_FAIL;
MainMemory_SetMBR(&data);
break;
case CPU:
if (fromRegister==CPU)
return Bus_FAIL;
Processor_SetMBR(&data);
break;
default:
return Bus_FAIL;
}

return Bus_SUCCESS;
}
@@ -0,0 +1,13 @@
#ifndef BUSES_H
#define BUSES_H

enum BusConnection { MAINMEMORY, MMU, CPU, INPUTDEVICE, OUTPUTDEVICE };

#define Bus_SUCCESS 1
#define Bus_FAIL -1

// Functions prototypes
int Buses_write_AddressBus_From_To(int, int);
int Buses_write_DataBus_From_To(int, int);

#endif
@@ -0,0 +1,16 @@
#include "Clock.h"
#include "Processor.h"
#include "ComputerSystem.h"

int tics=0;

void Clock_Update() {
tics++;
ComputerSystem_DebugMessage(97,CLOCK,tics);
}


int Clock_GetTime() {

return tics;
}
@@ -0,0 +1,8 @@
#ifndef Clock_H
#define Clock_H

// Functions prototypes
void Clock_Update();
int Clock_GetTime();

#endif
@@ -0,0 +1,66 @@
#include <stdio.h>
#include <stdlib.h>
#include "ComputerSystem.h"
#include "OperatingSystem.h"
#include "ComputerSystemBase.h"
#include "Processor.h"
#include "Messages.h"
#include "Asserts.h"

// Functions prototypes
void ComputerSystem_PrintProgramList();
// Array that contains basic data about all daemons
// and all user programs specified in the command line
PROGRAMS_DATA *programList[PROGRAMSMAXNUMBER];

// Powers on of the Computer System.
void ComputerSystem_PowerOn(int argc, char *argv[]) {

// Load debug messages
int nm=0;
nm=Messages_Load_Messages(nm,TEACHER_MESSAGES_FILE);
nm=Messages_Load_Messages(nm,STUDENT_MESSAGES_FILE);
printf("%d Messages Loaded\n",nm);

int na=Asserts_LoadAsserts();
if (na==-1)
printf("Asserts file unavailable\n");
else
printf("%d Asserts Loaded\n",na);

// Obtain a list of programs in the command line
int daemonsBaseIndex = ComputerSystem_ObtainProgramList(argc, argv);

//Show the loaded user programs
ComputerSystem_PrintProgramList();

// Request the OS to do the initial set of tasks. The last one will be
// the processor allocation to the process with the highest priority
OperatingSystem_Initialize(daemonsBaseIndex);


// Tell the processor to begin its instruction cycle
Processor_InstructionCycleLoop();

}

// Powers off the CS (the C program ends)
void ComputerSystem_PowerOff() {
// Show message in red colour: "END of the simulation\n"
ComputerSystem_DebugMessage(99,SHUTDOWN);
exit(0);
}

/////////////////////////////////////////////////////////
// New functions below this line //////////////////////
void ComputerSystem_PrintProgramList() {
int i;
PROGRAMS_DATA program;
ComputerSystem_DebugMessage(101, INIT);
for( i = 0; i < PROGRAMSMAXNUMBER; i++){
if(i != 0 && programList[i] != NULL){
program = *programList[i];
ComputerSystem_DebugMessage(102, INIT, program.executableName, program.arrivalTime);
}
}
}
@@ -0,0 +1,43 @@
#ifndef COMPUTERSYSTEM_H
#define COMPUTERSYSTEM_H

#include "Simulator.h"
#include "ComputerSystemBase.h"

// Functions prototypes
void ComputerSystem_PowerOn(int argc, char *argv[]);
void ComputerSystem_PowerOff();
// void ComputerSystem_ObtainProgramList(int argc, char *argv[]);

// Sections in which we divide our simulator in terms of
// debugging messages that show its internal working details

#define ALL 'a' // Show all the messages corresponding to calls to the ComputerSystem_DebugMessage() function
#define NONE 'n' // Do not show any message (not apply for ERROR messages)
#define INTERRUPT 'i' // Only messages related to interruptions
#define HARDWARE 'h' // Only messages related to the hardware
#define SYSFILE 'f' // Only messages related to the file system of the operating system
#define SYSPROC 'p' // Only messages related to the process management system of the operating system
#define SYSMEM 'm' // Only messages related to the memory management system of the operating system
#define INIT 't' // Only messages related to the initialization of the operating system
#define SHUTDOWN 'd' // Only messages related to the process of powering off the operating system
#define LONGTERMSCHEDULE 'l' // Only messages related to the long term scheduler of the operating system
#define SHORTTERMSCHEDULE 's' // Only messages related to the short term scheduler of the operating system
#define ERROR 'e' // Error messages
#define CLOCK 'c' // Clock time messages

// Basic data to collect about every program to be created
// User programs specified in the command line: name of the file, the time of its arrival time
// to the system (0, by default), and type USERPROGRAM
// Daemon programs of type DAEMONPROGRAM
typedef struct ProgramData {
char *executableName;
unsigned int arrivalTime;
unsigned int type;
} PROGRAMS_DATA;

// This "extern" declarations enables other source code files to gain access
// to the variables "programList", etc.
extern PROGRAMS_DATA *programList[PROGRAMSMAXNUMBER];

#endif
@@ -0,0 +1,198 @@
#include <string.h>
#include <stdarg.h>
#include <stdlib.h>
#include <ctype.h>
#include "ComputerSystem.h"
#include "ComputerSystemBase.h"
#include "Processor.h"
#include "Heap.h"
#include "OperatingSystemBase.h"
#include "Messages.h"

// Functions prototypes

int GEN_ASSERTS=0;
// String specified in the command line to tell the simulator which of its
// sections are interesting for the user so it must show debug messages
// related to them
char *debugLevel;

// Only one colour messages. Set to 1 for more colours checking uppercase in debugLevel
int COLOURED = 0 ;

// Fill in the array named userProgramsList with the information given
// by the user in the command line
// IT IS NOT NECESSARY TO COMPLETELY UNDERSTAND THIS FUNCTION
int ComputerSystem_ObtainProgramList(int argc, char *argv[]) {

int i;
int count=1; // 0 reserved for sipid
PROGRAMS_DATA *progData;

// To remember the simulator sections to be message-debugged
debugLevel = argv[1];
for (i=0; i< strlen(debugLevel);i++)
if (isupper(debugLevel[i])){
COLOURED = 1;
debugLevel[i]=tolower(debugLevel[i]);
}

if (strchr(debugLevel,'g'))
GEN_ASSERTS=1;

for (i=0; i<PROGRAMSMAXNUMBER;i++)
programList[i]=NULL;

// Store the names of the programs
for (i = 2; i < argc && count<PROGRAMSMAXNUMBER;) { // check number of programs < PROGRAMSMAXNUMBER
progData=(PROGRAMS_DATA *) malloc(sizeof(PROGRAMS_DATA));
// Save file name
progData->executableName = (char *) malloc((strlen(argv[i])+1)*sizeof(char));
strcpy(progData->executableName,argv[i]);
i++;
// Default arrival time: 0
progData->arrivalTime = 0;
// Try to store the arrival time if exists
if ((i < argc)
&& (sscanf(argv[i], "%d", &(progData->arrivalTime)) == 1))
// An arrival time has been read. Increment i
i++;

// Defaul user programs
progData->type=USERPROGRAM;

// Store the structure in the list
programList[count]=progData;

count++; // There is one program more
}
return count; // Next place for new programs
}

// Function used to show messages with details of the internal working of
// the simulator
// IT IS NOT NECESSARY TO UNDERSTAND ALL THE DETAILS OF THIS FUNCTION
void ComputerSystem_DebugMessage(int msgNo, char section, ...) {

va_list lp;
char c, *format;
int count, youHaveToContinue, colour=0;

int pos;

pos=Messages_Get_Pos(msgNo);
if (pos==-1) {
printf("Debug Message %d not defined\n",msgNo);
return;
}
format=DebugMessages[pos].format;

va_start(lp, section);

if ((strchr(debugLevel, ALL) != NULL) // Print the message because the user specified ALL
|| section == ERROR // Always print ERROR section
|| (strchr(debugLevel,section)) != NULL){ // or the section argument is included in the debugLevel string

for (count = 0, youHaveToContinue = 1; youHaveToContinue == 1; count++) {
//printf("(%c)",format[count]);
switch (format[count]) {
case '\\':count++;
switch (format[count]) {
case 'n': printf("\n");
break;
case 't': printf("\t");
break;
default: printf("\%c", format[count]);
} // switch Control Chars
break;
// case '%':
case '@': // Next color char
count++;
switch (format[count]) {
case 'R': // Text in red
if (COLOURED){
printf("%c[%d;%dm", 0x1B, 1, 31);
if (!colour) colour=1;
}
break;
case 'G': // Text in green
if (COLOURED){
printf("%c[%d;%dm", 0x1B, 1, 32);
if (!colour) colour=1;
}
break;
case 'Y': // Text in yellow
if (COLOURED){
printf("%c[%d;%dm", 0x1B, 1, 33);
if (!colour) colour=1;
}
break;
case 'B': // Text in blue
if (COLOURED){
printf("%c[%d;%dm", 0x1B, 1, 34);
if (!colour) colour=1;
}
break;
case 'M': // // Text in magenta
if (COLOURED){
printf("%c[%d;%dm", 0x1B, 1, 35);
if (!colour) colour=1;
}
break;
case 'C': // Text in cyan
if (COLOURED){
printf("%c[%d;%dm", 0x1B, 1, 36);
if (!colour) colour=1;
}
break;
case 'W': // Text in white
if (COLOURED){
printf("%c[%d;%dm", 0x1B, 1, 37);
if (!colour) colour=1;
}
break;
case '@': // Text without color
if (COLOURED && colour)
printf("%c[%dm", 0x1B, 0);
break;
} // switch colors chars
break;
case '%':
count++;
switch (format[count]) {
case 's':
printf("%s",va_arg(lp, char *));
// if (colour)
// printf("%c[%dm", 0x1B, 0);
break;
case 'd':
printf("%d",va_arg(lp, int));
// if (colour)
// printf("%c[%dm", 0x1B, 0);
break;
case 'f':
printf("%f",va_arg(lp, double));
// if (colour)
// printf("%c[%dm", 0x1B, 0);
break;
case 'c':
c = (char) va_arg(lp, int);
printf("%c", c);
// if (colour)
// printf("%c[%dm", 0x1B, 0);
break;
default:
youHaveToContinue = 0;
} // switch format chars
break;
default:if (format[count]==0)
youHaveToContinue=0;
else
printf("%c",format[count]);
} // switch
} // for
va_end(lp);
} // if
if (COLOURED && colour)
printf("%c[%dm", 0x1B, 0);
} // ComputerSystem_DebugMessage()
@@ -0,0 +1,12 @@
#ifndef COMPUTERSYSTEMBASE_H
#define COMPUTERSYSTEMBASE_H

#include "ComputerSystem.h"

// Functions prototypes
int ComputerSystem_ObtainProgramList(int , char *[]);
void ComputerSystem_DebugMessage(int, char , ...);

// This "extern" declarations enables other source code files to gain access to the variables

#endif
108 V1/Heap.c
@@ -0,0 +1,108 @@
#include "Heap.h"
#include <stdlib.h>

// Internal Functions prototypes
void Heap_swap_Up(int, int[], int);
void Heap_swap_Down(int, int[], int, int);


// Insertion of a PID into a binary heap
// info: PID to insert
// heap: Binary heap to insert: user o daemon ready queue, sleeping queue, ...
// queueType: QUEUE_PRIORITY, ...
// numElem: number of elements actually into the queue, if successfull is increased by one
// limit: max size of the queue
// return 0/-1 ok/fail
int Heap_add(int info, int heap[], int queueType, int *numElem, int limit) {
if (*numElem >= limit || info<0)
return -1;
heap[*numElem]=info;
Heap_swap_Up(*numElem, heap, queueType);
(*numElem)++;
return 0;
}

// Extract the more priority item
// heap: Binary heap to extract: user o daemon ready queue, sleeping queue, ...
// queueType: QUEUE_PRIORITY, ...
// numElem: number of elements actually into the queue, if successfull is decremented by one
// return more priority item into the queue
int Heap_poll(int heap[], int queueType, int *numElem) {
int info = heap[0];
if (*numElem==0)
return -1; // no hay elementos en la cola de prioridad
else {
heap[0]=heap[*numElem-1];
Heap_swap_Down(0, heap, queueType, *numElem);
(*numElem)--;
}
return info;
}

// Return top value of heap
// heap: Binary heap to get top value
// numElem: number of elements actually into the queue
// return more priority item, but not extract from heap
int Heap_getFirst(int heap[], int numElem) {
if (numElem>0)
return heap[0];
else
return -1;
}

// Auxiliar function for implementation of binary heaps
void Heap_swap_Up(int p, int heap[], int queueType) {
if (p > 0) { // if not at the top...
int padre = abs(p - 1) / 2; // integer operation
if (Heap_compare(heap[p],heap[padre],queueType)>0) { // less than father...
int aux = heap[padre];
heap[padre] = heap[p];
heap[p] = aux;
Heap_swap_Up(padre, heap, queueType);
} // if not less, don't switch
} // at the top...
}

// Auxiliar function for implementation of binary heaps
void Heap_swap_Down(int p, int heap[], int queueType, int numElem) {
int izq = 2*p+1;
int der = 2*p+2;
int aux = heap[p];

if (der < numElem) // 2 childs...
if ((Heap_compare(heap[izq],heap[der], queueType)>0) && (Heap_compare(heap[p],heap[izq],queueType)<0)){ // Switch with left-child if rigth-child greather
heap[p] = heap[izq];
heap[izq] = aux;
Heap_swap_Down(izq, heap, queueType, numElem);
} else { // rigth
if (Heap_compare(heap[p],heap[der], queueType)<0) { // Switch with rigth-child
heap[p] = heap[der];
heap[der] = aux;
Heap_swap_Down(der, heap, queueType, numElem);
}
}
else if (izq<numElem) { // only left-child...
if (Heap_compare(heap[p],heap[izq], queueType)<0){ // Switch with left-child
heap[p] = heap[izq];
heap[izq] = aux;
Heap_swap_Down(izq, heap, queueType, numElem);
} // Less than left-child, don't switch
} // leaf-node...
}

// Auxiliar for priority comparations
int Heap_compare_priority(int uno, int dos) {
return processTable[dos].priority-processTable[uno].priority;
}

// Auxiliar for generic comparations
int Heap_compare(int uno, int dos, int queueType) {

switch (queueType) {
case QUEUE_PRIORITY:
return Heap_compare_priority(uno, dos);
default:
return 0; //
}

}
@@ -0,0 +1,13 @@
#ifndef HEAP_H
#define HEAP_H

#include "OperatingSystem.h"

#define QUEUE_PRIORITY 1


int Heap_poll(int[], int, int*);
int Heap_add(int, int[], int , int*, int);
int Heap_compare(int, int, int);
int Heap_getFirst(int[], int);
#endif
105 V1/MMU.c
@@ -0,0 +1,105 @@
#include "MMU.h"
#include "Buses.h"
#include "Processor.h"
#include <string.h>

// The base register
int registerBase_MMU;

// The limit register
int registerLimit_MMU;

// The MAR register
int registerMAR_MMU;

// Logical address is in registerMAR_MMU. If correct, physical address is produced
// by adding logical address and base register
int MMU_readMemory() {

if (Processor_PSW_BitState(EXECUTION_MODE_BIT)){ // Protected mode
if (registerMAR_MMU < MAINMEMORYSIZE){
// Send to the main memory HW the physical address to write in
Buses_write_AddressBus_From_To(MMU, MAINMEMORY);
// Tell the main memory HW to read
MainMemory_readMemory();
return MMU_SUCCESS;
}
else {
return MMU_FAIL;
}
}
else // Non-Protected mode
if (registerMAR_MMU<registerLimit_MMU) {
// Physical address = logical address + base register
registerMAR_MMU+=registerBase_MMU;
// Send to the main memory HW the physical address to write in
Buses_write_AddressBus_From_To(MMU, MAINMEMORY);
// Tell the main memory HW to read
MainMemory_readMemory();
return MMU_SUCCESS;
}
else {
return MMU_FAIL;
}

}

// Logical address is in registerMAR_MMU. If correct, physical address is produced
// by adding logical address and base register
int MMU_writeMemory() {

if (Processor_PSW_BitState(EXECUTION_MODE_BIT)) // Protected mode
if (registerMAR_MMU < MAINMEMORYSIZE) {
// Send to the main memory HW the physical address to write in
Buses_write_AddressBus_From_To(MMU, MAINMEMORY);
// Tell the main memory HW to read
MainMemory_writeMemory();
return MMU_SUCCESS;
}
else {
return MMU_FAIL;
}
else // Non-Protected mode
if (registerMAR_MMU<registerLimit_MMU) {
// Physical address = logical address + base register
registerMAR_MMU+=registerBase_MMU;
// Send to the main memory HW the physical address to read from
Buses_write_AddressBus_From_To(MMU, MAINMEMORY);
// Tell the main memory HW to write
MainMemory_writeMemory();
return MMU_SUCCESS;
}
else {
return MMU_FAIL;
}
}

// Setter for registerMAR_MMU
void MMU_SetMAR (int newMAR) {
registerMAR_MMU = newMAR;
}

// Getter for registerMAR_MMU
int MMU_GetMAR () {
return registerMAR_MMU;
}

// Setter for registerBase_MMU
void MMU_SetBase (int newBase) {
registerBase_MMU = newBase;
}

// Getter for registerBase_MMU
int MMU_GetBase () {
return registerBase_MMU;
}

// Setter for registerLimit_MMU
void MMU_SetLimit (int newLimit) {
registerLimit_MMU = newLimit;
}

// Getter for registerLimit_MMU
int MMU_GetLimit () {
return registerLimit_MMU;
}
@@ -0,0 +1,20 @@
#ifndef MMU_H
#define MMU_H

#define MMU_SUCCESS 1
#define MMU_FAIL -1

// Functions prototypes
int MMU_readMemory();
int MMU_writeMemory();

int MMU_GetMAR();
void MMU_SetMAR(int);
void MMU_SetBase(int);
void MMU_SetLimit(int);

// Used for Asserts
int MMU_GetBase();
int MMU_GetLimit();

#endif
@@ -0,0 +1,51 @@
#include "MainMemory.h"
#include "Processor.h"
#include "Buses.h"
#include <string.h>

// Main memory can be simulated by a memory cell array
MEMORYCELL mainMemory[MAINMEMORYSIZE];

// Main memory has a MAR register whose value identifies where
// the next read/write operation will take place
int registerMAR_MainMemory;

// It also has a register that plays the rol of a buffer for the mentioned operations
MEMORYCELL registerMBR_MainMemory;

// To read the contents of a memory cell, the MAR register must point (index) it
// The result of the operation is sent to the processor MBR register by using the
// data bus
void MainMemory_readMemory() {

memcpy((void *) (&registerMBR_MainMemory), (void *) (&mainMemory[registerMAR_MainMemory]), sizeof(MEMORYCELL));
Buses_write_DataBus_From_To(MAINMEMORY, CPU);
}

// To write in a memory cell, the MAR and MBR registers are used, set by the processor,
// as described previously
void MainMemory_writeMemory() {

memcpy((void *) (&mainMemory[registerMAR_MainMemory]), (void *) (&registerMBR_MainMemory), sizeof(MEMORYCELL));
}

// Getter for the registerMAR_MainMemory
int MainMemory_GetMAR() {
return registerMAR_MainMemory;
}

// Setter for registerMAR_MainMemory
void MainMemory_SetMAR(int addr) {
registerMAR_MainMemory=addr;
}

// pseudo-getter for the registerMBR_MainMemory
void MainMemory_GetMBR(MEMORYCELL *toRegister) {
memcpy((void*) toRegister, (void *) (&registerMBR_MainMemory), sizeof(MEMORYCELL));
}

// pseudo-setter for the registerMBR_MainMemory
void MainMemory_SetMBR(MEMORYCELL *fromRegister) {
memcpy((void*) (&registerMBR_MainMemory), (void *) fromRegister, sizeof(MEMORYCELL));
}

@@ -0,0 +1,24 @@
#ifndef MAINMEMORY_H
#define MAINMEMORY_H

// Main memory size (number of memory cells)
#define MAINMEMORYSIZE 300

// A memory cell is capable of storing a structure of the
// MEMORYCELL TYPE
typedef struct {
char operationCode;
int operand1;
int operand2;
} MEMORYCELL;

// Function prototypes
void MainMemory_readMemory();
void MainMemory_writeMemory();

int MainMemory_GetMAR();
void MainMemory_SetMAR(int);
void MainMemory_GetMBR(MEMORYCELL *);
void MainMemory_SetMBR(MEMORYCELL *);

#endif
@@ -0,0 +1,74 @@
#
# Makefile for the Linux Simulator
#
########################################################

PROGRAM = Simulator

# Compilation Details
SHELL = /bin/sh
CC = cc
STDCFLAGS = -g -c -Wall -std=gnu90
INCLUDES =
LIBRERIAS =
ACC = /usr/share/ACC/bin/acc

${PROGRAM}: Simulator.o Aspect.o Buses.o Asserts.o Clock.o ComputerSystem.o ComputerSystemBase.o Heap.o MainMemory.o Messages.o MMU.o OperatingSystemAspect.o OperatingSystemBase.o ProcessorAspect.o
$(CC) -o ${PROGRAM} Simulator.o Aspect.o Buses.o Asserts.o Clock.o ComputerSystem.o ComputerSystemBase.o Heap.o MainMemory.o Messages.o MMU.o OperatingSystemAspect.o OperatingSystemBase.o ProcessorAspect.o $(LIBRERIAS)

Simulator.o: Simulator.c Simulator.h
$(CC) $(STDCFLAGS) $(INCLUDES) Simulator.c

Asserts.o: Asserts.c Asserts.h
$(CC) $(STDCFLAGS) $(INCLUDES) Asserts.c

ComputerSystem.o: ComputerSystem.c ComputerSystem.h ComputerSystemBase.h
$(CC) $(STDCFLAGS) $(INCLUDES) ComputerSystem.c

ComputerSystemBase.o: ComputerSystemBase.c ComputerSystemBase.h ComputerSystem.h
$(CC) $(STDCFLAGS) $(INCLUDES) ComputerSystemBase.c

Messages.o: Messages.c Messages.h
$(CC) $(STDCFLAGS) $(INCLUDES) Messages.c

MainMemory.o: MainMemory.c MainMemory.h
$(CC) $(STDCFLAGS) $(INCLUDES) MainMemory.c

OperatingSystemAspect.o: OperatingSystemAspect.mc Aspect.acc
$(ACC) OperatingSystemAspect.mc Aspect.acc
$(CC) $(STDCFLAGS) $(INCLUDES) -L /tmp/ACC/lib -lacc OperatingSystemAspect.c

OperatingSystemAspect.mc: OperatingSystem.c OperatingSystem.h
$(CC) -E $(INCLUDES) OperatingSystem.c > OperatingSystemAspect.mc

OperatingSystemBase.o: OperatingSystemBase.c OperatingSystemBase.h OperatingSystem.h
$(CC) $(STDCFLAGS) $(INCLUDES) OperatingSystemBase.c

ProcessorAspect.o: ProcessorAspect.mc Aspect.acc
$(ACC) ProcessorAspect.mc Aspect.acc
$(CC) $(STDCFLAGS) $(INCLUDES) -L /tmp/ACC/lib -lacc ProcessorAspect.c

ProcessorAspect.mc: Processor.c Processor.h
$(CC) -E $(INCLUDES) Processor.c > ProcessorAspect.mc

Aspect.o: Aspect.acc
$(ACC) Aspect.acc
$(CC) $(STDCFLAGS) $(INCLUDES) -L /tmp/ACC/lib -lacc Aspect.c

Aspect.acc: OperatingSystem.h Processor.h Asserts.h MyAspect.c
$(CC) -E $(INCLUDES) MyAspect.c > Aspect.acc

Buses.o: Buses.c Buses.h
$(CC) $(STDCFLAGS) $(INCLUDES) Buses.c

MMU.o: MMU.c MMU.h
$(CC) $(STDCFLAGS) $(INCLUDES) MMU.c

Clock.o: Clock.c Clock.h
$(CC) $(STDCFLAGS) $(INCLUDES) Clock.c

Heap.o: Heap.c Heap.h
$(CC) $(STDCFLAGS) $(INCLUDES) Heap.c

clean:
rm -f $(PROGRAM) *.o *~ *.mc *.acc Aspect.c ProcessorAspect.c OperatingSystemAspect.c core
@@ -0,0 +1,56 @@
#include <stdio.h>
#include <string.h>
#include "Messages.h"

#define MSGMAXIMUMLENGTH 132

DEBUG_MESSAGES DebugMessages[NUMBEROFMSGS] = {[0 ... NUMBEROFMSGS-1] {-1,""}};

int Messages_Load_Messages(int position, char * nameFileMessage) {

char lineRead[MSGMAXIMUMLENGTH];
FILE *mf;
char *number, *text;
int msgNumber;
int lineNumber=0;;
int rc;

mf=fopen(nameFileMessage, "r");
if (mf==NULL) {
printf("Verbose messages unavailable\n");
return -1;
}

while (fgets(lineRead, MSGMAXIMUMLENGTH, mf) != NULL) {
lineNumber++;
number=strtok(lineRead,",");
if ((number!=NULL) && (number[0]!='/') && (number[0]!='\n')) {
rc=sscanf(number,"%d",&msgNumber);
if (rc==0){
printf("Illegal Message Number in line %d of file %s\n",lineNumber,nameFileMessage);
continue;
}

text=strtok(NULL,"\n");
if (text==NULL){
printf("Illegal Message Format in line %d of file %s\n",lineNumber,nameFileMessage);
continue;
}

strcpy(DebugMessages[position].format,text);
DebugMessages[position++].number=msgNumber;
}
}
fclose(mf);
return position;
}

int Messages_Get_Pos(int number) {
int pos;

for (pos=0; DebugMessages[pos].number !=-1; pos++)
if (DebugMessages[pos].number==number)
return pos;

return -1;
}
@@ -0,0 +1,20 @@
#ifndef MESSAGES_H
#define MESSAGES_H

#define NUMBEROFMSGS 64

#define STUDENT_MESSAGES_FILE "messagesSTD.txt"
#define TEACHER_MESSAGES_FILE "messagesTCH.txt"

typedef struct {
int number;
char format[120];
} DEBUG_MESSAGES;

extern DEBUG_MESSAGES DebugMessages[NUMBEROFMSGS];

int Messages_Get_Pos(int number);
int Messages_Load_Messages(int, char *);

#endif

@@ -0,0 +1,16 @@
#include "Clock.h"
#include "Asserts.h"


before(): execution(void Processor_FetchInstruction()) {
Clock_Update();
}

after(): execution(void Processor_DecodeAndExecuteInstruction()){
Asserts_CheckAsserts();
}

before(): execution(void OperatingSystem_InterruptLogic(int)){
Clock_Update();
}

Large diffs are not rendered by default.

@@ -0,0 +1,70 @@
#ifndef OPERATINGSYSTEM_H
#define OPERATINGSYSTEM_H

#include "ComputerSystem.h"
#include <stdio.h>


#define SUCCESS 1
#define PROGRAMDOESNOTEXIST -1
#define PROGRAMNOTVALID -2

#define USERPROGRAM (unsigned int) 0
#define DAEMONPROGRAM (unsigned int) 1

#define MAXLINELENGTH 150

#define PROCESSTABLEMAXSIZE 4

#define INITIALPID 0

// In this version, every process occupies a 60 positions main memory chunk
// so we can use 60 positions for OS code and the system stack
#define MAINMEMORYSECTIONSIZE (MAINMEMORYSIZE / (PROCESSTABLEMAXSIZE+1))

#define NOFREEENTRY -3
#define TOOBIGPROCESS -4

#define NOPROCESS -1
#define NUMBEROFQUEUES 2
#define USERPROCESSQUEUE 0
#define DAEMONSQUEUE 1

//Constants for the statesNames
#define NEW_STATE 0
#define READY_STATE 1
#define EXECUTING_STATE 2
#define BLOCKED_STATE 3
#define EXIT_STATE 4

// Enumerated type containing all the possible process states
enum ProcessStates { NEW, READY, EXECUTING, BLOCKED, EXIT};

// Enumerated type containing the list of system calls and their numeric identifiers
enum SystemCallIdentifiers { SYSCALL_END=3,SYSCALL_YIELD=4, SYSCALL_PRINTEXECPID=5};

// A PCB contains all of the information about a process that is needed by the OS
typedef struct {
int busy;
int initialPhysicalAddress;
int processSize;
int state;
int priority;
int copyOfPCRegister;
unsigned int copyOfPSWRegister;
int programListIndex;
int queueID;
} PCB;

// These "extern" declaration enables other source code files to gain access
// to the variable listed
extern PCB processTable[PROCESSTABLEMAXSIZE];
extern int OS_address_base;
extern int sipID;

// Functions prototypes
void OperatingSystem_Initialize();
void OperatingSystem_InterruptLogic(int);


#endif

Large diffs are not rendered by default.

Large diffs are not rendered by default.

@@ -0,0 +1,160 @@
#include "OperatingSystemBase.h"
#include "OperatingSystem.h"
#include "Processor.h"
#include "Buses.h"
#include <string.h>
#include <ctype.h>
#include <stdlib.h>

// Code that students should NOT touch
int OperatingSystem_lineBeginsWithANumber(char *);

// Search for a free entry in the process table. The index of the selected entry
// will be used as the process identifier
int OperatingSystem_ObtainAnEntryInTheProcessTable() {

int orig=INITIALPID%PROCESSTABLEMAXSIZE;
int index=0;
int entry;

while (index<PROCESSTABLEMAXSIZE) {
entry = (orig+index)%PROCESSTABLEMAXSIZE;
if (processTable[entry].busy==0)
return entry;
else
index++;
}
return NOFREEENTRY;
}


// Returns the size of the program, stored in the program file
int OperatingSystem_ObtainProgramSize(FILE **programFile, char *program) {

char lineRead[MAXLINELENGTH];
int isComment=1;
int programSize;

*programFile= fopen(program, "r");

// Check if programFile exists
if (*programFile==NULL)
return PROGRAMDOESNOTEXIST;

// Read the first number as the size of the program. Skip all comments.
while (isComment==1) {
if (fgets(lineRead, MAXLINELENGTH, *programFile) == NULL)
return PROGRAMNOTVALID;
else
if (lineRead[0]!='/' && lineRead[0]!='\n') { // Line IS NOT a comment
isComment=0;
if (OperatingSystem_lineBeginsWithANumber(lineRead))
programSize=atoi(strtok(lineRead," "));
else
return PROGRAMNOTVALID;
}
}
// Only sizes above 0 are allowed
if (programSize<=0)
return PROGRAMNOTVALID;
else
return programSize;
}


// Returns the priority of the program, stored in the program file
int OperatingSystem_ObtainPriority(FILE *programFile) {

char lineRead[MAXLINELENGTH];
int isComment=1;
int processPriority;

// Read the second number as the priority of the program. Skip all comments.
while (isComment==1) {
if (fgets(lineRead, MAXLINELENGTH, programFile) == NULL)
return PROGRAMNOTVALID;
else
if (lineRead[0]!='/' && lineRead[0]!='\n') { // Line IS NOT a comment
isComment=0;
if (OperatingSystem_lineBeginsWithANumber(lineRead))
processPriority=atoi(strtok(lineRead," "));
else
return PROGRAMNOTVALID;
}
}
return processPriority;
}


// Function that processes the contents of the file named by the first argument
// in order to load it in main memory from the address given as the second
// argument
// IT IS NOT NECESSARY TO COMPLETELY UNDERSTAND THIS FUNCTION

int OperatingSystem_LoadProgram(FILE *programFile, int initialAddress, int size) {

char lineRead[MAXLINELENGTH];
char *token0, *token1, *token2;
MEMORYCELL data;
int nbInstructions = 0;

Processor_SetMAR(initialAddress);
while (fgets(lineRead, MAXLINELENGTH, programFile) != NULL) {
// REMARK: if lineRead is greater than MAXLINELENGTH in number of characters, the program
// loading does not work
data.operationCode=' ';data.operand1=data.operand2=0;
token0=strtok(lineRead," ");
if (token0!=NULL && token0[0]!='/' && token0[0]!='\n') {
// I have an instruction with, at least, an operation code
data.operationCode=tolower(token0[0]);
token1=strtok(NULL," ");
if (token1!=NULL && token1[0]!='/') {
// I have an instruction with, at least, an operand
data.operand1=atoi(token1);
token2=strtok(NULL," ");
if (token2!=NULL && token2[0]!='/') {
// The read line is similar to 'sum 2 3 //coment'
// I have an instruction with two operands
data.operand2=atoi(token2);
}
}

// More instructions than size...
if (++nbInstructions > size){
return TOOBIGPROCESS;
}

Processor_SetMBR(&data);
// Send data to main memory using the system buses
Buses_write_DataBus_From_To(CPU, MAINMEMORY);
Buses_write_AddressBus_From_To(CPU, MAINMEMORY);
// Tell the main memory controller to write
MainMemory_writeMemory();
Processor_SetMAR(Processor_GetMAR()+1);
}
}
return SUCCESS;
}


// Auxiliar for check that line begins with positive number
int OperatingSystem_lineBeginsWithANumber(char * line) {
int i;

for (i=0; i<strlen(line) && line[i]==' '; i++); // Don't consider blank spaces
// If is there a digit number...
if (i<strlen(line) && isdigit(line[i]))
// It's a positive number
return 1;
else
return 0;
}


void OperatingSystem_ReadyToShutdown(){
// Simulation must finish (done by modifying the PC of the System Idle Process so it points to its 'halt' instruction,
// located at the last memory position used by that process, and dispatching sipId (next ShortTermSheduled)
processTable[sipID].copyOfPCRegister=processTable[sipID].initialPhysicalAddress+processTable[sipID].processSize-1;

}

@@ -0,0 +1,14 @@
#ifndef OPERATINGSYSTEMBASE_H
#define OPERATINGSYSTEMBASE_H

#include "ComputerSystem.h"
#include <stdio.h>

// Prototypes of OS functions that students should not change
int OperatingSystem_ObtainAnEntryInTheProcessTable();
int OperatingSystem_ObtainProgramSize(FILE **, char *);
int OperatingSystem_ObtainPriority(FILE *);
int OperatingSystem_LoadProgram(FILE *, int, int);
void OperatingSystem_ReadyToShutdown();

#endif
@@ -0,0 +1,8 @@
11
YRET // Initial Operation for OS
// Here interrupt vector
OS 2 // SysCall Interrupt
YRET
OS 6 // Exception Interrupt
YRET

Large diffs are not rendered by default.

@@ -0,0 +1,52 @@
#ifndef PROCESSOR_H
#define PROCESSOR_H

#include "MainMemory.h"

#define INTERRUPTTYPES 10

// Enumerated type that connects bit positions in the PSW register with
// processor events and status
enum PSW_BITS {POWEROFF_BIT=0, ZERO_BIT=1, NEGATIVE_BIT=2, OVERFLOW_BIT=3, EXECUTION_MODE_BIT=7};

// Enumerated type that connects bit positions in the interruptLines with
// interrupt types
enum INT_BITS {SYSCALL_BIT=2, EXCEPTION_BIT=6};

// Functions prototypes
void Processor_InitializeInterruptVectorTable();
void Processor_InstructionCycleLoop();
void Processor_CopyInSystemStack(int, int);
int Processor_CopyFromSystemStack(int);
unsigned int Processor_PSW_BitState(const unsigned int);
char * Processor_ShowPSW();

// The OS needs to access MAR and MBR registers to save the context of
// the process to which the processor is being assigned
// Buses needs to access MAR and MBR
int Processor_GetMAR();
void Processor_SetMAR(int);
void Processor_GetMBR(MEMORYCELL *);
void Processor_SetMBR(MEMORYCELL *);
// int Processor_GetMBR_Value();

// The OS needs to access the accumulator register to restore the context of
// the process to which the processor is being assigned and to save the context
// of the process being preempted for another ready process
// void Processor_SetAccumulator(int);
// int Processor_GetAccumulator();

// The OS needs to access the PC register to restore the context of
// the process to which the processor is being assigned
void Processor_SetPC(int);

// The OS needs to access register A to when executing the system call management
// routine, so it will be able to know the invoked system call identifier
int Processor_GetRegisterA();

// The OS needs to access the PSW register to restore the context of
// the process to which the processor is being assigned
void Processor_SetPSW(unsigned int);

unsigned int Processor_GetPSW();
#endif

Large diffs are not rendered by default.

Large diffs are not rendered by default.

BIN +75.2 KB V1/Simulator
Binary file not shown.
@@ -0,0 +1,21 @@
#include <stdio.h>
#include <stdlib.h>
#include "Simulator.h"
#include "ComputerSystem.h"


int main(int argc, char *argv[]) {

// We now have a multiprogrammed computer system
// No more than PROGRAMSMAXNUMBER in the command line
if ((argc < 3) || (argc>PROGRAMSMAXNUMBER+2)) {
printf("USE: Simulator <sections to be debugged> <program1> [<program2> <program3> ....] \n");
exit(-1);
}

// The simulation starts
ComputerSystem_PowerOn(argc, argv);
// The simulation ends
ComputerSystem_PowerOff();
return 0;
}
@@ -0,0 +1,11 @@
#ifndef SIMULADOR_H
#define SIMULADOR_H


// General constants for the simulation

// Maximum number of programs in the command line plus daemons programs
#define PROGRAMSMAXNUMBER 20


#endif
@@ -0,0 +1,9 @@
// System Idle Process
// run NOP + JUMP to NOP indefinitely
4 // Program size in memory cells
100 // Priority of process (very low priority)

ADD 1301 417
NOP
JUMP -1 // Jump to NOP
HALT
BIN +81.5 KB V1/UO258654.zip
Binary file not shown.
Binary file not shown.
BIN +1.78 KB V1/V1-1-UOxxxx.zip
Binary file not shown.
@@ -0,0 +1,200 @@
20 Messages Loaded
Asserts file unavailable
User program list:
Program [programWhichDoesNotExist] with arrival time [0]
Program [programInvalidPriority] with arrival time [0]
Program [programInvalidSize] with arrival time [0]
Program [programTooBig] with arrival time [0]
Program [programWithTooManyInstructions] with arrival time [0]
Program [programMEMADD] with arrival time [0]
Process [0] created from program [SystemIdleProcess]
ERROR: Program [programWhichDoesNotExist] is not valid [---it does not exist---]
ERROR: Program [programInvalidPriority] is not valid [---it does not exist---]
ERROR: Program [programInvalidSize] is not valid [---invalid priority or size---]
ERROR: Program [programTooBig] is too big
ERROR: Program [programWithTooManyInstructions] is too big
ERROR: Program [programMEMADD] is not valid [---invalid priority or size---]
New Tick (1)
y 0 0 (PC: 0, Accumulator: 0, PSW: 130 [--------X-----Z-])
New Tick (2)
a 100 6 (PC: 1, Accumulator: 106, PSW: 128 [--------X-------])
New Tick (3)
n 0 0 (PC: 2, Accumulator: 106, PSW: 128 [--------X-------])
New Tick (4)
j -1 0 (PC: 1, Accumulator: 106, PSW: 128 [--------X-------])
New Tick (5)
n 0 0 (PC: 2, Accumulator: 106, PSW: 128 [--------X-------])
New Tick (6)
j -1 0 (PC: 1, Accumulator: 106, PSW: 128 [--------X-------])
New Tick (7)
n 0 0 (PC: 2, Accumulator: 106, PSW: 128 [--------X-------])
New Tick (8)
j -1 0 (PC: 1, Accumulator: 106, PSW: 128 [--------X-------])
New Tick (9)
n 0 0 (PC: 2, Accumulator: 106, PSW: 128 [--------X-------])
New Tick (10)
j -1 0 (PC: 1, Accumulator: 106, PSW: 128 [--------X-------])
New Tick (11)
n 0 0 (PC: 2, Accumulator: 106, PSW: 128 [--------X-------])
New Tick (12)
j -1 0 (PC: 1, Accumulator: 106, PSW: 128 [--------X-------])
New Tick (13)
n 0 0 (PC: 2, Accumulator: 106, PSW: 128 [--------X-------])
New Tick (14)
j -1 0 (PC: 1, Accumulator: 106, PSW: 128 [--------X-------])
New Tick (15)
n 0 0 (PC: 2, Accumulator: 106, PSW: 128 [--------X-------])
New Tick (16)
j -1 0 (PC: 1, Accumulator: 106, PSW: 128 [--------X-------])
New Tick (17)
n 0 0 (PC: 2, Accumulator: 106, PSW: 128 [--------X-------])
New Tick (18)
j -1 0 (PC: 1, Accumulator: 106, PSW: 128 [--------X-------])
New Tick (19)
n 0 0 (PC: 2, Accumulator: 106, PSW: 128 [--------X-------])
New Tick (20)
j -1 0 (PC: 1, Accumulator: 106, PSW: 128 [--------X-------])
New Tick (21)
n 0 0 (PC: 2, Accumulator: 106, PSW: 128 [--------X-------])
New Tick (22)
j -1 0 (PC: 1, Accumulator: 106, PSW: 128 [--------X-------])
New Tick (23)
n 0 0 (PC: 2, Accumulator: 106, PSW: 128 [--------X-------])
New Tick (24)
j -1 0 (PC: 1, Accumulator: 106, PSW: 128 [--------X-------])
New Tick (25)
n 0 0 (PC: 2, Accumulator: 106, PSW: 128 [--------X-------])
New Tick (26)
j -1 0 (PC: 1, Accumulator: 106, PSW: 128 [--------X-------])
New Tick (27)
n 0 0 (PC: 2, Accumulator: 106, PSW: 128 [--------X-------])
New Tick (28)
j -1 0 (PC: 1, Accumulator: 106, PSW: 128 [--------X-------])
New Tick (29)
n 0 0 (PC: 2, Accumulator: 106, PSW: 128 [--------X-------])
New Tick (30)
j -1 0 (PC: 1, Accumulator: 106, PSW: 128 [--------X-------])
New Tick (31)
n 0 0 (PC: 2, Accumulator: 106, PSW: 128 [--------X-------])
New Tick (32)
j -1 0 (PC: 1, Accumulator: 106, PSW: 128 [--------X-------])
New Tick (33)
n 0 0 (PC: 2, Accumulator: 106, PSW: 128 [--------X-------])
New Tick (34)
j -1 0 (PC: 1, Accumulator: 106, PSW: 128 [--------X-------])
New Tick (35)
n 0 0 (PC: 2, Accumulator: 106, PSW: 128 [--------X-------])
New Tick (36)
j -1 0 (PC: 1, Accumulator: 106, PSW: 128 [--------X-------])
New Tick (37)
n 0 0 (PC: 2, Accumulator: 106, PSW: 128 [--------X-------])
New Tick (38)
j -1 0 (PC: 1, Accumulator: 106, PSW: 128 [--------X-------])
New Tick (39)
n 0 0 (PC: 2, Accumulator: 106, PSW: 128 [--------X-------])
New Tick (40)
j -1 0 (PC: 1, Accumulator: 106, PSW: 128 [--------X-------])
New Tick (41)
n 0 0 (PC: 2, Accumulator: 106, PSW: 128 [--------X-------])
New Tick (42)
j -1 0 (PC: 1, Accumulator: 106, PSW: 128 [--------X-------])
New Tick (43)
n 0 0 (PC: 2, Accumulator: 106, PSW: 128 [--------X-------])
New Tick (44)
j -1 0 (PC: 1, Accumulator: 106, PSW: 128 [--------X-------])
New Tick (45)
n 0 0 (PC: 2, Accumulator: 106, PSW: 128 [--------X-------])
New Tick (46)
j -1 0 (PC: 1, Accumulator: 106, PSW: 128 [--------X-------])
New Tick (47)
n 0 0 (PC: 2, Accumulator: 106, PSW: 128 [--------X-------])
New Tick (48)
j -1 0 (PC: 1, Accumulator: 106, PSW: 128 [--------X-------])
New Tick (49)
n 0 0 (PC: 2, Accumulator: 106, PSW: 128 [--------X-------])
New Tick (50)
j -1 0 (PC: 1, Accumulator: 106, PSW: 128 [--------X-------])
New Tick (51)
n 0 0 (PC: 2, Accumulator: 106, PSW: 128 [--------X-------])
New Tick (52)
j -1 0 (PC: 1, Accumulator: 106, PSW: 128 [--------X-------])
New Tick (53)
n 0 0 (PC: 2, Accumulator: 106, PSW: 128 [--------X-------])
New Tick (54)
j -1 0 (PC: 1, Accumulator: 106, PSW: 128 [--------X-------])
New Tick (55)
n 0 0 (PC: 2, Accumulator: 106, PSW: 128 [--------X-------])
New Tick (56)
j -1 0 (PC: 1, Accumulator: 106, PSW: 128 [--------X-------])
New Tick (57)
n 0 0 (PC: 2, Accumulator: 106, PSW: 128 [--------X-------])
New Tick (58)
j -1 0 (PC: 1, Accumulator: 106, PSW: 128 [--------X-------])
New Tick (59)
n 0 0 (PC: 2, Accumulator: 106, PSW: 128 [--------X-------])
New Tick (60)
j -1 0 (PC: 1, Accumulator: 106, PSW: 128 [--------X-------])
New Tick (61)
n 0 0 (PC: 2, Accumulator: 106, PSW: 128 [--------X-------])
New Tick (62)
j -1 0 (PC: 1, Accumulator: 106, PSW: 128 [--------X-------])
New Tick (63)
n 0 0 (PC: 2, Accumulator: 106, PSW: 128 [--------X-------])
New Tick (64)
j -1 0 (PC: 1, Accumulator: 106, PSW: 128 [--------X-------])
New Tick (65)
n 0 0 (PC: 2, Accumulator: 106, PSW: 128 [--------X-------])
New Tick (66)
j -1 0 (PC: 1, Accumulator: 106, PSW: 128 [--------X-------])
New Tick (67)
n 0 0 (PC: 2, Accumulator: 106, PSW: 128 [--------X-------])
New Tick (68)
j -1 0 (PC: 1, Accumulator: 106, PSW: 128 [--------X-------])
New Tick (69)
n 0 0 (PC: 2, Accumulator: 106, PSW: 128 [--------X-------])
New Tick (70)
j -1 0 (PC: 1, Accumulator: 106, PSW: 128 [--------X-------])
New Tick (71)
n 0 0 (PC: 2, Accumulator: 106, PSW: 128 [--------X-------])
New Tick (72)
j -1 0 (PC: 1, Accumulator: 106, PSW: 128 [--------X-------])
New Tick (73)
n 0 0 (PC: 2, Accumulator: 106, PSW: 128 [--------X-------])
New Tick (74)
j -1 0 (PC: 1, Accumulator: 106, PSW: 128 [--------X-------])
New Tick (75)
n 0 0 (PC: 2, Accumulator: 106, PSW: 128 [--------X-------])
New Tick (76)
j -1 0 (PC: 1, Accumulator: 106, PSW: 128 [--------X-------])
New Tick (77)
n 0 0 (PC: 2, Accumulator: 106, PSW: 128 [--------X-------])
New Tick (78)
j -1 0 (PC: 1, Accumulator: 106, PSW: 128 [--------X-------])
New Tick (79)
n 0 0 (PC: 2, Accumulator: 106, PSW: 128 [--------X-------])
New Tick (80)
j -1 0 (PC: 1, Accumulator: 106, PSW: 128 [--------X-------])
New Tick (81)
n 0 0 (PC: 2, Accumulator: 106, PSW: 128 [--------X-------])
New Tick (82)
j -1 0 (PC: 1, Accumulator: 106, PSW: 128 [--------X-------])
New Tick (83)
n 0 0 (PC: 2, Accumulator: 106, PSW: 128 [--------X-------])
New Tick (84)
j -1 0 (PC: 1, Accumulator: 106, PSW: 128 [--------X-------])
New Tick (85)
n 0 0 (PC: 2, Accumulator: 106, PSW: 128 [--------X-------])
New Tick (86)
j -1 0 (PC: 1, Accumulator: 106, PSW: 128 [--------X-------])
New Tick (87)
n 0 0 (PC: 2, Accumulator: 106, PSW: 128 [--------X-------])
New Tick (88)
j -1 0 (PC: 1, Accumulator: 106, PSW: 128 [--------X-------])
New Tick (89)
n 0 0 (PC: 2, Accumulator: 106, PSW: 128 [--------X-------])
New Tick (90)
j -1 0 (PC: 1, Accumulator: 106, PSW: 128 [--------X-------])
New Tick (91)
n 0 0 (PC: 2, Accumulator: 106, PSW: 128 [--------X-------])
New Tick (92)
j -1 0 (PC: 1, Accumulator: 106, PSW: 128 [--------X-------])
BIN +24.7 KB V1/V1-2-UO258654.zip
Binary file not shown.
Empty file.
@@ -0,0 +1,2 @@
NOP
TRAP 3
@@ -0,0 +1,18 @@
// Students created messages
// Format: numberOfMessage,textPrintfFormatedWithColourCodes
//
// numbers of messages greather than 100 for students
//
101,User program list:\n
102,\tProgram [@B%s@@] with arrival time [@B%d@@]\n
103,@RERROR: There are not free entries in the process table for the program [%s]\n@@
104,@RERROR: Program [%s] is not valid [%s]\n@@
105,@RERROR: Program [%s] is too big\n@@
106,Ready-to-run process queue: \n
107,[@G%d@@,%d]
108,\n
110,Process [@G%d@@] moving from the [@G%s@@] state to the [@G%s@@] state\n
111,New process [@G%d@@] moving to the [@G%s@@]\n
112,\tUSER:
113,\tDAEMONS:
1100,PETA AQUI REDIOS
@@ -0,0 +1,28 @@
// Processor messages
1,%c %d %d
2,_ _ _
3, (PC: @R%d@@, Accumulator: @R%d@@, PSW: @R%d@@ [@R%s@@])\n


// OperatingSystem messages
21,@RERROR: Missing SIP program!@@\n
22,@GProcess [%d] created from program [%s]@@\n
23,@RProcess [%d] has generated an exception and is terminating@@\n
24,@RProcess [%d] has the processor assigned@@\n
25,@RProcess [%d] has requested to terminate@@\n

// Assert system messages
90,@RAssert failed. Time:@@ %d@R; Element:@@ %s;
91,@R Expected:@@ %c@R; Real:@@ %c
92,@R Expected:@@ %d@R; Real:@@ %d
93,@R; Memory address:@@ %d

// Time
97,New Tick (%d)\n

// Formating and generic messages
98,%s

// ComputerSystem messages
99,@REND of the simulation@@\n

@@ -0,0 +1,4 @@
-3
2
ADD 10 1
HALT
@@ -0,0 +1,9 @@
55

ADD 0 0
MEMADD 1 33
WRITE 33
INC -7
ZJUMP 2
JUMP -4
HALT
@@ -0,0 +1,7 @@

65
2
ADD 100 6
WRITE 7
NOP
TRAP 3
@@ -0,0 +1,7 @@

1
2
ADD 100 6
WRITE 7
NOP
TRAP 3
@@ -0,0 +1,7 @@

30
5
NOP
ADD 10 -13
WRITE 15
TRAP 3
@@ -0,0 +1,7 @@

30
-1
NOP
ADD 10 -13
WRITE 15
TRAP 3
@@ -0,0 +1,7 @@

1
2
ADD 100 6
WRITE 7
NOP
TRAP 3
@@ -0,0 +1,2 @@
The 12 exercise has been implemented (not tested), except from the check of the process type (as the exercise 11 was not finished)
The log will be empty, as I did not have time to execute them.
Empty file.
BIN +12 KB V2/.readme.txt.swp
Binary file not shown.
BIN +12 KB V2/.swp
Binary file not shown.
@@ -0,0 +1,394 @@
#include "Asserts.h"
#include <string.h>
#include <stdio.h>
#include "MainMemory.h"
#include "Clock.h"
#include "ComputerSystemBase.h"
#include "MMU.h"
#include "Heap.h"

extern MEMORYCELL mainMemory[];
extern int registerPC_CPU; // Program counter
extern int registerAccumulator_CPU; // Accumulator
extern MEMORYCELL registerIR_CPU; // Instruction register
extern unsigned int registerPSW_CPU; // Processor state word
extern int registerMAR_CPU; // Memory Address Register
extern MEMORYCELL registerMBR_CPU; // Memory Buffer Register
extern int executingProcessID; // Executing process PID


char *elements[]={
"RMEM_OP",
"RMEM_O1",
"RMEM_O2",
"AMEM_OP",
"AMEM_O1",
"AMEM_O2",
"PC",
"ACC",
"IR_OP",
"IR_O1",
"IR_O2",
"PSW",
"MAR",
"MBR_OP",
"MBR_O1",
"MBR_O2",
"MMU_BS",
"MMU_LM",
"MMU_MAR",
"MMEM_MAR",
"MMBR_OP",
"MMBR_O1",
"MMBR_O2",
"XPID",
NULL};

ASSERT_DATA asserts[MAX_ASSERTS];

// Montículo de asertos
int assertsQueue[MAX_ASSERTS];
int numOfElementsInAssertsQueue=0;

// La lista de asertos en todos los instantes está al final de la assertsQueue metida al revés
int beginOfAllTimeAsserts=MAX_ASSERTS;

// prototype functions
int Asserts_IsThereANewAssert(int);
void Asserts_CheckOneAssert(int);

extern int GEN_ASSERTS;

int elementNumber(char *cmp) {
int n=0;

while ((elements[n]!=NULL) && strcmp(cmp, elements[n]))
n++;

if (elements[n]==NULL) return -1;
else return n;

}

void strcmpSpaces(char *target, char *src, int nChars) {
int l, s, t;

l=strlen(src);
t=0;
for (s=0; (t<nChars-1) && (s<l); s++) {
if (src[s]!=' ') target[t++]=src[s];
}
target[t]=0;
}

int Asserts_LoadAsserts() {
// leer el fichero e ir almacenando en cada elemento lo que sea;
ASSERT_DATA a;

char lineRead[MAXIMUMLENGTH];
FILE *mf;
char *time, *element, *value, *address;
char svalue[E_SIZE];


int lineNumber=0;;
int numberAsserts=0;
int rc;
int en;

mf=fopen(ASSERTS_FILE, "r");
if (mf==NULL) {
asserts[0].time=-1;
return -1;
}

while (fgets(lineRead,MAXIMUMLENGTH, mf) != NULL && numberAsserts<MAX_ASSERTS) {
lineNumber++;
// Leemos hasta 4 elementos por aserto
time=strtok(lineRead,",");
if (time==NULL){
printf("Illegal Assert in line %d of file %s\n",lineNumber,ASSERTS_FILE);
continue;
}

if ((time[0]=='/') || (time[0]=='\n'))
continue;

element=strtok(NULL,",");
if (element==NULL){
printf("Illegal Assert in line %d of file %s\n",lineNumber,ASSERTS_FILE);
continue;
}

value=strtok(NULL,",");
if (value==NULL){
printf("Illegal Assert in line %d of file %s\n",lineNumber,ASSERTS_FILE);
continue;
}
address=strtok(NULL,"\n");

//printf("-> %s, %s, %s, %s\n",time, element, value, address);

strcmpSpaces(a.element, element,E_SIZE);
if (strcmp(time,"*")) {
rc=sscanf(time,"%d",&a.time);
if (rc==0){
printf("Illegal time format in line %d of file %s\n",lineNumber,ASSERTS_FILE);
continue;
}
}
else a.time=-33; // All the instants of time.

//printf("-%s-\n",a.element);
// Si vamos a verificar un código de operación leemos un char (RMEM_OP, AMEM_OP,IR_OP, MBR_OP, MMBR_OP)
en=elementNumber(a.element);
if ((en==RMEM_OP) || (en==AMEM_OP) || (en==IR_OP) || (en==MBR_OP) || (en==MMBR_OP)) {
strcmpSpaces(svalue, value,E_SIZE);
rc=sscanf(svalue,"%c",(char *) &a.value);

}
else
rc=sscanf(value,"%d",&a.value);

if (rc==0){
printf("Illegal expected value format in line %d of file %s (%s)\n",lineNumber,ASSERTS_FILE,value);
continue;
}

// Si vamos a verificar una posición de memoria leemos la dirección (RMEM_OP, RMEM_O1, RMEM_O2, AMEM_OP, AMEM_O1, AMEM_O2)
en=elementNumber(a.element);
if ((en==RMEM_OP) || (en==RMEM_O1) || (en==RMEM_O2) || (en==AMEM_OP) || (en==AMEM_O1) || (en==AMEM_O2)) {
if (address==NULL){
printf("Illegal Assert in line %d of file %s\n",lineNumber,ASSERTS_FILE);
continue;
}
rc=sscanf(address,"%d",&a.address);
if (rc==0){
printf("Illegal address format in line %d of file %s\n",lineNumber,ASSERTS_FILE);
continue;
}
}
else a.address=0;

asserts[numberAsserts]=a;

if (a.time!=-33)
// Lo mete en cola de asertos
Heap_add(numberAsserts,assertsQueue,QUEUE_ASSERTS,&numOfElementsInAssertsQueue,MAX_ASSERTS);
else
// Lo mete en lista al final y guarda donde empiezan los asertos sin tiempo
assertsQueue[--beginOfAllTimeAsserts]=numberAsserts;

numberAsserts++;
}
fclose(mf);
if (numberAsserts==MAX_ASSERTS)
printf("Warning maximun number of asserts reached !!! (%d)\n",numberAsserts);
else
asserts[numberAsserts].time=-1; // Para indicar el fin de los asertos (sobraría)
return numberAsserts;
}


void genAssertMsg(int time, char *ele, int realValue, int addr) {
int en;

printf("%d, %s",time, ele);
en=elementNumber(ele);

if ((en==RMEM_OP) || (en==AMEM_OP) || (en==IR_OP) || (en==MBR_OP))
printf(", %c",realValue);
else
printf(", %d", realValue);

if ((en==RMEM_OP) || (en==RMEM_O1) || (en==RMEM_O2) || (en==AMEM_OP) || (en==AMEM_O1) || (en==AMEM_O2))
printf(", %d", addr);

printf("\n");
}

void assertMsg(int time, char *ele, int expectedValue, int realValue, int addr) {
int en;

if (GEN_ASSERTS) {
genAssertMsg(time, ele, realValue,addr);
return;
}

// printf("Assert failed. Time: %d; Element: %s; ", time, ele);
ComputerSystem_DebugMessage(90,ERROR, time, ele);
en=elementNumber(ele);

if ((en==RMEM_OP) || (en==AMEM_OP) || (en==IR_OP) || (en==MBR_OP))
// printf("Expected: '%c'; Real: '%c'", expectedValue, realValue);
ComputerSystem_DebugMessage(91,ERROR, expectedValue, realValue);
else
// printf("Expected: %d; Real: %d", expectedValue, realValue);
ComputerSystem_DebugMessage(92,ERROR, expectedValue, realValue);

if ((en==RMEM_OP) || (en==RMEM_O1) || (en==RMEM_O2) || (en==AMEM_OP) || (en==AMEM_O1) || (en==AMEM_O2))
// printf("; Memory address: %d", addr);
ComputerSystem_DebugMessage(93,ERROR, addr);

// printf("\n");
ComputerSystem_DebugMessage(98, ERROR, "\n");
}


void Asserts_CheckAsserts(){
int na;
int globalCounter=Clock_GetTime();

// Checking unique time asserts
while (Asserts_IsThereANewAssert(globalCounter)>0) {
na=Heap_poll(assertsQueue,QUEUE_ASSERTS,&numOfElementsInAssertsQueue);
// if ((asserts[na].time==globalCounter) || (asserts[na].time==-33)) {
if ((asserts[na].time==globalCounter)/* || (asserts[na].time==-33)*/) {
Asserts_CheckOneAssert(na);
}
else {
ComputerSystem_DebugMessage(95,ERROR,asserts[na].time,asserts[na].element);
}
}

na=beginOfAllTimeAsserts;

// Checking asserts for all time
while (na<MAX_ASSERTS) {
Asserts_CheckOneAssert(assertsQueue[na++]);
}
}

void Asserts_CheckOneAssert(int na){
MEMORYCELL data;
int op=elementNumber(asserts[na].element);
int globalCounter=Clock_GetTime();

switch (op) {
case RMEM_OP:
if ((mainMemory[MMU_GetBase()+asserts[na].address].operationCode!=(char)asserts[na].value) || GEN_ASSERTS)
assertMsg(globalCounter,"RMEM_OP",asserts[na].value,mainMemory[MMU_GetBase()+asserts[na].address].operationCode,asserts[na].address);
break;
case RMEM_O1:
if ((mainMemory[MMU_GetBase()+asserts[na].address].operand1!=(char)asserts[na].value) || GEN_ASSERTS)
assertMsg(globalCounter,"RMEM_O1",asserts[na].value,mainMemory[MMU_GetBase()+asserts[na].address].operand1,asserts[na].address);
break;
case RMEM_O2:
if ((mainMemory[MMU_GetBase()+asserts[na].address].operand2!=(char)asserts[na].value) || GEN_ASSERTS)
assertMsg(globalCounter,"RMEM_O2",asserts[na].value,mainMemory[MMU_GetBase()+asserts[na].address].operand2,asserts[na].address);
break;
case AMEM_OP:
if ((mainMemory[asserts[na].address].operationCode!=(char)asserts[na].value) || GEN_ASSERTS)
assertMsg(globalCounter,"AMEM_OP",asserts[na].value,mainMemory[asserts[na].address].operationCode,asserts[na].address);
break;
case AMEM_O1:
if ((mainMemory[asserts[na].address].operand1!=asserts[na].value)|| GEN_ASSERTS)
assertMsg(globalCounter,"AMEM_01",asserts[na].value,mainMemory[asserts[na].address].operand1,asserts[na].address);
break;
case AMEM_O2:
if ((mainMemory[asserts[na].address].operand2!=asserts[na].value)|| GEN_ASSERTS)
assertMsg(globalCounter,"AMEM_02",asserts[na].value,mainMemory[asserts[na].address].operand2,asserts[na].address);
break;
case PC:
if ((registerPC_CPU!=asserts[na].value)|| GEN_ASSERTS)
assertMsg(globalCounter,"PC",asserts[na].value,registerPC_CPU,0);
break;
case ACC:
if ((registerAccumulator_CPU!=asserts[na].value)|| GEN_ASSERTS)
assertMsg(globalCounter,"ACC",asserts[na].value,registerAccumulator_CPU,0);
break;
case IR_OP:
if ((registerIR_CPU.operationCode!=(char) asserts[na].value)|| GEN_ASSERTS)
assertMsg(globalCounter,"IR_OP",asserts[na].value,registerIR_CPU.operationCode,0);
break;
case IR_O1:
if ((registerIR_CPU.operand1!= asserts[na].value)|| GEN_ASSERTS)
assertMsg(globalCounter,"IR_01",asserts[na].value,registerIR_CPU.operand1,0);
break;
case IR_O2:
if ((registerIR_CPU.operand2!=asserts[na].value)|| GEN_ASSERTS)
assertMsg(globalCounter,"IR_02",asserts[na].value,registerIR_CPU.operand2,0);
break;
case PSW:
if ((registerPSW_CPU!=asserts[na].value)|| GEN_ASSERTS)
assertMsg(globalCounter,"PSW",asserts[na].value,registerPSW_CPU,0);
break;
case MAR:
if ((registerMAR_CPU!=asserts[na].value)|| GEN_ASSERTS)
assertMsg(globalCounter,"MAR",asserts[na].value,registerMAR_CPU,0);
break;
case MBR_OP:
if ((registerMBR_CPU.operationCode!=(char) asserts[na].value)|| GEN_ASSERTS)
assertMsg(globalCounter,"MBR_OP",asserts[na].value,registerMBR_CPU.operationCode,0);
break;
case MBR_O1:
if ((registerMBR_CPU.operand1!= asserts[na].value)|| GEN_ASSERTS)
assertMsg(globalCounter,"MBR_O1",asserts[na].value,registerMBR_CPU.operand1,0);
break;
case MBR_O2:
if ((registerMBR_CPU.operand2!=asserts[na].value) || GEN_ASSERTS)
assertMsg(globalCounter,"MBR_02",asserts[na].value,registerMBR_CPU.operand2,0);
break;
case MMU_BS:
if ((MMU_GetBase()!=asserts[na].value) || GEN_ASSERTS)
assertMsg(globalCounter,"MMU_BS",asserts[na].value,MMU_GetBase(),0);
break;
case MMU_LM:
if ((MMU_GetLimit()!=asserts[na].value) || GEN_ASSERTS)
assertMsg(globalCounter,"MMU_LM",asserts[na].value,MMU_GetLimit(),0);
break;
case MMU_MAR:
if ((MMU_GetMAR()!=asserts[na].value) || GEN_ASSERTS)
assertMsg(globalCounter,"MMU_MAR",asserts[na].value,MMU_GetMAR(),0);
break;
case MMEM_MAR:
if ((MainMemory_GetMAR()!=asserts[na].value) || GEN_ASSERTS)
assertMsg(globalCounter,"MMEM_MAR",asserts[na].value,MainMemory_GetMAR(),0);
break;
case MMBR_OP:
MainMemory_GetMBR(&data);
if ((data.operationCode!=asserts[na].value) || GEN_ASSERTS)
assertMsg(globalCounter,"MMBR_OP",asserts[na].value,data.operationCode,0);
break;
case MMBR_O1:
MainMemory_GetMBR(&data);
if ((data.operand1!=asserts[na].value) || GEN_ASSERTS)
assertMsg(globalCounter,"MMBR_O1",asserts[na].value,data.operand1,0);
break;
case MMBR_O2:
MainMemory_GetMBR(&data);
if ((data.operand2!=asserts[na].value) || GEN_ASSERTS)
assertMsg(globalCounter,"MMBR_O2",asserts[na].value,data.operand2,0);
break;
case XPID:
if ((executingProcessID!=asserts[na].value) || GEN_ASSERTS)
assertMsg(globalCounter,"XPID",asserts[na].value,executingProcessID,0);
break;
default: ;

}
}

// This function returns:
// -1 if no asserts in assertsQueue
// 1 if any asserts is now
// 0 else
// considered by CheckAsserts to compare at the current time
int Asserts_IsThereANewAssert(int currentTime) {
#ifdef QUEUE_ASSERTS
int indexInAsserts = Heap_getFirst(assertsQueue,numOfElementsInAssertsQueue);

if (indexInAsserts < 0)
return -1; // No new asserts to check

if (asserts[indexInAsserts].time <= currentTime)
return 1; // There'is new assert
#endif
return 0; // No assert in current time
}

void Asserts_TerminateAssertions(){
if (numOfElementsInAssertsQueue)
// printf("Warning, numOfElementsInAssertsQueue unchecked asserts in Asserts queue !!! );
ComputerSystem_DebugMessage(94,ERROR,numOfElementsInAssertsQueue);
};
@@ -0,0 +1,50 @@
#ifndef CHECKASSERTS_H
#define CHECKASSERTS_H

#define MAX_ASSERTS 500
#define MAXIMUMLENGTH 64
#define ASSERTS_FILE "asserts"
#define E_SIZE 8



#define RMEM_OP 0
#define RMEM_O1 1
#define RMEM_O2 2
#define AMEM_OP 3
#define AMEM_O1 4
#define AMEM_O2 5
#define PC 6
#define ACC 7
#define IR_OP 8
#define IR_O1 9
#define IR_O2 10
#define PSW 11
#define MAR 12
#define MBR_OP 13
#define MBR_O1 14
#define MBR_O2 15
#define MMU_BS 16
#define MMU_LM 17
#define MMU_MAR 18
#define MMEM_MAR 19
#define MMBR_OP 20
#define MMBR_O1 21
#define MMBR_O2 22
#define XPID 23

typedef struct {
int time;
int value;
char element[E_SIZE]; // Se almacenará lo arriba indicado o MEM si es un elemento de memoria (o RMEM y AMEM en su caso)
int address;
} ASSERT_DATA;

// Functions prototypes
int Asserts_LoadAsserts();
void Asserts_CheckAsserts();
void Asserts_TerminateAssertions();

extern ASSERT_DATA asserts[MAX_ASSERTS];

#endif