diff --git a/cpu.c b/cpu.c index 9e22786..db3dcdd 100644 --- a/cpu.c +++ b/cpu.c @@ -10,7 +10,10 @@ struct fetch_data_t *malloc_fetch_data(){ void free_fetch_data(__attribute__((unused)) struct fetch_data_t *tofree){ } int fetch(struct simdata_t *simdata){ + free_instr_list(&simdata->cpu_gui_hints->fetching_list); 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->decode_data->address=simdata->PC; + add_to_instr_list(&simdata->cpu_gui_hints->fetching_list,simdata->PC); simdata->PC+=4; return 0; } @@ -26,6 +29,7 @@ void free_decode_data(struct decode_data_t *tofree){ } int decode(struct simdata_t *simdata){ uint16_t opcode,op1,op2,imm; + free_instr_list(&simdata->cpu_gui_hints->decoding_list); switch((simdata->decode_data->in_bytecode&0xE0000000)>>29){ case 0: opcode=(simdata->decode_data->in_bytecode&0x1F000000)>>24; @@ -126,6 +130,8 @@ int decode(struct simdata_t *simdata){ default: return 1; } + simdata->exec_data->address=simdata->decode_data->address; + add_to_instr_list(&simdata->cpu_gui_hints->decoding_list,simdata->decode_data->address); return 0; } @@ -164,6 +170,7 @@ void free_exec_data(struct exec_data_t *tofree){ free(tofree); } int exec(struct simdata_t *simdata){ + free_instr_list(&simdata->cpu_gui_hints->executing_list); switch(simdata->exec_data->EXEC_ACTION){ case JUMP: int condition=0; @@ -247,6 +254,7 @@ int exec(struct simdata_t *simdata){ break; } + add_to_instr_list(&simdata->cpu_gui_hints->executing_list,simdata->exec_data->address); return 0; } @@ -257,6 +265,9 @@ int exec(struct simdata_t *simdata){ int state=0; int cpu_cycle_clock(struct simdata_t *simdata){ + free_instr_list(&simdata->cpu_gui_hints->fetching_list); + free_instr_list(&simdata->cpu_gui_hints->decoding_list); + free_instr_list(&simdata->cpu_gui_hints->executing_list); switch(state){ case 0: if( fetch(simdata) ) return 3; break; case 1: if( decode(simdata) ) return 2; break; diff --git a/cpu.h b/cpu.h index f903e7b..223fd6a 100644 --- a/cpu.h +++ b/cpu.h @@ -6,6 +6,7 @@ struct fetch_data_t{ }; struct decode_data_t{ uint32_t in_bytecode; + uint32_t address; // used only for the gui hints (for now) }; @@ -55,6 +56,7 @@ struct exec_data_t { struct exec_op_t *in_op1; struct exec_op_t *in_op2; struct exec_op_t *out_op; + uint32_t address; // used only for the gui hints (for now) }; diff --git a/gui.c b/gui.c index 1b3ecb1..c6cb63a 100644 --- a/gui.c +++ b/gui.c @@ -128,6 +128,14 @@ int start_gui(){ init_pair(6, COLOR_BLACK,COLOR_GREEN); init_pair(7, COLOR_BLACK,COLOR_YELLOW); init_pair(8, COLOR_BLACK,COLOR_RED); + + //cpu instruction pipline location colors + init_pair(9, COLOR_MAGENTA,COLOR_BLACK); //fetch + init_pair(10, COLOR_YELLOW,COLOR_BLACK); //decode + init_pair(11, COLOR_GREEN,COLOR_BLACK); //exec + init_pair(12, COLOR_BLACK,COLOR_MAGENTA); //fetch + init_pair(13, COLOR_BLACK,COLOR_YELLOW); //decode + init_pair(14, COLOR_BLACK,COLOR_GREEN); //exec } noecho(); curs_set(0); @@ -189,12 +197,58 @@ int gui_error(char *str){ wattroff(error_win,COLOR_PAIR(1)); } +//// WARNING!! THIS ASSUMES THAT ADDRESS IS CORRECTLY ALIGNED!! +int select_instruction_color(struct simdata_t *simdata, WINDOW* window,uint32_t ADDRESS, int applyremove){ + if(simdata->cpu_gui_hints){ + struct instr_list_t* pointer; + pointer=simdata->cpu_gui_hints->fetching_list; + while(pointer!=NULL){ + if(pointer->address==ADDRESS){ + if(applyremove) + wattron(window,COLOR_PAIR(9)); + else + wattroff(window,COLOR_PAIR(9)); + return 0; + } + pointer=pointer->next; + } + pointer=simdata->cpu_gui_hints->decoding_list; + while(pointer!=NULL){ + if(pointer->address==ADDRESS){ + if(applyremove) + wattron(window,COLOR_PAIR(10)); + else + wattroff(window,COLOR_PAIR(10)); + return 0; + } + pointer=pointer->next; + } + pointer=simdata->cpu_gui_hints->executing_list; + while(pointer!=NULL){ + if(pointer->address==ADDRESS){ + if(applyremove) + wattron(window,COLOR_PAIR(11)); + else + wattroff(window,COLOR_PAIR(11)); + return 0; + } + pointer=pointer->next; + } + } + return 1; +} + int update_general_disas(struct simdata_t *simdata){ werase(general_disas); int width,height; getmaxyx(general_disas,height,width); box(general_disas, 0 , 0); int offset_arrow; + + int have_legend=(width>29); + + int usable_height=height-2-have_legend; + if(width<41) offset_arrow=2; else @@ -203,8 +257,8 @@ int update_general_disas(struct simdata_t *simdata){ if(width<18){ mvwprintw(general_disas,1,1,"too small window"); }else{ - uint32_t ADDRESS=(simdata->PC-(height/2-2)*4)&0x00FFFFFF; - for (int i=2;iPC-(usable_height/2-2)*4)&0x00FFFFFF; + for (int i=2;iPC) wattroff(general_disas,A_BOLD); ADDRESS=(ADDRESS+4)&0xFFFFFF; free(disas); } - mvwaddch(general_disas,height/2,offset_arrow,ACS_RARROW); - mvwaddch(general_disas,height/2,offset_arrow-1,ACS_ULCORNER); - mvwaddch(general_disas,height/2+1,offset_arrow-1,ACS_VLINE); - mvwaddch(general_disas,height/2+2,offset_arrow-1,ACS_VLINE); - mvwaddch(general_disas,height/2+3,offset_arrow-1,ACS_VLINE); - mvwaddch(general_disas,height/2+4,offset_arrow-1,ACS_VLINE); - mvwaddch(general_disas,height/2+5,offset_arrow-1,ACS_VLINE); - mvwaddch(general_disas,height/2+6,offset_arrow-1,'P'); + mvwaddch(general_disas,usable_height/2,offset_arrow,ACS_RARROW); + mvwaddch(general_disas,usable_height/2,offset_arrow-1,ACS_ULCORNER); + mvwaddch(general_disas,usable_height/2+1,offset_arrow-1,ACS_VLINE); + mvwaddch(general_disas,usable_height/2+2,offset_arrow-1,ACS_VLINE); + mvwaddch(general_disas,usable_height/2+3,offset_arrow-1,ACS_VLINE); + mvwaddch(general_disas,usable_height/2+4,offset_arrow-1,ACS_VLINE); + mvwaddch(general_disas,usable_height/2+5,offset_arrow-1,ACS_VLINE); + mvwaddch(general_disas,usable_height/2+6,offset_arrow-1,'P'); if(offset_arrow==2) - mvwaddch(general_disas,height/2+7,offset_arrow-1,'C'); + mvwaddch(general_disas,usable_height/2+7,offset_arrow-1,'C'); else - mvwaddch(general_disas,height/2+6,offset_arrow,'C'); + mvwaddch(general_disas,usable_height/2+6,offset_arrow,'C'); + if(have_legend){ + wattron(general_disas,COLOR_PAIR(12)); + mvwprintw(general_disas,height-2,2," "); + wattroff(general_disas,COLOR_PAIR(12)); + mvwprintw(general_disas,height-2,4,"=Fetch"); + + wattron(general_disas,COLOR_PAIR(13)); + mvwprintw(general_disas,height-2,11," "); + wattroff(general_disas,COLOR_PAIR(13)); + mvwprintw(general_disas,height-2,13,"=Decode"); + + wattron(general_disas,COLOR_PAIR(14)); + mvwprintw(general_disas,height-2,21," "); + wattroff(general_disas,COLOR_PAIR(14)); + mvwprintw(general_disas,height-2,23,"=Exec"); + } + } return 0; } @@ -307,6 +382,9 @@ int update_general_memdump(struct simdata_t *simdata){ int usable_height=height-3-(width-12)%2; uint32_t ADDRESS=(simdata->PC-n*usable_height/2)&0x00FFFFFF; + + uint32_t color_addr; + int have_color; for(int h=0;hRAM[ADDRESS]); ADDRESS=(ADDRESS+1)&0xFFFFFF; } + if(have_color) + select_instruction_color(simdata,general_memdump,color_addr,0); ADDRESS=temp_address; for (int i=0;i=simdata->PC&&ADDRESS<=simdata->PC+3) diff --git a/simdata.c b/simdata.c index ecbd768..6218187 100644 --- a/simdata.c +++ b/simdata.c @@ -40,11 +40,39 @@ struct simdata_t *init_simdata(){ ret->SP=0; ret->registers=NULL; ret->cpu_state=CPU_RUNNING; + ret->cpu_gui_hints=malloc(sizeof(struct cpu_gui_hints_t)); + ret->cpu_gui_hints->decoding_list=NULL; + ret->cpu_gui_hints->fetching_list=NULL; + ret->cpu_gui_hints->executing_list=NULL; return ret; } +void free_instr_list(struct instr_list_t **addr_of_tofree){ + struct instr_list_t *tofree=*addr_of_tofree; + while(tofree){ + struct instr_list_t *temp=tofree; + tofree=tofree->next; + free(temp); + } + *addr_of_tofree=0; +} + +int add_to_instr_list(struct instr_list_t **toadd,uint32_t address){ + while(*toadd){ + toadd=&((*toadd)->next); + } + *toadd=malloc(sizeof(struct instr_list_t)); + (*toadd)->address=address; + (*toadd)->next=NULL; + return 0; +} + void free_simdata(struct simdata_t *p){ free(p->RAM); + free_instr_list(&p->cpu_gui_hints->decoding_list); + free_instr_list(&p->cpu_gui_hints->fetching_list); + free_instr_list(&p->cpu_gui_hints->executing_list); + free(p->cpu_gui_hints); free(p); } diff --git a/simdata.h b/simdata.h index 733be2b..c83f6b3 100644 --- a/simdata.h +++ b/simdata.h @@ -16,11 +16,25 @@ struct simdata_t{ struct exec_data_t *exec_data; struct registers_t *registers; enum CPU_STATE_t cpu_state; + struct cpu_gui_hints_t *cpu_gui_hints; +}; + +struct instr_list_t{ + uint32_t address; + struct instr_list_t *next; +}; + +struct cpu_gui_hints_t{ + struct instr_list_t *fetching_list; + struct instr_list_t *decoding_list; + struct instr_list_t *executing_list; }; struct simdata_t *init_simdata(); void free_simdata(struct simdata_t *); +int add_to_instr_list(struct instr_list_t **addr_of_toadd,uint32_t address); +void free_instr_list(struct instr_list_t **addr_of_tofree); enum GUI_CPU_STATE_t{ GUI_CPU_RUNNING,