#include <stdio.h>
#include <math.h>
#include <stdlib.h>
/******OPERATION CODE DEFINITIONS********/
//input/output
#define READ 10
#define WRITE 11
#define READSTR 12
#define WRITESTR 13
//load/store
#define LOAD 20
#define STORE 21
//arithmetic
#define ADD 30
#define SUBTRACT 31
#define DIVIDE 32
#define MULTIPLY 33
#define MODULUS 34
#define EXPONENT 35
//transfer of control
#define BRANCH 40
#define BRANCHNEG 41
#define BRANCHZERO 42
#define HALT 43
/****************************************/
#define TRUE 1
#define FALSE 0
#define MEMLOCATIONS 100
//function prototypes
void loadProg(void);
void executeProg(void);
void memoryDump(void);
//external variables
int memory[MEMLOCATIONS] = {0};
int accumulator = 0,
instructionCounter = 0,
instructionRegister = 0,
operationCode = 0,
operand = 0;
main() {
loadProg();
executeProg();
printf("\n");
memoryDump();
return 0;
}
void loadProg(void) {
extern int memory[MEMLOCATIONS];
extern int accumulator, instructionCounter, instructionRegister,
operationCode, operand;
int i = 0, curr_memValue = 0;
printf("\n*** Welcome to Simpletron! ***\n");
printf("\n*** Please enter your program one instruction ***");
printf("\n*** (or data word) at a time. I will type the ***");
printf("\n*** location number and a question mark (?). ***");
printf("\n*** You then type the word for that location. ***");
printf("\n*** Type the sentinel -99999 to stop entering ***");
printf("\n*** your program. ***\n");
while(i < MEMLOCATIONS) {
printf("%02i ? ", i);
scanf("%i", &curr_memValue);
if (curr_memValue == -99999) break;
if ((curr_memValue < -9999) || (curr_memValue > 9999)) {
printf("*** Invalid instruction ***\n");
} else {
memory[i] = curr_memValue;
i++;
}
}
printf("*** Program loading completed ***");
}
void executeProg(void) {
extern int memory[MEMLOCATIONS];
extern int accumulator, instructionCounter, instructionRegister,
operationCode, operand;
int was_control_transfer = FALSE;
int should_halt = FALSE;
int error_condition_halt = FALSE;
printf("\n*** Program execution begins ***");
//pass through every location in memory and perform specified operations
instructionCounter = 0;
while(instructionCounter < MEMLOCATIONS) {
//update flags
was_control_transfer = FALSE;
should_halt = FALSE;
error_condition_halt = FALSE;
//update registers
instructionRegister = memory[instructionCounter];
operationCode = instructionRegister/100;
operand = instructionRegister%100;
//determine type of operation
switch(operationCode) {
case READ:
printf("\n? ");
scanf("%d", &memory[operand]);
break;
case WRITE:
printf("\n%i", memory[operand]);
break;
case LOAD:
accumulator = memory[operand];
break;
case STORE:
memory[operand] = accumulator;
break;
case ADD:
accumulator += memory[operand];
break;
case SUBTRACT:
accumulator -= memory[operand];
break;
case DIVIDE:
if (memory[operand] == 0) {
error_condition_halt = TRUE;
printf("\n*** Attempt to divide by zero ***");
} else accumulator /= memory[operand];
break;
case MULTIPLY:
accumulator *= memory[operand];
break;
case MODULUS:
accumulator %= memory[operand];
break;
case EXPONENT:
accumulator = (int) pow(accumulator, memory[operand]);
break;
case BRANCH:
instructionCounter = operand;
was_control_transfer = TRUE;
break;
case BRANCHNEG:
if(accumulator < 0) {
instructionCounter = operand;
was_control_transfer = TRUE;
}
break;
case BRANCHZERO:
if(accumulator == 0) {
instructionCounter = operand;
was_control_transfer = TRUE;
}
break;
case HALT:
should_halt = TRUE;
break;
default :
error_condition_halt = TRUE;
printf("\n*** Invalid operation code ***");
break;
}//end of switch
//if it was a control transfer, instructionCounter already updated
if(was_control_transfer == FALSE) ++instructionCounter;
//check if there should be a normal halt
if(should_halt == TRUE) {
printf("\n*** Simpletron execution terminated ***");
break;
}
//check if there was an error condition
if(error_condition_halt == TRUE) {
printf("\n*** Simpletron execution abnormally terminated ***");
break;
}
}//end of while
printf("\n");
system("pause");
//memory dump for debug under error condition
if (error_condition_halt == TRUE) memoryDump();
}
void memoryDump(void) {
extern int memory[MEMLOCATIONS];
extern int accumulator, instructionCounter, instructionRegister,
operationCode, operand;
int i = 0;
printf("\nREGISTERS:");
printf("\naccumulator %+05i", accumulator);
printf("\ninstructionCounter %02i", instructionCounter);
printf("\ninstructionRegister %+05i", instructionRegister);
printf("\noperationCode %02i", operationCode);
printf("\noperand %02i", operand);
printf("\nMEMORY:");
printf("\n 0 1 2 3 4 5 6 7 8 9");
for(i = 0; i <= (MEMLOCATIONS-10); i+=10) {
printf("\n%2i %+05i %+05i %+05i %+05i %+05i %+05i %+05i %+05i %+05i %+05i",
i, memory[i], memory[i+1], memory[i+2], memory[i+3], memory[i+4], memory[i+5], memory[i+6], memory[i+7], memory[i+8], memory[i+9]);
if (((i/10) % 10) == 9) {
printf("\n"); system("pause");
}
}
printf("\n");
}