#include "memory.h"
#include "cpu8051.h"
#include "pgmwin.h"
+#include "hexfile.h"
static GtkWidget *pgmlist;
-#define DATA_ROWS 24
+#define LIST_VIEW_NAME "Program"
+#define DATA_ROWS 100
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",
"B2",
"Mnemonic",
"Arguments",
+ "COLOR", /* Not displayed, used to set foreground color of cell. */
};
/* Creating a model */
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;
}
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);
}
}
GtkTreeModel *model;
GtkTreeIter iter;
-#ifdef EMU8051_DEBUG
- printf("pgmwin_sel_changed_event()\n");
-#endif
+ log_debug("pgmwin_sel_changed_event()");
/* This will only work in single or browse selection mode! */
selection = gtk_tree_view_get_selection(GTK_TREE_VIEW(pgmlist));
gtk_tree_model_get(model, &iter, COL_ADDR, &str_addr, -1);
/* Convert hex address in ASCII to integer. */
- sscanf(str_addr, "%x", &val);
+ val = asciihex2int(str_addr);
-#ifdef EMU8051_DEBUG
- printf(" row address is: $%04X\n", val);
-#endif
+ log_debug(" row address is: $%04X", val);
ToggleBreakpoint(val);
- pgmwin_Disasm();
+ pgmwin_refresh();
g_free(str_addr);
} else {
-#ifdef EMU8051_DEBUG
- printf(" no row selected.\n");
-#endif
+ log_debug(" no row selected");
}
return FALSE;
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),
/* Show disassembled program. */
void
-pgmwin_Disasm(void)
+pgmwin_refresh(void)
{
int row;
GtkListStore *store;
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. */
- sprintf(str, "%.4X", Address);
- gtk_list_store_set(store, &iter, COL_ADDR, str, -1);
+ /* Display base address. */
+ int2asciihex(Address, str, 4);
- OpCode = memory_read8(PGM_MEM_ID, Address);
- InstSize = cpu8051_get_instruction_size(OpCode);
+ gtk_list_store_set(store, &iter, COL_ADDR, str, -1);
- /* Display instruction hex bytes. */
- for (k = 0, col_id = COL_B0; k < InstSize; k++, col_id++) {
- sprintf(str, "%.2X", memory_read8(PGM_MEM_ID,
- Address + k));
- gtk_list_store_set(store, &iter, col_id, str, -1);
- }
+ OpCode = memory_read8(PGM_MEM_ID, Address);
+ InstSize = cpu8051_get_instruction_size(OpCode);
- /* Display instruction menmonic. */
- cpu8051_disasm_mnemonic(OpCode, str);
- gtk_list_store_set(store, &iter, COL_INST, 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 arguments (if applicable). */
- str[0] = '\0';
- cpu8051_disasm_args(Address, str);
- gtk_list_store_set(store, &iter, COL_ARGS, str, -1);
+ gtk_list_store_set(store, &iter, col_id, str, -1);
+ }
- Address += InstSize;
+ /* Display instruction menmonic. */
+ cpu8051_disasm_mnemonic(OpCode, str);
+ gtk_list_store_set(store, &iter, COL_INST, 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);
+
+ Address += InstSize;
+ }
}
}