GUI: Added colors to indicate where in the pipeline is each instruction

This commit is contained in:
(Tim) Efthimis Kritikos 2024-02-07 00:31:23 +00:00
parent 800e11be16
commit 4402688a20
5 changed files with 157 additions and 12 deletions

11
cpu.c
View File

@ -10,7 +10,10 @@ struct fetch_data_t *malloc_fetch_data(){
void free_fetch_data(__attribute__((unused)) struct fetch_data_t *tofree){ void free_fetch_data(__attribute__((unused)) struct fetch_data_t *tofree){
} }
int fetch(struct simdata_t *simdata){ 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->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; simdata->PC+=4;
return 0; return 0;
} }
@ -26,6 +29,7 @@ void free_decode_data(struct decode_data_t *tofree){
} }
int decode(struct simdata_t *simdata){ int decode(struct simdata_t *simdata){
uint16_t opcode,op1,op2,imm; uint16_t opcode,op1,op2,imm;
free_instr_list(&simdata->cpu_gui_hints->decoding_list);
switch((simdata->decode_data->in_bytecode&0xE0000000)>>29){ switch((simdata->decode_data->in_bytecode&0xE0000000)>>29){
case 0: case 0:
opcode=(simdata->decode_data->in_bytecode&0x1F000000)>>24; opcode=(simdata->decode_data->in_bytecode&0x1F000000)>>24;
@ -126,6 +130,8 @@ int decode(struct simdata_t *simdata){
default: default:
return 1; 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; return 0;
} }
@ -164,6 +170,7 @@ void free_exec_data(struct exec_data_t *tofree){
free(tofree); free(tofree);
} }
int exec(struct simdata_t *simdata){ int exec(struct simdata_t *simdata){
free_instr_list(&simdata->cpu_gui_hints->executing_list);
switch(simdata->exec_data->EXEC_ACTION){ switch(simdata->exec_data->EXEC_ACTION){
case JUMP: case JUMP:
int condition=0; int condition=0;
@ -247,6 +254,7 @@ int exec(struct simdata_t *simdata){
break; break;
} }
add_to_instr_list(&simdata->cpu_gui_hints->executing_list,simdata->exec_data->address);
return 0; return 0;
} }
@ -257,6 +265,9 @@ int exec(struct simdata_t *simdata){
int state=0; int state=0;
int cpu_cycle_clock(struct simdata_t *simdata){ 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){ switch(state){
case 0: if( fetch(simdata) ) return 3; break; case 0: if( fetch(simdata) ) return 3; break;
case 1: if( decode(simdata) ) return 2; break; case 1: if( decode(simdata) ) return 2; break;

2
cpu.h
View File

@ -6,6 +6,7 @@ struct fetch_data_t{
}; };
struct decode_data_t{ struct decode_data_t{
uint32_t in_bytecode; 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_op1;
struct exec_op_t *in_op2; struct exec_op_t *in_op2;
struct exec_op_t *out_op; struct exec_op_t *out_op;
uint32_t address; // used only for the gui hints (for now)
}; };

114
gui.c
View File

@ -128,6 +128,14 @@ int start_gui(){
init_pair(6, COLOR_BLACK,COLOR_GREEN); init_pair(6, COLOR_BLACK,COLOR_GREEN);
init_pair(7, COLOR_BLACK,COLOR_YELLOW); init_pair(7, COLOR_BLACK,COLOR_YELLOW);
init_pair(8, COLOR_BLACK,COLOR_RED); 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(); noecho();
curs_set(0); curs_set(0);
@ -189,12 +197,58 @@ int gui_error(char *str){
wattroff(error_win,COLOR_PAIR(1)); 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){ int update_general_disas(struct simdata_t *simdata){
werase(general_disas); werase(general_disas);
int width,height; int width,height;
getmaxyx(general_disas,height,width); getmaxyx(general_disas,height,width);
box(general_disas, 0 , 0); box(general_disas, 0 , 0);
int offset_arrow; int offset_arrow;
int have_legend=(width>29);
int usable_height=height-2-have_legend;
if(width<41) if(width<41)
offset_arrow=2; offset_arrow=2;
else else
@ -203,8 +257,8 @@ int update_general_disas(struct simdata_t *simdata){
if(width<18){ if(width<18){
mvwprintw(general_disas,1,1,"too small window"); mvwprintw(general_disas,1,1,"too small window");
}else{ }else{
uint32_t ADDRESS=(simdata->PC-(height/2-2)*4)&0x00FFFFFF; uint32_t ADDRESS=(simdata->PC-(usable_height/2-2)*4)&0x00FFFFFF;
for (int i=2;i<height-2;i++){ for (int i=2;i<usable_height;i++){
int overall_offset=offset_arrow-2; int overall_offset=offset_arrow-2;
mvwaddch(general_disas,i,11+overall_offset,ACS_VLINE); mvwaddch(general_disas,i,11+overall_offset,ACS_VLINE);
@ -216,25 +270,46 @@ int update_general_disas(struct simdata_t *simdata){
int space_left=width-14-2+(overall_offset?0:1); int space_left=width-14-2+(overall_offset?0:1);
if(space_left<25) if(space_left<25)
disas[space_left+1]=0; disas[space_left+1]=0;
select_instruction_color(simdata,general_disas,ADDRESS,1);
mvwprintw(general_disas,i,13+overall_offset,"%s",disas); mvwprintw(general_disas,i,13+overall_offset,"%s",disas);
select_instruction_color(simdata,general_disas,ADDRESS,0);
if(ADDRESS==simdata->PC) if(ADDRESS==simdata->PC)
wattroff(general_disas,A_BOLD); wattroff(general_disas,A_BOLD);
ADDRESS=(ADDRESS+4)&0xFFFFFF; ADDRESS=(ADDRESS+4)&0xFFFFFF;
free(disas); free(disas);
} }
mvwaddch(general_disas,height/2,offset_arrow,ACS_RARROW); mvwaddch(general_disas,usable_height/2,offset_arrow,ACS_RARROW);
mvwaddch(general_disas,height/2,offset_arrow-1,ACS_ULCORNER); mvwaddch(general_disas,usable_height/2,offset_arrow-1,ACS_ULCORNER);
mvwaddch(general_disas,height/2+1,offset_arrow-1,ACS_VLINE); mvwaddch(general_disas,usable_height/2+1,offset_arrow-1,ACS_VLINE);
mvwaddch(general_disas,height/2+2,offset_arrow-1,ACS_VLINE); mvwaddch(general_disas,usable_height/2+2,offset_arrow-1,ACS_VLINE);
mvwaddch(general_disas,height/2+3,offset_arrow-1,ACS_VLINE); mvwaddch(general_disas,usable_height/2+3,offset_arrow-1,ACS_VLINE);
mvwaddch(general_disas,height/2+4,offset_arrow-1,ACS_VLINE); mvwaddch(general_disas,usable_height/2+4,offset_arrow-1,ACS_VLINE);
mvwaddch(general_disas,height/2+5,offset_arrow-1,ACS_VLINE); mvwaddch(general_disas,usable_height/2+5,offset_arrow-1,ACS_VLINE);
mvwaddch(general_disas,height/2+6,offset_arrow-1,'P'); mvwaddch(general_disas,usable_height/2+6,offset_arrow-1,'P');
if(offset_arrow==2) 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 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; return 0;
} }
@ -307,6 +382,9 @@ int update_general_memdump(struct simdata_t *simdata){
int usable_height=height-3-(width-12)%2; int usable_height=height-3-(width-12)%2;
uint32_t ADDRESS=(simdata->PC-n*usable_height/2)&0x00FFFFFF; uint32_t ADDRESS=(simdata->PC-n*usable_height/2)&0x00FFFFFF;
uint32_t color_addr;
int have_color;
for(int h=0;h<usable_height;h++){ for(int h=0;h<usable_height;h++){
wmove(general_memdump,h+2,2+(width-12)%2); wmove(general_memdump,h+2,2+(width-12)%2);
wattroff(general_memdump,A_BOLD); wattroff(general_memdump,A_BOLD);
@ -317,9 +395,21 @@ int update_general_memdump(struct simdata_t *simdata){
wattron(general_memdump,A_BOLD); wattron(general_memdump,A_BOLD);
else else
wattroff(general_memdump,A_BOLD); wattroff(general_memdump,A_BOLD);
if(select_instruction_color(simdata,general_memdump,ADDRESS,1)==0){
have_color=5;
color_addr=ADDRESS;
}else if(have_color)
select_instruction_color(simdata,general_memdump,color_addr,1);
if(have_color){
have_color--;
if(!have_color)
select_instruction_color(simdata,general_memdump,color_addr,0);
}
wprintw(general_memdump,"%02x ",simdata->RAM[ADDRESS]); wprintw(general_memdump,"%02x ",simdata->RAM[ADDRESS]);
ADDRESS=(ADDRESS+1)&0xFFFFFF; ADDRESS=(ADDRESS+1)&0xFFFFFF;
} }
if(have_color)
select_instruction_color(simdata,general_memdump,color_addr,0);
ADDRESS=temp_address; ADDRESS=temp_address;
for (int i=0;i<n;i++){ for (int i=0;i<n;i++){
if(ADDRESS>=simdata->PC&&ADDRESS<=simdata->PC+3) if(ADDRESS>=simdata->PC&&ADDRESS<=simdata->PC+3)

View File

@ -40,11 +40,39 @@ struct simdata_t *init_simdata(){
ret->SP=0; ret->SP=0;
ret->registers=NULL; ret->registers=NULL;
ret->cpu_state=CPU_RUNNING; 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; 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){ void free_simdata(struct simdata_t *p){
free(p->RAM); 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); free(p);
} }

View File

@ -16,11 +16,25 @@ struct simdata_t{
struct exec_data_t *exec_data; struct exec_data_t *exec_data;
struct registers_t *registers; struct registers_t *registers;
enum CPU_STATE_t cpu_state; 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(); struct simdata_t *init_simdata();
void free_simdata(struct simdata_t *); 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{ enum GUI_CPU_STATE_t{
GUI_CPU_RUNNING, GUI_CPU_RUNNING,