diff --git a/.gitignore b/.gitignore index 37d3d43..e20c756 100644 --- a/.gitignore +++ b/.gitignore @@ -1,3 +1,4 @@ *.o first test.rom +make.deps diff --git a/Makefile b/Makefile index 6ee73f9..0a66dc8 100644 --- a/Makefile +++ b/Makefile @@ -2,7 +2,13 @@ QUIET=1 all:first -OBJECT_FILES=gui.o main.o simdata.o assembly.o +OBJECT_FILES=gui.o main.o simdata.o assembly.o cpu.o + +make.deps: $(subst .o,.c,${OBJECT_FILES}) $(wildcard *.h) + @$(CC) -MM $(subst .o,.c,${OBJECT_FILES}) > make.deps + +include make.deps + ifeq "${QUIET}" "1" QUIET_CC = @echo ' CC '$@; diff --git a/cpu.c b/cpu.c new file mode 100644 index 0000000..2c703a8 --- /dev/null +++ b/cpu.c @@ -0,0 +1,136 @@ +#include "simdata.h" +#include "cpu.h" +#include + + + +struct fetch_data_t *malloc_fetch_data(){ + return NULL; +} +void free_fetch_data(__attribute__((unused)) struct fetch_data_t *tofree){ +} +int fetch(struct simdata_t *simdata){ + simdata->decode_data->in_bytecode=(uint32_t)(simdata->RAM[simdata->PC])<<24|(uint32_t)(simdata->RAM[simdata->PC+1])<<16|(uint32_t)(simdata->RAM[simdata->PC+2])<<8|(uint32_t)(simdata->RAM[simdata->PC+3]); + simdata->PC+=4; + return 0; +} + + + + +struct decode_data_t *malloc_decode_data(){ + return malloc(sizeof(struct decode_data_t)); +} +void free_decode_data(struct decode_data_t *tofree){ + free(tofree); +} +int decode(struct simdata_t *simdata){ + uint16_t opcode; + switch((simdata->decode_data->in_bytecode&0xE0000000)>>29){ + case 0: + opcode=(simdata->decode_data->in_bytecode&0x1F000000)>>24; + switch(opcode){ + case 1: + simdata->exec_data->out_op->OP_ADDR=IMMEDIATE; + simdata->exec_data->out_op->data=simdata->decode_data->in_bytecode&0x00FFFFFF; + simdata->exec_data->EXEC_ACTION=JUMP; + break; + default: + return 1; + } + break; + case 1: + return 1; + break; + case 2: + return 1; + break; + default: + return 1; + } + return 0; +} + + + + +struct exec_data_t *malloc_exec_data(){ + struct exec_data_t *ret; + ret=malloc(sizeof(struct exec_data_t)); + if(!ret) + return 0; + ret->in_op1=malloc(sizeof(struct exec_op_t)); + if(!ret->in_op1){ + free(ret); + return 0; + } + ret->in_op2=malloc(sizeof(struct exec_op_t)); + if(!ret->in_op2){ + free(ret->in_op1); + free(ret); + return 0; + } + ret->out_op=malloc(sizeof(struct exec_op_t)); + if(!ret->out_op){ + free(ret->in_op1); + free(ret->in_op2); + free(ret); + return 0; + } + return ret; +} +void free_exec_data(struct exec_data_t *tofree){ + free(tofree->in_op1); + free(tofree->in_op2); + free(tofree->out_op); + free(tofree); +} +int exec(struct simdata_t *simdata){ + switch(simdata->exec_data->EXEC_ACTION){ + case JUMP: + if(simdata->exec_data->out_op->OP_ADDR==IMMEDIATE) + simdata->PC=simdata->exec_data->out_op->data; + else + return 1; + break; + case EXEC_ALU: + return 1; + } + return 0; +} + + + + + +int state=0; + +int cpu_cycle_clock(struct simdata_t *simdata){ + switch(state){ + case 0: if( fetch(simdata) ) return 1; break; + case 1: if( decode(simdata) ) return 1; break; + case 2: if( exec(simdata) ) return 1; break; + } + if(state==2) + state=0; + else + state++; + return 0; +} + + +int cpu_simdata_malloc(struct simdata_t *simdata){ + simdata->fetch_data=malloc_fetch_data(); + simdata->decode_data=malloc_decode_data(); + simdata->exec_data=malloc_exec_data(); + if((simdata->fetch_data!=NULL)&&(simdata->decode_data!=NULL)&&(simdata->exec_data!=NULL)) + return 1; + else + return 0; +} + +void cpu_simdata_free(struct simdata_t *simdata){ + free_fetch_data(simdata->fetch_data); + free_decode_data(simdata->decode_data); + free_exec_data(simdata->exec_data); +} diff --git a/cpu.h b/cpu.h new file mode 100644 index 0000000..6632a62 --- /dev/null +++ b/cpu.h @@ -0,0 +1,54 @@ +#ifndef CPU_HEADER +#include "simdata.h" + +struct fetch_data_t{ + +}; +struct decode_data_t{ + uint32_t in_bytecode; +}; + + + + +///// EXEC DATA STRUCTURES /////// +enum EXEC_ACTION_t { + EXEC_ALU, + JUMP +}; + +enum ALU_OP_t { + ALU_ADD, + ALU_SUB, + ALU_SL, + ALU_SR, + ALU_CMP +}; + +enum OP_ADDR_t { + IMMEDIATE, + REGISTER, +}; + +struct exec_op_t { + enum OP_ADDR_t OP_ADDR; + uint32_t data; +}; + + +struct exec_data_t { + enum EXEC_ACTION_t EXEC_ACTION; + enum ALU_OP_t ALU_OP; + struct exec_op_t *in_op1; + struct exec_op_t *in_op2; + struct exec_op_t *out_op; +}; + + + +void cpu_simdata_free(struct simdata_t *simdata); +int cpu_simdata_malloc(struct simdata_t *simdata); +int cpu_cycle_clock(struct simdata_t *simdata); + +#endif +#define CPU_HEADER diff --git a/gui.c b/gui.c index 0b9a95b..41c943b 100644 --- a/gui.c +++ b/gui.c @@ -170,6 +170,7 @@ int gui_error(char *str){ } int update_general_disas(struct simdata_t *simdata){ + wclear(general_disas); int width,height; getmaxyx(general_disas,height,width); box(general_disas, 0 , 0); @@ -219,6 +220,7 @@ int update_general_disas(struct simdata_t *simdata){ } int update_general_stack(struct simdata_t *simdata){ + wclear(general_stack); int width,height; getmaxyx(general_stack,height,width); box(general_stack, 0 , 0); @@ -275,6 +277,7 @@ int update_general_stack(struct simdata_t *simdata){ } int update_general_memdump(struct simdata_t *simdata){ + wclear(general_memdump); int width,height; getmaxyx(general_memdump,height,width); box(general_memdump, 0 , 0); @@ -292,7 +295,7 @@ int update_general_memdump(struct simdata_t *simdata){ wprintw(general_memdump,"%06x ",ADDRESS); uint32_t temp_address=ADDRESS; for (int i=0;i=simdata->PC&&ADDRESS<=simdata->PC+4) + if(ADDRESS>=simdata->PC&&ADDRESS<=simdata->PC+3) wattron(general_memdump,A_BOLD); else wattroff(general_memdump,A_BOLD); @@ -301,7 +304,7 @@ int update_general_memdump(struct simdata_t *simdata){ } ADDRESS=temp_address; for (int i=0;i=simdata->PC&&ADDRESS<=simdata->PC+4) + if(ADDRESS>=simdata->PC&&ADDRESS<=simdata->PC+3) wattron(general_memdump,A_BOLD); else wattroff(general_memdump,A_BOLD); diff --git a/main.c b/main.c index a912457..06952dc 100644 --- a/main.c +++ b/main.c @@ -24,6 +24,7 @@ #include #include #include "assembly.h" +#include "cpu.h" void help(char* progname){ printf("Usage: %s -i \n", progname); @@ -71,6 +72,10 @@ int main(int argc, char* argd[] ){ FILE* rom=fopen(infile,"r"); struct simdata_t *simdata = init_simdata(); + if(!simdata){ + printf("Couldn't allocate memory\n"); + return 1; + } if ( assemble != NULL ){ /* RUN ASSEMBLER */ @@ -127,7 +132,7 @@ int main(int argc, char* argd[] ){ fseek(rom, 0, SEEK_SET); if(!simdata){ - gui_error("failed to initialise simdata"); + gui_error("failed to initialise simdata\n"); fclose(rom); free_simdata(simdata); return 1; @@ -144,25 +149,42 @@ int main(int argc, char* argd[] ){ /// INITIALISE GUI /// if(start_gui()){ printf("Failed on start_gui()\n"); + cpu_simdata_free(simdata); free_simdata(simdata); return 1; } - update_gui(simdata); + cpu_simdata_malloc(simdata); - if(gui_continue_request()){ - end_gui(); - printf("Failed on gui_continue_request()\n"); - free_simdata(simdata); - return 1; + while(1){ + update_gui(simdata); + + if(gui_continue_request()){ + end_gui(); + printf("Failed on gui_continue_request()\n"); + cpu_simdata_free(simdata); + free_simdata(simdata); + return 1; + } + + if(cpu_cycle_clock(simdata)){ + cpu_simdata_free(simdata); + free_simdata(simdata); + end_gui(); + printf("Failed to execute instruction\n"); + return 1; + } } if(end_gui()){ printf("Failed on end_gui()\n"); + cpu_simdata_free(simdata); free_simdata(simdata); return 1; } + + cpu_simdata_free(simdata); free_simdata(simdata); } return 0; diff --git a/simdata.h b/simdata.h index 4a51d94..b689a18 100644 --- a/simdata.h +++ b/simdata.h @@ -6,6 +6,9 @@ struct simdata_t{ uint8_t *RAM; uint32_t PC; uint32_t SP; + struct fetch_data_t *fetch_data; + struct decode_data_t *decode_data; + struct exec_data_t *exec_data; }; struct simdata_t *init_simdata(); @@ -17,5 +20,6 @@ enum CPU_STATE_t{ SINGLE_STEPPING, STOPPED }; + #endif #define SIMDATA_HEADER diff --git a/test.asm b/test.asm index b7a8abd..d21cc29 100644 --- a/test.asm +++ b/test.asm @@ -1,4 +1,6 @@ -JMP $ABCDEF +JMP $000008 +SL %R7 +JMP $000000 JMP,NZ $DEADBA JMP,C $EEEEEF SL %R7