]> Untitled Git - emu8051.git/commitdiff
Improve performance of GUI step operations
authorHugo Villeneuve <hugo@hugovil.com>
Tue, 14 Jan 2014 04:07:41 +0000 (23:07 -0500)
committerHugo Villeneuve <hugo@hugovil.com>
Tue, 14 Jan 2014 04:36:37 +0000 (23:36 -0500)
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
src/common/memory.c
src/common/memory.h
src/gtk/Makefile.am
src/gtk/memwin.c

index 7deeb846bd29070f132be81b107ae0320c5f7566..ca66cc0c221a52a981a76df88fdfce1c34f74071 100644 (file)
@@ -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)
index c5b2acf51c7384776af89fe6b60ad346e27bebcd..9332ea76f1c1bd307f15631c85b62c56f2380680 100644 (file)
@@ -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)
 {
index 2d65d5ede5575b7a6ced9b0fb5f66484efd6bc2d..7beb0e864f7292636cb0b9a7d7e0e464b55ff1d4 100644 (file)
@@ -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);
 
index 699d76e2df514c51050b842adef063ab12d17ca0..6db03db1d0580047576da35352d6335ddb4d0834 100644 (file)
@@ -15,6 +15,7 @@ AM_CPPFLAGS = \
 LDADD = \
     $(top_builddir)/src/common/libemu8051.a \
     @GTK_LIBS@ \
+    @ZLIB_LIBS@ \
     @GLIB_LIBS@
 
 bin_PROGRAMS = emu8051-gtk
index 58ce1d2e6b7f87fae080c4fe57d1b2202a78c3d3..b31551f65bf134047878f248a689b963446fce35 100644 (file)
@@ -25,6 +25,7 @@
 
 #include <stdio.h>
 #include <ctype.h> /* For isprint */
+#include <zlib.h> /* 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;
        }
 }