Academic Integrity: tutoring, explanations, and feedback — we don’t complete graded work or submit on a student’s behalf.

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;
}

Hire Me For All Your Tutoring Needs
Integrity-first tutoring: clear explanations, guidance, and feedback.
Drop an Email at
drjack9650@gmail.com
Chat Now And Get Quote