#include #include // For error exit() // CPU Declarations -- a CPU is a structur
ID: 3593343 • Letter: #
Question
#include
#include // For error exit()
// CPU Declarations -- a CPU is a structure with fields for the
// different parts of the CPU.
//***STUB *** is to fill in code
typedef short int Word; // type that represents a word of SDC memory
typedef unsigned char Address; // type that represents an SDC address
#define MEMLEN 100
#define NREG 10
struct CPU {
Word mem[MEMLEN];
Word reg[NREG]; // Note: "register" is a reserved word
Address pc; // Program Counter
int running; // running = 1 iff CPU is executing instructions
Word ir; // Instruction Register
int instr_sign; // sign of instruction
int opcode; // opcode field
int reg_R; // register field
int addr_MM; // memory field
};
typedef struct CPU CPU;
// Prototypes [note the functions are also declared in this order]
//
int main(int argc, char *argv[]);
void initialize_control_unit(CPU *cpu);
void initialize_memory(int argc, char *argv[], CPU *cpu);
FILE *get_datafile(int argc, char *argv[]);
void dump_control_unit(CPU *cpu);
void dump_memory(CPU *cpu);
void print_instr(int instr);
// Main program: Initialize the cpu, and read the initial memory values ... (add more to this comment in Lab 6)
//
int main(int argc, char *argv[]) {
printf("SDC Simulator pt 1 for ***Your name, Lab section *** "); // STUB
CPU cpu_value, *cpu = &cpu_value;
initialize_control_unit(cpu);
initialize_memory(argc, argv, cpu);
dump_control_unit(cpu);
dump_memory(cpu);
// That's it for Lab 5
//
printf("*** That's it for Lab 5! *** "); // *** STUB for Lab 6 ***
return 0;
}
// Initialize the control unit (pc, ir, instruction sign,
// running flag, and the general-purpose registers).
//
void initialize_control_unit(CPU *cpu) {
// *** STUB ***
}
// Read and dump initial values for memory
//
void initialize_memory(int argc, char *argv[], CPU *cpu) {
FILE *datafile = get_datafile(argc, argv);
// *** STUB *** (Maybe want a message here or inside get_datafile)
// Buffer to read next line of text into
#define DATA_BUFFER_LEN 256
char buffer[DATA_BUFFER_LEN];
// Will read the next line (words_read = 1 if it started
// with a memory value). Will set memory location loc to
// value_read
//
int value_read, words_read, loc = 0, done = 0;
char *read_success; // NULL if reading in a line fails.
read_success = fgets(buffer, DATA_BUFFER_LEN, datafile);
while (read_success != NULL && !done) {
// If the line of input begins with an integer, treat
// it as the memory value to read in. Ignore junk
// after the number and ignore blank lines and lines
// that don't begin with a number.
//
words_read = sscanf(buffer, "%d", &value_read);
// *** STUB ***
// if an integer was actually read in, then
// set memory value at current location to
// value_read and increment location. Exceptions: If
// loc is out of range, complain and quit the loop. If
// value_read is outside -9999...9999, then it's a
// sentinel -- we should say so and quit the loop.
// Get next line and continue the loop
//
// *** STUB ***
}
// Initialize rest of memory
//
while (loc < MEMLEN) {
cpu -> mem[loc++] = 0;
}
}
// Get the data file to initialize memory with. If it was
// specified on the command line as argv[1], use that file
// otherwise use default.sdc. If file opening fails, complain
// and terminate program execution with an error.
// See linux command man 3 exit for details.
//
FILE *get_datafile(int argc, char *argv[]) {
char *default_datafile_name = "default.sdc";
char *datafile_name = NULL;
// *** STUB *** set datafile name to argv[1] or default
datafile_name = default_datafile_name; // *** STUB ***
FILE *datafile = fopen(datafile_name, "r");
// *** STUB *** if the open failed, complain and call
// exit(EXIT_FAILURE); to quit the entire program
// If open succeeded, you might want to print a message here
// or in caller.
return datafile;
}
// dump_control_unit(CPU *cpu): Print out the control unit
// (PC, IR, running flag, and general-purpose registers).
//
void dump_control_unit(CPU *cpu) {
printf(" Control and Data Registers:");
// *** STUB ****
}
// dump_memory(CPU *cpu): For each memory address that
// contains a non-zero value, print out a line with the
// address, the value as an integer, and the value
// interpreted as an instruction.
//
void dump_memory(CPU *cpu) {
printf(" Memory Dump: (nonzero values only): ");
// *** STUB ****
// for each location, if the value is nonzero, then
// print the location and value (as an integer),
// and call print_instr on the value to print out
// the value as an instruction
}
// print_instr(instr) prints the 4-digit instruction in a mnemonic format.
//
void print_instr(int instr) {
// *** STUB ***
}
For Lab 5, you should initialize the control unit, initialize memory by reading its contents from a file and dump the contents of the control unit and the values in memory. 1 To initialize the control unit, set the general purpose registers, the IR, and the Pc all to 0; set the instruction sign to 1, and set the running flag to true. The IR fields (instr_sign, opcode, reg_R, and mem MM) don't get used in this lab, but it can't hurt to initialize them too. 2. The linux command to execute your program can include the name of the file containing the initial values of the SDC memory. (For example, . /a. out my. sdc.) If the command line parameter is left out, behave as though it were default.sdc. Don't forget to tell the user what file you are trying to open, and if you can't open the file successfully, complain and quit the program with an error exit. 3. In its simplest form, an SDC data file is a sequence of lines containing one integer per line. E.g 1234 3456 -4567 0 2568Explanation / Answer
//main.c
#include <stdio.h>
#include <stdlib.h> // For error exit()
typedef short int Word; // type that represents a word of SDC memory
typedef unsigned char Address; // type that represents an SDC address
#define MEMLEN 100
#define NREG 10
struct CPU {
Word mem[MEMLEN];
Word reg[NREG]; // Note: "register" is a reserved word
Address pc; // Program Counter
int running; // running = 1 iff CPU is executing instructions
Word ir; // Instruction Register
int instr_sign; // sign of instruction
int opcode; // opcode field
int reg_R; // register field
int addr_MM; // memory field
};
typedef struct CPU CPU;
// Prototypes [note the functions are also declared in this order]
int main(int argc, char *argv[]);
void initialize_control_unit(CPU *cpu);
void initialize_memory(int argc, char *argv[], CPU *cpu);
FILE *get_datafile(int argc, char *argv[]);
void dump_control_unit(CPU *cpu);
void dump_memory(CPU *cpu);
void print_instr(int instr);
void dump_registers(CPU *cpu);
// Main program: Initialize the cpu, and read the initial memory values
int main(int argc, char *argv[]) {
printf("SDC Simulator // Part 1 // CS 350 Lab 5 // Morgan Wilson ");
CPU cpu_value, *cpu = &cpu_value;
initialize_control_unit(cpu);
initialize_memory(argc, argv, cpu);
dump_memory(cpu);
// That's it for Lab 5
return 0;
}
// Initialize the control unit (pc, ir, instruction sign,
// running flag, and the general-purpose registers)
void initialize_control_unit(CPU *cpu) {
cpu -> pc = 00;
cpu -> ir = 0000;
cpu -> instr_sign = 1;
cpu -> running = 1;
for (int i = 0; i < sizeof((*cpu).reg);i++) {
cpu -> reg[i] = 0;
}
printf(" Initial CPU: ");
dump_control_unit(cpu);
printf(" ");
}
// Read and dump initial values for memory
void initialize_memory(int argc, char *argv[], CPU *cpu) {
FILE *datafile = get_datafile(argc, argv);
// printf("Initialize memory from %s ", datafile_name);
// Buffer to read next line of text into
#define DATA_BUFFER_LEN 256
char buffer[DATA_BUFFER_LEN];
// Will read the next line (words_read = 1 if it started
// with a memory value). Will set memory location loc to
// value_read
int value_read, words_read, loc = 0, done = 0;
char *read_success; // NULL if reading in a line fails.
read_success = fgets(buffer, DATA_BUFFER_LEN, datafile);
while (read_success != NULL && !done) {
// If the line of input begins with an integer, treat
// it as the memory value to read in. Ignore junk
// after the number and ignore blank lines and lines
// that don't begin with a number.
words_read = sscanf(buffer, "%d", &value_read);
if (words_read == 1) {
if (loc > 99) {
printf("Trying to read from location greater than 99, error");
read_success = NULL;
}
if (-9999 > value_read || value_read > 9999) {
printf("Sentinel value: %d found @ %d ", value_read, loc);
read_success = NULL;
}
else {
cpu -> mem[loc] = value_read;
loc++;
}
}
// if an integer was actually read in, then
// set memory value at current location to
// value_read and increment location. Exceptions: If
// loc is out of range, complain and quit the loop. If
// value_read is outside -9999...9999, then it's a
// sentinel -- we should say so and quit the loop.
if (read_success != NULL) {
read_success = fgets(buffer, DATA_BUFFER_LEN, datafile);
}
}
// Initialize rest of memory
while (loc < MEMLEN) {
cpu -> mem[loc++] = 0;
}
}
// Get the data file to initialize memory with. If it was
// specified on the command line as argv[1], use that file
// otherwise use default.sdc. If file opening fails, complain
// and terminate program execution with an error.
// See linux command man 3 exit for details.
FILE *get_datafile(int argc, char *argv[]) {
char *default_datafile_name = "default.sdc";
char *datafile_name = NULL;
if(argc != 2) {
datafile_name = default_datafile_name;
printf("No file found, default file opening: %s ", default_datafile_name);
} else {
datafile_name = argv[1];
}
FILE *datafile = fopen(datafile_name, "r");
if(datafile == NULL) {
printf(" Failed to open file ");
exit(EXIT_FAILURE);
}
return datafile;
}
// dump_control_unit(CPU *cpu): Print out the control unit
// (PC, IR, running flag, and general-purpose registers).
void dump_control_unit(CPU *cpu) {
printf(" PC: %d IR: %d Running: %d ", cpu -> pc, cpu -> ir, cpu -> running);
dump_registers(cpu);
}
// dump_memory(CPU *cpu): For each memory address that
// contains a non-zero value, print out a line with the
// address, the value as an integer, and the value
// interpreted as an instruction.
void dump_memory(CPU *cpu) {
// for each location, if the value is nonzero, then
// print the location and value (as an integer),
// and call print_instr on the value to print out
// the value as an instruction
printf(" Memory dump: @Loc, value, instr, reg, mm:");
printf(" ");
for (int i = 0; i < MEMLEN; i++) {
if (cpu -> mem[i] != 0) {
int instr = cpu -> mem[i];
printf(" @ %02d %04d ", i, instr);
print_instr(instr);
printf(" ");
}
}
}
// dump_registers(CPU *cpu): Print register values in two rows of five
void dump_registers(CPU *cpu) {
printf ("R0: %d R1: %d R2: %d R3: %d R4: %d ",
cpu->reg[0],
cpu->reg[1],
cpu->reg[2],
cpu->reg[3],
cpu->reg[4]);
printf("R5: %d R6: %d R7: %d R8: %d R9: %d ",
cpu->reg[5],
cpu->reg[6],
cpu->reg[7],
cpu->reg[8],
cpu->reg[9]);
}
// print_instr(instr) prints the 4-digit instruction in a mnemonic format.
void print_instr(int instr) {
int LD = 1;
int ST = 2;
int ADD = 3;
int NEG = 4;
int LDM = 5;
int LDM_neg = -5;
int ADDM = 6;
int SUBM = -6;
int BR = 7;
int BRGE = 8;
int BRLE = -8;
int GETC = 0;
int OUT = 1;
int PUTS = 2;
int DMP = 3;
int MEM = 4;
if (abs(instr) < 1000) {
printf("HALT ");
} else {
int opcode = abs(instr / 1000);
int reg_operand = abs((instr / 100) % 10);
int mem_operand = (instr % 100);
if (opcode == LD) {
printf("LD R%d, %d", reg_operand, mem_operand);
} else if (opcode == ST) {
printf("ST R%d, %d", reg_operand, mem_operand);
} else if (opcode == ADD) {
printf("ADD R%d, %d", reg_operand, mem_operand);
} else if (opcode == NEG) {
printf("NEG R%d, %d", reg_operand, mem_operand);
} else if (opcode == LDM) {
printf("LDM R%d, %d", reg_operand, mem_operand);
} else if (opcode == LDM_neg) {
printf("-LDM R%d, %d", reg_operand, mem_operand);
} else if (opcode == ADDM) {
printf("ADDM R%d, %d", reg_operand, mem_operand);
} else if (opcode == SUBM) {
printf("SUBM R%d, %d", reg_operand, mem_operand);
} else if (opcode == BR) {
printf("BR R%d, %d", reg_operand, mem_operand);
} else if (opcode == BRGE) {
printf("BRGE R%d, %d", reg_operand, mem_operand);
} else if (opcode == BRLE) {
printf("BRLE R%d, %d", reg_operand, mem_operand);
} else if (opcode == 9) {
if (reg_operand == GETC) {
printf("GETC R%d, %d", reg_operand, mem_operand);
} else if (reg_operand == OUT) {
printf("OUT R%d, %d", reg_operand, mem_operand);
} else if (reg_operand == PUTS) {
printf("PUTS R%d, %d", reg_operand, mem_operand);
} else if (reg_operand == DMP) {
printf("DMP R%d, %d", reg_operand, mem_operand);
} else if (reg_operand == MEM) {
printf("MEM R%d, %d", reg_operand, mem_operand);
} else {
printf("NOP R%d, %d", reg_operand, mem_operand);
}
}
}
}
Related Questions
Navigate
Integrity-first tutoring: explanations and feedback only — we do not complete graded work. Learn more.