GUI: Added support for using tabs, filled out the memory tab and created a window with some interesting information in the debug tab

This commit is contained in:
(Tim) Efthimis Kritikos 2024-02-20 20:02:30 +00:00
parent 4da500e5ec
commit 5816fa316b

222
gui.c
View File

@ -40,6 +40,8 @@ WINDOW *general_stack;
WINDOW *general_disas; WINDOW *general_disas;
WINDOW *general_registers; WINDOW *general_registers;
WINDOW *general_terminal_output; WINDOW *general_terminal_output;
WINDOW *memory_memdump;
WINDOW *debug_simdata;
int monochrome; int monochrome;
@ -52,28 +54,37 @@ int get_terminal_size(){
return changed; return changed;
} }
char *tab_name[]={"Overview","Memory","Internal","Debug"};
unsigned int CURRENT_TAB=1;
int gui_ncurses_refresh(){ int gui_ncurses_refresh(){
if(refresh()==ERR) if(refresh()==ERR)
return 1; return 1;
if(wrefresh(tabs)==ERR) if(wrefresh(tabs)==ERR)
return 1; return 1;
if(wrefresh(general_memdump)==ERR) if(CURRENT_TAB==1){
return 1; if(wrefresh(general_memdump)==ERR)
if(wrefresh(general_stack)==ERR) return 1;
return 1; if(wrefresh(general_stack)==ERR)
if(wrefresh(general_disas)==ERR) return 1;
return 1; if(wrefresh(general_disas)==ERR)
if(wrefresh(general_registers)==ERR) return 1;
return 1; if(wrefresh(general_registers)==ERR)
if(wrefresh(general_terminal_output)==ERR) return 1;
return 1; if(wrefresh(general_terminal_output)==ERR)
return 1;
}else if(CURRENT_TAB==2){
if(wrefresh(memory_memdump)==ERR)
return 1;
}else if(CURRENT_TAB==4){
if(wrefresh(debug_simdata)==ERR)
return 1;
}
return 0; return 0;
} }
char *tab_name[]={"Overview","Memory","Internal"};
unsigned int CURRENT_TAB=0;
enum GUI_CPU_STATE_t GUI_CPU_STATE=GUI_CPU_SINGLE_STEPPING; enum GUI_CPU_STATE_t GUI_CPU_STATE=GUI_CPU_SINGLE_STEPPING;
void update_tabs(){ void update_tabs(){
@ -83,7 +94,7 @@ void update_tabs(){
mvwprintw(tabs,0,i," "); mvwprintw(tabs,0,i," ");
int x=2; int x=2;
for(unsigned int i=0;i<sizeof(tab_name)/sizeof(tab_name[0]);i++){ for(unsigned int i=1;i<=sizeof(tab_name)/sizeof(tab_name[0]);i++){
if(i==CURRENT_TAB) if(i==CURRENT_TAB)
wattron(tabs,COLOR_PAIR(4)); wattron(tabs,COLOR_PAIR(4));
else else
@ -96,9 +107,9 @@ void update_tabs(){
wattron(tabs,COLOR_PAIR(2)); wattron(tabs,COLOR_PAIR(2));
wattroff(tabs,A_BOLD); wattroff(tabs,A_BOLD);
} }
mvwprintw(tabs,0,x," %s ",tab_name[i]); mvwprintw(tabs,0,x," %s ",tab_name[i-1]);
wattron(tabs,A_BOLD); wattron(tabs,A_BOLD);
x+=strlen(tab_name[i])+2+3; x+=strlen(tab_name[i-1])+2+3;
} }
switch(GUI_CPU_STATE){ switch(GUI_CPU_STATE){
case GUI_CPU_RUNNING: case GUI_CPU_RUNNING:
@ -144,6 +155,9 @@ int start_gui(){
init_pair(12, COLOR_BLACK,COLOR_MAGENTA); //fetch init_pair(12, COLOR_BLACK,COLOR_MAGENTA); //fetch
init_pair(13, COLOR_BLACK,COLOR_YELLOW); //decode init_pair(13, COLOR_BLACK,COLOR_YELLOW); //decode
init_pair(14, COLOR_BLACK,COLOR_GREEN); //exec init_pair(14, COLOR_BLACK,COLOR_GREEN); //exec
//debug window colors
init_pair(15, COLOR_RED,COLOR_BLACK); //decode
} }
noecho(); noecho();
curs_set(0); curs_set(0);
@ -193,8 +207,12 @@ int start_gui(){
x+=terminal_width/2; x+=terminal_width/2;
x++; x++;
memory_memdump=newwin(terminal_height-1-border*2,terminal_width-border*2,1+border,border);
debug_simdata=newwin(terminal_height-1-border*2,terminal_width-border*2,1+border,border);
gui_settings=malloc(sizeof(struct gui_settings_t)); gui_settings=malloc(sizeof(struct gui_settings_t));
gui_settings->cycles_per_frame=100; gui_settings->cycles_per_frame=40;
if(gui_ncurses_refresh()) if(gui_ncurses_refresh())
return 1; return 1;
@ -399,57 +417,66 @@ int update_general_stack(struct simdata_t *simdata){
return 0; return 0;
} }
int update_general_memdump(struct simdata_t *simdata){ //address: If within legal limit (address<0x00FFFFFF) then address*bytes_per_line will be used for the center of the memdump
// otherwise PC will be used
int update_memdump(WINDOW *win,uint32_t address,struct simdata_t *simdata){
int width,height; int width,height;
getmaxyx(general_memdump,height,width); getmaxyx(win,height,width);
box(general_memdump, 0 , 0); box(win, 0 , 0);
mvwprintw(general_memdump,0,terminal_width/4-6,"[ MEMDUMP ]"); mvwprintw(win,0,width/2-6,"[ MEMDUMP ]");
if(simdata->registers==NULL||simdata->RAM==NULL){ if(simdata->registers==NULL||simdata->RAM==NULL){
mvwprintw(general_memdump,1,1,"Data not initialised"); mvwprintw(win,1,1,"Data not initialised");
return 0; return 0;
} }
if(width<16){ if(width<16){
mvwprintw(general_memdump,1,1,"too small window"); mvwprintw(win,1,1,"too small window");
}else{ }else{
int n=(width-12)/4; // bytes in each line int n=(width-12)/4; // bytes in each line
int usable_height=height-3-(width-12)%2; int usable_height=height-3-(width-12)%2;
uint32_t ADDRESS=(simdata->registers->PC-n*usable_height/2)&0x00FFFFFF; uint32_t center_address;
if(address<=0x00FFFFFF)
center_address=address*n;
else
center_address=simdata->registers->PC;
uint32_t ADDRESS=(center_address-n*usable_height/2)&0x00FFFFFF;
uint32_t color_addr; uint32_t color_addr;
int have_color=0; int have_color=0;
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(win,h+2,2+(width-12)%2);
wattroff(general_memdump,A_BOLD); wattroff(win,A_BOLD);
wprintw(general_memdump,"%06x ",ADDRESS); wprintw(win,"%06x ",ADDRESS);
uint32_t temp_address=ADDRESS; uint32_t temp_address=ADDRESS;
for (int i=0;i<n;i++){ for (int i=0;i<n;i++){
if(ADDRESS>=simdata->registers->PC&&ADDRESS<=simdata->registers->PC+3) if(ADDRESS>=simdata->registers->PC&&ADDRESS<=simdata->registers->PC+3)
wattron(general_memdump,A_BOLD); wattron(win,A_BOLD);
else else
wattroff(general_memdump,A_BOLD); wattroff(win,A_BOLD);
if(select_instruction_color(simdata,general_memdump,ADDRESS,1)==0){ if(select_instruction_color(simdata,win,ADDRESS,1)==0){
have_color=5; have_color=5;
color_addr=ADDRESS; color_addr=ADDRESS;
}else if(have_color) }else if(have_color)
select_instruction_color(simdata,general_memdump,color_addr,1); select_instruction_color(simdata,win,color_addr,1);
if(have_color){ if(have_color){
have_color--; have_color--;
if(!have_color) if(!have_color)
select_instruction_color(simdata,general_memdump,color_addr,0); select_instruction_color(simdata,win,color_addr,0);
} }
wprintw(general_memdump,"%02x ",simdata->RAM[ADDRESS]); wprintw(win,"%02x ",simdata->RAM[ADDRESS]);
ADDRESS=(ADDRESS+1)&0xFFFFFF; ADDRESS=(ADDRESS+1)&0xFFFFFF;
} }
if(have_color) if(have_color)
select_instruction_color(simdata,general_memdump,color_addr,0); select_instruction_color(simdata,win,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->registers->PC&&ADDRESS<=simdata->registers->PC+3) if(ADDRESS>=simdata->registers->PC&&ADDRESS<=simdata->registers->PC+3)
wattron(general_memdump,A_BOLD); wattron(win,A_BOLD);
else else
wattroff(general_memdump,A_BOLD); wattroff(win,A_BOLD);
wprintw(general_memdump,"%c",(simdata->RAM[ADDRESS]>=0x20&&simdata->RAM[ADDRESS]<0x7F)?simdata->RAM[ADDRESS]:'.'); wprintw(win,"%c",(simdata->RAM[ADDRESS]>=0x20&&simdata->RAM[ADDRESS]<0x7F)?simdata->RAM[ADDRESS]:'.');
ADDRESS=(ADDRESS+1)&0xFFFFFF; ADDRESS=(ADDRESS+1)&0xFFFFFF;
} }
} }
@ -457,12 +484,22 @@ int update_general_memdump(struct simdata_t *simdata){
return 0; return 0;
} }
uint32_t memory_window_address=0x00000000;
int update_memory_memdump(struct simdata_t *simdata){
return update_memdump(memory_memdump,memory_window_address,simdata);
}
int update_general_memdump(struct simdata_t *simdata){
return update_memdump(general_memdump,0xFFFFFFFF,simdata);
}
int update_general_registers(struct simdata_t *simdata){ int update_general_registers(struct simdata_t *simdata){
int width,height; int width,height;
werase(general_registers); werase(general_registers);
getmaxyx(general_registers,height,width); getmaxyx(general_registers,height,width);
box(general_registers, 0 , 0); box(general_registers, 0 , 0);
mvwprintw(general_registers,0,terminal_width/4-7,"[ REGISTERS ]"); mvwprintw(general_registers,0,width/2-7,"[ REGISTERS ]");
if(simdata->registers==NULL){ if(simdata->registers==NULL){
mvwprintw(general_registers,1,1,"Data not initialised"); mvwprintw(general_registers,1,1,"Data not initialised");
return 0; return 0;
@ -710,6 +747,41 @@ int update_general_terminal_output(struct simdata_t *simdata){
return 0; return 0;
} }
int update_debug_simdata(struct simdata_t *simdata){
int width,height;
werase(debug_simdata);
getmaxyx(debug_simdata,height,width);
box(debug_simdata, 0 , 0);
mvwprintw(debug_simdata,0,width/2-5,"[ SIMDATA ]");
if(simdata->registers==NULL||simdata->RAM==NULL){
mvwprintw(debug_simdata,1,1,"Data not initialised");
return 0;
}
int term_size;
char* term_size_unit;
if(simdata->terminal_output_size<(1024))
term_size=simdata->terminal_output_size,term_size_unit="Bytes";
else if(simdata->terminal_output_size<(1024*1024))
term_size=simdata->terminal_output_size/1024,term_size_unit="KiB";
else if(simdata->terminal_output_size<(1024*1024*1024))
term_size=simdata->terminal_output_size/(1024*1024),term_size_unit="MiB";
else
term_size=simdata->terminal_output_size/(1024*1024*1024),term_size_unit="GiB";
mvwprintw(debug_simdata,1,1,"simdata->terminal_output_size: ");
if(simdata->terminal_output_size<100*1024)
wattron(debug_simdata,COLOR_PAIR(11));
else
wattron(debug_simdata,COLOR_PAIR(15));
wprintw(debug_simdata,"%d%s",term_size,term_size_unit);
if(simdata->terminal_output_size<100*1024)
wattroff(debug_simdata,COLOR_PAIR(11));
else
wattroff(debug_simdata,COLOR_PAIR(15));
if(height==3)
return 0;
else
return 0;
}
int clear_back_window=1; int clear_back_window=1;
int update_gui(struct simdata_t *simdata){ int update_gui(struct simdata_t *simdata){
@ -721,16 +793,24 @@ int update_gui(struct simdata_t *simdata){
} }
if((simdata->current_clock)%(gui_settings->cycles_per_frame)==0 || GUI_CPU_STATE!=GUI_CPU_RUNNING ){ if((simdata->current_clock)%(gui_settings->cycles_per_frame)==0 || GUI_CPU_STATE!=GUI_CPU_RUNNING ){
update_tabs(); update_tabs();
if(update_general_memdump(simdata)) if(CURRENT_TAB==1){
return 1; if(update_general_memdump(simdata))
if(update_general_stack(simdata)) return 1;
return 1; if(update_general_stack(simdata))
if(update_general_disas(simdata)) return 1;
return 1; if(update_general_disas(simdata))
if(update_general_registers(simdata)) return 1;
return 1; if(update_general_registers(simdata))
if(update_general_terminal_output(simdata)) return 1;
return 1; if(update_general_terminal_output(simdata))
return 1;
}else if(CURRENT_TAB==2){
if(update_memory_memdump(simdata))
return 1;
}else if(CURRENT_TAB==4){
if(update_debug_simdata(simdata))
return 1;
}
} }
if(gui_ncurses_refresh()) if(gui_ncurses_refresh())
return 1; return 1;
@ -765,6 +845,50 @@ int gui_continue_request(struct simdata_t *simdata){
case '\n': case '\n':
release=1; release=1;
break; break;
case '1':
if(CURRENT_TAB!=1){
CURRENT_TAB=1;
clear();
update_gui(simdata);
}
break;
case '2':
if(CURRENT_TAB!=2){
CURRENT_TAB=2;
clear();
update_gui(simdata);
}
break;
case '3':
if(CURRENT_TAB!=3){
CURRENT_TAB=3;
clear();
update_gui(simdata);
}
break;
case '4':
if(CURRENT_TAB!=4){
CURRENT_TAB=4;
clear();
update_gui(simdata);
}
break;
case 'j':
if(CURRENT_TAB==2){
memory_window_address++;
if(memory_window_address==0x01000000)
memory_window_address=0x00000000;
update_gui(simdata);
}
break;
case 'k':
if(CURRENT_TAB==2){
memory_window_address--;
if(memory_window_address==0xFFFFFFFF)
memory_window_address=0x00FFFFFF;
update_gui(simdata);
}
break;
default: default:
break; break;
} }