The Problem Using C programming language write a program that simulates the Tiny
ID: 3775974 • Letter: T
Question
The Problem
Using C programming language write a program that simulates the Tiny Machine Architecture. Your code must implement the basic instruction set that the Tiny Machine Architecture adheres to (LOAD[1], ADD[2], STORE[3], SUB[4], IN[5], OUT[6], END[7], JMP[8], SKIPZ[9]). Each piece of the architecture must be accurately represented in your code (Instruction Register, Program Counter, Memory Address Register, Data Memory, Memory Data Register, and Accumulator). Data Memory will be represented by a 0-9 array. Your Program Counter will begin at 10.
For the sake of simplicity Program Memory and Data Memory may be implemented as separate arrays.
Hint: Implementing a struct for your Instructions and an array of these structs as your Program Memory greatly simplifies this program.
Example:
typedef struct {
int opCode, deviceOrAddress;
} Instruction;
Instruction programMemory[MAXPROGRAMSIZE];
Input Specifications
Your simulator must run from the command line with a single input file as a parameter to main. This file will contain a sequence of instructions for your simulator to assemble (store in “program memory”) and then run via the fetch/execute cycle.
Example:
5 5 //IN 5
6 7 //OUT 7
3 0 //STORE 0
5 5 //IN 5
6 7 //OUT 7
3 1 //STORE 1
1 0 //LOAD 0
4 1 //SUB 1
3 0 //STORE 0
6 7 //OUT 7
1 1 //LOAD 1
6 7 //OUT 7
7 0 //END
Output Specifications
Your simulator should provide output according to the input file. Along with this output your program should provide status messages identifying details on the workings of your simulator. Output text does not have to reflect my example word-for-word, but please provide detail on the program as it runs in a readable format that does not conflict with the actual output of your simulator. After each instruction print the current state of the Program Counter, Accumulator, and Data Memory. The INPUT instruction is the only one that should prompt an interaction from the user.
Example:
Assembling Program…
Program Assembled.
Run.
PC = 10 | A = NULL | MEM = [0, 0, 0, 0, 0, 0, 0, 0, 0, 0]
/* input value */
X
PC = 11 | A = X | MEM = [0, 0, 0, 0, 0, 0, 0, 0, 0, 0]
/* outputting accumulator to screen */
X
PC = 12 | A = X | MEM = [0, 0, 0, 0, 0, 0, 0, 0, 0, 0]
/* storing accumulator to memory location 0 */
PC = 13 | A = X | MEM = [X, 0, 0, 0, 0, 0, 0, 0, 0, 0]
… etc
Program complete.
Grading
Your simulator will be graded on the above criteria. Your program should compile and run from the command line with one input file parameter. Please note that your program will not just be graded on whether or not it runs successfully; accurate simulation and a thorough demonstration of your understanding on the workings of this architecture will constitute a large portion of this grade. As that is the case it is in your best interest to comment your program in a concise and readable way. However, if your program does not run or compile the maximum points possible will be 50 (up to 25 may be recovered by debugging and demonstrating an understanding of your errors during TA’s office hours).
For instance, to implement FETCH and instruction LOAD you must implement each step:
FETCH
MAR ß PC
PC ß PC + 1
MDR ß M [MAR]
IR ß MDR
LOAD (Execute cycle)
MAR ß IR.ADDR */
MDR ß MEM[MAR] */
A ß MDR */
Note: Lecture 1 describes the instruction set architecture of the Tiny Machine.
Submission
Your program must be submitted as a C file. For example: NameMyProgram.c
Please check and double check your submission.
Explanation / Answer
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <ctype.h>
//Function used to count the amount of lines in text file
int getProgramSize();
//Function used to parse instruction into machine code
void toMachine();
//Global variable used to store the aforementioned
int MAXPROGRAMSIZE;
//Tiny Machine variables
int programCounter = 10;
int instructionRegister = 0;
int memoryAddressRegister = 0;
int dataMemory[9];
int memoryDataRegister = 0;
int accumulator = 0;
//Creating struct
typedef struct
{
int opCode;
int deviceOrAddress;
}Instruction;
int main(int argc, char *argv[])
{
//This is where we get the size of the program and define it
MAXPROGRAMSIZE = getProgramSize(fopen(argv[argc-1], "r"));
//This creates our struct array based on the amount of instructions
Instruction programMemory[MAXPROGRAMSIZE];
//Reading a file line by line
FILE *file = fopen(argv[argc-1], "r");
char fileBuffer[MAXPROGRAMSIZE];
int i = 0;
if (file == NULL)
{
printf("Error opening file!");
exit(0);
}
//Had to do some manipulation and checks here to make sure I only store the 1st and 3rd char of every line
while(fgets(fileBuffer, sizeof(MAXPROGRAMSIZE), file)!=NULL)
{
if ((*fileBuffer == ' ' || *fileBuffer != ' ') && isdigit(*fileBuffer) && (int)fileBuffer[2] != 0)
{
programMemory[i].opCode = atoi(&fileBuffer[0]);
programMemory[i].deviceOrAddress = atoi(&fileBuffer[2]);
i += 1;
}
}
//Need to close the file
fclose(file);
//Just some text output
printf(" Otis Diaz --- CGS3269 ============================== Tiny Machine Simulator ============================== ");
printf("Assembling program... ");
printf("Program assembled ");
//Get the instruction from our struct and figure out what they mean by passing it into our parser function
for (i=(programCounter/10)-1; i<sizeof(programMemory); i+=1)
{ toMachine(programMemory[i].opCode, programMemory[i].deviceOrAddress); }
printf(" Program concluded... ");
return 0;
}
void toMachine(int a, int b)
{
int i;
//We need to parse the opcode and device/memoryaddress and see what is being asked of us to do and where
//All I can say is.... I am not completely sure that the Tiny Machine works like this
//These were basically conjured from the presented LOAD instructions
//Good ole C, only way I know how to display each index of an array is to loop through it all
switch (a)
{
case 1:
//LOAD
printf(" >> Loading from address [%d]... << ", b);
instructionRegister = b;
memoryAddressRegister = instructionRegister;
memoryDataRegister = dataMemory[memoryAddressRegister];
accumulator = memoryDataRegister;
printf(" PC: %d | A: %d | MEM: [", programCounter, accumulator);
for (i=0; i<9; i+=1)
{ printf("%d,", dataMemory[i]); }
printf("] ");
programCounter += 1;
break;
case 2:
//ADD
printf(" >> Adding accumulator and value obtain from address [%d]... << ", b);
instructionRegister = b;
memoryAddressRegister = instructionRegister;
memoryDataRegister = dataMemory[memoryAddressRegister];
accumulator += memoryDataRegister;
printf(" PC: %d | A: %d | MEM: [", programCounter, accumulator);
for (i=0; i<9; i+=1)
{ printf("%d,", dataMemory[i]); }
printf("] ");
programCounter += 1;
break;
case 3:
//STORE
printf(" >> Storing accumulator value into memory... << ");
memoryDataRegister = accumulator;
instructionRegister = b;
memoryAddressRegister = instructionRegister;
dataMemory[memoryAddressRegister] = memoryDataRegister;
printf(" PC: %d | A: %d | MEM: [", programCounter, accumulator);
for (i=0; i<9; i+=1)
{ printf("%d,", dataMemory[i]); }
printf("] ");
programCounter += 1;
break;
case 4:
//SUB
printf(" >> Subtracting memory address value [%d] from accumulator... << ", b);
instructionRegister = b;
memoryAddressRegister = instructionRegister;
memoryDataRegister = dataMemory[memoryAddressRegister];
accumulator -= memoryDataRegister;
printf(" PC: %d | A: %d | MEM: [", programCounter, accumulator);
for (i=0; i<9; i+=1)
{ printf("%d,", dataMemory[i]); }
printf("] ");
programCounter += 1;
break;
case 5:
//GET INPUT
printf(" Please input a number: ");
scanf("%d", &accumulator);
printf(" PC: %d | A: %d | MEM: [", programCounter, accumulator);
for (i=0; i<9; i+=1)
{ printf("%d,", dataMemory[i]); }
printf("] ");
programCounter += 1;
break;
case 6:
//OUTPUT TO SCREEN
printf(" >> Accumulator current value = %d << ", accumulator);
printf(" PC: %d | A: %d | MEM: [", programCounter, accumulator);
for (i=0; i<9; i+=1)
{ printf("%d,", dataMemory[i]); }
printf("] ");
programCounter += 1;
break;
case 7:
//END PROGRAM
printf(" Program concluded... ");
exit(1);
case 8:
//JMP
// *Jump to address
printf(" >> Setting program counter to %d... << ", b);
programCounter = b;
printf(" PC: %d | A: %d | MEM: [", programCounter, accumulator);
for (i=0; i<9; i+=1)
{ printf("%d,", dataMemory[i]); }
printf("] ");
break;
case 9:
//SKIPZ
// *Check if acc is 0, if it is skip next instruction, else proceed as normal
printf(" >> Skipping the next instruction... << ");
if (accumulator == 0)
{ programCounter += 2; }
else
{ programCounter += 1; }
printf(" PC: %d | A: %d | MEM: [", programCounter, accumulator);
for (i=0; i<9; i+=1)
{ printf("%d,", dataMemory[i]); }
printf("] ");
break;
default:
printf(" There was an error parsing that opcode! Exiting program ");
exit(0);
}
}
int getProgramSize(FILE *file)
{
char fileBuffer[100];
int length = 0;
if (file == NULL)
{
printf("Error opening file!");
exit(0);
}
//This is where I kinda have to buck down and choose an arbitrary number... 1000 might be overkill but w/e
while(fgets(fileBuffer, 1000 ,file)!=NULL)
{ length += 1; }
fclose(file);
return length;
}
Related Questions
drjack9650@gmail.com
Navigate
Integrity-first tutoring: explanations and feedback only — we do not complete graded work. Learn more.