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_registers;
WINDOW *general_terminal_output;
WINDOW *memory_memdump;
WINDOW *debug_simdata;
int monochrome;
@ -52,28 +54,37 @@ int get_terminal_size(){
return changed;
}
char *tab_name[]={"Overview","Memory","Internal","Debug"};
unsigned int CURRENT_TAB=1;
int gui_ncurses_refresh(){
if(refresh()==ERR)
return 1;
if(wrefresh(tabs)==ERR)
return 1;
if(wrefresh(general_memdump)==ERR)
return 1;
if(wrefresh(general_stack)==ERR)
return 1;
if(wrefresh(general_disas)==ERR)
return 1;
if(wrefresh(general_registers)==ERR)
return 1;
if(wrefresh(general_terminal_output)==ERR)
return 1;
if(CURRENT_TAB==1){
if(wrefresh(general_memdump)==ERR)
return 1;
if(wrefresh(general_stack)==ERR)
return 1;
if(wrefresh(general_disas)==ERR)
return 1;
if(wrefresh(general_registers)==ERR)
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;
}
char *tab_name[]={"Overview","Memory","Internal"};
unsigned int CURRENT_TAB=0;
enum GUI_CPU_STATE_t GUI_CPU_STATE=GUI_CPU_SINGLE_STEPPING;
void update_tabs(){
@ -83,7 +94,7 @@ void update_tabs(){
mvwprintw(tabs,0,i," ");
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)
wattron(tabs,COLOR_PAIR(4));
else
@ -96,9 +107,9 @@ void update_tabs(){
wattron(tabs,COLOR_PAIR(2));
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);
x+=strlen(tab_name[i])+2+3;
x+=strlen(tab_name[i-1])+2+3;
}
switch(GUI_CPU_STATE){
case GUI_CPU_RUNNING:
@ -144,6 +155,9 @@ int start_gui(){
init_pair(12, COLOR_BLACK,COLOR_MAGENTA); //fetch
init_pair(13, COLOR_BLACK,COLOR_YELLOW); //decode
init_pair(14, COLOR_BLACK,COLOR_GREEN); //exec
//debug window colors
init_pair(15, COLOR_RED,COLOR_BLACK); //decode
}
noecho();
curs_set(0);
@ -193,8 +207,12 @@ int start_gui(){
x+=terminal_width/2;
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->cycles_per_frame=100;
gui_settings->cycles_per_frame=40;
if(gui_ncurses_refresh())
return 1;
@ -399,57 +417,66 @@ int update_general_stack(struct simdata_t *simdata){
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;
getmaxyx(general_memdump,height,width);
box(general_memdump, 0 , 0);
mvwprintw(general_memdump,0,terminal_width/4-6,"[ MEMDUMP ]");
getmaxyx(win,height,width);
box(win, 0 , 0);
mvwprintw(win,0,width/2-6,"[ MEMDUMP ]");
if(simdata->registers==NULL||simdata->RAM==NULL){
mvwprintw(general_memdump,1,1,"Data not initialised");
mvwprintw(win,1,1,"Data not initialised");
return 0;
}
if(width<16){
mvwprintw(general_memdump,1,1,"too small window");
mvwprintw(win,1,1,"too small window");
}else{
int n=(width-12)/4; // bytes in each line
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;
int have_color=0;
for(int h=0;h<usable_height;h++){
wmove(general_memdump,h+2,2+(width-12)%2);
wattroff(general_memdump,A_BOLD);
wprintw(general_memdump,"%06x ",ADDRESS);
wmove(win,h+2,2+(width-12)%2);
wattroff(win,A_BOLD);
wprintw(win,"%06x ",ADDRESS);
uint32_t temp_address=ADDRESS;
for (int i=0;i<n;i++){
if(ADDRESS>=simdata->registers->PC&&ADDRESS<=simdata->registers->PC+3)
wattron(general_memdump,A_BOLD);
wattron(win,A_BOLD);
else
wattroff(general_memdump,A_BOLD);
if(select_instruction_color(simdata,general_memdump,ADDRESS,1)==0){
wattroff(win,A_BOLD);
if(select_instruction_color(simdata,win,ADDRESS,1)==0){
have_color=5;
color_addr=ADDRESS;
}else if(have_color)
select_instruction_color(simdata,general_memdump,color_addr,1);
select_instruction_color(simdata,win,color_addr,1);
if(have_color){
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;
}
if(have_color)
select_instruction_color(simdata,general_memdump,color_addr,0);
select_instruction_color(simdata,win,color_addr,0);
ADDRESS=temp_address;
for (int i=0;i<n;i++){
if(ADDRESS>=simdata->registers->PC&&ADDRESS<=simdata->registers->PC+3)
wattron(general_memdump,A_BOLD);
wattron(win,A_BOLD);
else
wattroff(general_memdump,A_BOLD);
wprintw(general_memdump,"%c",(simdata->RAM[ADDRESS]>=0x20&&simdata->RAM[ADDRESS]<0x7F)?simdata->RAM[ADDRESS]:'.');
wattroff(win,A_BOLD);
wprintw(win,"%c",(simdata->RAM[ADDRESS]>=0x20&&simdata->RAM[ADDRESS]<0x7F)?simdata->RAM[ADDRESS]:'.');
ADDRESS=(ADDRESS+1)&0xFFFFFF;
}
}
@ -457,12 +484,22 @@ int update_general_memdump(struct simdata_t *simdata){
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 width,height;
werase(general_registers);
getmaxyx(general_registers,height,width);
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){
mvwprintw(general_registers,1,1,"Data not initialised");
return 0;
@ -710,6 +747,41 @@ int update_general_terminal_output(struct simdata_t *simdata){
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 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 ){
update_tabs();
if(update_general_memdump(simdata))
return 1;
if(update_general_stack(simdata))
return 1;
if(update_general_disas(simdata))
return 1;
if(update_general_registers(simdata))
return 1;
if(update_general_terminal_output(simdata))
return 1;
if(CURRENT_TAB==1){
if(update_general_memdump(simdata))
return 1;
if(update_general_stack(simdata))
return 1;
if(update_general_disas(simdata))
return 1;
if(update_general_registers(simdata))
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())
return 1;
@ -765,6 +845,50 @@ int gui_continue_request(struct simdata_t *simdata){
case '\n':
release=1;
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:
break;
}