diff --git a/makefile b/makefile index 9ce8ebf..95467d1 100644 --- a/makefile +++ b/makefile @@ -7,7 +7,7 @@ DEBUG = -DNDEBUG VPATH = src src/debug #--------------Linker-Part----------------- -toy_cpu : main.o toy.o debug.o +toy_cpu : main.o toy.o helper.o echo $@ is now linked $(CC) $(LDFLAGS) -o $@ $^ #--------------Compiler-Part--------------- @@ -17,7 +17,7 @@ main.o : main.c toy.o : toy.c toy.h $(CC) $(DEBUG) $(CFLAGS) -o $@ -c $< -debug.o : debug.c debug.h +helper.o : helper.c helper.h $(CC) $(DEBUG) $(CFLAGS) -o $@ -c $< clean : diff --git a/src/debug/debug.c b/src/helper.c similarity index 93% rename from src/debug/debug.c rename to src/helper.c index eea9258..85ec053 100644 --- a/src/debug/debug.c +++ b/src/helper.c @@ -1,6 +1,8 @@ -#include "debug.h" -#include "../toy.h" +#include +#include +#include #include +#include "toy.h" //assumes little endian //stackoverflow.com/questions/111928 diff --git a/src/debug/debug.h b/src/helper.h similarity index 88% rename from src/debug/debug.h rename to src/helper.h index a077e3c..e8a2701 100644 --- a/src/debug/debug.h +++ b/src/helper.h @@ -1,8 +1,6 @@ #ifndef DEBUG_H #define DEBUG_H -#include "../toy.h" - void fprintBits(size_t const size, void const * const ptr, FILE *file_pointer); void makeHexDump(bool base_2, uint16_t ram[]); diff --git a/src/main.c b/src/main.c index ca21fdd..d8694c4 100644 --- a/src/main.c +++ b/src/main.c @@ -1,5 +1,8 @@ +#include +#include +#include #include "toy.h" -#include "./debug/debug.h" +#include "helper.h" #include @@ -28,9 +31,9 @@ int main(int argc, char *argv[]) while(run) { - ir = ram[pc]; //get instruction from RAM - op_code = get_opcode(ir); //determine the instruction form - data_addr=find_data(ir); //locate the 2nd operand (ignord from OP_Code 8 to 15) + ir = ram[pc]; //get instruction from RAM + op_code = get_opcode(ir); //determine the instruction form + data_addr=get_data(ir); //locate the 2nd operand (ignord from OP_Code 8 to 15) //Handele user output printf("\ninstruction: "); @@ -41,26 +44,24 @@ int main(int argc, char *argv[]) //CPU control flow if(execute(op_code,data_addr,ram)) //EXECUTE instruction, jump if ALU says - pc=find_data(ir); + pc=get_data(ir); else pc++; - if(pc>=RAM_SIZE) pc %= RAM_SIZE; //TOY_CPU can only address 12 Bit + if(pc>=RAM_SIZE) pc %= RAM_SIZE; //TOY_CPU can only address 12 Bit //Handele user output printf("PROGRAM COUNTER: %" PRIu16 "\n",pc); printf("\x1b[32m \n(n)ext step or (q)uit or (c)oredump ?\n \x1b[0m"); - //handel program flow - while((quit = getchar()) != '\n' && quit != EOF) + //handle program flow + while((quit = getchar()) != '\n') { - if(quit == 'c') makeHexDump(true,ram); - - else if(quit == 'q') - { - run = false; - printf("\nThis is an interpreter for the "CPU_TYPE" by\n" - "\tmichael.krause@uni-leipzig.de\n\n"); - } + switch(quit) + { + case EOF: break; + case 'c': makeHexDump(true,ram); break; + case 'q': run = false; + } } } return 0; diff --git a/src/toy.c b/src/toy.c index 27ed46c..2a92b04 100644 --- a/src/toy.c +++ b/src/toy.c @@ -1,3 +1,9 @@ +#include +#include +#include +#include +#include + #include "toy.h" void print_instructionSet(void) @@ -35,16 +41,15 @@ void print_instructionSet(void) "\tmichael.krause@uni-leipzig.de\n"); } -//gibt Anzahl der erfolgreich gelesenen Maschinenworte zurück(-1 im Fehlerfall). int initialise_ram(uint16_t *ram, int argc, char **argv ) { - //open Input Stream + //open and check the input stream FILE *fp; - int j=0; + int j=0,int_cache=0; char tempS[CPU_WORD_SIZE+1]; //+1 for "\0" - for(int i=0;i= RAM_SIZE ) + { + fprintf(stderr,"%s","input file corrupted\n"); + fclose(fp); + return -1; + } + tempS[i] = int_cache; + } + if(feof(fp)) break; + tempS[CPU_WORD_SIZE] = '\0'; //replace \n by \0 + ram[j] = strtoul(tempS,NULL,2); + j++; + } fclose(fp); - return j-1; + return j; } uint8_t get_opcode(uint16_t instruction) @@ -101,7 +115,7 @@ uint8_t get_opcode(uint16_t instruction) return opcode; } -uint16_t find_data(uint16_t instruction) +uint16_t get_data(uint16_t instruction) { uint16_t operand; operand = instruction & 4095; @@ -110,7 +124,7 @@ uint16_t find_data(uint16_t instruction) int get2compl(uint16_t value) { - int sign_value = value; + int32_t sign_value = value; if(value>32767) { value=(~value)+1; @@ -129,7 +143,7 @@ bool execute(uint8_t op_code, int data_addr, uint16_t *ram) // jump if true { case 0: ram[data_addr] = accu; break; //STORE case 1: accu = ram[data_addr]; break; //LOAD - case 2: jump = ((accu==0) ? true : false); break; //JMPZ + case 2: jump = (accu == 0); break; //JMP case 3: accu = accu + ram[data_addr]; break; //ADD case 4: accu = accu - ram[data_addr]; break; //SUB case 5: accu = accu | ram[data_addr]; break; //OR diff --git a/src/toy.h b/src/toy.h index 14bacce..a263512 100644 --- a/src/toy.h +++ b/src/toy.h @@ -1,22 +1,57 @@ #ifndef TOY_H #define TOY_H -#include -#include -#include -#include -#include - #define CPU_TYPE "Koopman_TOY_CPU" #define RAM_SIZE 4096 #define CPU_WORD_SIZE 16 +/** +* print_instructionSet(): print the cpu instruction set +* This is a user help function, can be activated via +* the -h paramter. +* Return: none +*/ + void print_instructionSet(void); + +/** +* initialise_ram(): read inputstream into the toy-ram +* Return: +* the number of successfully read machine words, +* -1 in case of error +*/ + int initialise_ram(uint16_t *ram, int argc, char **argv ); + +/** +* get_opcode(): segments the mashine code in the OP-Code +* Return: 4 bit OP-Code +*/ + uint8_t get_opcode(uint16_t instruction); -uint16_t find_data(uint16_t instruction); + +/** +* get_data(): get the addressed data from the RAM +* Return: the 12 bit data address +*/ + +uint16_t get_data(uint16_t instruction); + +/** +* get2compl(): interpret the transfer value as tow's complement +* Return: tow's complement value between -255 and 254 +*/ + int get2compl(uint16_t value); //not good place for something! + +/** +* execute(): execute the toy-CPU instruction +* This function implements the CPU instruction set, +* use print_instructionSet() for an overview. +* Return: true if there is a jump +*/ + bool execute(uint8_t op_code, int data_addr,uint16_t *ram); #endif