GUI: Added colors to indicate where in the pipeline is each instruction
This commit is contained in:
parent
800e11be16
commit
4402688a20
11
cpu.c
11
cpu.c
@ -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
2
cpu.h
@ -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
114
gui.c
@ -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)
|
||||||
|
28
simdata.c
28
simdata.c
@ -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);
|
||||||
}
|
}
|
||||||
|
14
simdata.h
14
simdata.h
@ -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,
|
||||||
|
Loading…
Reference in New Issue
Block a user