From 7657e4d7db609460aa6d7bc993ee1ec2aa94670f Mon Sep 17 00:00:00 2001 From: Hugo Villeneuve Date: Sun, 20 Oct 2013 21:46:07 -0400 Subject: [PATCH 01/16] Harmonize windows refresh function names --- src/emugtk.c | 8 ++++---- src/memwin.c | 9 ++++----- src/memwin.h | 2 +- src/pgmwin.c | 7 +++---- src/pgmwin.h | 2 +- src/regwin.c | 2 +- src/regwin.h | 2 +- 7 files changed, 15 insertions(+), 17 deletions(-) diff --git a/src/emugtk.c b/src/emugtk.c index f4f9301..3ca0c04 100644 --- a/src/emugtk.c +++ b/src/emugtk.c @@ -60,10 +60,10 @@ void emugtk_UpdateDisplay(void) { log_debug("UpdateDisplay()"); - regwin_Show(); - pgmwin_Disasm(); - memwin_DumpD(INT_MEM_ID); - memwin_DumpD(EXT_MEM_ID); + regwin_refresh(); + pgmwin_refresh(); + memwin_refresh(INT_MEM_ID); + memwin_refresh(EXT_MEM_ID); } /* Step out of running state */ diff --git a/src/memwin.c b/src/memwin.c index 17b9413..ffe5e56 100644 --- a/src/memwin.c +++ b/src/memwin.c @@ -32,6 +32,7 @@ #include "cpu8051.h" #include "regwin.h" #include "memwin.h" +#include "emugtk.h" #define DATA_COLS 16 /* Must be a power of 2 */ #define DATA_ROWS_INT (INT_MEM_SIZE / DATA_COLS) @@ -132,7 +133,7 @@ memwin_cell_edited(GtkCellRendererText *cell, gchar *path_string, * Make sure to update all registers and memory. * For example, BANKed registers depends on internal memory. */ - regwin_Show(); + emugtk_UpdateDisplay(); }; static void @@ -247,9 +248,9 @@ memwin_init(char *title, int memory_id) return frame; } -/* Dump up to 256 bytes from Address in Memory (direct addressing) */ +/* Dump internal or external memory. */ void -memwin_DumpD(int memory_id) +memwin_refresh(int memory_id) { int row; unsigned int Address; @@ -257,8 +258,6 @@ memwin_DumpD(int memory_id) GtkWidget *memlist; int data_rows; - log_info("memwin_DumpD()"); - Address = 0; if (memory_id == INT_MEM_ID) { diff --git a/src/memwin.h b/src/memwin.h index 3d0704f..ccb528d 100644 --- a/src/memwin.h +++ b/src/memwin.h @@ -28,6 +28,6 @@ GtkWidget * memwin_init(char *title, int memory_id); void -memwin_DumpD(int memory_id); +memwin_refresh(int memory_id); #endif /* MEMWIN_H */ diff --git a/src/pgmwin.c b/src/pgmwin.c index 04cff15..69410bc 100644 --- a/src/pgmwin.c +++ b/src/pgmwin.c @@ -144,7 +144,7 @@ pgmwin_sel_changed_event(GtkWidget *widget, GdkEvent *event, gpointer data) log_debug(" row address is: $%04X", val); ToggleBreakpoint(val); - pgmwin_Disasm(); + pgmwin_refresh(); g_free(str_addr); } else { @@ -205,7 +205,7 @@ pgmwin_init(void) /* Show disassembled program. */ void -pgmwin_Disasm(void) +pgmwin_refresh(void) { int row; GtkListStore *store; @@ -219,8 +219,7 @@ pgmwin_Disasm(void) int valid; GtkTreeIter iter; char str[128]; - int k; - int col_id; + int k; int col_id; int InstSize; unsigned char OpCode; diff --git a/src/pgmwin.h b/src/pgmwin.h index 0276e7f..952d931 100644 --- a/src/pgmwin.h +++ b/src/pgmwin.h @@ -28,7 +28,7 @@ GtkWidget * pgmwin_init(void); void -pgmwin_Disasm(void); +pgmwin_refresh(void); int pgmwin_IsBreakpoint(unsigned int address); diff --git a/src/regwin.c b/src/regwin.c index aaa006b..f94b8f9 100644 --- a/src/regwin.c +++ b/src/regwin.c @@ -466,7 +466,7 @@ regwin_init(void) /* Show registers. */ void -regwin_Show(void) +regwin_refresh(void) { int row; GtkListStore *store; diff --git a/src/regwin.h b/src/regwin.h index 45e71e2..a526f6f 100644 --- a/src/regwin.h +++ b/src/regwin.h @@ -28,6 +28,6 @@ GtkWidget * regwin_init(void); void -regwin_Show(void); +regwin_refresh(void); #endif /* REGWIN_H */ -- 2.20.1 From 45be0d02186f8c48dc3705de2a71ade93705ae1d Mon Sep 17 00:00:00 2001 From: Hugo Villeneuve Date: Sun, 20 Oct 2013 22:09:50 -0400 Subject: [PATCH 02/16] Adjust memory index column header according to number of data columns --- src/memwin.c | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) diff --git a/src/memwin.c b/src/memwin.c index ffe5e56..d8441fb 100644 --- a/src/memwin.c +++ b/src/memwin.c @@ -94,6 +94,7 @@ memwin_cell_edited(GtkCellRendererText *cell, gchar *path_string, columnptr = g_object_get_data(G_OBJECT(cell), "column"); column = GPOINTER_TO_UINT(columnptr); + /* Memory ID is passed as renderer object data */ memory_id_ptr = g_object_get_data(G_OBJECT(cell), "memory_id"); memory_id = GPOINTER_TO_UINT(memory_id_ptr); @@ -166,13 +167,17 @@ memwin_init_columns(GtkWidget *listview, int memory_id) gtk_tree_view_get_model( GTK_TREE_VIEW(listview))); - /* Add column index, used when editing the cell. */ + /* Add column index and memory_id, used when editing the cell. */ g_object_set_data(G_OBJECT(renderer), "column", GUINT_TO_POINTER(i)); g_object_set_data(G_OBJECT(renderer), "memory_id", GUINT_TO_POINTER(memory_id)); - sprintf(col_name, "B%02d", i - COL_DATA0); + /* Use two digits only if DATA_ROWS > 10 */ + if (DATA_COLS < 10) + sprintf(col_name, "B%1d", i - COL_DATA0); + else + sprintf(col_name, "B%02d", i - COL_DATA0); column = gtk_tree_view_column_new_with_attributes( col_name, renderer, "text", i, NULL); -- 2.20.1 From 42f213fff59103c0f9ba464057bc1dee8dd0e78b Mon Sep 17 00:00:00 2001 From: Hugo Villeneuve Date: Sun, 20 Oct 2013 22:12:19 -0400 Subject: [PATCH 03/16] Align memory data columns text on left side --- src/memwin.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/memwin.c b/src/memwin.c index d8441fb..2c7fde1 100644 --- a/src/memwin.c +++ b/src/memwin.c @@ -159,8 +159,8 @@ memwin_init_columns(GtkWidget *listview, int memory_id) /* Create new renderer for each editable cell. */ renderer = gtk_cell_renderer_text_new(); - /* Allow edition, align to right side. */ - g_object_set(renderer, "editable", TRUE, "xalign", 1.0, NULL); + /* Allow edition, align to left side. */ + g_object_set(renderer, "editable", TRUE, "xalign", 0, NULL); g_signal_connect(renderer, "edited", G_CALLBACK(memwin_cell_edited), -- 2.20.1 From 02656a7a705cf0db1cc6c4e8e6b2671bee7f2a12 Mon Sep 17 00:00:00 2001 From: Hugo Villeneuve Date: Sun, 20 Oct 2013 22:18:53 -0400 Subject: [PATCH 04/16] Use fixed font for ASCII column --- src/memwin.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/src/memwin.c b/src/memwin.c index 2c7fde1..4c8cc22 100644 --- a/src/memwin.c +++ b/src/memwin.c @@ -186,7 +186,9 @@ memwin_init_columns(GtkWidget *listview, int memory_id) gtk_tree_view_append_column(GTK_TREE_VIEW(listview), column); } - /* Add ASCII column */ + /* Add ASCII column, using fixed-font. */ + renderer = gtk_cell_renderer_text_new(); + g_object_set(renderer, "family", "Monospace", NULL); column = gtk_tree_view_column_new_with_attributes( "ASCII", renderer, "text", COL_ASCII, NULL); gtk_tree_view_column_set_sizing(column, GTK_TREE_VIEW_COLUMN_AUTOSIZE); -- 2.20.1 From bd0627548f7258b54a615787d0515d3e2bde648e Mon Sep 17 00:00:00 2001 From: Hugo Villeneuve Date: Mon, 21 Oct 2013 22:36:40 -0400 Subject: [PATCH 05/16] Add live option to change windows layout Restart UI when changing layout. This is working, altough the main window temporarily disapear in doing so. --- src/app-config.c | 19 ++++++-- src/app-config.h | 21 +++++++-- src/emugtk.c | 117 ++++++++++++++++++++++++++++------------------- src/emugtk.h | 6 +++ src/filemenu.c | 2 +- src/viewmenu.c | 79 ++++++++++++++++++++++---------- 6 files changed, 164 insertions(+), 80 deletions(-) diff --git a/src/app-config.c b/src/app-config.c index 6d65df9..58f76e5 100644 --- a/src/app-config.c +++ b/src/app-config.c @@ -51,11 +51,12 @@ app_config_init(void) cfg->clear_ram_on_file_load = false; /* UI settings */ + cfg->layout = UI_LAYOUT1; cfg->win_width = 640; cfg->win_height = 480; cfg->hpane_pos = 100; cfg->vpane_pos = 200; - cfg->vpane_mem_pos = 200; + cfg->main_pane_pos = 200; } static int @@ -82,12 +83,19 @@ app_config_load_from_key_file(GKeyFile *kf) &cfg->clear_ram_on_file_load); /* ui */ + app_config_key_file_get_int(kf, "ui", "layout", &cfg->layout); + + if ((cfg->layout != UI_LAYOUT1) && (cfg->layout != UI_LAYOUT2)) { + log_fail_no_exit("Invalid layout, defaulting to layout 1"); + cfg->layout = UI_LAYOUT1; + } + app_config_key_file_get_int(kf, "ui", "win_width", &cfg->win_width); app_config_key_file_get_int(kf, "ui", "win_height", &cfg->win_height); app_config_key_file_get_int(kf, "ui", "hpane_pos", &cfg->hpane_pos); app_config_key_file_get_int(kf, "ui", "vpane_pos", &cfg->vpane_pos); - app_config_key_file_get_int(kf, "ui", "vpane_mem_pos", - &cfg->vpane_mem_pos); + app_config_key_file_get_int(kf, "ui", "main_pane_pos", + &cfg->main_pane_pos); } static char * @@ -164,12 +172,13 @@ app_config_save(void) g_string_append(buf, "\n[ui]\n"); + g_string_append_printf(buf, "layout=%d\n", cfg->layout); g_string_append_printf(buf, "win_width=%d\n", cfg->win_width); g_string_append_printf(buf, "win_height=%d\n", cfg->win_height); g_string_append_printf(buf, "hpane_pos=%d\n", cfg->hpane_pos); g_string_append_printf(buf, "vpane_pos=%d\n", cfg->vpane_pos); - g_string_append_printf(buf, "vpane_mem_pos=%d\n", - cfg->vpane_mem_pos); + g_string_append_printf(buf, "main_pane_pos=%d\n", + cfg->main_pane_pos); file_path = app_config_get_file_path(); diff --git a/src/app-config.h b/src/app-config.h index f6c27b9..c655041 100644 --- a/src/app-config.h +++ b/src/app-config.h @@ -21,17 +21,32 @@ #ifndef APP_CONFIG_H #define APP_CONFIG_H 1 +/* + * Layout1: Layout2: + * + * REGS | PROGRAM | | IRAM + * -------------- REGS | PROGRAM | ---- + * IRAM | | XRAM + * -------------- + * XRAM + */ +enum layout_t { + UI_LAYOUT1 = 1, + UI_LAYOUT2, +}; + struct app_config_t { /* Emulation options */ int clear_ram_on_file_load; /* UI settings */ + int layout; /* UI Layout 1 or 2 */ int win_width; int win_height; - int hpane_pos; - int vpane_pos; /* Registers and memory windows. */ - int vpane_mem_pos; /* Internal and external memory windows. */ + int hpane_pos; /* For registers and program windows. */ + int vpane_pos; /* For internal and external memory windows. */ + int main_pane_pos; /* Between hpane and vpane. */ }; int diff --git a/src/emugtk.c b/src/emugtk.c index 3ca0c04..1c114fc 100644 --- a/src/emugtk.c +++ b/src/emugtk.c @@ -50,6 +50,7 @@ static int running; static int running_function_tag; +static int restart_gui = true; GtkWidget *mainwin; @@ -248,25 +249,43 @@ mainwin_configure_event(GtkWindow *window, GdkEvent *event, gpointer data) static void hpaned_notify_event(GtkWindow *window, GdkEvent *event, gpointer data) { - GtkWidget *hpaned = data; + GtkWidget *paned = data; - cfg->hpane_pos = gtk_paned_get_position(GTK_PANED(hpaned)); + cfg->hpane_pos = gtk_paned_get_position(GTK_PANED(paned)); } static void vpaned_notify_event(GtkWindow *window, GdkEvent *event, gpointer data) { - GtkWidget *vpaned = data; + GtkWidget *paned = data; - cfg->vpane_pos = gtk_paned_get_position(GTK_PANED(vpaned)); + cfg->vpane_pos = gtk_paned_get_position(GTK_PANED(paned)); } static void -vpaned_mem_notify_event(GtkWindow *window, GdkEvent *event, gpointer data) +main_paned_notify_event(GtkWindow *window, GdkEvent *event, gpointer data) { - GtkWidget *vpaned = data; + GtkWidget *paned = data; - cfg->vpane_mem_pos = gtk_paned_get_position(GTK_PANED(vpaned)); + cfg->main_pane_pos = gtk_paned_get_position(GTK_PANED(paned)); +} + +void +emugtk_restart_gui(void) +{ + emugtk_stop_running(); + + gtk_widget_destroy(mainwin); + + restart_gui = true; +} + +void +emugtk_quit_gui(void) +{ + gtk_main_quit(); + + restart_gui = false; } /* @@ -290,7 +309,7 @@ vpaned_mem_notify_event(GtkWindow *window, GdkEvent *event, gpointer data) * | | | | * | |---------------------------------------------------------------| | * | | | | - * | | vpaned | | + * | | main_paned | | * | | +---------------------------------------------------------+ | | * | | | | | | * | | | hpaned | | | @@ -305,7 +324,7 @@ vpaned_mem_notify_event(GtkWindow *window, GdkEvent *event, gpointer data) * | | | | | | * | | |--------------------------***----------------------------- | | * | | | | | | - * | | | vpaned_mem | | | + * | | | vpaned | | | * | | | +---------------------------------------------------+ | | | * | | | | | | | | * | | | | scrollwin | | | | @@ -339,7 +358,7 @@ emugtk_window_init(void) GtkWidget *scrollwin; GtkWidget *hpaned; GtkWidget *vpaned; - GtkWidget *vpaned_mem; + GtkWidget *main_paned; mainwin = gtk_window_new(GTK_WINDOW_TOPLEVEL); gtk_window_set_title(GTK_WINDOW(mainwin), PACKAGE); @@ -354,31 +373,11 @@ emugtk_window_init(void) g_signal_connect(G_OBJECT(mainwin), "configure-event", G_CALLBACK(mainwin_configure_event), NULL); - /* - * vbox contains the menu bar and body_vbox (for all remaining - * items). - */ - vbox = gtk_vbox_new(FALSE, 1); - /* Creating the menu bar. */ menu_bar = AddMenu(); - /* Adding menu bar to vbox */ - gtk_box_pack_start(GTK_BOX(vbox), menu_bar, FALSE, FALSE, 1); /* Creating the buttons bar. */ buttons_bar = AddButtons(); - /* Adding buttons bar to vbox */ - gtk_box_pack_start(GTK_BOX(vbox), buttons_bar, FALSE, FALSE, 1); - - /* - * vpaned will contain: - * Top: registers and disassembly windows. - * Bottom: memory windows - */ - vpaned = gtk_vpaned_new(); - gtk_paned_set_position(GTK_PANED(vpaned), cfg->vpane_pos); - g_signal_connect(G_OBJECT(vpaned), "notify::position", - G_CALLBACK(vpaned_notify_event), vpaned); /* hpaned will contain registers and disassembly windows. */ hpaned = gtk_hpaned_new(); @@ -394,29 +393,49 @@ emugtk_window_init(void) scrollwin = pgmwin_init(); gtk_paned_pack2(GTK_PANED(hpaned), scrollwin, TRUE, FALSE); - gtk_paned_pack1(GTK_PANED(vpaned), hpaned, FALSE, FALSE); - - vpaned_mem = gtk_vpaned_new(); - gtk_paned_set_position(GTK_PANED(vpaned_mem), cfg->vpane_mem_pos); - g_signal_connect(G_OBJECT(vpaned_mem), "notify::position", - G_CALLBACK(vpaned_mem_notify_event), vpaned_mem); + vpaned = gtk_vpaned_new(); + gtk_paned_set_position(GTK_PANED(vpaned), cfg->vpane_pos); + g_signal_connect(G_OBJECT(vpaned), "notify::position", + G_CALLBACK(vpaned_notify_event), vpaned); /* Internal memory dump frame. */ scrollwin = memwin_init("Internal memory (IRAM)", INT_MEM_ID); - gtk_paned_pack1(GTK_PANED(vpaned_mem), scrollwin, FALSE, FALSE); + gtk_paned_pack1(GTK_PANED(vpaned), scrollwin, FALSE, FALSE); /* External memory dump frame. */ scrollwin = memwin_init("External memory (XRAM)", EXT_MEM_ID); - gtk_paned_pack2(GTK_PANED(vpaned_mem), scrollwin, TRUE, FALSE); + gtk_paned_pack2(GTK_PANED(vpaned), scrollwin, TRUE, FALSE); + + /* + * main_paned will contain two groups: + * group1: registers and disassembly windows. + * group2: memory windows + */ + if (cfg->layout == UI_LAYOUT1) + main_paned = gtk_vpaned_new(); + else + main_paned = gtk_hpaned_new(); - gtk_paned_pack2(GTK_PANED(vpaned), vpaned_mem, TRUE, FALSE); + gtk_paned_set_position(GTK_PANED(main_paned), cfg->main_pane_pos); + g_signal_connect(G_OBJECT(main_paned), "notify::position", + G_CALLBACK(main_paned_notify_event), main_paned); + gtk_paned_pack1(GTK_PANED(main_paned), hpaned, FALSE, FALSE); + gtk_paned_pack2(GTK_PANED(main_paned), vpaned, TRUE, FALSE); - /* Adding vpaned window to vbox */ - gtk_box_pack_start(GTK_BOX(vbox), vpaned, true, true, 1); + /* + * vbox contains the menu bar and body_vbox (for all remaining + * items). + */ + vbox = gtk_vbox_new(FALSE, 1); + gtk_box_pack_start(GTK_BOX(vbox), menu_bar, FALSE, FALSE, 1); + gtk_box_pack_start(GTK_BOX(vbox), buttons_bar, FALSE, FALSE, 1); + gtk_box_pack_start(GTK_BOX(vbox), main_paned, true, true, 1); /* Adding the vbox to the main window. */ gtk_container_add(GTK_CONTAINER(mainwin), vbox); + g_signal_connect(mainwin, "destroy", G_CALLBACK(emugtk_quit_gui), NULL); + gtk_widget_show_all(mainwin); } @@ -436,7 +455,7 @@ emugtk_new_file(char *file) LoadHexFile(file); - emugtk_Reset(); + emugtk_Reset(); /* Use app-config->clear_ram_on_file_load */ emugtk_UpdateDisplay(); } @@ -452,14 +471,18 @@ main(int argc, char **argv) gtk_init(&argc, &argv); - emugtk_window_init(); - if (options.filename != NULL) - emugtk_new_file(options.filename); + LoadHexFile(options.filename); else - emugtk_Reset(); + cpu8051_Reset(); - gtk_main(); + while (restart_gui == true) { + log_info("Init GUI"); + + emugtk_window_init(); + emugtk_UpdateDisplay(); + gtk_main(); + } log_info("Terminate"); diff --git a/src/emugtk.h b/src/emugtk.h index 35ac1e4..8e47427 100644 --- a/src/emugtk.h +++ b/src/emugtk.h @@ -33,4 +33,10 @@ emugtk_new_file(char *file); void emugtk_UpdateDisplay(void); +void +emugtk_restart_gui(void); + +void +emugtk_quit_gui(void); + #endif /* EMUGTK_H */ diff --git a/src/filemenu.c b/src/filemenu.c index 47e18aa..d2dae9c 100644 --- a/src/filemenu.c +++ b/src/filemenu.c @@ -107,7 +107,7 @@ FileOpenEvent(GtkObject *object, gpointer data) static void FileQuitEvent(gchar *string) { - gtk_main_quit(); + emugtk_quit_gui(); } void diff --git a/src/viewmenu.c b/src/viewmenu.c index b167274..3024877 100644 --- a/src/viewmenu.c +++ b/src/viewmenu.c @@ -29,19 +29,54 @@ #include "emugtk.h" /* For AddMenuSeparator() function. */ #include "messagebox.h" #include "viewmenu.h" +#include "app-config.h" -static void -ViewMenuExternalDump(gchar *string) +extern struct app_config_t *cfg; + +void toggle_layout(GtkWidget *widget, gpointer data) { - ShowMessage("External Memory Dump", "Not implemented yet!", - GTK_JUSTIFY_CENTER, MESSAGE_DIALOG_NORMAL_FONT); + int id; + + id = GPOINTER_TO_UINT(data); + + if (gtk_check_menu_item_get_active(GTK_CHECK_MENU_ITEM(widget))) { + log_info(" Switching to layout %d", id); + cfg->layout = id; + emugtk_restart_gui(); + } } -static void -ViewMenuInternalDump(gchar *string) +void +view_add_layout_submenu(GtkWidget *parent) { - ShowMessage("Internal Memory Dump", "Not implemented yet!", - GTK_JUSTIFY_CENTER, MESSAGE_DIALOG_NORMAL_FONT); + GtkWidget *submenu; + GtkWidget *layout; + GtkWidget *layout1; + GtkWidget *layout2; + GSList *group = NULL; + + submenu = gtk_menu_new(); + + layout = gtk_menu_item_new_with_label("Layout"); + + layout1 = gtk_radio_menu_item_new_with_label(group, "Layout1"); + group = gtk_radio_menu_item_get_group(GTK_RADIO_MENU_ITEM(layout1)); + layout2 = gtk_radio_menu_item_new_with_label(group, "Layout2"); + + if (cfg->layout == UI_LAYOUT1) + gtk_check_menu_item_set_active(GTK_CHECK_MENU_ITEM(layout1), TRUE); + else + gtk_check_menu_item_set_active(GTK_CHECK_MENU_ITEM(layout2), TRUE); + + g_signal_connect(G_OBJECT(layout1), "activate", + G_CALLBACK(toggle_layout), (gpointer) UI_LAYOUT1); + g_signal_connect(G_OBJECT(layout2), "activate", + G_CALLBACK(toggle_layout), (gpointer) UI_LAYOUT2); + + gtk_menu_item_set_submenu(GTK_MENU_ITEM(layout), submenu); + gtk_menu_shell_append(GTK_MENU_SHELL(submenu), layout1); + gtk_menu_shell_append(GTK_MENU_SHELL(submenu), layout2); + gtk_menu_shell_append(GTK_MENU_SHELL(parent), layout); } void @@ -49,27 +84,23 @@ ViewAddMenu(GtkWidget *menu_bar) { GtkWidget *item; GtkWidget *menu; + GtkWidget *view; menu = gtk_menu_new(); - /* Create the 'Viewmenu External Memory Dump' item. */ - item = gtk_menu_item_new_with_label("External Memory Dump"); + view = gtk_menu_item_new_with_label("View"); + + item = gtk_menu_item_new_with_label("Internal Memory"); + gtk_menu_shell_append(GTK_MENU_SHELL(menu), item); + + item = gtk_menu_item_new_with_label("External Memory"); gtk_menu_shell_append(GTK_MENU_SHELL(menu), item); - /* Attach the callback functions to the activate signal. */ - g_signal_connect(item, "activate", G_CALLBACK(ViewMenuExternalDump), - NULL); AddMenuSeparator(menu); - /* Create the 'Viewmenu Internal Memory Dump' item. */ - item = gtk_menu_item_new_with_label("Internal Memory Dump"); - gtk_menu_shell_append(GTK_MENU_SHELL(menu), item); - /* Attach the callback functions to the activate signal. */ - g_signal_connect(item, "activate", G_CALLBACK(ViewMenuInternalDump), - NULL); - - /* Adding submenu title. */ - item = gtk_menu_item_new_with_label("View"); - gtk_menu_item_set_submenu(GTK_MENU_ITEM(item), menu); - gtk_menu_shell_append((GtkMenuShell *) menu_bar, item); + /* Add layout submenu */ + view_add_layout_submenu(menu); + + gtk_menu_item_set_submenu(GTK_MENU_ITEM(view), menu); + gtk_menu_shell_append(GTK_MENU_SHELL(menu_bar), view); } -- 2.20.1 From ca2a000a22e5b5121a61833198966f001aa2a77f Mon Sep 17 00:00:00 2001 From: Hugo Villeneuve Date: Mon, 21 Oct 2013 22:57:28 -0400 Subject: [PATCH 06/16] Add support for bits per row in config file Also add support for viewing internal and external memory windows in config file. These 3 new variables are not yet connected (TODO). --- src/app-config.c | 37 ++++++++++++++++++++++++++++--------- src/app-config.h | 7 ++++++- src/viewmenu.c | 30 ++++++++++++++++++++++++++++-- 3 files changed, 62 insertions(+), 12 deletions(-) diff --git a/src/app-config.c b/src/app-config.c index 58f76e5..ba9a18a 100644 --- a/src/app-config.c +++ b/src/app-config.c @@ -51,12 +51,17 @@ app_config_init(void) cfg->clear_ram_on_file_load = false; /* UI settings */ - cfg->layout = UI_LAYOUT1; cfg->win_width = 640; cfg->win_height = 480; cfg->hpane_pos = 100; cfg->vpane_pos = 200; cfg->main_pane_pos = 200; + + /* View menu options */ + cfg->layout = UI_LAYOUT1; + cfg->view_int_memory = 1; + cfg->view_ext_memory = 1; + cfg->bits_per_row = 16; /* 8 or 16 */ } static int @@ -83,19 +88,25 @@ app_config_load_from_key_file(GKeyFile *kf) &cfg->clear_ram_on_file_load); /* ui */ - app_config_key_file_get_int(kf, "ui", "layout", &cfg->layout); - - if ((cfg->layout != UI_LAYOUT1) && (cfg->layout != UI_LAYOUT2)) { - log_fail_no_exit("Invalid layout, defaulting to layout 1"); - cfg->layout = UI_LAYOUT1; - } - app_config_key_file_get_int(kf, "ui", "win_width", &cfg->win_width); app_config_key_file_get_int(kf, "ui", "win_height", &cfg->win_height); app_config_key_file_get_int(kf, "ui", "hpane_pos", &cfg->hpane_pos); app_config_key_file_get_int(kf, "ui", "vpane_pos", &cfg->vpane_pos); app_config_key_file_get_int(kf, "ui", "main_pane_pos", &cfg->main_pane_pos); + + /* View */ + app_config_key_file_get_int(kf, "view", "layout", &cfg->layout); + if ((cfg->layout != UI_LAYOUT1) && (cfg->layout != UI_LAYOUT2)) { + log_fail_no_exit("Invalid layout, defaulting to layout 1"); + cfg->layout = UI_LAYOUT1; + } + app_config_key_file_get_int(kf, "view", "int_memory", + &cfg->view_int_memory); + app_config_key_file_get_int(kf, "view", "ext_memory", + &cfg->view_ext_memory); + app_config_key_file_get_int(kf, "view", "bits_per_row", + &cfg->bits_per_row); } static char * @@ -172,7 +183,6 @@ app_config_save(void) g_string_append(buf, "\n[ui]\n"); - g_string_append_printf(buf, "layout=%d\n", cfg->layout); g_string_append_printf(buf, "win_width=%d\n", cfg->win_width); g_string_append_printf(buf, "win_height=%d\n", cfg->win_height); g_string_append_printf(buf, "hpane_pos=%d\n", cfg->hpane_pos); @@ -180,6 +190,15 @@ app_config_save(void) g_string_append_printf(buf, "main_pane_pos=%d\n", cfg->main_pane_pos); + g_string_append(buf, "\n[view]\n"); + g_string_append_printf(buf, "layout=%d\n", cfg->layout); + g_string_append_printf(buf, "int_memory=%d\n", + cfg->view_int_memory); + g_string_append_printf(buf, "ext_memory=%d\n", + cfg->view_ext_memory); + g_string_append_printf(buf, "bits_per_row=%d\n", + cfg->bits_per_row); + file_path = app_config_get_file_path(); g_file_set_contents(file_path, buf->str, buf->len, NULL); diff --git a/src/app-config.h b/src/app-config.h index c655041..f153a9d 100644 --- a/src/app-config.h +++ b/src/app-config.h @@ -41,12 +41,17 @@ struct app_config_t int clear_ram_on_file_load; /* UI settings */ - int layout; /* UI Layout 1 or 2 */ int win_width; int win_height; int hpane_pos; /* For registers and program windows. */ int vpane_pos; /* For internal and external memory windows. */ int main_pane_pos; /* Between hpane and vpane. */ + + /* View menu options */ + int layout; /* UI Layout 1 or 2 */ + int view_int_memory; + int view_ext_memory; + int bits_per_row; /* 8 or 16 */ }; int diff --git a/src/viewmenu.c b/src/viewmenu.c index 3024877..cf27685 100644 --- a/src/viewmenu.c +++ b/src/viewmenu.c @@ -46,6 +46,26 @@ void toggle_layout(GtkWidget *widget, gpointer data) } } +void toggle_int_memory(GtkWidget *widget, gpointer data) +{ + if (gtk_check_menu_item_get_active(GTK_CHECK_MENU_ITEM(widget))) { + log_info(" View internal memory (TODO)"); + cfg->view_int_memory = 1; + } else { + cfg->view_int_memory = 0; + } +} + +void toggle_ext_memory(GtkWidget *widget, gpointer data) +{ + if (gtk_check_menu_item_get_active(GTK_CHECK_MENU_ITEM(widget))) { + log_info(" View external memory (TODO)"); + cfg->view_ext_memory = 1; + } else { + cfg->view_ext_memory = 0; + } +} + void view_add_layout_submenu(GtkWidget *parent) { @@ -90,11 +110,17 @@ ViewAddMenu(GtkWidget *menu_bar) view = gtk_menu_item_new_with_label("View"); - item = gtk_menu_item_new_with_label("Internal Memory"); + item = gtk_check_menu_item_new_with_label("Internal Memory"); gtk_menu_shell_append(GTK_MENU_SHELL(menu), item); + gtk_check_menu_item_set_active(GTK_CHECK_MENU_ITEM(item), TRUE); + g_signal_connect(G_OBJECT(item), "activate", + G_CALLBACK(toggle_int_memory), NULL); - item = gtk_menu_item_new_with_label("External Memory"); + item = gtk_check_menu_item_new_with_label("External Memory"); gtk_menu_shell_append(GTK_MENU_SHELL(menu), item); + gtk_check_menu_item_set_active(GTK_CHECK_MENU_ITEM(item), TRUE); + g_signal_connect(G_OBJECT(item), "activate", + G_CALLBACK(toggle_ext_memory), NULL); AddMenuSeparator(menu); -- 2.20.1 From 3edb6517f8ddd7e7d9b10a9f4cfe794cdf4981e6 Mon Sep 17 00:00:00 2001 From: Hugo Villeneuve Date: Mon, 21 Oct 2013 23:04:16 -0400 Subject: [PATCH 07/16] Add view menu option for selecting bits per row (8/16) --- src/memwin.c | 53 ++++++++++++++++++++++++++++++------------------ src/viewmenu.c | 55 ++++++++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 88 insertions(+), 20 deletions(-) diff --git a/src/memwin.c b/src/memwin.c index 4c8cc22..446f9d4 100644 --- a/src/memwin.c +++ b/src/memwin.c @@ -33,17 +33,17 @@ #include "regwin.h" #include "memwin.h" #include "emugtk.h" +#include "app-config.h" -#define DATA_COLS 16 /* Must be a power of 2 */ -#define DATA_ROWS_INT (INT_MEM_SIZE / DATA_COLS) -#define DATA_ROWS_EXT (1024 / DATA_COLS) +extern struct app_config_t *cfg; + +static int COL_ASCII; +static int N_COLUMNS; enum { COL_ADDRESS = 0, COL_DATA0, - COL_ASCII = DATA_COLS + 1, - N_COLUMNS, }; static GtkWidget *memlist_internal; @@ -153,7 +153,7 @@ memwin_init_columns(GtkWidget *listview, int memory_id) gtk_tree_view_column_set_sizing(column, GTK_TREE_VIEW_COLUMN_AUTOSIZE); gtk_tree_view_append_column(GTK_TREE_VIEW(listview), column); - for (i = COL_DATA0; i < (COL_DATA0 + DATA_COLS); i++) { + for (i = COL_DATA0; i < (COL_DATA0 + cfg->bits_per_row); i++) { char col_name[8]; /* Create new renderer for each editable cell. */ @@ -174,7 +174,7 @@ memwin_init_columns(GtkWidget *listview, int memory_id) GUINT_TO_POINTER(memory_id)); /* Use two digits only if DATA_ROWS > 10 */ - if (DATA_COLS < 10) + if (cfg->bits_per_row < 10) sprintf(col_name, "B%1d", i - COL_DATA0); else sprintf(col_name, "B%02d", i - COL_DATA0); @@ -195,6 +195,23 @@ memwin_init_columns(GtkWidget *listview, int memory_id) gtk_tree_view_append_column(GTK_TREE_VIEW(listview), column); } +static int +compute_data_rows(int memory_id) +{ + int data_rows; + + if (memory_id == INT_MEM_ID) { + data_rows = (INT_MEM_SIZE / cfg->bits_per_row); + } else if (memory_id == EXT_MEM_ID) { + data_rows = 1024 / cfg->bits_per_row; + } else { + log_fail("Invalid memory type"); + exit(1); + } + + return data_rows; +} + GtkWidget * memwin_init(char *title, int memory_id) { @@ -204,6 +221,9 @@ memwin_init(char *title, int memory_id) GtkWidget *memlist; int data_rows; + COL_ASCII = cfg->bits_per_row + 1; + N_COLUMNS = COL_ASCII + 1; + frame = gtk_frame_new(title); scrollwin = gtk_scrolled_window_new(NULL, NULL); @@ -217,14 +237,7 @@ memwin_init(char *title, int memory_id) gtk_container_add(GTK_CONTAINER(frame), scrollwin); - if (memory_id == INT_MEM_ID) { - data_rows = DATA_ROWS_INT; - } else if (memory_id == EXT_MEM_ID) { - data_rows = DATA_ROWS_EXT; - } else { - log_fail("Invalid memory type"); - exit(1); - } + data_rows = compute_data_rows(memory_id); /* Creating a model */ store = memwin_init_store(data_rows); @@ -267,12 +280,12 @@ memwin_refresh(int memory_id) Address = 0; + data_rows = compute_data_rows(memory_id); + if (memory_id == INT_MEM_ID) { memlist = memlist_internal; - data_rows = DATA_ROWS_INT; } else if (memory_id == EXT_MEM_ID) { memlist = memlist_external; - data_rows = DATA_ROWS_EXT; } else { log_fail("Invalid memory type"); exit(1); @@ -284,7 +297,7 @@ memwin_refresh(int memory_id) int valid; GtkTreeIter iter; char str[4+1]; /* Maximum str len is for address column (4 digits) */ - char ascii_str[DATA_COLS+1]; + char ascii_str[16+1]; /* Maximum 16 data columns. */ int col; if (row == 0) { @@ -307,7 +320,7 @@ memwin_refresh(int memory_id) gtk_list_store_set(store, &iter, COL_ADDRESS, str, -1); - for (col = 0; col < DATA_COLS; col++) { + for (col = 0; col < cfg->bits_per_row; col++) { u_int8_t data; data = memory_read8(memory_id, Address + col); @@ -326,6 +339,6 @@ memwin_refresh(int memory_id) /* Display ASCII characters. */ gtk_list_store_set(store, &iter, COL_ASCII, ascii_str, -1); - Address += DATA_COLS; + Address += cfg->bits_per_row; } } diff --git a/src/viewmenu.c b/src/viewmenu.c index cf27685..37d5b9a 100644 --- a/src/viewmenu.c +++ b/src/viewmenu.c @@ -46,6 +46,19 @@ void toggle_layout(GtkWidget *widget, gpointer data) } } +void toggle_bits_per_row(GtkWidget *widget, gpointer data) +{ + int bits_per_row; + + bits_per_row = GPOINTER_TO_UINT(data); + + if (gtk_check_menu_item_get_active(GTK_CHECK_MENU_ITEM(widget))) { + log_info(" Bits per row = %d", bits_per_row); + cfg->bits_per_row = bits_per_row; + emugtk_restart_gui(); + } +} + void toggle_int_memory(GtkWidget *widget, gpointer data) { if (gtk_check_menu_item_get_active(GTK_CHECK_MENU_ITEM(widget))) { @@ -54,6 +67,8 @@ void toggle_int_memory(GtkWidget *widget, gpointer data) } else { cfg->view_int_memory = 0; } + + emugtk_restart_gui(); } void toggle_ext_memory(GtkWidget *widget, gpointer data) @@ -64,6 +79,8 @@ void toggle_ext_memory(GtkWidget *widget, gpointer data) } else { cfg->view_ext_memory = 0; } + + emugtk_restart_gui(); } void @@ -99,6 +116,39 @@ view_add_layout_submenu(GtkWidget *parent) gtk_menu_shell_append(GTK_MENU_SHELL(parent), layout); } +void +view_add_bits_per_row_submenu(GtkWidget *parent) +{ + GtkWidget *submenu; + GtkWidget *item; + GtkWidget *item1; + GtkWidget *item2; + GSList *group = NULL; + + submenu = gtk_menu_new(); + + item = gtk_menu_item_new_with_label("Bits per row"); + + item1 = gtk_radio_menu_item_new_with_label(group, "8"); + group = gtk_radio_menu_item_get_group(GTK_RADIO_MENU_ITEM(item1)); + item2 = gtk_radio_menu_item_new_with_label(group, "16"); + + if (cfg->bits_per_row == 8) + gtk_check_menu_item_set_active(GTK_CHECK_MENU_ITEM(item1), TRUE); + else + gtk_check_menu_item_set_active(GTK_CHECK_MENU_ITEM(item2), TRUE); + + g_signal_connect(G_OBJECT(item1), "activate", + G_CALLBACK(toggle_bits_per_row), (gpointer) 8); + g_signal_connect(G_OBJECT(item2), "activate", + G_CALLBACK(toggle_bits_per_row), (gpointer) 16); + + gtk_menu_item_set_submenu(GTK_MENU_ITEM(item), submenu); + gtk_menu_shell_append(GTK_MENU_SHELL(submenu), item1); + gtk_menu_shell_append(GTK_MENU_SHELL(submenu), item2); + gtk_menu_shell_append(GTK_MENU_SHELL(parent), item); +} + void ViewAddMenu(GtkWidget *menu_bar) { @@ -127,6 +177,11 @@ ViewAddMenu(GtkWidget *menu_bar) /* Add layout submenu */ view_add_layout_submenu(menu); + AddMenuSeparator(menu); + + /* Add bits per row submenu */ + view_add_bits_per_row_submenu(menu); + gtk_menu_item_set_submenu(GTK_MENU_ITEM(view), menu); gtk_menu_shell_append(GTK_MENU_SHELL(menu_bar), view); } -- 2.20.1 From 4c86604f944240034b02db1bd37b9092455d5d9f Mon Sep 17 00:00:00 2001 From: Hugo Villeneuve Date: Tue, 22 Oct 2013 22:56:02 -0400 Subject: [PATCH 08/16] Add view menu option to enable/disable IRAM/XRAM windows --- src/emugtk.c | 48 ++++++++++++++++++++++++++++++++---------------- src/viewmenu.c | 10 ++++++---- 2 files changed, 38 insertions(+), 20 deletions(-) diff --git a/src/emugtk.c b/src/emugtk.c index 1c114fc..9ade2cd 100644 --- a/src/emugtk.c +++ b/src/emugtk.c @@ -63,8 +63,12 @@ emugtk_UpdateDisplay(void) log_debug("UpdateDisplay()"); regwin_refresh(); pgmwin_refresh(); - memwin_refresh(INT_MEM_ID); - memwin_refresh(EXT_MEM_ID); + + if (cfg->view_int_memory) + memwin_refresh(INT_MEM_ID); + + if (cfg->view_ext_memory) + memwin_refresh(EXT_MEM_ID); } /* Step out of running state */ @@ -393,19 +397,6 @@ emugtk_window_init(void) scrollwin = pgmwin_init(); gtk_paned_pack2(GTK_PANED(hpaned), scrollwin, TRUE, FALSE); - vpaned = gtk_vpaned_new(); - gtk_paned_set_position(GTK_PANED(vpaned), cfg->vpane_pos); - g_signal_connect(G_OBJECT(vpaned), "notify::position", - G_CALLBACK(vpaned_notify_event), vpaned); - - /* Internal memory dump frame. */ - scrollwin = memwin_init("Internal memory (IRAM)", INT_MEM_ID); - gtk_paned_pack1(GTK_PANED(vpaned), scrollwin, FALSE, FALSE); - - /* External memory dump frame. */ - scrollwin = memwin_init("External memory (XRAM)", EXT_MEM_ID); - gtk_paned_pack2(GTK_PANED(vpaned), scrollwin, TRUE, FALSE); - /* * main_paned will contain two groups: * group1: registers and disassembly windows. @@ -420,7 +411,32 @@ emugtk_window_init(void) g_signal_connect(G_OBJECT(main_paned), "notify::position", G_CALLBACK(main_paned_notify_event), main_paned); gtk_paned_pack1(GTK_PANED(main_paned), hpaned, FALSE, FALSE); - gtk_paned_pack2(GTK_PANED(main_paned), vpaned, TRUE, FALSE); + + /* Create vpaned (memory windows) only if necessary. */ + if (cfg->view_int_memory || cfg->view_ext_memory) { + vpaned = gtk_vpaned_new(); + gtk_paned_set_position(GTK_PANED(vpaned), cfg->vpane_pos); + g_signal_connect(G_OBJECT(vpaned), "notify::position", + G_CALLBACK(vpaned_notify_event), vpaned); + + /* Internal memory dump frame. */ + if (cfg->view_int_memory) { + scrollwin = memwin_init("Internal memory (IRAM)", + INT_MEM_ID); + gtk_paned_pack1(GTK_PANED(vpaned), scrollwin, + FALSE, FALSE); + } + + /* External memory dump frame. */ + if (cfg->view_ext_memory) { + scrollwin = memwin_init("External memory (XRAM)", + EXT_MEM_ID); + gtk_paned_pack2(GTK_PANED(vpaned), scrollwin, + TRUE, FALSE); + } + + gtk_paned_pack2(GTK_PANED(main_paned), vpaned, TRUE, FALSE); + } /* * vbox contains the menu bar and body_vbox (for all remaining diff --git a/src/viewmenu.c b/src/viewmenu.c index 37d5b9a..99fa0ab 100644 --- a/src/viewmenu.c +++ b/src/viewmenu.c @@ -62,7 +62,7 @@ void toggle_bits_per_row(GtkWidget *widget, gpointer data) void toggle_int_memory(GtkWidget *widget, gpointer data) { if (gtk_check_menu_item_get_active(GTK_CHECK_MENU_ITEM(widget))) { - log_info(" View internal memory (TODO)"); + log_info(" View internal memory"); cfg->view_int_memory = 1; } else { cfg->view_int_memory = 0; @@ -74,7 +74,7 @@ void toggle_int_memory(GtkWidget *widget, gpointer data) void toggle_ext_memory(GtkWidget *widget, gpointer data) { if (gtk_check_menu_item_get_active(GTK_CHECK_MENU_ITEM(widget))) { - log_info(" View external memory (TODO)"); + log_info(" View external memory"); cfg->view_ext_memory = 1; } else { cfg->view_ext_memory = 0; @@ -162,13 +162,15 @@ ViewAddMenu(GtkWidget *menu_bar) item = gtk_check_menu_item_new_with_label("Internal Memory"); gtk_menu_shell_append(GTK_MENU_SHELL(menu), item); - gtk_check_menu_item_set_active(GTK_CHECK_MENU_ITEM(item), TRUE); + gtk_check_menu_item_set_active(GTK_CHECK_MENU_ITEM(item), + cfg->view_int_memory); g_signal_connect(G_OBJECT(item), "activate", G_CALLBACK(toggle_int_memory), NULL); item = gtk_check_menu_item_new_with_label("External Memory"); gtk_menu_shell_append(GTK_MENU_SHELL(menu), item); - gtk_check_menu_item_set_active(GTK_CHECK_MENU_ITEM(item), TRUE); + gtk_check_menu_item_set_active(GTK_CHECK_MENU_ITEM(item), + cfg->view_ext_memory); g_signal_connect(G_OBJECT(item), "activate", G_CALLBACK(toggle_ext_memory), NULL); -- 2.20.1 From 0f98327ed353861d9958cf77a0e00549d5147b56 Mon Sep 17 00:00:00 2001 From: Hugo Villeneuve Date: Tue, 22 Oct 2013 23:16:35 -0400 Subject: [PATCH 09/16] Add option to specify maximum memory sizes --- src/memwin.c | 6 ++++-- src/options.c | 42 +++++++++++++++++++++++++++++++++++++++++- src/options.h | 2 ++ 3 files changed, 47 insertions(+), 3 deletions(-) diff --git a/src/memwin.c b/src/memwin.c index 446f9d4..58ce1d2 100644 --- a/src/memwin.c +++ b/src/memwin.c @@ -33,9 +33,11 @@ #include "regwin.h" #include "memwin.h" #include "emugtk.h" +#include "options.h" #include "app-config.h" extern struct app_config_t *cfg; +extern struct options_t options; static int COL_ASCII; static int N_COLUMNS; @@ -201,9 +203,9 @@ compute_data_rows(int memory_id) int data_rows; if (memory_id == INT_MEM_ID) { - data_rows = (INT_MEM_SIZE / cfg->bits_per_row); + data_rows = options.iram_size / cfg->bits_per_row; } else if (memory_id == EXT_MEM_ID) { - data_rows = 1024 / cfg->bits_per_row; + data_rows = options.xram_size / cfg->bits_per_row; } else { log_fail("Invalid memory type"); exit(1); diff --git a/src/options.c b/src/options.c index 94f1063..c5833b3 100644 --- a/src/options.c +++ b/src/options.c @@ -26,6 +26,7 @@ #include "common.h" #include "options.h" +#include "memory.h" const char *argp_program_version = PACKAGE_VERSION; const char *argp_program_bug_address = PACKAGE_BUGREPORT; @@ -43,7 +44,9 @@ static const char args_doc[] = "[FILENAME]"; /* The options we understand. */ static struct argp_option argp_options[] = { - {"debug", 'd', "level", 0, "Produce debugging output" }, + {"debug", 'd', "level", 0, "Produce debugging output" }, + {"iram", 'i', "size", 0, "Set internal ram size" }, + {"xram", 'x', "size", 0, "Set external ram size" }, { 0 } }; @@ -76,6 +79,35 @@ decode_debug_option(char *arg, struct argp_state *state) log_set_level(log_level); } +static void +decode_memory_size(char *arg, struct argp_state *state, int memid) +{ + char *endptr; + int max_size; + int *dest; + + if (memid == INT_MEM_ID) { + max_size = INT_MEM_SIZE; + dest = &options.iram_size; + } else { + max_size = EXT_MEM_SIZE; + dest = &options.xram_size; + } + + *dest = strtol(arg, &endptr, 0); + + if (*endptr != '\0') { + log_fail_no_exit("Invalid memory size"); + argp_usage(state); + } + + if (*dest > max_size) { + log_fail_no_exit("Invalid maximum memory size (max = %d)", + max_size); + argp_usage(state); + } +} + /* Parse a single option. */ static error_t parse_opt(int key, char *arg, struct argp_state *state) @@ -84,6 +116,12 @@ parse_opt(int key, char *arg, struct argp_state *state) case 'd': decode_debug_option(arg, state); break; + case 'i': + decode_memory_size(arg, state, INT_MEM_ID); + break; + case 'x': + decode_memory_size(arg, state, EXT_MEM_ID); + break; case ARGP_KEY_ARG: if (state->arg_num >= ARGS_COUNT) { /* Too many arguments. */ @@ -117,6 +155,8 @@ parse_command_line_options(int argc, char *argv[]) /* Setting default values. */ options.filename = NULL; + options.iram_size = INT_MEM_SIZE; + options.xram_size = EXT_MEM_SIZE; /* Parse our arguments. */ argp_parse(&argp, argc, argv, 0, 0, NULL); diff --git a/src/options.h b/src/options.h index f71427f..b58b636 100644 --- a/src/options.h +++ b/src/options.h @@ -28,6 +28,8 @@ " -version display version information and exit\n" struct options_t { + int iram_size; /* Maximum internal ram size. */ + int xram_size; /* Maximum external ram size. */ char *filename; } options_t; -- 2.20.1 From fb0a9a8db49f7dc69486643fbb72a67ce793b35a Mon Sep 17 00:00:00 2001 From: Hugo Villeneuve Date: Wed, 23 Oct 2013 23:07:34 -0400 Subject: [PATCH 10/16] Add Timers 0 and 1 to SFR window --- src/regwin.c | 30 ++++++++++++++++++++++++++++-- 1 file changed, 28 insertions(+), 2 deletions(-) diff --git a/src/regwin.c b/src/regwin.c index f94b8f9..e549c96 100644 --- a/src/regwin.c +++ b/src/regwin.c @@ -37,7 +37,7 @@ static GtkWidget *reglist; -#define DATA_ROWS 24 +#define DATA_ROWS 26 enum { @@ -65,7 +65,7 @@ regwin_read(int addr, int width) return cpu8051_ReadD(addr); else if (width == 4) { /* Address is low address. */ - return (cpu8051_ReadD(addr + 1) << 8) + + return (cpu8051_ReadD(addr + 1) << 8) | cpu8051_ReadD(addr); } else return 0xFFFFFFFF; @@ -97,6 +97,20 @@ regwin_write_pc(int param, int val) cpu8051.pc = (u_int16_t) val; } +static unsigned int +regwin_read_timer(int timer_low_addr) +{ + return (cpu8051_ReadD(timer_low_addr + 2) << 8) | + cpu8051_ReadD(timer_low_addr); +} + +static void +regwin_write_timer(int timer_low_addr, int val) +{ + cpu8051_WriteD(timer_low_addr + 2, (u_int8_t) ((val & 0x0000FFFF) >> 8)); + cpu8051_WriteD(timer_low_addr, (u_int8_t) val); +} + static unsigned int regwin_read_bank(int dummy) { @@ -203,6 +217,18 @@ static struct regwin_infos_t regwin_infos[DATA_ROWS] = { NULL, NULL, _TMOD_, }, + { + "TIMER0", + HEX_DIGITS_4, + regwin_read_timer, regwin_write_timer, + _TL0_, + }, + { + "TIMER1", + HEX_DIGITS_4, + regwin_read_timer, regwin_write_timer, + _TL1_, + }, { "SCON", HEX_DIGITS_2, -- 2.20.1 From 83d7d5ddbea0460029314ef84bbfdb0f59fed07f Mon Sep 17 00:00:00 2001 From: Hugo Villeneuve Date: Wed, 23 Oct 2013 23:32:00 -0400 Subject: [PATCH 11/16] Do not reset emulator on file load (no ram clear) Reset only when loading first file at application startup. --- src/emugtk.c | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/src/emugtk.c b/src/emugtk.c index 9ade2cd..06741ff 100644 --- a/src/emugtk.c +++ b/src/emugtk.c @@ -471,7 +471,9 @@ emugtk_new_file(char *file) LoadHexFile(file); - emugtk_Reset(); /* Use app-config->clear_ram_on_file_load */ + if (cfg->clear_ram_on_file_load) + emugtk_Reset(); + emugtk_UpdateDisplay(); } @@ -489,8 +491,8 @@ main(int argc, char **argv) if (options.filename != NULL) LoadHexFile(options.filename); - else - cpu8051_Reset(); + + cpu8051_Reset(); while (restart_gui == true) { log_info("Init GUI"); -- 2.20.1 From ae3a0ccd898b3257b93437e1007a2d595461ac5b Mon Sep 17 00:00:00 2001 From: Hugo Villeneuve Date: Thu, 24 Oct 2013 21:25:54 -0400 Subject: [PATCH 12/16] Fix syntax error in comment --- src/cpu8051.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/cpu8051.c b/src/cpu8051.c index 22ecf1e..b83175d 100644 --- a/src/cpu8051.c +++ b/src/cpu8051.c @@ -114,7 +114,7 @@ cpu8051_Reset(void) /* Reset registers */ for (i = 0; i < 256; i++) { - /* Clear IRAM nad SFR */ + /* Clear IRAM and SFR */ memory_write8(INT_MEM_ID, i, 0); } -- 2.20.1 From 276025c2488166d5a4495b93f1b64d7d574dc9a6 Mon Sep 17 00:00:00 2001 From: Hugo Villeneuve Date: Sun, 27 Oct 2013 22:26:43 -0400 Subject: [PATCH 13/16] Limit default external memory size to 1024 bytes Emulator is running very slow if external memory is at its maximum of 64K. --- src/memory.h | 1 + src/options.c | 4 ++-- 2 files changed, 3 insertions(+), 2 deletions(-) diff --git a/src/memory.h b/src/memory.h index 4166da9..faaba95 100644 --- a/src/memory.h +++ b/src/memory.h @@ -28,6 +28,7 @@ #define INT_MEM_SIZE 256 /* IRAM = Direct addresses $00 to $7F * SFR = Direct addresses $80 to $FF */ #define EXT_MEM_SIZE 65536 +#define EXT_MEM_DEFAULT_SIZE 1024 enum { PGM_MEM_ID, diff --git a/src/options.c b/src/options.c index c5833b3..7b6143d 100644 --- a/src/options.c +++ b/src/options.c @@ -46,7 +46,7 @@ static const char args_doc[] = "[FILENAME]"; static struct argp_option argp_options[] = { {"debug", 'd', "level", 0, "Produce debugging output" }, {"iram", 'i', "size", 0, "Set internal ram size" }, - {"xram", 'x', "size", 0, "Set external ram size" }, + {"xram", 'x', "size", 0, "Set external ram size (default is 1024)" }, { 0 } }; @@ -156,7 +156,7 @@ parse_command_line_options(int argc, char *argv[]) /* Setting default values. */ options.filename = NULL; options.iram_size = INT_MEM_SIZE; - options.xram_size = EXT_MEM_SIZE; + options.xram_size = EXT_MEM_DEFAULT_SIZE; /* Parse our arguments. */ argp_parse(&argp, argc, argv, 0, 0, NULL); -- 2.20.1 From dd2261ab6cd2b8ddc9fd0078c995ec943fee8dbd Mon Sep 17 00:00:00 2001 From: Hugo Villeneuve Date: Sun, 27 Oct 2013 22:28:03 -0400 Subject: [PATCH 14/16] Rename macros for maximum memory sizes --- src/memory.c | 30 +++++++++++++++--------------- src/memory.h | 13 +++++++++---- src/options.c | 6 +++--- 3 files changed, 27 insertions(+), 22 deletions(-) diff --git a/src/memory.c b/src/memory.c index 402e73c..c748cfe 100644 --- a/src/memory.c +++ b/src/memory.c @@ -27,33 +27,33 @@ #include "hexfile.h" #include "memory.h" -static u_int8_t pgm_mem[PGM_MEM_SIZE]; -static u_int8_t int_mem[INT_MEM_SIZE]; -static u_int8_t ext_mem[EXT_MEM_SIZE]; +static u_int8_t pgm_mem[PGM_MEM_MAX_SIZE]; +static u_int8_t int_mem[INT_MEM_MAX_SIZE]; +static u_int8_t ext_mem[EXT_MEM_MAX_SIZE]; void memory_write8(int memory_id, unsigned long address, u_int8_t value) { switch (memory_id) { case PGM_MEM_ID: - if (address >= PGM_MEM_SIZE) { - printf("Address (%lu) is greater than PGM_MEM_SIZE\n", + if (address >= PGM_MEM_MAX_SIZE) { + printf("Address (%lu) is greater than PGM_MEM_MAX_SIZE\n", address); return; } else pgm_mem[address] = value; break; case INT_MEM_ID: - if (address >= INT_MEM_SIZE) { - printf("Address (%lu) is greater than INT_MEM_SIZE\n", + if (address >= INT_MEM_MAX_SIZE) { + printf("Address (%lu) is greater than INT_MEM_MAX_SIZE\n", address); return; } else int_mem[address] = value; break; case EXT_MEM_ID: - if (address >= EXT_MEM_SIZE) { - printf("Address (%lu) is greater than EXT_MEM_SIZE\n", + if (address >= EXT_MEM_MAX_SIZE) { + printf("Address (%lu) is greater than EXT_MEM_MAX_SIZE\n", address); return; } else @@ -70,28 +70,28 @@ memory_read8(int memory_id, unsigned long address) { switch (memory_id) { case PGM_MEM_ID: - if (address < PGM_MEM_SIZE) + if (address < PGM_MEM_MAX_SIZE) return pgm_mem[address]; else { - printf("Address (%lu) is greater than PGM_MEM_SIZE\n", + printf("Address (%lu) is greater than PGM_MEM_MAX_SIZE\n", address); return 0; } break; case INT_MEM_ID: - if (address < INT_MEM_SIZE) + if (address < INT_MEM_MAX_SIZE) return int_mem[address]; else { - printf("Address (%lu) is greater than INT_MEM_SIZE\n", + printf("Address (%lu) is greater than INT_MEM_MAX_SIZE\n", address); return 0; } break; case EXT_MEM_ID: - if (address < EXT_MEM_SIZE) + if (address < EXT_MEM_MAX_SIZE) return ext_mem[address]; else { - printf("Address (%lu) is greater than EXT_MEM_SIZE\n", + printf("Address (%lu) is greater than EXT_MEM_MAX_SIZE\n", address); return 0; } diff --git a/src/memory.h b/src/memory.h index faaba95..d5e426d 100644 --- a/src/memory.h +++ b/src/memory.h @@ -24,10 +24,15 @@ #include -#define PGM_MEM_SIZE 65536 -#define INT_MEM_SIZE 256 /* IRAM = Direct addresses $00 to $7F - * SFR = Direct addresses $80 to $FF */ -#define EXT_MEM_SIZE 65536 +#define PGM_MEM_MAX_SIZE 65536 +/* + * Direct addressing $00 to $7F = IRAM (8051) + * Direct addressing $80 to $FF = SFR (8051) + * Indirect addressing $80 to $FF = IRAM (8052) + */ +#define INT_MEM_MAX_SIZE 256 +#define EXT_MEM_MAX_SIZE 65536 + #define EXT_MEM_DEFAULT_SIZE 1024 enum { diff --git a/src/options.c b/src/options.c index 7b6143d..3616f51 100644 --- a/src/options.c +++ b/src/options.c @@ -87,10 +87,10 @@ decode_memory_size(char *arg, struct argp_state *state, int memid) int *dest; if (memid == INT_MEM_ID) { - max_size = INT_MEM_SIZE; + max_size = INT_MEM_MAX_SIZE; dest = &options.iram_size; } else { - max_size = EXT_MEM_SIZE; + max_size = EXT_MEM_MAX_SIZE; dest = &options.xram_size; } @@ -155,7 +155,7 @@ parse_command_line_options(int argc, char *argv[]) /* Setting default values. */ options.filename = NULL; - options.iram_size = INT_MEM_SIZE; + options.iram_size = INT_MEM_MAX_SIZE; options.xram_size = EXT_MEM_DEFAULT_SIZE; /* Parse our arguments. */ -- 2.20.1 From 593009d28f70be7e5deebc7a44c16e85c2574422 Mon Sep 17 00:00:00 2001 From: Hugo Villeneuve Date: Sun, 27 Oct 2013 22:48:24 -0400 Subject: [PATCH 15/16] Refactor code to read/write different memory types Dynamic memory buffers allocation depending on sizes specified with command-line options. Add future support for separate IRAM and SFR buffers. --- src/cpu8051.c | 22 ++++---- src/memory.c | 144 +++++++++++++++++++++++++++----------------------- src/memory.h | 26 ++++++--- src/options.c | 20 +++---- src/regwin.c | 40 ++++++++------ 5 files changed, 140 insertions(+), 112 deletions(-) diff --git a/src/cpu8051.c b/src/cpu8051.c index b83175d..a44cd7f 100644 --- a/src/cpu8051.c +++ b/src/cpu8051.c @@ -95,6 +95,8 @@ ToggleBreakpoint(unsigned int address) void cpu8051_init(void) { + memory_init(); + cpu8051.pc = 0; cpu8051.clock = 0; cpu8051.active_priority = -1; @@ -105,24 +107,18 @@ cpu8051_init(void) void cpu8051_Reset(void) { - int i; - cpu8051.pc = 0; cpu8051.clock = 0; cpu8051.active_priority = -1; - /* Reset registers */ - - for (i = 0; i < 256; i++) { - /* Clear IRAM and SFR */ - memory_write8(INT_MEM_ID, i, 0); - } + /* Clear IRAM and SFR. */ + memory_clear(INT_MEM_ID); - memory_write8(INT_MEM_ID, _P0_, 0xFF); - memory_write8(INT_MEM_ID, _P1_, 0xFF); - memory_write8(INT_MEM_ID, _P2_, 0xFF); - memory_write8(INT_MEM_ID, _P3_, 0xFF); - memory_write8(INT_MEM_ID, _SP_, 0x07); + memory_sfr_write8(_P0_, 0xFF); + memory_sfr_write8(_P1_, 0xFF); + memory_sfr_write8(_P2_, 0xFF); + memory_sfr_write8(_P3_, 0xFF); + memory_sfr_write8(_SP_, 0x07); } static void diff --git a/src/memory.c b/src/memory.c index c748cfe..fec85c1 100644 --- a/src/memory.c +++ b/src/memory.c @@ -26,81 +26,95 @@ #include "cpu8051.h" #include "hexfile.h" #include "memory.h" +#include "options.h" -static u_int8_t pgm_mem[PGM_MEM_MAX_SIZE]; -static u_int8_t int_mem[INT_MEM_MAX_SIZE]; -static u_int8_t ext_mem[EXT_MEM_MAX_SIZE]; +struct mem_infos_t { + int size; + int max_size; + u_int8_t *buf; +}; + +struct mem_infos_t mem_infos[MEM_ID_COUNT]; +extern struct options_t options; + +/* Init each 8051 memory sections. */ void -memory_write8(int memory_id, unsigned long address, u_int8_t value) +memory_init(void) { - switch (memory_id) { - case PGM_MEM_ID: - if (address >= PGM_MEM_MAX_SIZE) { - printf("Address (%lu) is greater than PGM_MEM_MAX_SIZE\n", - address); - return; - } else - pgm_mem[address] = value; - break; - case INT_MEM_ID: - if (address >= INT_MEM_MAX_SIZE) { - printf("Address (%lu) is greater than INT_MEM_MAX_SIZE\n", - address); - return; - } else - int_mem[address] = value; - break; - case EXT_MEM_ID: - if (address >= EXT_MEM_MAX_SIZE) { - printf("Address (%lu) is greater than EXT_MEM_MAX_SIZE\n", - address); - return; - } else - ext_mem[address] = value; - break; - default: - /* Error. */ - break; + int k; + struct mem_infos_t *m; + + /* Set desired and maximum allowable sizes for each memory type. */ + mem_infos[PGM_MEM_ID].size = options.pram_size; + mem_infos[PGM_MEM_ID].max_size = PGM_MEM_MAX_SIZE; + + mem_infos[INT_MEM_ID].size = options.iram_size; + mem_infos[INT_MEM_ID].max_size = INT_MEM_MAX_SIZE; + + mem_infos[EXT_MEM_ID].size = options.xram_size; + mem_infos[EXT_MEM_ID].max_size = EXT_MEM_MAX_SIZE; + + /* Verify if desired sizes are valid, and if so allocate memory. */ + for (k = 0; k < MEM_ID_COUNT; k++) { + m = &mem_infos[k]; + + if (m->size > m->max_size) { + log_fail_no_exit("Memory size invalid (max = %d)", + m->max_size); + exit(1); + } + + m->buf = malloc(m->size); + if (m->buf == NULL) { + log_fail_no_exit("%s", strerror(errno)); + exit(1); + } } } +void +memory_clear(enum mem_id_t id) +{ + memset(mem_infos[id].buf, 0, mem_infos[id].size); +} + +void +memory_write8(enum mem_id_t id, unsigned long address, u_int8_t value) +{ + if (address >= mem_infos[id].max_size) { + printf("Error writing to memory ID: %d\n", id); + printf(" Address (%lu) greater than maximum memory size\n", + address); + return; + } else + mem_infos[id].buf[address] = value; +} + +void +memory_sfr_write8(unsigned long address, u_int8_t value) +{ + /* SFR registers are from addresses $80 to $FF. */ + memory_write8(INT_MEM_ID, address, value); +} + u_int8_t -memory_read8(int memory_id, unsigned long address) +memory_read8(enum mem_id_t id, unsigned long address) { - switch (memory_id) { - case PGM_MEM_ID: - if (address < PGM_MEM_MAX_SIZE) - return pgm_mem[address]; - else { - printf("Address (%lu) is greater than PGM_MEM_MAX_SIZE\n", - address); - return 0; - } - break; - case INT_MEM_ID: - if (address < INT_MEM_MAX_SIZE) - return int_mem[address]; - else { - printf("Address (%lu) is greater than INT_MEM_MAX_SIZE\n", - address); - return 0; - } - break; - case EXT_MEM_ID: - if (address < EXT_MEM_MAX_SIZE) - return ext_mem[address]; - else { - printf("Address (%lu) is greater than EXT_MEM_MAX_SIZE\n", - address); - return 0; - } - break; - default: - /* Error. */ + if (address >= mem_infos[id].max_size) { + printf("Error reading from memory ID: %d\n", id); + printf(" Address (%lu) greater than maximum memory size\n", + address); return 0; - break; - } + } else + return mem_infos[id].buf[address]; +} + +u_int8_t +memory_sfr_read8(unsigned long address) +{ + /* SFR registers are from addresses $80 to $FF. */ + return memory_read8(INT_MEM_ID, address); } /* Dump memory */ diff --git a/src/memory.h b/src/memory.h index d5e426d..9064813 100644 --- a/src/memory.h +++ b/src/memory.h @@ -33,19 +33,33 @@ #define INT_MEM_MAX_SIZE 256 #define EXT_MEM_MAX_SIZE 65536 +#define PGM_MEM_DEFAULT_SIZE 8192 #define EXT_MEM_DEFAULT_SIZE 1024 -enum { - PGM_MEM_ID, - INT_MEM_ID, - EXT_MEM_ID +enum mem_id_t { + PGM_MEM_ID, + INT_MEM_ID, + EXT_MEM_ID, + MEM_ID_COUNT }; void -memory_write8(int memory_id, unsigned long address, u_int8_t value); +memory_init(void); + +void +memory_clear(enum mem_id_t id); + +void +memory_write8(enum mem_id_t id, unsigned long address, u_int8_t value); + +void +memory_sfr_write8(unsigned long address, u_int8_t value); + +u_int8_t +memory_read8(enum mem_id_t id, unsigned long address); u_int8_t -memory_read8(int memory_id, unsigned long address); +memory_sfr_read8(unsigned long address); void DumpMem(char *Address, char *Asize, int memory_id); diff --git a/src/options.c b/src/options.c index 3616f51..3c292d4 100644 --- a/src/options.c +++ b/src/options.c @@ -83,29 +83,25 @@ static void decode_memory_size(char *arg, struct argp_state *state, int memid) { char *endptr; - int max_size; int *dest; - if (memid == INT_MEM_ID) { - max_size = INT_MEM_MAX_SIZE; + if (memid == INT_MEM_ID) dest = &options.iram_size; - } else { - max_size = EXT_MEM_MAX_SIZE; + else if (memid == EXT_MEM_ID) dest = &options.xram_size; - } + else + exit(1); /* Programming error. */ + /* + * Sizes versus max memory sizes will be checked when calling + * memory_init(). + */ *dest = strtol(arg, &endptr, 0); if (*endptr != '\0') { log_fail_no_exit("Invalid memory size"); argp_usage(state); } - - if (*dest > max_size) { - log_fail_no_exit("Invalid maximum memory size (max = %d)", - max_size); - argp_usage(state); - } } /* Parse a single option. */ diff --git a/src/regwin.c b/src/regwin.c index e549c96..e5708f2 100644 --- a/src/regwin.c +++ b/src/regwin.c @@ -28,6 +28,7 @@ #include "common.h" #include "reg8051.h" #include "cpu8051.h" +#include "memory.h" #include "regwin.h" #include "memwin.h" #include "pgmwin.h" @@ -62,11 +63,11 @@ static unsigned int regwin_read(int addr, int width) { if (width == 2) - return cpu8051_ReadD(addr); + return memory_sfr_read8(addr); else if (width == 4) { /* Address is low address. */ - return (cpu8051_ReadD(addr + 1) << 8) | - cpu8051_ReadD(addr); + return (memory_sfr_read8(addr + 1) << 8) | + memory_sfr_read8(addr); } else return 0xFFFFFFFF; } @@ -75,11 +76,11 @@ static void regwin_write(int addr, int val, int width) { if (width == 2) - cpu8051_WriteD(addr, (u_int8_t) val); + memory_sfr_write8(addr, (u_int8_t) val); else if (width == 4) { /* Address is low address. */ - cpu8051_WriteD(addr + 1, (u_int8_t) ((val & 0x0000FFFF) >> 8)); - cpu8051_WriteD(addr, (u_int8_t) val); + memory_sfr_write8(addr + 1, (u_int8_t) ((val & 0x0000FFFF) >> 8)); + memory_sfr_write8(addr, (u_int8_t) val); } }; @@ -100,47 +101,54 @@ regwin_write_pc(int param, int val) static unsigned int regwin_read_timer(int timer_low_addr) { - return (cpu8051_ReadD(timer_low_addr + 2) << 8) | - cpu8051_ReadD(timer_low_addr); + return (memory_sfr_read8(timer_low_addr + 2) << 8) | + memory_sfr_read8(timer_low_addr); } static void regwin_write_timer(int timer_low_addr, int val) { - cpu8051_WriteD(timer_low_addr + 2, (u_int8_t) ((val & 0x0000FFFF) >> 8)); - cpu8051_WriteD(timer_low_addr, (u_int8_t) val); + memory_sfr_write8(timer_low_addr + 2, (u_int8_t) ((val & 0x0000FFFF) >> 8)); + memory_sfr_write8(timer_low_addr, (u_int8_t) val); +} + +static u_int8_t +regwin_read_bank_offset(void) +{ + return memory_sfr_read8(_PSW_) & 0x18; } static unsigned int regwin_read_bank(int dummy) { - return BANKPSW >> 3; + return regwin_read_bank_offset() >> 3; } static void regwin_write_bank(int param, int bank_number) { - u_int8_t psw = cpu8051_ReadD(_PSW_); + u_int8_t psw = memory_sfr_read8(_PSW_); if ((bank_number < 0) || (bank_number > 3)) { log_info("Error: invalid bank number: %d", bank_number); bank_number = 0; } - cpu8051_WriteD(_PSW_, (psw & ~0x18) | (bank_number << 3)); + memory_sfr_write8(_PSW_, (psw & ~0x18) | (bank_number << 3)); } -/* Read R0 - R7 in current bank. */ +/* Indirect read of R0 - R7 in current bank from internal memory. */ static unsigned int regwin_read_rx(int offset) { - return cpu8051_ReadD(BANKPSW + offset); + return memory_read8(INT_MEM_ID, regwin_read_bank_offset() + offset); } +/* Indirect write to R0 - R7 in current bank to internal memory. */ static void regwin_write_rx(int offset, int val) { - cpu8051_WriteD(BANKPSW + offset, (u_int8_t) val); + memory_write8(INT_MEM_ID, regwin_read_bank_offset() + offset, (u_int8_t) val); } /* This array defines how to read value for each register. */ -- 2.20.1 From add152ddb851575c885208c12b008887e68b9f48 Mon Sep 17 00:00:00 2001 From: Hugo Villeneuve Date: Sun, 27 Oct 2013 22:46:52 -0400 Subject: [PATCH 16/16] Add option to specify maximum pgm memory size --- src/options.c | 9 ++++++++- src/options.h | 1 + 2 files changed, 9 insertions(+), 1 deletion(-) diff --git a/src/options.c b/src/options.c index 3c292d4..138507e 100644 --- a/src/options.c +++ b/src/options.c @@ -46,6 +46,7 @@ static const char args_doc[] = "[FILENAME]"; static struct argp_option argp_options[] = { {"debug", 'd', "level", 0, "Produce debugging output" }, {"iram", 'i', "size", 0, "Set internal ram size" }, + {"pram", 'p', "size", 0, "Set program memory size" }, {"xram", 'x', "size", 0, "Set external ram size (default is 1024)" }, { 0 } }; @@ -85,7 +86,9 @@ decode_memory_size(char *arg, struct argp_state *state, int memid) char *endptr; int *dest; - if (memid == INT_MEM_ID) + if (memid == PGM_MEM_ID) + dest = &options.pram_size; + else if (memid == INT_MEM_ID) dest = &options.iram_size; else if (memid == EXT_MEM_ID) dest = &options.xram_size; @@ -115,6 +118,9 @@ parse_opt(int key, char *arg, struct argp_state *state) case 'i': decode_memory_size(arg, state, INT_MEM_ID); break; + case 'p': + decode_memory_size(arg, state, PGM_MEM_ID); + break; case 'x': decode_memory_size(arg, state, EXT_MEM_ID); break; @@ -151,6 +157,7 @@ parse_command_line_options(int argc, char *argv[]) /* Setting default values. */ options.filename = NULL; + options.pram_size = PGM_MEM_DEFAULT_SIZE; options.iram_size = INT_MEM_MAX_SIZE; options.xram_size = EXT_MEM_DEFAULT_SIZE; diff --git a/src/options.h b/src/options.h index b58b636..b75a827 100644 --- a/src/options.h +++ b/src/options.h @@ -28,6 +28,7 @@ " -version display version information and exit\n" struct options_t { + int pram_size; /* Maximum program memory size. */ int iram_size; /* Maximum internal ram size. */ int xram_size; /* Maximum external ram size. */ char *filename; -- 2.20.1