void
menu_display_usage(void)
{
+ int id;
+
printf(" " PACKAGE_NAME " commands, [] = options:\n"
"\n"
" sb [ADDRESS] Set breakpoint at PC or ADDRESS\n"
" wr REGISTER VAL Write VAL at REGISTER (REGISTER is name of"
" register)\n"
" z Reset processor\n"
- " zt Reset emulator (not processor) timer\n");
+ " zt ID Reset emulator timer ID (");
+
+ for (id = 0; id < GP_TIMERS_COUNT; id++) {
+ printf("%c", 'A' + id);
+ if (id < (GP_TIMERS_COUNT - 1))
+ printf(", ");
+ }
+ printf(")\n");
}
/* Disassemble NumberInst instructions at Address */
static void
console_dump_sfr_registers_compact(void)
{
+ int id;
unsigned char PSW = cpu8051_ReadD(_PSW_);
int BankSelect = (PSW & 0x18);
printf("---------------------------------------------------------------"
"-------\n");
- printf("| Emulator timer: %08d |\n", gp_timer_read());
- printf("----------------------------\n");
+ for (id = 0; id < GP_TIMERS_COUNT; id++)
+ printf("| Emulator timer %c: %08d |\n", 'A' + id, gp_timer_read(id));
+
+ printf("------------------------------\n");
+
+
}
/* Show CPU registers */
%token TOK_UNASM
%token TOK_MOD_EXT TOK_MOD_INT TOK_MOD_PROG TOK_MOD_REG
%token TOK_QUIT
+%token TOK_A TOK_B TOK_C TOK_D
%%
cpu8051_Reset();
}
|
- TOK_RST_TIMER TOK_ENTER
+ TOK_RST_TIMER TOK_A TOK_ENTER
{
- gp_timer_reset();
+ gp_timer_reset(0);
+ }
+ |
+ TOK_RST_TIMER TOK_B TOK_ENTER
+ {
+ gp_timer_reset(1);
+ }
+ |
+ TOK_RST_TIMER TOK_C TOK_ENTER
+ {
+ gp_timer_reset(2);
+ }
+ |
+ TOK_RST_TIMER TOK_D TOK_ENTER
+ {
+ gp_timer_reset(3);
}
;
z return TOK_RST;
zt return TOK_RST_TIMER;
all return TOK_ALL;
+a return TOK_A;
+b return TOK_B;
+c return TOK_C;
+d return TOK_D;
[a-z0-9]+ { yylval.string = strdup(yytext); return WORD; }
[\n] return TOK_ENTER;
[ \t]+ { /* ignore whitespace */ }
void
cpu8051_init(void)
{
+ int id;
+
memory_init();
- gp_timer_reset();
+ for (id = 0; id < GP_TIMERS_COUNT; id++)
+ gp_timer_reset(id);
cpu8051.pc = 0;
cpu8051.clock = 0;
*/
psw_compute_parity_bit();
- gp_timer_increment(insttiming);
+ gp_timers_increment(insttiming);
for (i = 0; i < insttiming; i++) {
cpu8051_CheckInterrupts();
#include "psw.h"
#include "options.h"
#include "instructions_8051.h"
+#include "timers.h"
-static int gp_timer_value;
+static int gp_timer_value[GP_TIMERS_COUNT];
extern struct options_t options;
void
-gp_timer_reset(void)
+gp_timer_reset(int id)
{
- log_debug("gp timer reset");
- gp_timer_value = 0;
+ log_debug("gp timer %d reset", id);
+ gp_timer_value[id] = 0;
}
void
-gp_timer_increment(int count)
+gp_timers_increment(int count)
{
- log_debug("gp timer increment");
- gp_timer_value += count;
+ int id;
+
+ log_debug("gp timers increment");
+
+ for (id = 0; id < GP_TIMERS_COUNT; id++)
+ gp_timer_value[id] += count;
}
int
-gp_timer_read(void)
+gp_timer_read(int id)
{
- return gp_timer_value;
+ return gp_timer_value[id];
}
static void
#include <stdint.h>
+/* Maximum of 4 for CLI version */
+#define GP_TIMERS_COUNT 2
+
void
-gp_timer_reset(void);
+gp_timer_reset(int id);
void
-gp_timer_increment(int count);
+gp_timers_increment(int count);
int
-gp_timer_read(void);
+gp_timer_read(int id);
-int
+void
timers_check(void);
#endif /* TIMERS_H */
#include "memory.h"
#include "options.h"
#include "hexfile.h"
-
+#include "timers.h"
#include "main.h"
#include "reset.xpm"
#include "run.xpm"
static void
emugtk_window_init(void)
{
+ int id;
GtkWidget *vbox;
GtkWidget *menu_bar;
GtkWidget *buttons_bar;
buttons_bar = AddButtons();
scrollwin = pswwin_init();
- gtk_box_pack_start(GTK_BOX(buttons_bar), scrollwin, FALSE, FALSE, 100);
+ gtk_box_pack_start(GTK_BOX(buttons_bar), scrollwin, FALSE, FALSE, 50);
- scrollwin = timerwin_init();
- gtk_box_pack_start(GTK_BOX(buttons_bar), scrollwin, FALSE, FALSE, 100);
+ for (id = 0; id < GP_TIMERS_COUNT; id++) {
+ scrollwin = timerwin_init(id);
+ gtk_box_pack_start(GTK_BOX(buttons_bar), scrollwin, FALSE, FALSE, 15);
+ }
/* hpaned will contain registers and disassembly windows. */
hpaned = gtk_hpaned_new();
#include "timers.h"
#include "main.h"
-static GtkWidget *label;
+static GtkWidget *label[GP_TIMERS_COUNT];
static GtkWidget *
button_add_stock(GtkWidget *box, gchar *stock_id, int display_label)
void
timerwin_update(void)
{
+ int id;
char buf[128];
- /* Display textin bold, with big font size. */
- sprintf(buf , "<b><big>%08d</big></b> cycles", gp_timer_read());
+ for (id = 0; id < GP_TIMERS_COUNT; id++) {
+ /* Display textin bold, with big font size. */
+ sprintf(buf , "<b><big>%08d</big></b> cycles", gp_timer_read(id));
- gtk_label_set_markup(GTK_LABEL(label), buf);
+ gtk_label_set_markup(GTK_LABEL(label[id]), buf);
+ }
}
static void
timer_reset_callback(GtkWidget *widget, gpointer data)
{
+ int id = GPOINTER_TO_INT(data);
+
/* Remove compiler warning about unused variables. */
(void) widget;
- (void) data;
- gp_timer_reset();
+ log_info("timer_reset_callback ID = %d", id);
+
+ gp_timer_reset(id);
timerwin_update();
}
GtkWidget *
-timerwin_init(void)
+timerwin_init(int id)
{
GtkWidget *frame;
GtkWidget *hbox;
GtkWidget *vbox;
GtkWidget *timer_reset_button;
+ char title[100];
log_debug("timer window init");
- frame = gtk_frame_new("General-purpose Timer");
+ sprintf(title, "Emulator timer %c", 'A' + id);
+ frame = gtk_frame_new(title);
/* The items of the hbox are NOT given equal space in the box. */
hbox = gtk_hbox_new(false, 0);
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);
+ G_CALLBACK(timer_reset_callback), GINT_TO_POINTER(id));
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);
+ label[id] = gtk_label_new(NULL);
+ gtk_label_set_markup(GTK_LABEL(label[id]), "<small>Small text</small>");
+ gtk_box_pack_start(GTK_BOX(hbox), label[id], false, false, 10);
gtk_container_add(GTK_CONTAINER(frame), hbox);
#include <gtk/gtk.h>
GtkWidget *
-timerwin_init(void);
+timerwin_init(int id);
void
timerwin_update(void);