Remove superfluous bytes in program disassembly
[emu8051.git] / src / pgmwin.c
index 41c74d8..0e8961b 100644 (file)
@@ -33,7 +33,8 @@
 
 static GtkWidget *pgmlist;
 
-#define DATA_ROWS 24
+#define LIST_VIEW_NAME "Program"
+#define DATA_ROWS 100
 
 enum
 {
@@ -44,10 +45,11 @@ enum
        COL_B2,
        COL_INST,
        COL_ARGS,
+       COL_COLOR,
        N_COLUMNS,
 };
 
-char *col_names[N_COLUMNS] = {
+static char *col_names[N_COLUMNS] = {
        "BPT",
        "Address",
        "B0",
@@ -55,6 +57,7 @@ char *col_names[N_COLUMNS] = {
        "B2",
        "Mnemonic",
        "Arguments",
+       "COLOR", /* Not displayed, used to set foreground color of cell. */
 };
 
 /* Creating a model */
@@ -62,20 +65,28 @@ static GtkListStore *
 pgmwin_init_store(void)
 {
        GtkTreeIter iter;
-       int rows;
+       int row;
        int col;
        GtkListStore *store;
        GType col_types[N_COLUMNS];
 
+       /* No need for static array, all our columns are of the same type. */
        for (col = 0; col < N_COLUMNS; col++)
                col_types[col] = G_TYPE_STRING;
 
        store = gtk_list_store_newv(N_COLUMNS, col_types);
 
-       /* Initialize with rows of dummy data... */
-       for (rows = 0; rows < DATA_ROWS; rows++)
+       /* Add rows. */
+       for (row = 0; row < DATA_ROWS; row++) {
                gtk_list_store_append(store, &iter);
 
+               /* Color first row in red (current instruction). */
+               if (row == 0)
+                       gtk_list_store_set(store, &iter, COL_COLOR, "red", -1);
+               else
+                       gtk_list_store_set(store, &iter, COL_COLOR, "black", -1);
+       }
+
        return store;
 }
 
@@ -85,18 +96,27 @@ pgmwin_init_columns(void)
        int k;
        GtkCellRenderer *renderer;
 
-       /* Columns and cell renderers */
+       /* Create renderer */
        renderer = gtk_cell_renderer_text_new();
 
-       /* Add columns */
-       for (k = 0; k < N_COLUMNS; k++) {
+       /* Add columns, except for last one (COL_COLOR). */
+       for (k = 0; k < COL_COLOR; k++) {
                GtkTreeViewColumn *col;
 
-               col = gtk_tree_view_column_new_with_attributes(
-                       col_names[k], renderer, "text", k, NULL);
+               /* Create tree view column */
+               col = gtk_tree_view_column_new();
+               gtk_tree_view_column_set_title(col, col_names[k]);
                gtk_tree_view_column_set_sizing(col,
                                                GTK_TREE_VIEW_COLUMN_AUTOSIZE);
                gtk_tree_view_append_column(GTK_TREE_VIEW(pgmlist), col);
+
+               /* Pack cell renderer into column */
+               gtk_tree_view_column_pack_start(col, renderer, TRUE);
+
+               /* Establish connection between cell renderer and data store. */
+               gtk_tree_view_column_set_attributes(col, renderer, "text", k,
+                                                   "foreground", COL_COLOR,
+                                                   NULL);
        }
 }
 
@@ -125,7 +145,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 {
@@ -143,7 +163,7 @@ pgmwin_init(void)
        GtkListStore *store;
        GtkTreeSelection *selection;
 
-       frame = gtk_frame_new("Program");
+       frame = gtk_frame_new(LIST_VIEW_NAME);
 
        scrollwin = gtk_scrolled_window_new(NULL, NULL);
        gtk_scrolled_window_set_shadow_type(GTK_SCROLLED_WINDOW(scrollwin),
@@ -186,7 +206,7 @@ pgmwin_init(void)
 
 /* Show disassembled program. */
 void
-pgmwin_Disasm(void)
+pgmwin_refresh(void)
 {
        int row;
        GtkListStore *store;
@@ -220,38 +240,60 @@ pgmwin_Disasm(void)
                        return;
                }
 
-               /* Display breakpoints. */
-               if (IsBreakpoint(Address))
-                       sprintf(str, "*");
-               else
-                       str[0] = '\0';
+               if (Address > 0xFFFF) {
+                       /*
+                        * Not the most elegant solution, but it works to not
+                        * display instructions past last address, 0xFFFF.
+                        */
+                       gtk_list_store_set(store, &iter,
+                                          COL_BREAKPT, NULL,
+                                          COL_ADDR, NULL,
+                                          COL_B0, NULL,
+                                          COL_B1, NULL,
+                                          COL_B2, NULL,
+                                          COL_INST, NULL,
+                                          COL_ARGS, NULL,
+                                          COL_COLOR, NULL,
+                                          -1);
+               } else {
+                       /* Display breakpoints. */
+                       if (IsBreakpoint(Address))
+                               sprintf(str, "*");
+                       else
+                               str[0] = '\0';
 
-               gtk_list_store_set(store, &iter, COL_BREAKPT, str, -1);
+                       gtk_list_store_set(store, &iter, COL_BREAKPT, str, -1);
 
-               /* Display base address. */
-               int2asciihex(Address, str, 4);
+                       /* Display base address. */
+                       int2asciihex(Address, str, 4);
 
-               gtk_list_store_set(store, &iter, COL_ADDR, str, -1);
+                       gtk_list_store_set(store, &iter, COL_ADDR, str, -1);
 
-               OpCode = memory_read8(PGM_MEM_ID, Address);
-               InstSize = cpu8051_get_instruction_size(OpCode);
+                       OpCode = memory_read8(PGM_MEM_ID, Address);
+                       InstSize = cpu8051_get_instruction_size(OpCode);
 
-               /* Display instruction hex bytes. */
-               for (k = 0, col_id = COL_B0; k < InstSize; k++, col_id++) {
-                       int2asciihex(memory_read8(PGM_MEM_ID, Address + k),
-                                    str, 2);
-                       gtk_list_store_set(store, &iter, col_id, str, -1);
-               }
+                       /* Display instruction hex bytes. */
+                       for (k = 0, col_id = COL_B0; k < 3; k++, col_id++) {
+                               if (k < InstSize)
+                                       int2asciihex(memory_read8(PGM_MEM_ID,
+                                                                 Address + k),
+                                                    str, 2);
+                               else
+                                       str[0] = '\0';
 
-               /* Display instruction menmonic. */
-               cpu8051_disasm_mnemonic(OpCode, str);
-               gtk_list_store_set(store, &iter, COL_INST, str, -1);
+                               gtk_list_store_set(store, &iter, col_id, str, -1);
+                       }
 
-               /* Display instruction arguments (if applicable). */
-               str[0] = '\0';
-               cpu8051_disasm_args(Address, str);
-               gtk_list_store_set(store, &iter, COL_ARGS, str, -1);
+                       /* Display instruction menmonic. */
+                       cpu8051_disasm_mnemonic(OpCode, str);
+                       gtk_list_store_set(store, &iter, COL_INST, str, -1);
 
-               Address += InstSize;
+                       /* Display instruction arguments (if applicable). */
+                       str[0] = '\0';
+                       cpu8051_disasm_args(Address, str);
+                       gtk_list_store_set(store, &iter, COL_ARGS, str, -1);
+
+                       Address += InstSize;
+               }
        }
 }