Add general-purpose timer to GUI
authorHugo Villeneuve <hugo@hugovil.com>
Sat, 25 Jan 2014 22:38:50 +0000 (17:38 -0500)
committerHugo Villeneuve <hugo@hugovil.com>
Sat, 25 Jan 2014 22:38:50 +0000 (17:38 -0500)
This timer is not part of the 8051 hardware. It is a free running
timer/counter added as a mean to quickly measure delays in instruction
cyles.

For now, it is implemented only in GUI version.

src/common/cpu8051.c
src/common/timers.c
src/common/timers.h
src/gtk/Makefile.am
src/gtk/emugtk.c
src/gtk/timerwin.c [new file with mode: 0644]
src/gtk/timerwin.h [new file with mode: 0644]

index 2c2845e..107f2ef 100644 (file)
@@ -114,6 +114,8 @@ cpu8051_init(void)
 {
        memory_init();
 
+       gp_timer_reset();
+
        cpu8051.pc = 0;
        cpu8051.clock = 0;
        cpu8051.active_priority = -1;
@@ -314,6 +316,8 @@ cpu8051_Exec(void)
         */
        psw_compute_parity_bit();
 
+       gp_timer_increment(insttiming);
+
        for (i = 0; i < insttiming; i++) {
                cpu8051_CheckInterrupts();
                timers_check();
index 68a92bc..d0700ad 100644 (file)
 #include "options.h"
 #include "instructions_8051.h"
 
+static int gp_timer_value;
+
 extern struct options_t options;
 
+void
+gp_timer_reset(void)
+{
+       log_debug("gp timer reset");
+       gp_timer_value = 0;
+}
+
+void
+gp_timer_increment(int count)
+{
+       log_debug("gp timer increment");
+       gp_timer_value += count;
+}
+
+int
+gp_timer_read(void)
+{
+       return gp_timer_value;
+}
+
 static void
 timer_increment_check_overflow(uint8_t counter_address, uint8_t tf_mask)
 {
@@ -115,7 +137,7 @@ process_timer(uint8_t tl, uint8_t th, uint8_t tf_mask, uint8_t TR, uint8_t mode,
        }
 }
 
-/* Run timers */
+/* Run 8051 timers */
 void
 timers_check(void)
 {
index 932ace4..0e633e9 100644 (file)
 
 #include <stdint.h>
 
+void
+gp_timer_reset(void);
+
+void
+gp_timer_increment(int count);
+
+int
+gp_timer_read(void);
+
 int
 timers_check(void);
 
index 6db03db..980609b 100644 (file)
@@ -27,6 +27,7 @@ emu8051_gtk_SOURCES = \
     pgmwin.c pgmwin.h \
     regwin.c regwin.h \
     pswwin.c pswwin.h \
+    timerwin.c timerwin.h \
     filemenu.c filemenu.h \
     viewmenu.c viewmenu.h \
     helpmenu.c helpmenu.h \
index d2fc533..72b7ea5 100644 (file)
@@ -45,6 +45,7 @@
 #include "pgmwin.h"
 #include "memwin.h"
 #include "pswwin.h"
+#include "timerwin.h"
 #include "app-config.h"
 
 #define BUTTONS_BORDER 2
@@ -69,6 +70,7 @@ emugtk_UpdateDisplay(void)
        regwin_refresh();
        pgmwin_refresh();
        pswwin_refresh();
+       timerwin_update();
 
        if (cfg->view_int_memory && scrollwin_int)
                memwin_refresh(INT_MEM_ID);
@@ -507,6 +509,9 @@ emugtk_window_init(void)
        scrollwin = pswwin_init();
        gtk_box_pack_start(GTK_BOX(buttons_bar), scrollwin, FALSE, FALSE, 100);
 
+       scrollwin = timerwin_init();
+       gtk_box_pack_start(GTK_BOX(buttons_bar), scrollwin, FALSE, FALSE, 100);
+
        /* hpaned will contain registers and disassembly windows. */
        hpaned = gtk_hpaned_new();
        gtk_paned_set_position(GTK_PANED(hpaned), cfg->hpane_pos);
diff --git a/src/gtk/timerwin.c b/src/gtk/timerwin.c
new file mode 100644 (file)
index 0000000..2687c5a
--- /dev/null
@@ -0,0 +1,114 @@
+/*
+ * timerwin.c
+ *
+ * Copyright (C) 1999 Jonathan St-AndrĂ©
+ * Copyright (C) 1999 Hugo Villeneuve <hugo@hugovil.com>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA.
+ */
+
+#if HAVE_CONFIG_H
+#  include "config.h"
+#endif
+
+#include <stdio.h>
+#include <stdbool.h>
+#include <stdint.h>
+
+#include "common.h"
+#include "timers.h"
+#include "emugtk.h"
+
+static GtkWidget *label;
+
+static GtkWidget *
+button_add_stock(GtkWidget *box, gchar *stock_id, int display_label)
+{
+       GtkWidget *button;
+
+       /* Create the button. */
+       if (display_label != false)
+               button = gtk_button_new_from_stock(stock_id);
+       else {
+               GtkWidget *icon;
+
+               button = gtk_button_new();
+               gtk_button_set_relief(GTK_BUTTON(button), GTK_RELIEF_NORMAL);
+               icon = gtk_image_new_from_stock(stock_id,
+                                               GTK_ICON_SIZE_SMALL_TOOLBAR);
+               gtk_container_add(GTK_CONTAINER(button), icon);
+       }
+
+       gtk_box_pack_start(GTK_BOX(box), button, false, false, 2);
+
+       return button;
+}
+
+void
+timerwin_update(void)
+{
+       char buf[128];
+
+       /* Display textin bold, with big font size. */
+       sprintf(buf , "<b><big>%08d</big></b> cycles", gp_timer_read());
+
+       gtk_label_set_markup(GTK_LABEL(label), buf);
+}
+
+static void
+timer_reset_callback(GtkWidget *widget, gpointer data)
+{
+       /* Remove compiler warning about unused variables. */
+       (void) widget;
+       (void) data;
+
+       gp_timer_reset();
+       timerwin_update();
+}
+
+GtkWidget *
+timerwin_init(void)
+{
+       GtkWidget *frame;
+       GtkWidget *hbox;
+       GtkWidget *vbox;
+       GtkWidget *timer_reset_button;
+
+       log_debug("timer window init");
+
+       frame = gtk_frame_new("General-purpose Timer");
+
+       /* The items of the hbox are NOT given equal space in the box. */
+       hbox = gtk_hbox_new(false, 0);
+
+       /*
+        * If the button was added directly to the hbox, it would be as high
+        * as the frame widget (ugly). Adding it first to a vbox makes it have
+        * a box shape.
+        */
+       vbox = gtk_vbox_new(true, 0);
+       timer_reset_button = button_add_stock(vbox, GTK_STOCK_REFRESH, false);
+       g_signal_connect(G_OBJECT(timer_reset_button), "clicked",
+                        G_CALLBACK(timer_reset_callback), NULL);
+       gtk_box_pack_start(GTK_BOX(hbox), vbox, false, false, 3);
+
+       label = gtk_label_new(NULL);
+       gtk_label_set_markup(GTK_LABEL(label), "<small>Small text</small>");
+       gtk_box_pack_start(GTK_BOX(hbox), label, false, false, 10);
+
+       gtk_container_add(GTK_CONTAINER(frame), hbox);
+
+       return frame;
+}
diff --git a/src/gtk/timerwin.h b/src/gtk/timerwin.h
new file mode 100644 (file)
index 0000000..4b6220b
--- /dev/null
@@ -0,0 +1,33 @@
+/*
+ * timerwin.h
+ *
+ * Copyright (C) 1999 Jonathan St-AndrĂ©
+ * Copyright (C) 1999 Hugo Villeneuve <hugo@hugovil.com>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA.
+ */
+
+#ifndef TIMERWIN_H
+#define TIMERWIN_H 1
+
+#include <gtk/gtk.h>
+
+GtkWidget *
+timerwin_init(void);
+
+void
+timerwin_update(void);
+
+#endif /* TIMERWIN_H */