From 84a325ac72ede9baaca30d57c4d522fdf81bf839 Mon Sep 17 00:00:00 2001 From: Hugo Villeneuve Date: Mon, 13 Jan 2014 23:07:41 -0500 Subject: [PATCH] Improve performance of GUI step operations Use CRC to detect which memory rows have changed. This is only to improve GUI performance when using stepping mode, as we then only update rows which have been modified. --- configure.ac | 15 ++++++++++++ src/common/memory.c | 6 +++++ src/common/memory.h | 3 +++ src/gtk/Makefile.am | 1 + src/gtk/memwin.c | 58 +++++++++++++++++++++++++++++++++++++++++---- 5 files changed, 78 insertions(+), 5 deletions(-) diff --git a/configure.ac b/configure.ac index 7deeb84..ca66cc0 100644 --- a/configure.ac +++ b/configure.ac @@ -82,6 +82,21 @@ AM_CONDITIONAL([USE_AS504HV],[test x"$AS504HV_CHECK" = x"yes"]) AM_CONDITIONAL([USE_AS504],[test x"$AS504_CHECK" = x"yes"]) AM_CONDITIONAL([USE_AS51],[test x"$ASEM51_CHECK" = x"yes"]) +dnl zlib required for its crc32 function +ac_have_zlib=no + +PKG_CHECK_MODULES([zlib], [zlib > 1.2.1], + [AC_CHECK_LIB([z], [crc32], + [ac_have_zlib=yes], + [ac_have_zlib=no])]) + +if test x"$ac_have_zlib" = x"yes" ; then + ZLIB_LIBS='-lz' + AC_SUBST(ZLIB_LIBS) +else + AC_MSG_ERROR([Please install zlib and zlib-devel packages]) +fi + AC_SUBST(WARNINGCFLAGS) AC_SUBST(LIBS) AC_SUBST(ac_aux_dir) diff --git a/src/common/memory.c b/src/common/memory.c index c5b2acf..9332ea7 100644 --- a/src/common/memory.c +++ b/src/common/memory.c @@ -75,6 +75,12 @@ memory_init(void) } } +u_int8_t * +memory_getbuf(enum mem_id_t id, unsigned long address) +{ + return &mem_infos[id].buf[address]; +} + void memory_clear(enum mem_id_t id) { diff --git a/src/common/memory.h b/src/common/memory.h index 2d65d5e..7beb0e8 100644 --- a/src/common/memory.h +++ b/src/common/memory.h @@ -46,6 +46,9 @@ enum mem_id_t { void memory_init(void); +u_int8_t * +memory_getbuf(enum mem_id_t id, unsigned long address); + void memory_clear(enum mem_id_t id); diff --git a/src/gtk/Makefile.am b/src/gtk/Makefile.am index 699d76e..6db03db 100644 --- a/src/gtk/Makefile.am +++ b/src/gtk/Makefile.am @@ -15,6 +15,7 @@ AM_CPPFLAGS = \ LDADD = \ $(top_builddir)/src/common/libemu8051.a \ @GTK_LIBS@ \ + @ZLIB_LIBS@ \ @GLIB_LIBS@ bin_PROGRAMS = emu8051-gtk diff --git a/src/gtk/memwin.c b/src/gtk/memwin.c index 58ce1d2..b31551f 100644 --- a/src/gtk/memwin.c +++ b/src/gtk/memwin.c @@ -25,6 +25,7 @@ #include #include /* For isprint */ +#include /* For crc32 routine */ #include "common.h" #include "memory.h" @@ -51,6 +52,12 @@ enum static GtkWidget *memlist_internal; static GtkWidget *memlist_external; +static int data_rows_internal; +static int data_rows_external; + +static u_int32_t *crc_internal; +static u_int32_t *crc_external; + /* Creating a model */ static GtkListStore * memwin_init_store(int data_rows) @@ -201,16 +208,32 @@ static int compute_data_rows(int memory_id) { int data_rows; + u_int32_t *crc; if (memory_id == INT_MEM_ID) { data_rows = options.iram_size / cfg->bits_per_row; + crc = crc_internal; } else if (memory_id == EXT_MEM_ID) { data_rows = options.xram_size / cfg->bits_per_row; + crc = crc_external; } else { log_fail("Invalid memory type"); exit(1); } + if (crc) + free(crc); + + crc = malloc(data_rows * sizeof(u_int32_t)); + + if (memory_id == INT_MEM_ID) { + data_rows_internal = data_rows; + crc_internal = crc; + } else if (memory_id == EXT_MEM_ID) { + data_rows_external = data_rows; + crc_external = crc; + } + return data_rows; } @@ -282,12 +305,14 @@ memwin_refresh(int memory_id) Address = 0; - data_rows = compute_data_rows(memory_id); - if (memory_id == INT_MEM_ID) { + log_debug("memory ID = INTERNAL"); memlist = memlist_internal; + data_rows = data_rows_internal; } else if (memory_id == EXT_MEM_ID) { + log_debug("memory ID = EXTERNAL"); memlist = memlist_external; + data_rows = data_rows_external; } else { log_fail("Invalid memory type"); exit(1); @@ -295,12 +320,15 @@ memwin_refresh(int memory_id) store = GTK_LIST_STORE(gtk_tree_view_get_model(GTK_TREE_VIEW(memlist))); - for (row = 0; row < data_rows; row++) { + for (row = 0; row < data_rows; row++, Address += cfg->bits_per_row) { int valid; GtkTreeIter iter; char str[4+1]; /* Maximum str len is for address column (4 digits) */ char ascii_str[16+1]; /* Maximum 16 data columns. */ int col; + u_int32_t crc_new = 0; + u_int32_t *crc_old = NULL; + u_int8_t *buf8; if (row == 0) { /* Get first row in list store */ @@ -317,6 +345,28 @@ memwin_refresh(int memory_id) return; } + if (memory_id == INT_MEM_ID) { + crc_old = crc_internal; + } else if (memory_id == EXT_MEM_ID) { + crc_old = crc_external; + } + + /* + * Use CRC to detect which rows have changed. This is only to + * improve performance when using stepping mode, as we then only update + * rows which have been modified. + */ + buf8 = memory_getbuf(memory_id, Address); + crc_new = crc32(0L, Z_NULL, 0); + crc_new = crc32(crc_new, buf8, cfg->bits_per_row); + + if (crc_new == crc_old[row]) { + continue; + } else { + crc_old[row] = crc_new; + log_debug(" Row %02d value(s) change", row); + } + /* Display base address. */ int2asciihex(Address, str, 4); @@ -340,7 +390,5 @@ memwin_refresh(int memory_id) /* Display ASCII characters. */ gtk_list_store_set(store, &iter, COL_ASCII, ascii_str, -1); - - Address += cfg->bits_per_row; } } -- 2.20.1