Separate cli and gtk sources into separate directories
authorHugo Villeneuve <hugo@hugovil.com>
Sat, 7 Dec 2013 23:48:25 +0000 (18:48 -0500)
committerHugo Villeneuve <hugo@hugovil.com>
Sat, 7 Dec 2013 23:50:45 +0000 (18:50 -0500)
Also added a common directory to hold common files to both interfaces,
and compiled into a static library.

94 files changed:
.gitignore
Makefile.am
configure.ac
src/Makefile.am [deleted file]
src/app-config.c [deleted file]
src/app-config.h [deleted file]
src/cli/Makefile.am [new file with mode: 0644]
src/cli/emuconsole.c [new file with mode: 0644]
src/cli/keyboard.c [new file with mode: 0644]
src/cli/keyboard.h [new file with mode: 0644]
src/common.h [deleted file]
src/common/Makefile.am [new file with mode: 0644]
src/common/common.h [new file with mode: 0644]
src/common/cpu8051.c [new file with mode: 0644]
src/common/cpu8051.h [new file with mode: 0644]
src/common/hexfile.c [new file with mode: 0644]
src/common/hexfile.h [new file with mode: 0644]
src/common/log.c [new file with mode: 0644]
src/common/log.h [new file with mode: 0644]
src/common/memory.c [new file with mode: 0644]
src/common/memory.h [new file with mode: 0644]
src/common/opcode2c.pl [new file with mode: 0755]
src/common/opcodes.lst [new file with mode: 0644]
src/common/options.c [new file with mode: 0644]
src/common/options.h [new file with mode: 0644]
src/common/psw.c [new file with mode: 0644]
src/common/psw.h [new file with mode: 0644]
src/common/reg8051.h [new file with mode: 0644]
src/common/sfr.c [new file with mode: 0644]
src/common/sfr.h [new file with mode: 0644]
src/common/timers.c [new file with mode: 0644]
src/common/timers.h [new file with mode: 0644]
src/cpu8051.c [deleted file]
src/cpu8051.h [deleted file]
src/emuconsole.c [deleted file]
src/emugtk.c [deleted file]
src/emugtk.h [deleted file]
src/filemenu.c [deleted file]
src/filemenu.h [deleted file]
src/gtk/Makefile.am [new file with mode: 0644]
src/gtk/app-config.c [new file with mode: 0644]
src/gtk/app-config.h [new file with mode: 0644]
src/gtk/emugtk.c [new file with mode: 0644]
src/gtk/emugtk.h [new file with mode: 0644]
src/gtk/filemenu.c [new file with mode: 0644]
src/gtk/filemenu.h [new file with mode: 0644]
src/gtk/helpmenu.c [new file with mode: 0644]
src/gtk/helpmenu.h [new file with mode: 0644]
src/gtk/memwin.c [new file with mode: 0644]
src/gtk/memwin.h [new file with mode: 0644]
src/gtk/messagebox.c [new file with mode: 0644]
src/gtk/messagebox.h [new file with mode: 0644]
src/gtk/pgmwin.c [new file with mode: 0644]
src/gtk/pgmwin.h [new file with mode: 0644]
src/gtk/pswwin.c [new file with mode: 0644]
src/gtk/pswwin.h [new file with mode: 0644]
src/gtk/regwin.c [new file with mode: 0644]
src/gtk/regwin.h [new file with mode: 0644]
src/gtk/viewmenu.c [new file with mode: 0644]
src/gtk/viewmenu.h [new file with mode: 0644]
src/helpmenu.c [deleted file]
src/helpmenu.h [deleted file]
src/hexfile.c [deleted file]
src/hexfile.h [deleted file]
src/keyboard.c [deleted file]
src/keyboard.h [deleted file]
src/log.c [deleted file]
src/log.h [deleted file]
src/memory.c [deleted file]
src/memory.h [deleted file]
src/memwin.c [deleted file]
src/memwin.h [deleted file]
src/messagebox.c [deleted file]
src/messagebox.h [deleted file]
src/opcode2c.pl [deleted file]
src/opcodes.lst [deleted file]
src/options.c [deleted file]
src/options.h [deleted file]
src/pgmwin.c [deleted file]
src/pgmwin.h [deleted file]
src/psw.c [deleted file]
src/psw.h [deleted file]
src/pswwin.c [deleted file]
src/pswwin.h [deleted file]
src/reg8051.h [deleted file]
src/regwin.c [deleted file]
src/regwin.h [deleted file]
src/sfr.c [deleted file]
src/sfr.h [deleted file]
src/timers.c [deleted file]
src/timers.h [deleted file]
src/viewmenu.c [deleted file]
src/viewmenu.h [deleted file]
tests/opcodes.sh

index f8db576..0ec666a 100644 (file)
@@ -11,6 +11,7 @@
 /build-aux/install-sh
 /build-aux/missing
 /build-aux/test-driver
+/build-aux/ar-lib
 /config.cache
 /config.log
 /config.status
index 0304f0a..df08920 100644 (file)
@@ -2,7 +2,7 @@
 
 AUTOMAKE_OPTIONS = gnu
 
-SUBDIRS = src data doc tests
+SUBDIRS = src/common src/cli src/gtk data doc tests
 
 ## We want these in the dist tarball
 EXTRA_DIST = autogen.sh \
@@ -20,4 +20,5 @@ MAINTAINERCLEANFILES = Makefile.in aclocal.m4 configure config-h.in \
                        $(ac_aux_dir)/mkinstalldirs $(ac_aux_dir)/config.guess \
                        $(ac_aux_dir)/config.sub $(ac_aux_dir)/ltmain.sh \
                        $(ac_aux_dir)/compile \
-                       $(ac_aux_dir)/test-driver
+                       $(ac_aux_dir)/test-driver \
+                       $(ac_aux_dir)/ar-lib
index 8b7ed65..d39a607 100644 (file)
@@ -4,7 +4,7 @@ dnl Initialization stuff.
 AC_INIT([emu8051], [1.1.2], [hugo@hugovil.com], [emu8051],
        [http://www.hugovil.com/fr/emu8051/])
 AC_CONFIG_AUX_DIR([build-aux])
-AC_CONFIG_SRCDIR(src/cpu8051.c)
+AC_CONFIG_SRCDIR(src/common/cpu8051.c)
 AM_CONFIG_HEADER(config.h:config-h.in)
 dnl Checking if the NEWS file has been updated to reflect the current version.
 AM_INIT_AUTOMAKE(check-news -Wall std-options color-tests parallel-tests)
@@ -13,6 +13,10 @@ AM_SILENT_RULES([yes])
 dnl Testing the C compiler.
 AC_LANG_C
 
+dnl Testing for libtool support.
+AC_PROG_RANLIB
+AM_PROG_AR
+
 dnl Checking for typedefs, structures, and compiler characteristics.
 AC_C_CONST
 AC_TYPE_PID_T
@@ -83,4 +87,10 @@ AC_SUBST(LIBS)
 AC_SUBST(ac_aux_dir)
 
 dnl Creating output file(s)
-AC_OUTPUT(Makefile src/Makefile data/Makefile doc/Makefile tests/Makefile)
+AC_OUTPUT(Makefile
+    src/common/Makefile
+    src/cli/Makefile
+    src/gtk/Makefile
+    data/Makefile
+    doc/Makefile
+    tests/Makefile)
diff --git a/src/Makefile.am b/src/Makefile.am
deleted file mode 100644 (file)
index 1bb89bb..0000000
+++ /dev/null
@@ -1,75 +0,0 @@
-# This file is processed by GNU automake to generate Makefile.in
-
-AM_CPPFLAGS = \
-    -I$(top_srcdir) \
-    $(GLIB_CFLAGS)
-
-LDADD = $(GLIB_LIBS)
-
-bin_PROGRAMS = emu8051-cli
-if USE_GTK
-  bin_PROGRAMS += emu8051-gtk
-endif
-
-# instructions_8051.c must be first, because it and other files
-# (instructions_8051.h and disasm.h) are automatically generated by a perl
-# script, and other source files include them (the .h).
-common_SOURCES = \
-       instructions_8051.c \
-       options.c options.h \
-       log.c log.h \
-       app-config.c app-config.h \
-       hexfile.c hexfile.h \
-       cpu8051.c cpu8051.h \
-       memory.c memory.h \
-       psw.c psw.h \
-       sfr.c sfr.h \
-       timers.c timers.h \
-       common.h \
-       reg8051.h
-
-emu8051_cli_SOURCES = \
-       $(common_SOURCES) \
-       emuconsole.c \
-       keyboard.c keyboard.h
-
-if USE_GTK
-  emu8051_gtk_SOURCES = \
-       $(common_SOURCES) \
-       emugtk.c emugtk.h \
-       memwin.c memwin.h \
-       pgmwin.c pgmwin.h \
-       regwin.c regwin.h \
-       pswwin.c pswwin.h \
-       filemenu.c filemenu.h \
-       viewmenu.c viewmenu.h \
-       helpmenu.c helpmenu.h \
-       messagebox.c messagebox.h
-
-  emu8051_gtk_CPPFLAGS = \
-    -I$(top_srcdir)/pixmaps \
-    $(GTK_CFLAGS) \
-    $(AM_CPPFLAGS)
-
-  emu8051_gtk_LDADD = $(GTK_LIBS)
-endif
-
-# These files are generated automatically by a perl script.
-instructions_8051.c instructions_8051.h disasm.h : opcode2c.pl opcodes.lst
-       ./opcode2c.pl
-
-CLEANFILES     = *~
-
-DISTCLEANFILES = .deps/*.P
-
-MAINTAINERCLEANFILES = \
-       Makefile.in \
-       instructions_8051.c \
-       instructions_8051.h \
-       disasm.h
-
-EXTRA_DIST = \
-       opcode2c.pl \
-       opcodes.lst \
-       instructions_8051.h \
-       disasm.h
diff --git a/src/app-config.c b/src/app-config.c
deleted file mode 100644 (file)
index 90022f2..0000000
+++ /dev/null
@@ -1,218 +0,0 @@
-/*
- * Handle loading and saving of application configuration settings
- *
- * Copyright (C) 2013 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 <stdint.h>
-#include <stdbool.h>
-#include <unistd.h>
-#include <stdio.h>
-#include <stdlib.h>
-
-#if STDC_HEADERS
-#  include <string.h>
-#elif HAVE_STRINGS_H
-#  include <strings.h>
-#endif
-
-#include <glib.h>
-
-#include "common.h"
-#include "app-config.h"
-
-static const char profile_name[] = "default";
-static struct app_config_t app_config;
-
-struct app_config_t *cfg = &app_config;
-
-static void
-app_config_init(void)
-{
-       /* Emulation options */
-       cfg->clear_ram_on_file_load = false;
-
-       /* UI settings */
-       cfg->win_width = 640;
-       cfg->win_height = 480;
-       cfg->hpane_pos = 100;
-       cfg->vpane_pos = 200;
-       cfg->main_pane_pos = 200;
-
-       /* View menu options */
-       cfg->layout = UI_LAYOUT1;
-       cfg->view_int_memory = 1;
-       cfg->view_sfr_memory = 1;
-       cfg->view_ext_memory = 1;
-       cfg->bits_per_row = 16; /* 8 or 16 */
-}
-
-static int
-app_config_key_file_get_int(GKeyFile *kf, const char *grp, const char *key, int *value)
-{
-    char *str = g_key_file_get_value(kf, grp, key, NULL);
-
-    log_debug("key: %s", key);
-
-    if (G_LIKELY(str)) {
-           *value = atoi(str);
-           log_debug("  value = %d", *value);
-           g_free(str);
-    }
-
-    return str != NULL;
-}
-
-static void
-app_config_load_from_key_file(GKeyFile *kf)
-{
-       /* Emulation options */
-       app_config_key_file_get_int(kf, "emulation", "clear_ram_on_file_load",
-                                   &cfg->clear_ram_on_file_load);
-
-       /* ui */
-       app_config_key_file_get_int(kf, "ui", "win_width",  &cfg->win_width);
-       app_config_key_file_get_int(kf, "ui", "win_height", &cfg->win_height);
-       app_config_key_file_get_int(kf, "ui", "hpane_pos",  &cfg->hpane_pos);
-       app_config_key_file_get_int(kf, "ui", "vpane_pos",  &cfg->vpane_pos);
-       app_config_key_file_get_int(kf, "ui", "main_pane_pos",
-                                   &cfg->main_pane_pos);
-
-       /* View */
-       app_config_key_file_get_int(kf, "view", "layout",  &cfg->layout);
-       if ((cfg->layout != UI_LAYOUT1) && (cfg->layout != UI_LAYOUT2)) {
-               log_err("Invalid layout, defaulting to layout 1");
-               cfg->layout = UI_LAYOUT1;
-       }
-       app_config_key_file_get_int(kf, "view", "int_memory",
-                                   &cfg->view_int_memory);
-       app_config_key_file_get_int(kf, "view", "sfr_memory",
-                                   &cfg->view_sfr_memory);
-       app_config_key_file_get_int(kf, "view", "ext_memory",
-                                   &cfg->view_ext_memory);
-       app_config_key_file_get_int(kf, "view", "bits_per_row",
-                                   &cfg->bits_per_row);
-}
-
-static char *
-app_config_get_dir_path(void)
-{
-       char *dir_path;
-
-       dir_path = g_build_filename(g_get_user_config_dir(), PACKAGE,
-                                   profile_name, NULL);
-
-       return dir_path;
-}
-
-static char *
-app_config_get_file_path(void)
-{
-       char *file_path;
-       char *dir_path;
-       char file[MAX_FILENAME_LENGTH];
-
-       sprintf(file, "%s.conf", PACKAGE);
-
-       dir_path = app_config_get_dir_path();
-
-       file_path = g_build_filename(dir_path, file, NULL);
-
-       log_info("app. config file = %s", file_path);
-
-       g_free(dir_path);
-
-       return file_path;
-}
-
-int
-app_config_load(void)
-{
-       char *file_path;
-       GKeyFile *kf;
-
-       /* Load default values before config file */
-       app_config_init();
-
-       kf = g_key_file_new();
-
-       file_path = app_config_get_file_path();
-
-       if (g_key_file_load_from_file(kf, file_path, 0, NULL))
-               app_config_load_from_key_file(kf);
-
-       g_free(file_path);
-
-       g_key_file_free(kf);
-
-       /* ??? */
-       return 0;
-}
-
-int
-app_config_save(void)
-{
-       char *dir_path;
-
-       dir_path = app_config_get_dir_path();
-
-       if (g_mkdir_with_parents(dir_path, 0700) != -1)
-       {
-               char *file_path;
-               GString* buf = g_string_sized_new(1024);
-
-               g_string_append(buf, "\n[emulation]\n");
-
-               g_string_append_printf(buf, "clear_ram_on_file_load=%d\n",
-                                      cfg->clear_ram_on_file_load);
-
-               g_string_append(buf, "\n[ui]\n");
-
-               g_string_append_printf(buf, "win_width=%d\n", cfg->win_width);
-               g_string_append_printf(buf, "win_height=%d\n", cfg->win_height);
-               g_string_append_printf(buf, "hpane_pos=%d\n", cfg->hpane_pos);
-               g_string_append_printf(buf, "vpane_pos=%d\n", cfg->vpane_pos);
-               g_string_append_printf(buf, "main_pane_pos=%d\n",
-                                      cfg->main_pane_pos);
-
-               g_string_append(buf, "\n[view]\n");
-               g_string_append_printf(buf, "layout=%d\n", cfg->layout);
-               g_string_append_printf(buf, "int_memory=%d\n",
-                                      cfg->view_int_memory);
-               g_string_append_printf(buf, "sfr_memory=%d\n",
-                                      cfg->view_sfr_memory);
-               g_string_append_printf(buf, "ext_memory=%d\n",
-                                      cfg->view_ext_memory);
-               g_string_append_printf(buf, "bits_per_row=%d\n",
-                                      cfg->bits_per_row);
-
-               file_path = app_config_get_file_path();
-
-               g_file_set_contents(file_path, buf->str, buf->len, NULL);
-               g_string_free(buf, TRUE);
-               g_free(file_path);
-       }
-
-       g_free(dir_path);
-
-       /* ??? */
-       return 0;
-}
diff --git a/src/app-config.h b/src/app-config.h
deleted file mode 100644 (file)
index 1c418b5..0000000
+++ /dev/null
@@ -1,64 +0,0 @@
-/*
- * app_config.h
- *
- * 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 APP_CONFIG_H
-#define APP_CONFIG_H 1
-
-/*
- *    Layout1:              Layout2:
- *
- * REGS | PROGRAM           |         | IRAM
- * --------------      REGS | PROGRAM | ----
- *     IRAM                 |         | XRAM
- * --------------
- *     XRAM
- */
-enum layout_t {
-       UI_LAYOUT1 = 1,
-       UI_LAYOUT2,
-};
-
-struct app_config_t
-{
-       /* Emulation options */
-       int clear_ram_on_file_load;
-
-       /* UI settings */
-       int win_width;
-       int win_height;
-       int hpane_pos;     /* For registers and program windows. */
-       int vpane_pos; /* For internal and external memory windows. */
-       int main_pane_pos; /* Between hpane and vpane. */
-
-       /* View menu options */
-       int layout; /* UI Layout 1 or 2 */
-       int view_int_memory;
-       int view_sfr_memory;
-       int view_ext_memory;
-       int bits_per_row; /* 8 or 16 */
-};
-
-int
-app_config_load(void);
-
-int
-app_config_save(void);
-
-#endif /* APP_CONFIG_H */
diff --git a/src/cli/Makefile.am b/src/cli/Makefile.am
new file mode 100644 (file)
index 0000000..deaae8a
--- /dev/null
@@ -0,0 +1,22 @@
+# This file is processed by GNU automake to generate Makefile.in
+
+AM_CPPFLAGS = \
+    -Wall \
+    -I@top_srcdir@ \
+    -I@top_srcdir@/src/common
+
+LDADD = \
+    $(top_builddir)/src/common/libemu8051.a
+
+bin_PROGRAMS = emu8051-cli
+
+emu8051_cli_SOURCES = \
+    emuconsole.c \
+    keyboard.c keyboard.h
+
+# we want these in the dist tarball
+EXTRA_DIST =
+
+CLEANFILES = *~
+
+MAINTAINERCLEANFILES = Makefile.in
diff --git a/src/cli/emuconsole.c b/src/cli/emuconsole.c
new file mode 100644 (file)
index 0000000..f29146d
--- /dev/null
@@ -0,0 +1,518 @@
+/*
+ * emuconsole.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.
+ */
+
+#define _GNU_SOURCE /* For getline() */
+#include <stdio.h>
+#include <string.h>
+#include <ctype.h> /* For isblank, toupper() */
+#include "config.h"
+
+#include "common.h"
+#include "cpu8051.h"
+#include "reg8051.h"
+#include "sfr.h"
+#include "memory.h"
+#include "options.h"
+#include "hexfile.h"
+#include "keyboard.h"
+
+extern struct options_t options;
+
+/* Capitalize all letters in buffer */
+static void
+Capitalize(char *buffer)
+{
+       int k;
+
+       for (k = 0; k < strlen(buffer); k++)
+               buffer[k] = toupper(buffer[k]);
+}
+
+/* Remove leading spaces from string in buffer */
+static void
+RemoveSpaces(char *buffer)
+{
+       int k = 0;
+
+       while ((k < strlen(buffer)) && isblank(buffer[k]))
+               k++;
+
+       if (k != 0)
+               strcpy(buffer, &buffer[k]);
+}
+
+/* CPU exec and Console UI update */
+static void
+console_exec(char *Address, char *NumberInst)
+{
+       int NbInst = -1; /* -1 is infinity */
+       if (strlen(Address) == 0) {
+               log_err("Invalid address");
+               return;
+       }
+
+       if (!STREQ(Address, "PC"))
+               cpu8051.pc = Ascii2Hex(Address, strlen(Address));
+
+       if (NumberInst)
+               if (strlen(NumberInst) != 0)
+                       NbInst = Ascii2Hex(NumberInst, strlen(NumberInst));
+
+       InitUnixKB();
+
+       log_info("Program executing...");
+
+       do {
+               cpu8051_Exec();
+               if (NbInst > 0)
+                       NbInst--;
+       } while (!IsBreakpoint(cpu8051.pc) && !IsStoppoint(cpu8051.pc) &&
+                (NbInst != 0) && !kbhit());
+       if (kbhit()) {
+               (void) getch(); /* Flush key */
+               log_info("Caught break signal!");
+       }
+       if (NbInst == 0)
+               log_info("Number of instructions reached! Stopping!");
+       if (IsBreakpoint(cpu8051.pc))
+               log_info("Breakpoint hit at %.4X! Stopping!", cpu8051.pc);
+       if (IsStoppoint(cpu8051.pc))
+               log_info("Stoppoint hit at %.4X! Stopping!", cpu8051.pc);
+
+       ResetUnixKB();
+}
+
+/* Disassemble NumberInst instructions at Address */
+static void
+DisasmN(unsigned int Address, int NumberInst)
+{
+       char TextTmp[255];
+       int Row;
+
+       for (Row = 0; Row < NumberInst ; Row++) {
+               Address += cpu8051_Disasm(Address, TextTmp);
+               printf("%s\n", TextTmp);
+
+               if (Address > 0xFFFF)
+                       return;
+       }
+}
+
+/* Disassemble 16 instructions at Address */
+static void
+Disasm(char *Address, char *NumberInst)
+{
+       unsigned int MemAddress, NbInst;
+
+       if ((strlen(Address) == 0) || (STREQ(Address, "PC")))
+               MemAddress = cpu8051.pc;
+       else
+               MemAddress = Ascii2Hex(Address, strlen(Address));
+
+       if (strlen(NumberInst) == 0)
+               NumberInst = "10";
+       NbInst = Ascii2Hex(NumberInst, strlen(NumberInst));
+       DisasmN(MemAddress, NbInst);
+}
+
+/* Set NewValue to Register */
+static void
+SetRegister(char *Register, char *NewValue)
+{
+       if (STREQ(Register, "PC"))
+               cpu8051.pc = Ascii2Hex(NewValue, 4);
+       else if (STREQ(Register, "A"))
+               cpu8051_WriteD(_ACC_, Ascii2Hex(NewValue, 2));
+       else if (STREQ(Register, "B"))
+               cpu8051_WriteD(_B_, Ascii2Hex(NewValue, 2));
+       else if (STREQ(Register, "SP"))
+               cpu8051_WriteD(_SP_, Ascii2Hex(NewValue, 2));
+       else {
+               printf("\nInvalid register name!\n");
+               printf("Valid registers are A, B, PC and SP.\n");
+       }
+}
+
+/* Show CPU registers, one per line */
+static void
+console_dump_sfr_registers_detailed(void)
+{
+       int k;
+
+       for (k = 0; k < SFR_REGS; k++) {
+               struct regwin_infos_t *regwin_infos;
+               int val;
+
+               regwin_infos = sfr_get_infos_from_row(k);
+
+               printf("%s = ", regwin_infos->name);
+
+               val = regwin_read(k);
+               if (regwin_infos->w == 2)
+                       printf("$%02X", val);
+               else if (regwin_infos->w == 4)
+                       printf("$%04X", val);
+
+               printf("\n");
+       }
+}
+
+/* Show CPU registers, compact format */
+static void
+console_dump_sfr_registers_compact(void)
+{
+       unsigned char PSW = cpu8051_ReadD(_PSW_);
+       int BankSelect = (PSW & 0x18);
+
+       printf("---------------------------------------------------------------"
+              "-------\n");
+       printf("|  PC  | SP | DPTR | ACC |  B | PSW:  CY  AC  F0 RS1 RS0  OV"
+              "   -   P |\n");
+       printf("| %.4X | %.2X | %.4X |  %.2X | %.2X |", cpu8051.pc,
+              cpu8051_ReadD(_SP_),
+              memory_sfr_read_dptr(),
+              cpu8051_ReadD(_ACC_), cpu8051_ReadD(_B_));
+       printf("        %d   %d   %d   %d   %d   %d   %d   %d |",
+              (PSW >> 7) & 1, (PSW >> 6) & 1, (PSW >> 5) & 1, (PSW >> 4) & 1,
+              (PSW >> 3) & 1, (PSW >> 2) & 1, (PSW >> 1) & 1, PSW & 1);
+       printf("\n");
+       printf("---------------------------------------------------------------"
+              "-------\n");
+
+       printf("| TCON | TMOD | IE | IP | R0 | R1 | R2 | R3 | R4 | R5 | R6 | R7"
+              " |    |\n");
+       printf("|   %.2X |   %.2X | %.2X | %.2X ", cpu8051_ReadD(_TCON_),
+              cpu8051_ReadD(_TMOD_), cpu8051_ReadD(_IE_), cpu8051_ReadD(_IP_));
+       printf("| %.2X | %.2X | %.2X | %.2X ",
+              cpu8051_ReadD(BankSelect + _R0_),
+              cpu8051_ReadD(BankSelect + _R1_),
+              cpu8051_ReadD(BankSelect + _R2_),
+              cpu8051_ReadD(BankSelect + _R3_));
+       printf("| %.2X | %.2X | %.2X | %.2X ",
+              cpu8051_ReadD(BankSelect + _R4_),
+              cpu8051_ReadD(BankSelect + _R5_),
+              cpu8051_ReadD(BankSelect + _R6_),
+              cpu8051_ReadD(BankSelect + _R7_));
+       printf("|    |\n");
+       printf("---------------------------------------------------------------"
+              "-------\n");
+}
+
+/* Show CPU registers */
+static void
+console_show_registers(void)
+{
+       if (options.stop_address != 0)
+               console_dump_sfr_registers_detailed();
+       else
+               console_dump_sfr_registers_compact();
+}
+
+/* CPU reset and Console UI update */
+static void
+console_reset(void)
+{
+       log_info("Resetting...");
+       cpu8051_Reset();
+       log_info("Done");
+}
+
+/* CPU trace and Console UI update */
+static void
+console_trace(char *Address)
+{
+       if (strlen(Address) != 0)
+               cpu8051.pc = Ascii2Hex(Address, strlen(Address));
+       cpu8051_Exec();
+       console_show_registers();
+       DisasmN(cpu8051.pc, 1);
+}
+
+/* EmuConsole main loop */
+static void
+console_main(void)
+{
+       unsigned int Index;
+       char *line = NULL;
+       int QuitRequest = 0;
+       char prompt[] = "-> ";
+
+       char *Title[] = { "      *******************",
+                         "      *  8051 Emulator  *",
+                         "      *******************",
+                         "", 0 };
+
+       char *Menu[] = {
+               "      Available commands, [ ] = options",
+               "",
+               "  Set Breakpoint.............. SB [address]",
+               "  Remove Breakpoint........... RB [address]",
+               "  Display Breakpoint(s)....... DB",
+               "  Dump External Data Memory... DE [address] [size]",
+               "  Dump Internal Data Memory... DI [address] [size]",
+               "  Dump Program Memory......... DP [address] [size]",
+               "  Display Registers content... DR",
+               "  Execute..................... EM [address"
+               " [number of instructions]]",
+               "  Help........................ H or ?",
+               "  Modify External Data Memory. ME address value",
+               "  Modify Internal Data Memory. MI address value",
+               "  Modify Program Memory....... MP address value",
+               "  Modify Register............. MR register value",
+               "  Quit Emulator............... Q",
+               "  Trace mode.................. T [address]",
+               "  Unassemble.................. U [address]"
+               " [number of instructions]",
+               "  Reset processor............. Z", 0 };
+
+       console_reset();
+
+       if (options.stop_address != 0) {
+               /* Automatically run program and stop at specified address. */
+               console_exec("0x0000", NULL);
+               console_show_registers();
+               QuitRequest = 1;
+       } else {
+               Index = 0;
+               while (Title[Index] != 0)
+                       printf("%s\n", Title[Index++]);
+
+               Index = 0;
+               while (Menu[Index] != 0)
+                       printf("%s\n", Menu[Index++]);
+
+               console_show_registers();
+       }
+
+       while (!QuitRequest) {
+               int slen;
+               size_t len = 0;
+               char Command[256];
+               char Args[256];
+               char Parameter1[256];
+               char Parameter2[256];
+
+               Parameter1[0] = '\0';
+               Parameter2[0] = '\0';
+
+               printf(prompt);
+               (void) getline(&line, &len, stdin);
+               Capitalize(line);
+               RemoveSpaces(line);
+
+               /* Strip trailing newline */
+               slen = strlen(line);
+               if (line[slen - 1] == '\n')
+                       line[slen - 1] = '\0';
+
+               /* Find command-arguments delimiter */
+               for (Index = 0; Index < strlen(line); Index++) {
+                       if (isblank(line[Index]))
+                               break;
+               }
+
+               /* Keep only the Command part from the input line */
+               memcpy(Command, &line[0], Index);
+               Command[Index] = '\0';
+
+               /* Keep only the arguments part from the input line */
+               if (Index < strlen(line)) {
+                       slen = strlen(line) - Index;
+                       memcpy(Args, &line[Index + 1], slen);
+               } else {
+                       slen = 0;
+               }
+               Args[slen] = '\0';
+               RemoveSpaces(Args);
+
+               /* Find multi-arguments delimiter */
+               for (Index = 0; Index < strlen(Args); Index++) {
+                       if (isblank(Args[Index]))
+                               break;
+               }
+
+               memcpy(Parameter1, &Args[0], Index);
+               Parameter1[Index] = '\0';
+
+               if (Index < strlen(Args)) {
+                       slen = strlen(Args) - Index;
+                       memcpy(Parameter2, &Args[Index + 1], slen);
+               } else {
+                       slen = 0;
+               }
+               Parameter2[slen] = '\0';
+               RemoveSpaces(Parameter2);
+
+               if (strlen(Command) == 0) {
+                       goto syntax_error;
+                       continue;
+               }
+
+               if ((strlen(Parameter1) > 4) || (strlen(Parameter2) > 4)) {
+                       printf("Invalid Parameter Format!\n");
+                       continue;
+               }
+
+               switch (Command[0]) {
+               case 'D':
+                       if (STREQ(Command, "DB") &&
+                           (strlen(Parameter1) == 0))
+                               ShowBreakpoints();
+                       else if (STREQ(Command, "DE"))
+                               DumpMem(Parameter1, Parameter2, EXT_MEM_ID);
+                       else if (STREQ(Command, "DI"))
+                               DumpMem(Parameter1, Parameter2, INT_MEM_ID);
+                       else if (STREQ(Command, "DP")) {
+                               if ((strlen(Parameter1) == 0))
+                                       strcpy(Parameter1, "PC");
+                               DumpMem(Parameter1, Parameter2, PGM_MEM_ID);
+                       } else if (STREQ(Command, "DR") &&
+                                  (strlen(Parameter1) == 0))
+                               console_show_registers();
+                       else
+                               goto syntax_error;
+                       break;
+               case 'E':
+                       if (STREQ(Command, "EM"))
+                               console_exec(Parameter1, Parameter2);
+                       else
+                               goto syntax_error;
+                       break;
+               case 'H':
+               case '?':
+                       if ((STREQ(Command, "H") || STREQ(Command, "?")) &&
+                           (strlen(Parameter1) == 0) &&
+                           (strlen(Parameter2) == 0)) {
+                               Index = 0;
+                               while (Menu[Index] != 0)
+                                       printf("%s\n", Menu[Index++]);
+                       } else
+                               goto syntax_error;
+                       break;
+               case 'M':
+                       if ((strlen(Parameter1) == 0) ||
+                           (strlen(Parameter2) == 0))
+                               printf("Missing Parameter!\n");
+                       else if (STREQ(Command, "ME")) {
+                               unsigned int adresse = Ascii2Hex(Parameter1, 4);
+                               unsigned char valeur = Ascii2Hex(Parameter2, 2);
+                               memory_write8(EXT_MEM_ID, adresse, valeur);
+                       } else if (STREQ(Command, "MI")) {
+                               unsigned int adresse = Ascii2Hex(Parameter1, 2);
+                               unsigned char valeur = Ascii2Hex(Parameter2, 2);
+                               memory_write8(INT_MEM_ID, adresse, valeur);
+                       } else if (STREQ(Command, "MP")) {
+                               unsigned int adresse = Ascii2Hex(Parameter1, 4);
+                               unsigned char valeur = Ascii2Hex(Parameter2, 2);
+                               memory_write8(PGM_MEM_ID, adresse, valeur);
+                       } else if (STREQ(Command, "MR"))
+                               SetRegister(Parameter1, Parameter2);
+                       else
+                               goto syntax_error;
+                       break;
+               case 'Q':
+                       if (STREQ(Command, "Q") && (strlen(Parameter1) == 0) &&
+                           (strlen(Parameter2) == 0))
+                               QuitRequest = 1;
+                       else
+                               goto syntax_error;
+                       break;
+               case 'R':
+                       if (strlen(Parameter2) != 0)
+                               goto TooMuchParameters;
+                       if (STREQ(Command, "RB")) {
+                               if (strlen(Parameter1) == 0)
+                                       ClearBreakpoint(cpu8051.pc);
+                               else
+                                       ClearBreakpoint(
+                                               Ascii2Hex(Parameter1, 4));
+                       } else
+                               goto syntax_error;
+                       break;
+               case 'S':
+                       if (strlen(Parameter2) != 0)
+                               goto TooMuchParameters;
+
+                       if (STREQ(Command, "SB")) {
+                               if (strlen(Parameter1) == 0)
+                                       SetBreakpoint(cpu8051.pc);
+                               else
+                                       SetBreakpoint(Ascii2Hex(Parameter1, 4));
+                       } else
+                               goto syntax_error;
+                       break;
+               case 'T':
+                       if (strlen(Parameter2) != 0)
+                               printf("Wrong Number of Parameters!\n");
+
+                       if (STREQ(Command, "T"))
+                               console_trace(Parameter1);
+                       else
+                               goto syntax_error;
+                       break;
+               case 'U':
+                       if (STREQ(Command, "U"))
+                               Disasm(Parameter1, Parameter2);
+                       else
+                               goto syntax_error;
+                       break;
+               case 'Z':
+                       if (STREQ(Command, "Z") && (strlen(Parameter1) == 0) &&
+                           (strlen(Parameter2) == 0))
+                               cpu8051_Reset();
+                       else
+                               goto syntax_error;
+                       break;
+               case '\n':
+                       break;
+               default:
+                       goto syntax_error;
+               }
+               continue;
+
+syntax_error:
+               printf("Syntax Error!\n");
+               continue;
+TooMuchParameters:
+               printf("Wrong Number of Parameters!\n");
+               continue;
+       }
+
+       if (line)
+               free(line);
+}
+
+int
+main(int argc, char **argv)
+{
+       parse_command_line_options(argc, argv);
+
+       cpu8051_init();
+
+       if (options.filename != NULL)
+               LoadHexFile(options.filename);
+
+       console_main();
+
+       log_info("Terminate");
+
+       return 0;
+}
diff --git a/src/cli/keyboard.c b/src/cli/keyboard.c
new file mode 100644 (file)
index 0000000..654087e
--- /dev/null
@@ -0,0 +1,77 @@
+/*
+ * keyboard.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.
+ */
+
+#include <termios.h>
+#include <unistd.h>
+
+static struct termios orig, newtio;
+static int peek = -1;
+
+int
+kbhit(void)
+{
+       char ch;
+       int nread;
+       if (peek != -1)
+               return 1;
+       newtio.c_cc[VMIN] = 0;
+       tcsetattr(0, TCSANOW, &newtio);
+       nread = read(0, &ch, 1);
+       newtio.c_cc[VMIN] = 1;
+       tcsetattr(0, TCSANOW, &newtio);
+       if (nread == 1) {
+               peek = ch;
+               return 1;
+       }
+       return 0;
+}
+
+int
+getch(void)
+{
+       char ch;
+       if (peek != -1) {
+               ch = peek;
+               peek = -1;
+               return ch;
+       }
+       read(0, &ch, 1);
+       return ch;
+}
+
+void
+InitUnixKB(void)
+{
+       tcgetattr(0, &orig);
+       newtio = orig;
+       newtio.c_lflag &= ~ICANON;
+       newtio.c_lflag &= ~ECHO;
+       newtio.c_lflag &= ~ISIG;
+       newtio.c_cc[VMIN] = 1;
+       newtio.c_cc[VTIME] = 0;
+       tcsetattr(0, TCSANOW, &newtio);
+}
+
+void
+ResetUnixKB(void)
+{
+       tcsetattr(0, TCSANOW, &orig);
+}
diff --git a/src/cli/keyboard.h b/src/cli/keyboard.h
new file mode 100644 (file)
index 0000000..8660616
--- /dev/null
@@ -0,0 +1,37 @@
+/*
+ * keyboard.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 _KEYBOARD_H_
+#define _KEYBOARD_H_
+
+int
+kbhit(void);
+
+int
+getch(void);
+
+void
+InitUnixKB(void);
+
+void
+ResetUnixKB(void);
+
+#endif /* _KEYBOARD_H_ */
diff --git a/src/common.h b/src/common.h
deleted file mode 100644 (file)
index 0058a01..0000000
+++ /dev/null
@@ -1,60 +0,0 @@
-/*
- * common.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 COMMON_H
-#define COMMON_H 1
-
-#include <stdio.h>
-#include <stdlib.h>
-#include <errno.h>
-
-#if STDC_HEADERS
-#  include <string.h>
-#elif HAVE_STRINGS_H
-#  include <strings.h>
-#endif
-
-#include "log.h"
-
-#define FIXED_FONT "monospace 12"
-
-#define MAX_FILENAME_LENGTH 1024
-
-/* Common constants. */
-#ifndef EXIT_SUCCESS
-#  define EXIT_SUCCESS 0
-#  define EXIT_FAILURE 1
-#endif
-
-/* Returns TRUE if the strings 'a' and 'b' are equal. */
-#define STREQ(a, b) (strcasecmp((a), (b)) == 0)
-
-/* Returns TRUE if the first 'c' characters of strings 'a' and 'b' are equal. */
-#define STREQ_LEN(a, b, c) (strncasecmp((a), (b), (c)) == 0)
-
-
-inline void
-ErrorLocation(const char *file, int line);
-
-void *
-xmalloc(size_t size, const char *filename, int line_number);
-
-#endif /* COMMON_H */
diff --git a/src/common/Makefile.am b/src/common/Makefile.am
new file mode 100644 (file)
index 0000000..2d0df82
--- /dev/null
@@ -0,0 +1,38 @@
+# This file is processed by GNU automake to generate Makefile.in
+
+AM_CPPFLAGS = \
+       -Wall \
+       -I$(top_srcdir)
+
+noinst_LIBRARIES = libemu8051.a
+
+libemu8051_a_SOURCES = \
+       instructions_8051.c \
+       options.c options.h \
+       log.c log.h \
+       hexfile.c hexfile.h \
+       cpu8051.c cpu8051.h \
+       memory.c memory.h \
+       psw.c psw.h \
+       sfr.c sfr.h \
+       timers.c timers.h \
+       common.h \
+       reg8051.h
+
+# These files are generated automatically by a perl script.
+instructions_8051.c instructions_8051.h disasm.h : opcode2c.pl opcodes.lst
+       ./opcode2c.pl
+
+CLEANFILES = *~
+
+MAINTAINERCLEANFILES = \
+       Makefile.in \
+       instructions_8051.c \
+       instructions_8051.h \
+       disasm.h
+
+EXTRA_DIST = \
+       opcode2c.pl \
+       opcodes.lst \
+       instructions_8051.h \
+       disasm.h
diff --git a/src/common/common.h b/src/common/common.h
new file mode 100644 (file)
index 0000000..0058a01
--- /dev/null
@@ -0,0 +1,60 @@
+/*
+ * common.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 COMMON_H
+#define COMMON_H 1
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <errno.h>
+
+#if STDC_HEADERS
+#  include <string.h>
+#elif HAVE_STRINGS_H
+#  include <strings.h>
+#endif
+
+#include "log.h"
+
+#define FIXED_FONT "monospace 12"
+
+#define MAX_FILENAME_LENGTH 1024
+
+/* Common constants. */
+#ifndef EXIT_SUCCESS
+#  define EXIT_SUCCESS 0
+#  define EXIT_FAILURE 1
+#endif
+
+/* Returns TRUE if the strings 'a' and 'b' are equal. */
+#define STREQ(a, b) (strcasecmp((a), (b)) == 0)
+
+/* Returns TRUE if the first 'c' characters of strings 'a' and 'b' are equal. */
+#define STREQ_LEN(a, b, c) (strncasecmp((a), (b), (c)) == 0)
+
+
+inline void
+ErrorLocation(const char *file, int line);
+
+void *
+xmalloc(size_t size, const char *filename, int line_number);
+
+#endif /* COMMON_H */
diff --git a/src/common/cpu8051.c b/src/common/cpu8051.c
new file mode 100644 (file)
index 0000000..bf7bd99
--- /dev/null
@@ -0,0 +1,651 @@
+/*
+ * cpu8051.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.
+ */
+
+/* Define only here, for not having extern scope on local variables. */
+#define CPU8051_M 1
+
+#include <stdio.h>
+#include <stdint.h>
+
+#include "reg8051.h"
+#include "cpu8051.h"
+#include "memory.h"
+#include "psw.h"
+#include "timers.h"
+#include "disasm.h"
+#include "options.h"
+#include "instructions_8051.h"
+
+extern struct options_t options;
+
+/* Check if the address is a breakpoint */
+int
+IsBreakpoint(unsigned int address)
+{
+       int k;
+
+       for (k = 0; k < cpu8051.bp_count; k++) {
+               if (cpu8051.bp[k] == address)
+                       return 1;
+       }
+
+       /* The address was not found in the list of breakpoints */
+       return 0;
+}
+
+/* Check if the address is a stop point */
+int
+IsStoppoint(unsigned int address)
+{
+       if ((options.stop_address != 0) && (options.stop_address == address))
+               return 1;
+       else
+               return 0;
+}
+
+/* Show Breakpoints list */
+void
+ShowBreakpoints(void)
+{
+       int k;
+
+       for (k = 0; k < cpu8051.bp_count; k++)
+               printf("Breakpoint at address = %.4X\n", cpu8051.bp[k]);
+}
+
+/* Set Breakpoint at address at the end of the breakpoint list */
+void
+SetBreakpoint(unsigned int address)
+{
+       if (IsBreakpoint(address))
+               return; /* Already a breakpoint */
+
+       if (cpu8051.bp_count < MAXBP)
+               cpu8051.bp[cpu8051.bp_count++] = address;
+}
+
+/* Clear Breakpoint at Address from list */
+void
+ClearBreakpoint(unsigned int address)
+{
+       int k;
+
+       for (k = 0; k < cpu8051.bp_count; k++) {
+               if (cpu8051.bp[k] == address) {
+                       /* Fill removed breakpoint slot with last entry */
+                       cpu8051.bp[k] = cpu8051.bp[cpu8051.bp_count - 1];
+                       cpu8051.bp_count--;
+               }
+       }
+}
+
+/* Toggle the breakpoint at Address. */
+void
+ToggleBreakpoint(unsigned int address)
+{
+       if (IsBreakpoint(address))
+               ClearBreakpoint(address);
+       else
+               SetBreakpoint(address);
+}
+
+void
+cpu8051_init(void)
+{
+       memory_init();
+
+       cpu8051.pc = 0;
+       cpu8051.clock = 0;
+       cpu8051.active_priority = -1;
+       cpu8051.bp_count = 0;
+}
+
+/* Reset the registers and CPU state */
+void
+cpu8051_Reset(void)
+{
+       cpu8051.pc = 0;
+       cpu8051.clock = 0;
+       cpu8051.active_priority = -1;
+
+       /* Clear IRAM and SFR. */
+       memory_clear(INT_MEM_ID);
+
+       memory_sfr_write8(_P0_, 0xFF);
+       memory_sfr_write8(_P1_, 0xFF);
+       memory_sfr_write8(_P2_, 0xFF);
+       memory_sfr_write8(_P3_, 0xFF);
+
+       /* The default value of SP (after system reset) is 07 */
+       memory_sfr_write8(_SP_, 0x07);
+}
+
+static void
+cpu8051_convert_bit_address(uint8_t bit_address, uint8_t *byte_address,
+                           uint8_t *bit_number)
+{
+       if (bit_address > 0x7F) {
+               /* SFR 80-FF */
+               *byte_address = bit_address & 0xF8;
+               *bit_number = bit_address & 0x07;
+       } else {
+               /* 20-2F */
+               *byte_address = (bit_address >> 3) + 0x20;
+               *bit_number = bit_address & 0x07;
+       }
+}
+
+/* Write with a direct addressing mode at Address the new Value */
+void
+cpu8051_WriteD(unsigned int Address, unsigned char Value)
+{
+       memory_write8(INT_MEM_ID, Address, Value);
+}
+
+/* Write with an indirect addressing mode at Address the new Value */
+void
+cpu8051_WriteI(unsigned int Address, unsigned char Value)
+{
+       if (Address > 0x7F) {
+               memory_write8(EXT_MEM_ID, Address, Value);
+               return;
+       }
+
+       memory_write8(INT_MEM_ID, Address, Value);
+}
+
+/* Write with a bit addressing mode at BitAddress the new Value */
+void
+cpu8051_WriteB(uint8_t bit_address, uint8_t value)
+{
+       uint8_t byte_address;
+       uint8_t bit_number;
+       unsigned char ByteValue, ByteMask;
+
+       cpu8051_convert_bit_address(bit_address, &byte_address, &bit_number);
+
+       ByteMask = ((1 << bit_number) ^ 0xFF);
+       ByteValue = cpu8051_ReadD(byte_address) & ByteMask;
+       ByteValue += value << bit_number;
+       cpu8051_WriteD(byte_address, ByteValue);
+}
+
+/* Read with a direct addressing mode at Address */
+unsigned char
+cpu8051_ReadD(unsigned int Address)
+{
+       if (Address > 0xFF)
+               return memory_read8(EXT_MEM_ID, Address);
+       else
+               return memory_read8(INT_MEM_ID, Address);
+}
+
+/* Read with a indirect addressing mode at Address */
+unsigned char
+cpu8051_ReadI(unsigned int Address)
+{
+       if (Address > 0x7F)
+               return memory_read8(EXT_MEM_ID, Address);
+       else
+               return memory_read8(INT_MEM_ID, Address);
+}
+
+/* Read with a bit addressing mode at BitAddress */
+unsigned char
+cpu8051_ReadB(uint8_t bit_address)
+{
+       uint8_t byte_address;
+       uint8_t bit_number;
+       unsigned char BitValue;
+
+       cpu8051_convert_bit_address(bit_address, &byte_address, &bit_number);
+
+       BitValue = (cpu8051_ReadD(byte_address) >> bit_number);
+       BitValue &= 1;
+       return BitValue;
+}
+
+static int
+cpu8051_interrupt_fire(int interrupt_no, int priority)
+{
+       if (cpu8051_ReadD(_IP_) & INTERRUPT_MASK(interrupt_no))
+               return priority;
+       else
+               return !priority;
+}
+
+static int
+cpu8051_interrupt_enabled(int interrupt_no)
+{
+       return (cpu8051_ReadD(_IE_) & INTERRUPT_MASK(interrupt_no)) ? 1 : 0;
+}
+
+static void
+cpu8051_process_interrupt(int pc, int pri)
+{
+       stack_push16(cpu8051.pc);
+       cpu8051.pc = pc;
+       cpu8051.active_priority = pri;
+}
+
+
+/* Check interrupts state and process them as needed */
+static void
+cpu8051_CheckInterrupts(void)
+{
+       int i;
+
+       if ((cpu8051_ReadD(_IE_) & 0x80) == 0)
+               return;
+
+       for (i = INTERRUPT_PRIORITY_HIGH; i >= INTERRUPT_PRIORITY_LOW; i--) {
+               if (cpu8051.active_priority < i) {
+                       /* Interrupt timer 0 */
+                       if (cpu8051_interrupt_enabled(INTERRUPT_1) &&
+                           cpu8051_interrupt_fire(INTERRUPT_1, i) &&
+                            (cpu8051_ReadD(_TCON_) & 0x20)) {
+                               cpu8051_WriteD(_TCON_,
+                                              cpu8051_ReadD(_TCON_) & 0xDF);
+                               cpu8051_process_interrupt(0x0B, i);
+                               return;
+                       }
+                       /* Interrupt timer 1 */
+                       if (cpu8051_interrupt_enabled(INTERRUPT_3) &&
+                           cpu8051_interrupt_fire(INTERRUPT_3, i) &&
+                           (cpu8051_ReadD(_TCON_) & 0x80)) {
+                               cpu8051_WriteD(_TCON_,
+                                              cpu8051_ReadD(_TCON_) & 0x7F);
+                               cpu8051_process_interrupt(0x1B, i);
+                               return;
+                       }
+                       /* Serial Interrupts */
+                       if (cpu8051_interrupt_enabled(INTERRUPT_4) &&
+                           cpu8051_interrupt_fire(INTERRUPT_4, i) &&
+                           (cpu8051_ReadD(_SCON_) & 0x03)) {
+                               cpu8051_process_interrupt(0x23, i);
+                               return;
+                       }
+                       /* Interrupt timer 2 */
+                       if (cpu8051_interrupt_enabled(INTERRUPT_5) &&
+                           cpu8051_interrupt_fire(INTERRUPT_5, i) &&
+                           (cpu8051_ReadD(_T2CON_) & 0x80)) {
+                               cpu8051_process_interrupt(0x2B, i);
+                               return;
+                       }
+               }
+       }
+}
+
+/* Execute at address cpu8051.pc from PGMMem */
+void
+cpu8051_Exec(void)
+{
+       int i;
+       unsigned char opcode;
+       int insttiming;
+
+       opcode = memory_read8(PGM_MEM_ID, cpu8051.pc);
+       cpu8051.pc++;
+       insttiming = (*opcode_table[opcode])(); /* Function callback. */
+
+       /*
+        * Parity bit (p): is automatically set or cleared in each machine
+        * cycle to establish even parity in the accumulator.
+        */
+       psw_compute_parity_bit();
+
+       for (i = 0; i < insttiming; i++) {
+               cpu8051_CheckInterrupts();
+               timers_check();
+               cpu8051.clock++;
+       }
+}
+
+/*
+ * Addressing modes defined in the order as they appear in disasm.h
+ * from table argstext[]
+ */
+#define ADDR11 0
+#define ADDR16 1
+#define DIRECT 3
+#define BITADDR 14
+#define RELADDR 15
+#define DATAIMM 16
+#define DATA16 22
+#define CBITADDR 23
+
+/*
+ * SFR Memory map [80h - FFh]
+ * ---------------------------------------------------------------
+ * F8 |      |      |      |      |      |      |      |      | FF
+ * F0 |   B  |      |      |      |      |      |      |      | F7
+ * E8 |      |      |      |      |      |      |      |      | EF
+ * E0 |  ACC |      |      |      |      |      |      |      | E7
+ * D8 |      |      |      |      |      |      |      |      | DF
+ * D0 |  PSW |      |      |      |      |      |      |      | D7
+ * C8 | T2CON|      |RCAP2L|RCAP2H|  TL2 |  TH2 |      |      | CF
+ * C0 |      |      |      |      |      |      |      |      | C7
+ * B8 |  IP  |      |      |      |      |      |      |      | BF
+ * B0 |  P3  |      |      |      |      |      |      |      | B7
+ * A8 |  IE  |      |      |      |      |      |      |      | AF
+ * A0 |  P2  |      |      |      |      |      |      |      | A7
+ * 98 | SCON | SBUF |      |      |      |      |      |      | 9F
+ * 90 |  P1  |      |      |      |      |      |      |      | 97
+ * 88 | TCON | TMOD |  TL0 |  TL1 |  TH0 |  TH1 |      |      | 8F
+ * 80 |  P0  |  SP  |  DPL |  DPH |      |      |      | PCON | 87
+ * ---------------------------------------------------------------
+ */
+
+/* Return as Text the name of the SFR register at Address if any */
+static int
+cpu8051_SFRMemInfo(unsigned int Address, char *Text)
+{
+       switch (Address) {
+       case 0x80: return sprintf(Text, "P0");
+       case 0x81: return sprintf(Text, "SP");
+       case 0x82: return sprintf(Text, "DPL");
+       case 0x83: return sprintf(Text, "DPH");
+       case 0x87: return sprintf(Text, "PCON");
+       case 0x88: return sprintf(Text, "TCON");
+       case 0x89: return sprintf(Text, "TMOD");
+       case 0x8A: return sprintf(Text, "TL0");
+       case 0x8B: return sprintf(Text, "TL1");
+       case 0x8C: return sprintf(Text, "TH0");
+       case 0x8D: return sprintf(Text, "TH1");
+       case 0x90: return sprintf(Text, "P1");
+       case 0x98: return sprintf(Text, "SCON");
+       case 0x99: return sprintf(Text, "SBUF");
+       case 0xA0: return sprintf(Text, "P2");
+       case 0xA8: return sprintf(Text, "IE");
+       case 0xB0: return sprintf(Text, "P3");
+       case 0xB8: return sprintf(Text, "IP");
+       case 0xC8: return sprintf(Text, "T2CON");
+       case 0xCA: return sprintf(Text, "RCAP2L");
+       case 0xCB: return sprintf(Text, "RCAP2H");
+       case 0xCC: return sprintf(Text, "TL2");
+       case 0xCD: return sprintf(Text, "TH2");
+       case 0xD0: return sprintf(Text, "PSW");
+       case 0xE0: return sprintf(Text, "ACC");
+       case 0xF0: return sprintf(Text, "B");
+       default: return sprintf(Text, "%.2XH", Address);
+       }
+}
+
+/* Return as Text the decoded BitAddress */
+static void
+cpu8051_IntMemBitInfo(uint8_t bit_address, char *text)
+{
+       uint8_t byte_address;
+       uint8_t bit_number;
+       int len;
+
+       cpu8051_convert_bit_address(bit_address, &byte_address, &bit_number);
+
+       len = cpu8051_SFRMemInfo(byte_address, text);
+       sprintf(&text[len], ".%X", bit_address);
+}
+
+/* Get instruction size from opcode */
+int
+cpu8051_get_instruction_size(unsigned char opcode)
+{
+       return InstSizesTbl[opcode];
+}
+
+/* Display instruction mnemonic. */
+void
+cpu8051_disasm_mnemonic(unsigned char OpCode, char *buf)
+{
+       sprintf(buf, "%s", InstTextTbl[InstTypesTbl[OpCode]]);
+}
+
+/* Disasm instruction arguments starting at address into a text string */
+void
+cpu8051_disasm_args(unsigned int address, char *buf)
+{
+       int len = 0;
+       char TextTmp[20];
+       unsigned char OpCode;
+       int ArgTblOfs;
+       int i;
+
+       OpCode = memory_read8(PGM_MEM_ID, address);
+       ArgTblOfs = OpCode << 2;
+       address++;
+
+       /*
+        * MOV direct, direct (OpCode 85h) is peculiar, the operands
+        * are inverted
+        */
+       if (OpCode == 0x85) {
+               cpu8051_SFRMemInfo(memory_read8(PGM_MEM_ID, address + 1),
+                                  TextTmp);
+               len += sprintf(&buf[len], "%s,", TextTmp);
+               cpu8051_SFRMemInfo(memory_read8(PGM_MEM_ID, address),
+                                  TextTmp);
+               len += sprintf(&buf[len], "%s", TextTmp);
+               address += 2;
+               return;
+       }
+
+       for (i = 1; i <= InstArgTbl[ArgTblOfs]; i++) {
+               switch (InstArgTbl[ArgTblOfs + i]) {
+               case ADDR11: {
+                       len += sprintf(&buf[len],
+                                      "%.4XH", ((OpCode << 3) & 0xF00) +
+                                      (memory_read8(PGM_MEM_ID, address)));
+                       address++;
+                       break;
+               }
+               case ADDR16: {
+                       len += sprintf(
+                               &buf[len], "%.4XH",
+                               ((memory_read8(PGM_MEM_ID, address) << 8) +
+                                memory_read8(PGM_MEM_ID, address + 1)));
+                       address += 2;
+                       break;
+               }
+               case DIRECT: {
+                       cpu8051_SFRMemInfo(memory_read8(PGM_MEM_ID, address),
+                                          TextTmp);
+                       len += sprintf(&buf[len], "%s", TextTmp);
+                       address++;
+                       break;
+               }
+               case BITADDR: {
+                       cpu8051_IntMemBitInfo(
+                               (memory_read8(PGM_MEM_ID, address) & 0xF8),
+                               TextTmp);
+                       len += sprintf(&buf[len], "%s.%X" , TextTmp,
+                                      (memory_read8(PGM_MEM_ID, address) & 7));
+                       address++;
+                       break;
+               }
+               case RELADDR: {
+                       address++;
+                       len += sprintf(&buf[len], "%.4XH", (address & 0xFF00) +
+                                      (((address & 0xFF) +
+                                        memory_read8(PGM_MEM_ID,
+                                                     address - 1)) & 0xFF));
+                       break;
+               }
+               case DATAIMM: {
+                       len += sprintf(&buf[len], "#%.2XH",
+                                      memory_read8(PGM_MEM_ID, address));
+                       address++;
+                       break;
+               }
+               case DATA16: {
+                       len += sprintf(&buf[len], "#%.4XH",
+                                      ((memory_read8(PGM_MEM_ID,
+                                                     address) << 8) +
+                                       memory_read8(PGM_MEM_ID, address+1)));
+                       address += 2;
+                       break;
+               }
+               case CBITADDR: {
+                       cpu8051_IntMemBitInfo((memory_read8(PGM_MEM_ID,
+                                                           address) & 0xF8),
+                                             TextTmp);
+                       len += sprintf(&buf[len], "/%s.%X", TextTmp,
+                                      (memory_read8(PGM_MEM_ID, address) & 7));
+                       address++;
+                       break;
+               }
+               default: {
+                       len += sprintf(&buf[len], "%s",
+                                      ArgsTextTbl[InstArgTbl[ArgTblOfs + i]]);
+               }
+               }
+               if (i < InstArgTbl[ArgTblOfs])
+                       len += sprintf(&buf[len], ",");
+       }
+}
+
+/* Disasm one instruction at Address into a Text string */
+int
+cpu8051_Disasm(unsigned int Address, char *Text)
+{
+       int len = 0;
+       char TextTmp[20];
+       unsigned char OpCode;
+       int ArgTblOfs;
+       int InstSize;
+       int i;
+
+       /* Display address. */
+       len += sprintf(Text, " %.4X ", Address);
+
+       OpCode = memory_read8(PGM_MEM_ID, Address);
+       InstSize = InstSizesTbl[OpCode];
+
+       /* Display hex bytes. */
+       for (i = 0; i < InstSize; i++)
+               len += sprintf(&Text[len], " %.2X",
+                                     memory_read8(PGM_MEM_ID, Address + i));
+
+       Address++;
+
+       /* Padd remaining area with spaces. */
+       for (; len < 17;)
+               len += sprintf(&Text[len], " ");
+
+       /* Display instruction mnemonic. */
+       len += sprintf(&Text[len], "%s ",
+                             InstTextTbl[InstTypesTbl[OpCode]]);
+       ArgTblOfs = OpCode << 2;
+
+       /* Padd remaining area with spaces. */
+       for (; len < 25;)
+               len += sprintf(&Text[len], " ");
+
+       /* Display instruction arguments. */
+
+       /*
+        * MOV direct, direct (OpCode 85h) is peculiar, the operands
+        * are inverted
+        */
+       if (OpCode == 0x85) {
+               cpu8051_SFRMemInfo(memory_read8(PGM_MEM_ID, Address + 1),
+                                  TextTmp);
+               len += sprintf(&Text[len], "%s,", TextTmp);
+               cpu8051_SFRMemInfo(memory_read8(PGM_MEM_ID, Address),
+                                  TextTmp);
+               len += sprintf(&Text[len], "%s", TextTmp);
+               Address += 2;
+               return InstSize;
+       }
+
+       for (i = 1; i <= InstArgTbl[ArgTblOfs]; i++) {
+               switch (InstArgTbl[ArgTblOfs + i]) {
+               case ADDR11: {
+                       len += sprintf(&Text[len],
+                                      "%.4XH", ((OpCode << 3) & 0xF00) +
+                                      (memory_read8(PGM_MEM_ID, Address)));
+                       Address++;
+                       break;
+               }
+               case ADDR16: {
+                       len += sprintf(
+                               &Text[len], "%.4XH",
+                               ((memory_read8(PGM_MEM_ID, Address) << 8) +
+                                memory_read8(PGM_MEM_ID, Address + 1)));
+                       Address += 2;
+                       break;
+               }
+               case DIRECT: {
+                       cpu8051_SFRMemInfo(memory_read8(PGM_MEM_ID, Address),
+                                          TextTmp);
+                       len += sprintf(&Text[len], "%s", TextTmp);
+                       Address++;
+                       break;
+               }
+               case BITADDR: {
+                       cpu8051_IntMemBitInfo(
+                               (memory_read8(PGM_MEM_ID, Address) & 0xF8),
+                               TextTmp);
+                       len += sprintf(&Text[len], "%s.%X" , TextTmp,
+                                      (memory_read8(PGM_MEM_ID, Address) & 7));
+                       Address++;
+                       break;
+               }
+               case RELADDR: {
+                       Address++;
+                       len += sprintf(&Text[len], "%.4XH", (Address & 0xFF00) +
+                                      (((Address & 0xFF) +
+                                        memory_read8(PGM_MEM_ID,
+                                                     Address - 1)) & 0xFF));
+                       break;
+               }
+               case DATAIMM: {
+                       len += sprintf(&Text[len], "#%.2XH",
+                                      memory_read8(PGM_MEM_ID, Address));
+                       Address++;
+                       break;
+               }
+               case DATA16: {
+                       len += sprintf(&Text[len], "#%.4XH",
+                                      ((memory_read8(PGM_MEM_ID,
+                                                     Address) << 8) +
+                                       memory_read8(PGM_MEM_ID, Address+1)));
+                       Address += 2;
+                       break;
+               }
+               case CBITADDR: {
+                       cpu8051_IntMemBitInfo((memory_read8(PGM_MEM_ID,
+                                                           Address) & 0xF8),
+                                             TextTmp);
+                       len += sprintf(&Text[len], "/%s.%X", TextTmp,
+                                      (memory_read8(PGM_MEM_ID, Address) & 7));
+                       Address++;
+                       break;
+               }
+               default: {
+                       len += sprintf(&Text[len], "%s",
+                                      ArgsTextTbl[InstArgTbl[ArgTblOfs + i]]);
+               }
+               }
+               if (i < InstArgTbl[ArgTblOfs])
+                       len += sprintf(&Text[len], ",");
+       }
+
+       return InstSize;
+}
diff --git a/src/common/cpu8051.h b/src/common/cpu8051.h
new file mode 100644 (file)
index 0000000..adb96c8
--- /dev/null
@@ -0,0 +1,116 @@
+/*
+ * cpu8051.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 CPU8051_H
+#define CPU8051_H 1
+
+#include <stdint.h>
+
+/* Maximum number of BreakPoints */
+#define MAXBP 32
+
+#define INTERRUPT_0 (0)
+#define INTERRUPT_1 (1)
+#define INTERRUPT_2 (2)
+#define INTERRUPT_3 (3)
+#define INTERRUPT_4 (4)
+#define INTERRUPT_5 (5)
+#define INTERRUPT_MASK(n) (1 << n)
+
+#define INTERRUPT_PRIORITY_HIGH     (1)
+#define INTERRUPT_PRIORITY_LOW      (0)
+
+struct cpu8051_t {
+       unsigned int pc; /* Program counter */
+       unsigned long clock;
+       int active_priority;
+       int bp_count;
+       unsigned int bp[MAXBP]; /* List of breakpoints */
+};
+
+/* Exported variables */
+#undef _SCOPE_
+#ifdef CPU8051_M
+#  define _SCOPE_ /**/
+#else
+#  define _SCOPE_ extern
+#endif
+
+_SCOPE_ struct cpu8051_t cpu8051;
+
+int
+IsBreakpoint(unsigned int Address);
+
+int
+IsStoppoint(unsigned int address);
+
+void
+ShowBreakpoints(void);
+
+void
+SetBreakpoint(unsigned int Address);
+
+void
+ClearBreakpoint(unsigned int Address);
+
+void
+ToggleBreakpoint(unsigned int Address);
+
+void
+cpu8051_init(void);
+
+void
+cpu8051_Exec(void);
+
+void
+cpu8051_Reset(void);
+
+void
+cpu8051_WriteD(unsigned int Address, unsigned char Value);
+
+void
+cpu8051_WriteI(unsigned int Address, unsigned char Value);
+
+void
+cpu8051_WriteB(uint8_t bit_address, uint8_t value);
+
+unsigned char
+cpu8051_ReadD(unsigned int Address);
+
+unsigned char
+cpu8051_ReadI(unsigned int Address);
+
+unsigned char
+cpu8051_ReadB(uint8_t bit_address);
+
+int
+cpu8051_get_instruction_size(unsigned char opcode);
+
+void
+cpu8051_disasm_mnemonic(unsigned char OpCode, char *buf);
+
+void
+cpu8051_disasm_args(unsigned int address, char *buf);
+
+int
+cpu8051_Disasm(unsigned int Address, char *Text);
+
+#endif /* CPU8051_H */
diff --git a/src/common/hexfile.c b/src/common/hexfile.c
new file mode 100644 (file)
index 0000000..6411166
--- /dev/null
@@ -0,0 +1,186 @@
+/*
+ * Functions for loading an Intel HEX file.
+ *
+ * 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 <unistd.h>
+#include <stdio.h>
+#include <stdlib.h>
+
+#if STDC_HEADERS
+#  include <string.h>
+#elif HAVE_STRINGS_H
+#  include <strings.h>
+#endif
+
+#include "common.h"
+#include "memory.h"
+
+/* Convert integer to ASCII hex string. */
+void
+int2asciihex(int val, char *str, int width)
+{
+       if (width == 1)
+               sprintf(str , "%.1X", (u_int8_t) val);
+       else if (width == 2)
+               sprintf(str , "%.2X", (u_int8_t) val);
+       else if (width == 4)
+               sprintf(str , "%.4X", (u_int16_t) val);
+       else
+               sprintf(str , "Err");
+}
+
+/* Convert ASCII hex string to integer. */
+int
+asciihex2int(char *str)
+{
+       int val;
+
+       sscanf(str, "%X", &val);
+
+       return val;
+}
+
+/* Convert an ascii string to an hexadecimal number. */
+unsigned int
+Ascii2Hex(char *istring, int length)
+{
+       unsigned int result = 0;
+       int i, ascii_code;
+
+       if (!length || (length > (int) strlen(istring)))
+               length = strlen(istring);
+
+       for (i = 0; i < length; i++) {
+               ascii_code = istring[i];
+               if (ascii_code > 0x39)
+                       ascii_code &= 0xDF;
+
+               if ((ascii_code >= 0x30 && ascii_code <= 0x39) ||
+                    (ascii_code >= 0x41 && ascii_code <= 0x46)) {
+                       ascii_code -= 0x30;
+                       if (ascii_code > 9)
+                               ascii_code -= 7;
+
+                       result <<= 4;
+                       result += ascii_code;
+               } else {
+                       printf("%s: In Ascii2Hex(), syntax error.\n", PACKAGE);
+                       printf("  str=%s, length=%d\n", istring, length);
+               }
+       }
+       return result;
+}
+
+void
+LoadHexFile(const char *filename)
+{
+       int i, j, RecLength, LoadOffset, RecType, Data, Checksum;
+
+#define LINE_BUFFER_LEN 256
+       FILE *fp;
+       int status;
+       char line[LINE_BUFFER_LEN];
+
+       if (filename == NULL) {
+               printf("%s: No file specified\n", PACKAGE);
+               exit(EXIT_FAILURE);
+       }
+
+       /* Trying to open the file. */
+       fp = fopen(filename, "r");
+       if (fp == NULL) {
+               perror(filename);
+               /*ErrorLocation(__FILE__, __LINE__);*/
+               exit(EXIT_FAILURE);
+       }
+
+       /* Reading one line of data from the hex file. */
+       /* char *fgets(char *s, int size, FILE *stream);
+          Reading stops after an EOF or a newline. If a newline is read, it is
+          stored into the buffer.  A '\0'  is  stored after the last character
+          in the buffer.
+       */
+       while (fgets(line, LINE_BUFFER_LEN, fp) != NULL) {
+               i = 0;
+               Checksum = 0;
+
+               if (line[i++] != ':') {
+                       printf("%s: line not beginning with \":\"\n", PACKAGE);
+                       goto close_file;
+               }
+
+               RecLength = Ascii2Hex(&line[i], 2);
+               i += 2;
+               Checksum += RecLength;
+
+               LoadOffset = Ascii2Hex(&line[i], 4);
+               Checksum += LoadOffset / 256;
+               Checksum += LoadOffset % 256;
+               i += 4;
+
+               RecType = Ascii2Hex(&line[i], 2);
+               i += 2;
+               Checksum += RecType;
+
+               if (RecType == 1) {
+                       Checksum += Ascii2Hex(&line[i], 2);
+                       Checksum &= 0x000000FF;
+
+                       if (Checksum) {
+                               /* Error. */
+                               printf("%s: Invalid format\n", PACKAGE);
+                               goto close_file;
+                       } else {
+                               /* OK */
+                               goto close_file;
+                       }
+               }
+
+               for (j = 0; j < RecLength; j++) {
+                       Data = Ascii2Hex(&line[i], 2);
+                       memory_write8(PGM_MEM_ID,
+                                     (unsigned int)(LoadOffset + j),
+                                     (unsigned char)Data);
+                       i += 2;
+                       Checksum += Data;
+               }
+
+               RecType = Ascii2Hex(&line[i], 2);
+               Checksum += RecType;
+               Checksum &= 0x000000FF;
+
+               if (Checksum) {
+                       printf("%s: Invalid format\n", PACKAGE);
+                       goto close_file;
+               }
+       }
+
+close_file:
+       status = fclose(fp);
+       if (status != EXIT_SUCCESS) {
+               fprintf(stderr, "%s: Error closing hex file.\n", PACKAGE);
+               /*ErrorLocation(__FILE__, __LINE__);*/
+               exit(EXIT_FAILURE);
+       }
+}
diff --git a/src/common/hexfile.h b/src/common/hexfile.h
new file mode 100644 (file)
index 0000000..0f46527
--- /dev/null
@@ -0,0 +1,37 @@
+/*
+ * hexfile.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 HEXFILE_H
+#define HEXFILE_H 1
+
+void
+int2asciihex(int val, char *str, int width);
+
+int
+asciihex2int(char *str);
+
+unsigned int
+Ascii2Hex(char *istring, int length);
+
+void
+LoadHexFile(const char *filename);
+
+#endif /* HEXFILE_H */
diff --git a/src/common/log.c b/src/common/log.c
new file mode 100644 (file)
index 0000000..b378575
--- /dev/null
@@ -0,0 +1,130 @@
+/*
+ * log.c -- debug functions for logging.
+ *
+ * Copyright (C) 2011 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.
+ */
+
+#include "config.h"
+
+#include <unistd.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <stdarg.h>
+#include <string.h>
+
+#include "common.h"
+#include "options.h"
+
+#define PREFIX_PACKAGE_NAME 1
+#define ADD_LINEFEED        1
+
+extern struct options_t options;
+
+static void
+log_prefix_package_name(FILE *stream, const char *severity)
+{
+#if PREFIX_PACKAGE_NAME
+       /* Printing the name of the program first if desired. */
+       fprintf(stream, "%s %s: ", PACKAGE_NAME, severity);
+#endif /* PREFIX_PACKAGE_NAME */
+}
+
+static void
+log_suffix_newline(FILE *stream)
+{
+#if ADD_LINEFEED
+       fprintf(stream, "\n");
+#endif /* ADD_LINEFEED */
+}
+
+void
+log_debug(const char *format, ...)
+{
+       FILE *stream = stdout;
+
+       if (options.log >= LOG_LEVEL_DEBUG) {
+               va_list ap;
+
+               log_prefix_package_name(stream, "debug");
+
+               va_start(ap, format);
+               vfprintf(stream, format, ap);
+               va_end(ap);
+
+               log_suffix_newline(stream);
+       }
+}
+
+void
+log_info(const char *format, ...)
+{
+       FILE *stream = stdout;
+
+       if (options.log >= LOG_LEVEL_INFO) {
+               va_list ap;
+
+               log_prefix_package_name(stream, "info");
+
+               va_start(ap, format);
+               vfprintf(stream, format, ap);
+               va_end(ap);
+
+               log_suffix_newline(stream);
+       }
+}
+
+void
+log_warn(const char *format, ...)
+{
+       FILE *stream = stderr;
+
+       if (options.log >= LOG_LEVEL_WARN) {
+               va_list ap;
+
+               log_prefix_package_name(stream, "warn");
+
+               va_start(ap, format);
+               vfprintf(stream, format, ap);
+               va_end(ap);
+
+               log_suffix_newline(stream);
+       }
+}
+
+void
+log_err(const char *format, ...)
+{
+       FILE *stream = stderr;
+       va_list ap;
+
+       log_prefix_package_name(stream, "error");
+
+       va_start(ap, format);
+       vfprintf(stream, format, ap);
+       va_end(ap);
+
+       log_suffix_newline(stream);
+}
+
+/* Log error message and exits with error code. */
+void
+log_fail(const char *format, ...)
+{
+       FILE *stream = stderr;
+       va_list ap;
+
+       log_prefix_package_name(stream, "error");
+
+       va_start(ap, format);
+       vfprintf(stream, format, ap);
+       va_end(ap);
+
+       log_suffix_newline(stream);
+
+       exit(EXIT_FAILURE);
+}
diff --git a/src/common/log.h b/src/common/log.h
new file mode 100644 (file)
index 0000000..6b3e2e9
--- /dev/null
@@ -0,0 +1,46 @@
+/*
+ * log.h
+ *
+ * Copyright (C) 2011 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.
+ */
+
+#ifndef LOG_H
+#define LOG_H 1
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <stdint.h>
+#include <errno.h>
+#include <string.h>
+
+#include "common.h"
+
+enum LOG_LEVEL {
+       LOG_LEVEL_ERR = 0, /* Display only errors */
+       LOG_LEVEL_WARN,    /* Display warnings */
+       LOG_LEVEL_INFO,    /* Display information messages */
+       LOG_LEVEL_DEBUG,   /* Display all messages */
+};
+
+void
+log_debug(const char *format, ...);
+
+void
+log_info(const char *format, ...);
+
+void
+log_warn(const char *format, ...);
+
+void
+log_err(const char *format, ...);
+
+/* Log error message and exits with error code. */
+void
+log_fail(const char *format, ...);
+
+#endif /* LOG_H */
diff --git a/src/common/memory.c b/src/common/memory.c
new file mode 100644 (file)
index 0000000..c5b2acf
--- /dev/null
@@ -0,0 +1,245 @@
+/*
+ * memory.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.
+ */
+
+#include <stdio.h>
+#include <string.h>
+
+#include "common.h"
+#include "cpu8051.h"
+#include "reg8051.h"
+#include "hexfile.h"
+#include "memory.h"
+#include "options.h"
+
+struct mem_infos_t {
+       int size;
+       int max_size;
+       u_int8_t *buf;
+};
+
+struct mem_infos_t mem_infos[MEM_ID_COUNT];
+
+extern struct options_t options;
+
+/* Init each 8051 memory sections. */
+void
+memory_init(void)
+{
+       int k;
+       struct mem_infos_t *m;
+
+       /* Set desired and maximum allowable sizes for each memory type. */
+       mem_infos[PGM_MEM_ID].size = options.pram_size;
+       mem_infos[PGM_MEM_ID].max_size = PGM_MEM_MAX_SIZE;
+
+       mem_infos[INT_MEM_ID].size = options.iram_size;
+       mem_infos[INT_MEM_ID].max_size = INT_MEM_MAX_SIZE;
+
+       mem_infos[EXT_MEM_ID].size = options.xram_size;
+       mem_infos[EXT_MEM_ID].max_size = EXT_MEM_MAX_SIZE;
+
+       /* Verify if desired sizes are valid, and if so allocate memory. */
+       for (k = 0; k < MEM_ID_COUNT; k++) {
+               m = &mem_infos[k];
+
+               if (m->size > m->max_size) {
+                       log_err("Memory size invalid (max = %d)", m->max_size);
+                       exit(1);
+               }
+
+               m->buf = malloc(m->size);
+               if (m->buf == NULL) {
+                       log_err("%s", strerror(errno));
+                       exit(1);
+               }
+
+               memset(m->buf, 0x00, m->size);
+       }
+}
+
+void
+memory_clear(enum mem_id_t id)
+{
+       memset(mem_infos[id].buf, 0, mem_infos[id].size);
+}
+
+void
+memory_write8(enum mem_id_t id, unsigned long address, u_int8_t value)
+{
+       if (address >= mem_infos[id].max_size) {
+               printf("Error writing to memory ID: %d\n", id);
+               printf("  Address (%lu) greater than maximum memory size\n",
+                      address);
+               return;
+       } else
+               mem_infos[id].buf[address] = value;
+}
+
+void
+memory_sfr_write8(unsigned long address, u_int8_t value)
+{
+       /* SFR registers are from addresses $80 to $FF. */
+       memory_write8(INT_MEM_ID, address, value);
+}
+
+void
+memory_sfr_write_dptr(u_int16_t value)
+{
+       memory_write8(INT_MEM_ID, _DPTRHIGH_, value >> 8);
+       memory_write8(INT_MEM_ID, _DPTRLOW_, (uint8_t) value);
+}
+
+u_int8_t
+memory_read8(enum mem_id_t id, unsigned long address)
+{
+       if (address >= mem_infos[id].max_size) {
+               printf("Error reading from memory ID: %d\n", id);
+               printf("  Address (%lu) greater than maximum memory size\n",
+                      address);
+               return 0;
+       } else
+               return mem_infos[id].buf[address];
+}
+
+u_int8_t
+memory_sfr_read8(unsigned long address)
+{
+       /* SFR registers are from addresses $80 to $FF. */
+       return memory_read8(INT_MEM_ID, address);
+}
+
+u_int16_t
+memory_sfr_read_dptr(void)
+{
+       return (memory_read8(INT_MEM_ID, _DPTRHIGH_) << 8) +
+               memory_read8(INT_MEM_ID, _DPTRLOW_);
+}
+
+void
+stack_push8(uint8_t value)
+{
+       uint8_t sp;
+
+       sp = memory_read8(INT_MEM_ID, _SP_);
+
+       memory_write8(INT_MEM_ID, ++sp, value);
+       memory_write8(INT_MEM_ID, _SP_, sp); /* Save new stack pointer */
+}
+
+void
+stack_push16(uint16_t value)
+{
+       uint8_t sp;
+
+       sp = memory_read8(INT_MEM_ID, _SP_);
+
+       memory_write8(INT_MEM_ID, ++sp, (uint8_t) value); /* Write LSB */
+       memory_write8(INT_MEM_ID, ++sp, value >> 8);      /* Write MSB */
+       memory_write8(INT_MEM_ID, _SP_, sp); /* Save new stack pointer */
+}
+
+uint8_t
+stack_pop8(void)
+{
+       uint8_t sp;
+       uint8_t value;
+
+       sp = memory_read8(INT_MEM_ID, _SP_);
+
+       value = memory_read8(INT_MEM_ID, sp--);
+       memory_write8(INT_MEM_ID, _SP_, sp); /* Save new stack pointer */
+
+       return value;
+}
+
+uint16_t
+stack_pop16(void)
+{
+       uint8_t sp;
+       uint16_t value;
+
+       sp = memory_read8(INT_MEM_ID, _SP_);
+
+       value = memory_read8(INT_MEM_ID, sp--) << 8; /* Read MSB */
+       value |= memory_read8(INT_MEM_ID, sp--);     /* Read LSB */
+       memory_write8(INT_MEM_ID, _SP_, sp); /* Save new stack pointer */
+
+       return value;
+}
+
+/* Read a 16-bit address from PGM memory, starting at <base> offset */
+uint16_t
+pgm_read_addr16(uint16_t base)
+{
+       uint16_t addr;
+
+       addr = memory_read8(PGM_MEM_ID, base) << 8; /* MSB */
+       addr |= memory_read8(PGM_MEM_ID, base + 1); /* LSB */
+
+       return addr;
+}
+
+/* Dump memory */
+void
+DumpMem(char *Address, char *Asize, int memory_id)
+{
+       unsigned int MemAddress;
+       int size;
+       int Offset, Column;
+
+       if (strlen(Address) != 0) {
+               if (STREQ(Address, "PC"))
+                       MemAddress = cpu8051.pc;
+               else
+                       MemAddress = Ascii2Hex(Address, strlen(Address));
+       } else {
+               MemAddress = 0;
+       }
+
+       if (strlen(Asize) != 0) {
+               size = Ascii2Hex(Asize, strlen(Asize));
+       } else {
+               size = 256; /* Default size if not specified. */
+       }
+
+       for (Offset = 0; Offset < size; Offset += 16) {
+               unsigned char data[16];
+
+               printf("%.4X ", MemAddress + Offset);
+
+               for (Column = 0; Column < 16; Column++) {
+                       data[Column] = memory_read8(memory_id, MemAddress +
+                                                   Offset + Column);
+                       printf(" %.2X", (int) data[Column]);
+               }
+               printf("  ");
+
+               /* Display any ASCII characters */
+               for (Column = 0; Column < 16; Column++) {
+                       if ((int) data[Column] >= 32 &&
+                           (int) data[Column] <= 126) {
+                               printf("%c", data[Column]);
+                       } else
+                               printf(".");
+               }
+               printf("\n");
+       }
+}
diff --git a/src/common/memory.h b/src/common/memory.h
new file mode 100644 (file)
index 0000000..fee41a6
--- /dev/null
@@ -0,0 +1,88 @@
+/*
+ * memory.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 MEMORY_H
+#define MEMORY_H 1
+
+#include <sys/types.h>
+
+#define PGM_MEM_MAX_SIZE 65536
+/*
+ *   Direct addressing $00 to $7F = IRAM (8051)
+ *   Direct addressing $80 to $FF = SFR  (8051)
+ * Indirect addressing $80 to $FF = IRAM (8052)
+ */
+#define INT_MEM_MAX_SIZE   256
+#define EXT_MEM_MAX_SIZE 65536
+
+#define PGM_MEM_DEFAULT_SIZE 8192
+#define EXT_MEM_DEFAULT_SIZE 1024
+
+enum mem_id_t {
+       PGM_MEM_ID,
+       INT_MEM_ID,
+       EXT_MEM_ID,
+       MEM_ID_COUNT
+};
+
+void
+memory_init(void);
+
+void
+memory_clear(enum mem_id_t id);
+
+void
+memory_write8(enum mem_id_t id, unsigned long address, u_int8_t value);
+
+void
+memory_sfr_write8(unsigned long address, u_int8_t value);
+
+void
+memory_sfr_write_dptr(u_int16_t value);
+
+u_int8_t
+memory_read8(enum mem_id_t id, unsigned long address);
+
+u_int8_t
+memory_sfr_read8(unsigned long address);
+
+u_int16_t
+memory_sfr_read_dptr(void);
+
+void
+stack_push8(uint8_t value);
+
+void
+stack_push16(uint16_t value);
+
+uint8_t
+stack_pop8(void);
+
+uint16_t
+stack_pop16(void);
+
+uint16_t
+pgm_read_addr16(uint16_t base);
+
+void
+DumpMem(char *Address, char *Asize, int memory_id);
+
+#endif /* MEMORY_H */
diff --git a/src/common/opcode2c.pl b/src/common/opcode2c.pl
new file mode 100755 (executable)
index 0000000..035c718
--- /dev/null
@@ -0,0 +1,851 @@
+#!/usr/bin/perl
+#
+# 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.
+
+open INST_DEF, ">instructions_8051.h" or die "Error creating <instructions_8051.h> : $!\n";
+open INST_IMP, ">instructions_8051.c" or die "Error creating <instructions_8051.c> : $!\n";
+open OPCODELST, "opcodes.lst" or die "Error opening <opcodes.lst> : $!\n";
+open DISASM_H, ">disasm.h" or die "Error creating <disasm.h> : $!\n";
+
+# Write GPL license
+# Argument 0 is file descriptor
+sub write_header
+{
+    my $fd = $_[0];
+
+    print $fd " *\n";
+    print $fd " * Do not modify this file directly, as it was created by opcode2c.pl\n";
+    print $fd " * Any modifications made directly to this file will be lost.\n";
+    print $fd " *\n";
+    print $fd " * Copyright (C) 1999 Jonathan St-André\n";
+    print $fd " * Copyright (C) 1999 Hugo Villeneuve <hugo@hugovil.com>\n";
+    print $fd " *\n";
+    print $fd " * This program is free software; you can redistribute it and/or modify\n";
+    print $fd " * it under the terms of the GNU General Public License as published by\n";
+    print $fd " * the Free Software Foundation; either version 2 of the License, or\n";
+    print $fd " * (at your option) any later version.\n";
+    print $fd " *\n";
+    print $fd " * This program is distributed in the hope that it will be useful,\n";
+    print $fd " * but WITHOUT ANY WARRANTY; without even the implied warranty of\n";
+    print $fd " * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n";
+    print $fd " * GNU General Public License for more details.\n";
+    print $fd " *\n";
+    print $fd " * You should have received a copy of the GNU General Public License\n";
+    print $fd " * along with this program; if not, write to the Free Software\n";
+    print $fd " * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA.\n";
+    print $fd " */\n\n";
+}
+
+# Write C function source code line to INST_IMP file.
+# Prefix each line with a tab (indentation) and add newline character at the end.
+sub cfw
+{
+    print INST_IMP "\t",$_[0],"\n";
+}
+
+# Header for instructions_8051.c
+print INST_IMP "/*\n";
+print INST_IMP " * instructions_8051.c\n";
+write_header(INST_IMP);
+print INST_IMP "/* Define only here, for not having extern scope on local variables. */\n";
+print INST_IMP "#define INSTRUCTIONS_8051_M 1\n\n\n";
+print INST_IMP "#include \"reg8051.h\"\n";
+print INST_IMP "#include \"cpu8051.h\"\n";
+print INST_IMP "#include \"memory.h\"\n";
+print INST_IMP "#include \"psw.h\"\n";
+print INST_IMP "#include \"instructions_8051.h\"\n\n\n";
+
+# Header for disasm.h
+print DISASM_H "/*\n";
+print DISASM_H " * disasm.h\n";
+write_header(DISASM_H);
+print DISASM_H "#ifndef DISASM_H\n";
+print DISASM_H "#define DISASM_H 1\n\n";
+
+$nbinst=0;
+$nbaddr=0;
+$nbargs=0;
+$instnumb=0;
+
+$ligne=<OPCODELST>;
+$ligne=<OPCODELST>;
+while($ligne=<OPCODELST>) {
+    chop $ligne;
+    if (length $ligne < 2) {next;}
+    @wordlist=split ' ',$ligne;
+    $nbword=@wordlist;
+    $instruction=$wordlist[2];
+    for($i=3;$i<($nbword-2);$i++) {$instruction="$instruction $wordlist[$i]";}
+
+    $a_instruction[$instnumb]=$instruction;
+    $a_bytes[$instnumb]=$wordlist[$nbword-2];
+    $a_cycles[$instnumb]=$wordlist[$nbword-1];
+    $a_opcodehex[$instnumb]=$wordlist[1];
+    $a_opcodebin[$instnumb]=$wordlist[0];
+
+    $instfunction[$instnumb]="CPU8051::OP_$wordlist[1]";
+
+    $instargs[$instnumb << 2]=$instargs[($instnumb << 2) + 1]=$instargs[($instnumb << 2) + 2]=$instargs[($instnumb << 2) + 3]=0;
+    if ($nbword > 5) {
+       @argslist=split /\,/,$wordlist[3];
+       $argslistsize=@argslist;
+       $instargs[$instnumb << 2]=$argslistsize;
+       for ($i=0;$i<$argslistsize;$i++) {
+           if (not exists $argstypes{$argslist[$i]}) {
+               $argstypes[$nbargs]=$argslist[$i];
+               $argstypes{$argslist[$i]}=$nbargs++;
+           }
+           $instargs[($instnumb << 2) + $i + 1]=$argstypes{$argslist[$i]};
+       }
+    }
+
+    if (not exists $insttext{$wordlist[2]}) {
+       $insttext[$nbinst]=$wordlist[2];
+       $insttext{$wordlist[2]}=$nbinst++;
+    }
+
+    $insttype[$instnumb]=$insttext{$wordlist[2]};
+
+    if ( not exists $addrmode{$wordlist[3]}) {
+       $addrmode[$nbaddr]=$wordlist[3];
+       $addrmode{$wordlist[3]}=$nbaddr++;
+    }
+
+    $nbbytes[$instnumb]=$wordlist[$nbword-2];
+
+    $instaddr[$instnumb]=$addrmode{$wordlist[3]};
+
+    $instnumb++;
+}
+# ------------------------------------------------------------------------------
+print DISASM_H "/*\n";
+print DISASM_H " * For all 256 opcodes, the value in this table gives the instruction type\n";
+print DISASM_H " * ex.: MOV, INC, CLR, CPL,...\n";
+print DISASM_H " * To know what is the instruction type, use\n";
+print DISASM_H " * the number as an offset in the InstTextTbl[]\n";
+print DISASM_H " */\n";
+print DISASM_H "static int InstTypesTbl[] = {\n";
+for($i=0;$i<256;$i++) {
+    print DISASM_H " $insttype[$i]";
+    ($i != 255) and print DISASM_H ",";
+    if (($i+1) % 16 == 0) { print DISASM_H "\n"; }
+}
+print DISASM_H "};\n";
+print DISASM_H "\n";
+# ------------------------------------------------------------------------------
+print DISASM_H "/* Size(in bytes) of each instruction (offset in table is instruction opcode) */\n";
+print DISASM_H "static int InstSizesTbl[] = {\n";
+for($i=0;$i<256;$i++) {
+    print DISASM_H " $nbbytes[$i]";
+    ($i != 255) and print DISASM_H ",";
+    if (($i+1) % 16 == 0) { print DISASM_H "\n"; }
+}
+print DISASM_H "};\n";
+print DISASM_H "\n";
+# ------------------------------------------------------------------------------
+print DISASM_H "/* List of instructions types referenced by InstTypesTbl[] */\n";
+$nbelement=@insttext;
+print DISASM_H "\#define InstTextTblLength $nbelement\n";
+$elementnb=0;
+print DISASM_H "static char *InstTextTbl[] = {\n";
+foreach $instruc (@insttext) {
+    print DISASM_H " \"$instruc\"";
+    ($elementnb++ < $nbelement-1) and print DISASM_H ",";
+    print DISASM_H "\n";
+}
+print DISASM_H "};\n";
+print DISASM_H "\n";
+# ------------------------------------------------------------------------------
+print DISASM_H "/*\n";
+print DISASM_H " * Table describing all arguments types of an instruction\n";
+print DISASM_H " * The table is indexed InstArgTbl[ opcode * 4]\n";
+print DISASM_H " * InstArgTbl[opcode*4 + 1] gives the number of arguments the instruction has\n";
+print DISASM_H " * InstArgTbl[opcode*4 + i] for i=1,2 and 3 give the type of each argument\n";
+print DISASM_H " * for most instructions, the 3rd argument isn't used\n";
+print DISASM_H " * the argument type is referecing to ArgsTextTbl[]\n";
+print DISASM_H " */\n";
+print DISASM_H "\#define InstArgTblLength 256\n";
+print DISASM_H "static int InstArgTbl[] = {\n";
+for($i=0;$i<1024;$i++) {
+    print DISASM_H " $instargs[$i]";
+    ($i != 1023) and print DISASM_H ",";
+    if (($i+1) % 16 == 0) { print DISASM_H "\n"; }
+}
+print DISASM_H "};\n";
+print DISASM_H "\n";
+# ------------------------------------------------------------------------------
+print DISASM_H "/*\n";
+print DISASM_H " * List all types of arguments available to instructions\n";
+print DISASM_H " * Referenced by InstArgsTbl[]\n";
+print DISASM_H " */\n";
+$nbelement=@argstypes;
+print DISASM_H "\#define ArgsTextTblLength $nbelement\n";
+$elementnb=0;
+print DISASM_H "static char *ArgsTextTbl[] = {\n";
+foreach $args (@argstypes) {
+    print DISASM_H " \"$args\"";
+    ($elementnb++ < $nbelement-1) and print DISASM_H ",";
+    print DISASM_H "\n";
+}
+print DISASM_H "};\n";
+print DISASM_H "\n";
+
+# ------------------------------------------------------------------------------
+for ($i=0 ; $i< 256; $i++) {
+    print INST_IMP "/*","*"x76,"\n";
+    print INST_IMP " * Instruction \"$a_instruction[$i]\" takes $a_cycles[$i] cycle(s) and $a_bytes[$i] byte(s).\n";
+    print INST_IMP " ","*"x76,"/\n";
+    print INST_IMP "int\n";
+    print INST_IMP "cpu8051_OP_$a_opcodehex[$i](void)\n";
+    print INST_IMP "{\n";
+
+    if( $i == 0x85 ) {
+       # Cas particulier pour MOV direct,direct -> src et dest sont inverses dans la memoire
+        print INST_IMP "  unsigned char srcaddr = memory_read8( PGM_MEM_ID, cpu8051.pc++ );\n";
+       print INST_IMP "  unsigned char source = cpu8051_ReadD( srcaddr );\n";
+       print INST_IMP "  unsigned char destaddr = memory_read8( PGM_MEM_ID, cpu8051.pc++ );\n";
+       print INST_IMP "  unsigned char destination = cpu8051_ReadD( destaddr );\n";
+       print INST_IMP "  destination = source;\n";
+       print INST_IMP "  cpu8051_WriteD( destaddr, destination );\n";
+    }
+    else {
+       if ($instargs[$i*4] > 0) {
+           $op_destination=$instargs[$i*4+1];
+           if ($op_destination == 0) { # addr11
+               cfw("unsigned int addr11 = ( ( memory_read8( PGM_MEM_ID, cpu8051.pc - 1 ) << 3 ) & 0xF00 ) + memory_read8( PGM_MEM_ID, cpu8051.pc );");
+               cfw("cpu8051.pc++;");
+           }
+           if ($op_destination == 1) { # addr16
+               cfw("uint16_t addr16 = pgm_read_addr16(cpu8051.pc);");
+               cfw("cpu8051.pc += 2;");
+           }
+           if ($op_destination == 2) { # A
+               cfw("unsigned char destination = cpu8051_ReadD( _ACC_ );");
+           }
+           if ($op_destination == 3) { # direct
+               cfw("unsigned char destaddr = memory_read8( PGM_MEM_ID, cpu8051.pc++ );");
+               cfw("unsigned char destination = cpu8051_ReadD( destaddr );");
+           }
+           if ($op_destination == 4) { # @R0
+               cfw("unsigned char destination = cpu8051_ReadI ( cpu8051_ReadD( BANKPSW + _R0_ ) );");
+           }
+           if ($op_destination == 5) { # @R1
+               cfw("unsigned char destination = cpu8051_ReadI ( cpu8051_ReadD( BANKPSW + _R1_ ) );");
+           }
+           if ($op_destination == 6) { # R0
+               cfw("unsigned char destination = cpu8051_ReadD( BANKPSW + _R0_ );");
+           }
+           if ($op_destination == 7) { # R1
+               cfw("unsigned char destination = cpu8051_ReadD( BANKPSW + _R1_ );");
+           }
+           if ($op_destination == 8) { # R2
+               cfw("unsigned char destination = cpu8051_ReadD( BANKPSW + _R2_ );");
+           }
+           if ($op_destination == 9) { # R3
+               cfw("unsigned char destination = cpu8051_ReadD( BANKPSW + _R3_ );");
+           }
+           if ($op_destination == 10) { # R4
+               cfw("unsigned char destination = cpu8051_ReadD( BANKPSW + _R4_ );");
+           }
+           if ($op_destination == 11) { # R5
+               cfw("unsigned char destination = cpu8051_ReadD( BANKPSW + _R5_ );");
+           }
+           if ($op_destination == 12) { # R6
+               cfw("unsigned char destination = cpu8051_ReadD( BANKPSW + _R6_ );");
+           }
+           if ($op_destination == 13) { # R7
+               cfw("unsigned char destination = cpu8051_ReadD( BANKPSW + _R7_ );");
+           }
+           if ($op_destination == 14) { # bitaddr
+               cfw("unsigned char destination, dstbitaddr = memory_read8( PGM_MEM_ID, cpu8051.pc++ );");
+               cfw("destination = cpu8051_ReadB( dstbitaddr );");
+           }
+           if ($op_destination == 15) { # reladdr
+               cfw("cpu8051.pc++;");
+               cfw("unsigned int destination = ((char) memory_read8(PGM_MEM_ID, cpu8051.pc - 1)) + cpu8051.pc;");
+           }
+           if ($op_destination == 16) { # #data
+               cfw("unsigned char destination = memory_read8( PGM_MEM_ID, cpu8051.pc++ );");
+           }
+           if ($op_destination == 17) { # C
+               cfw("unsigned char destination = psw_read_cy();");
+           }
+           if ($op_destination == 18) { # @A+DPTR
+               cfw("unsigned int destination = cpu8051_ReadD( _ACC_ ) + memory_sfr_read_dptr();");
+           }
+            if ($op_destination == 20) { # AB
+                cfw("unsigned char destination = cpu8051_ReadD( _ACC_ );");
+                cfw("unsigned char source = cpu8051_ReadD( _B_ );");
+            }
+           if ($op_destination == 21) { # DPTR
+               cfw("unsigned int destination = memory_sfr_read_dptr();");
+           }
+           if ($op_destination == 23) { # /bitaddr
+               cfw("unsigned char destination, dstbitaddr = memory_read8( PGM_MEM_ID, (cpu8051.pc)++ );");
+               cfw("destination = ( cpu8051_ReadB( dstbitaddr ) ^ 1 );");
+           }
+           if ($op_destination == 24) { # @DPTR
+               cfw("unsigned char destination = cpu8051_ReadI(memory_sfr_read_dptr());");
+           }
+       }
+
+       if ($instargs[$i*4] > 1) {
+           $op_source=$instargs[$i*4+2];
+           if ($op_source == 0) { # addr11
+               cfw("unsigned int addr11 = ( ( memory_read8( PGM_MEM_ID, cpu8051.pc - 1 ) << 3 ) & 0xF00 ) + memory_read8( PGM_MEM_ID, (cpu8051.pc)++ );");
+           }
+           if ($op_source == 1) { # addr16
+               cfw("uint16_t addr16 = pgm_read_addr16(cpu8051.pc);");
+               cfw("cpu8051.pc += 2;");
+           }
+           if ($op_source == 2) { # A
+               cfw("unsigned char source = cpu8051_ReadD( _ACC_ );");
+           }
+           if ($op_source == 3) { # direct
+               cfw("unsigned char srcaddr = memory_read8( PGM_MEM_ID, (cpu8051.pc)++ );");
+               cfw("unsigned char source = cpu8051_ReadD( srcaddr );");
+           }
+           if ($op_source == 4) { # @R0
+               cfw("unsigned char source = cpu8051_ReadI ( cpu8051_ReadD( BANKPSW + _R0_ ) );");
+           }
+           if ($op_source == 5) { # @R1
+               cfw("unsigned char source = cpu8051_ReadI ( cpu8051_ReadD( BANKPSW + _R1_ ) );");
+           }
+           if ($op_source == 6) { # R0
+               cfw("unsigned char source = cpu8051_ReadD( BANKPSW + _R0_ );");
+           }
+           if ($op_source == 7) { # R1
+               cfw("unsigned char source = cpu8051_ReadD( BANKPSW + _R1_ );");
+           }
+           if ($op_source == 8) { # R2
+               cfw("unsigned char source = cpu8051_ReadD( BANKPSW + _R2_ );");
+           }
+           if ($op_source == 9) { # R3
+               cfw("unsigned char source = cpu8051_ReadD( BANKPSW + _R3_ );");
+           }
+           if ($op_source == 10) { # R4
+               cfw("unsigned char source = cpu8051_ReadD( BANKPSW + _R4_ );");
+           }
+           if ($op_source == 11) { # R5
+               cfw("unsigned char source = cpu8051_ReadD( BANKPSW + _R5_ );");
+           }
+           if ($op_source == 12) { # R6
+               cfw("unsigned char source = cpu8051_ReadD( BANKPSW + _R6_ );");
+           }
+           if ($op_source == 13) { # R7
+               cfw("unsigned char source = cpu8051_ReadD( BANKPSW + _R7_ );");
+           }
+
+           if ($op_source == 14) { # bitaddr
+               cfw("unsigned char source, srcbitaddr = memory_read8( PGM_MEM_ID, (cpu8051.pc)++ );");
+               cfw("source = cpu8051_ReadB( srcbitaddr );");
+           }
+           if ($op_source == 15) { # reladdr
+               cfw("(cpu8051.pc)++;");
+               cfw("unsigned int source = ((char) memory_read8(PGM_MEM_ID, cpu8051.pc - 1)) + cpu8051.pc;");
+           }
+           if ($op_source == 16) { # #data
+               cfw("unsigned char source = memory_read8( PGM_MEM_ID, (cpu8051.pc)++ );");
+           }
+           if ($op_source == 17) { # C
+               cfw("unsigned char source = psw_read_cy();");
+           }
+           if ($op_source == 18) { # @A+DPTR
+               cfw("unsigned char source = memory_read8( PGM_MEM_ID, cpu8051_ReadD( _ACC_ ) + memory_sfr_read_dptr());");
+           }
+           if ($op_source == 19) { # @A+PC
+               cfw("unsigned char source = memory_read8( PGM_MEM_ID, cpu8051_ReadD( _ACC_ ) + ( ++cpu8051.pc ) );");
+           }
+           if ($op_source == 21) { # DPTR
+               cfw("unsigned int source = memory_sfr_read_dptr();");
+           }
+           if ($op_source == 22) { # #data16
+               cfw("uint16_t source = pgm_read_addr16(cpu8051.pc);");
+               cfw("cpu8051.pc += 2;");
+           }
+           if ($op_source == 23) { # /bitaddr
+               cfw("unsigned char source, srcbitaddr = memory_read8( PGM_MEM_ID, (cpu8051.pc)++ );");
+               cfw("source = ( cpu8051_ReadB( srcbitaddr ) ^ 1 );");
+           }
+           if ($op_source == 24) { # @DPTR
+               cfw("unsigned char source = cpu8051_ReadI(memory_sfr_read_dptr());");
+           }
+       }
+
+##############################################################################
+       $modifysrc=0;
+
+       # RR
+       if ($insttype[$i] == 3) {
+           cfw("destination = ( destination >> 1 ) | ( destination << 7 );");
+       }
+
+       # INC
+       if ($insttype[$i] == 4) {
+           cfw("destination++;");
+       }
+
+       # JBC
+       if ($insttype[$i] == 5) {
+           cfw("if ( destination == 1 ) { cpu8051.pc = source; destination = 0; }");
+       }
+
+       # ACALL
+       if ($insttype[$i] == 6) {
+           cfw("stack_push16(cpu8051.pc);");
+       }
+
+       # LCALL
+       if ($insttype[$i] == 7) {
+           cfw("stack_push16(cpu8051.pc);");
+       }
+
+       # RRC
+       if ($insttype[$i] == 8) {
+           cfw("unsigned char new_cy = destination & 0x01;");
+           cfw("destination = ( destination >> 1 ) | (psw_read_cy() << 7);");
+           cfw("psw_write_cy(new_cy);");
+       }
+
+       # DEC
+       if ($insttype[$i] == 9) {
+           cfw("destination--;");
+       }
+
+       # JB
+       if ($insttype[$i] == 10) {
+           cfw("if ( destination == 1 ) { cpu8051.pc = source; }");
+       }
+
+       # RET
+       if ($insttype[$i] == 11) {
+            cfw("cpu8051.pc = stack_pop16();");
+       }
+
+       # RL
+       if ($insttype[$i] == 12) {
+           cfw("destination = ( destination << 1 ) | ( destination >> 7 );");
+       }
+
+       # ADD
+       if ($insttype[$i] == 13) {
+           cfw("psw_clr_cy();");
+           cfw("psw_clr_ac();");
+           cfw("psw_clr_ov();");
+            # The Overflow (OV) bit is set if there is a carry-out of bit 6 or
+            # out of bit 7, but not both. In other words, if the addition of the
+            # Accumulator, operand and (in the case of ADDC) the Carry flag
+            # treated as signed values results in a value that is out of the
+            # range of a signed byte (-128 through +127) the Overflow flag is
+            # set. Otherwise, the Overflow flag is cleared.
+           cfw("if ( destination + source > 0xFF ) {");
+            # Carry from bit 7
+           cfw("   psw_set_cy();");
+            # If no carry from bit 6, set OV
+           cfw("   if (((destination & 0x7F) + (source & 0x7F)) < 0x80)");
+           cfw("       psw_set_ov();");
+            # If no carry from bit 7, but caary from bit 6, set OV
+           cfw("} else if (((destination & 0x7F) + (source & 0x7F)) > 0x7F )  psw_set_ov();");
+           cfw("if (((destination & 0x0F) + (source & 0x0F)) > 0x0F)  psw_set_ac();");
+           cfw("destination += source;");
+       }
+
+       # JNB
+       if ($insttype[$i] == 14) {
+           cfw("if ( destination == 0 ) { cpu8051.pc = source; }");
+       }
+
+       # RETI
+       if ($insttype[$i] == 15) {
+           cfw("cpu8051.active_priority = -1;");
+            cfw("cpu8051.pc = stack_pop16();");
+       }
+
+       # RLC
+       if ($insttype[$i] == 16) {
+           cfw("unsigned char new_cy = destination & 0x80;");
+           cfw("destination = ( destination << 1 ) | psw_read_cy();");
+           cfw("psw_write_cy(new_cy);");
+       }
+
+       # ADDC
+       if ($insttype[$i] == 17) {
+           cfw("unsigned char carryflag = psw_read_cy();");
+           cfw("psw_clr_cy();");
+           cfw("psw_clr_ac();");
+           cfw("psw_clr_ov();");
+           cfw("if ( destination + source + carryflag > 0xFF ) {");
+           cfw("   psw_set_cy();");
+           cfw("   if (((destination & 0x7F) + (source & 0x7F) + carryflag) < 0x80);");
+           cfw("       psw_set_ov();");
+           cfw("} else if (((destination & 0x7F) + (source & 0x7F) + carryflag) > 0x7F)  psw_set_ov();");
+           cfw("if (((destination & 0x0F) + (source & 0x0F) + carryflag) > 0x0F)  psw_set_ac();");
+           cfw("destination += source;");
+       }
+
+       # JC
+       if ($insttype[$i] == 18) {
+           cfw("if (psw_read_cy()) { cpu8051.pc = destination; }");
+       }
+
+       # ORL
+       if ($insttype[$i] == 19) {
+            cfw("destination |= source;");
+       }
+
+       # JNC
+       if ($insttype[$i] == 20) {
+           cfw("if (psw_read_cy() == 0) { cpu8051.pc = destination; }");
+       }
+
+       # ANL
+       if ($insttype[$i] == 21) {
+            cfw("destination &= source;");
+       }
+
+       # JZ
+       if ($insttype[$i] == 22) {
+           cfw("if ( cpu8051_ReadD( _ACC_ ) == 0 ) { cpu8051.pc = destination; }");
+       }
+
+       # XRL
+       if ($insttype[$i] == 23) {
+           cfw("destination ^= source;");
+       }
+
+       # JNZ
+       if ($insttype[$i] == 24) {
+           cfw("if ( cpu8051_ReadD( _ACC_ ) != 0 ) { cpu8051.pc = destination; }");
+       }
+
+       # JMP
+       if ($insttype[$i] == 25) {
+           cfw("cpu8051.pc = destination;");
+       }
+
+       # MOV
+       if ($insttype[$i] == 26) {
+           cfw("destination = source;");
+       }
+
+       # SJMP
+       if ($insttype[$i] == 27) {
+           cfw("cpu8051.pc = destination;");
+       }
+
+       # MOVC
+       if ($insttype[$i] == 28) {
+           cfw("destination = source;");
+       }
+
+       # DIV
+       if ($insttype[$i] == 29) {
+            # A = destination
+            # B = source
+           cfw("psw_clr_cy();");
+            # If B is zero, the OV flag will be set indicating a
+            # division-by-zero error
+           cfw("if (source != 0) {");
+           cfw("    cpu8051_WriteD(_ACC_, destination/source);");
+            cfw("    cpu8051_WriteD( _B_, destination%source);");
+           cfw("    psw_clr_ov();");
+           cfw("} else {");
+           cfw("    psw_set_ov();");
+           cfw("}");
+       }
+
+       # SUBB
+       if ($insttype[$i] == 30) {
+           cfw("unsigned char carryflag = psw_read_cy();");
+           cfw("psw_clr_cy();");
+           cfw("psw_clr_ac();");
+           cfw("psw_clr_ov();");
+           cfw("if ( destination < ( source + carryflag ) ) {");
+           cfw("  psw_set_cy();");
+           cfw("  if ((destination & 0x7F) > ((source + carryflag) & 0x7F))  psw_set_ov();");
+           cfw("} else if ((destination & 0x7F) < ((source + carryflag) & 0x7F))   psw_set_ov();");
+           cfw("if ((destination & 0x0F) < ((source + carryflag) & 0x0F))   psw_set_ac();");
+           cfw("destination -= source + carryflag;");
+       }
+
+       # MUL
+       if ($insttype[$i] == 31) {
+            # A = destination
+            # B = source
+           cfw("psw_clr_cy();");
+           cfw("cpu8051_WriteD(_ACC_, destination * source);");
+            cfw("cpu8051_WriteD(_B_, (destination * source) / 0x100);");
+           cfw("if (cpu8051_ReadD(_B_) > 0)");
+           cfw("    psw_set_ov();");
+           cfw("else");
+           cfw("    psw_clr_ov();");
+       }
+
+       # CPL
+       if ($insttype[$i] == 33) {
+           if ($instargs[$i*4+1] == 2) { cfw("destination ^= 0xFF;"); }
+           else { cfw("destination ^= 0x01;"); }
+       }
+
+       # CJNE
+       if ($insttype[$i] == 34) {
+           cfw("unsigned int reladdr = ((char) memory_read8(PGM_MEM_ID, cpu8051.pc)) + (cpu8051.pc + 1);");
+           cfw("psw_clr_cy();");
+           cfw("if ( destination < source ) psw_set_cy();");
+           cfw("if ( destination != source ) cpu8051.pc = reladdr; else cpu8051.pc++;");
+       }
+
+       # PUSH
+       if ($insttype[$i] == 35) {
+           cfw("stack_push8(destination);");
+       }
+
+       # CLR
+       if ($insttype[$i] == 36) {
+           cfw("destination = 0;");
+       }
+
+       # SWAP
+       if ($insttype[$i] == 37) {
+           cfw("destination = ( destination << 4 ) + ( destination >> 4 );");
+       }
+
+       # XCH
+       if ($insttype[$i] == 38) {
+           cfw("unsigned char tmpval = destination;");
+           cfw("destination = source; source = tmpval;");
+           $modifysrc=1;
+       }
+
+       # POP
+       if ($insttype[$i] == 39) {
+            cfw("destination = stack_pop8();");
+       }
+
+       # SETB
+       if ($insttype[$i] == 40) {
+           cfw("destination = 1;");
+       }
+
+       # DA
+       if ($insttype[$i] == 41) {
+           cfw("if (((destination & 0x0F) > 9) || psw_read_ac()) {");
+           cfw("   if ( ( destination + 6 ) > 0xFF)  psw_set_cy();");
+           cfw("   destination += 6;");
+           cfw("}");
+           cfw("if ( psw_read_cy() || ( ( destination & 0xF0 ) > 0x90 ) ) {");
+           cfw("   if ( ( destination + 0x60 ) > 0xFF ) psw_set_cy();");
+           cfw("   destination += 0x60;");
+           cfw("}");
+       }
+
+       # DJNZ
+       if ($insttype[$i] == 42) {
+           cfw("destination--;");
+           cfw("if ( destination != 0 ) cpu8051.pc = source;");
+       }
+
+       # XCHD
+       if ($insttype[$i] == 43) {
+           cfw("unsigned char tmpval = ( destination & 0x0F );");
+           cfw("destination = ( destination & 0xF0 ) + ( source & 0x0F );");
+           cfw("source = ( source & 0xF0 ) + tmpval;");
+           $modifysrc=1;
+       }
+
+       # MOVX
+       if ($insttype[$i] == 44) {
+           cfw("destination = source;");
+       }
+
+
+
+##############################################################################
+
+
+       if ($instargs[$i*4] > 0) {
+           $op_destination=$instargs[$i*4+1];
+           if ($op_destination == 0) { # addr11
+               cfw("cpu8051.pc = ( cpu8051.pc & 0xF800 ) | addr11;");
+           }
+           if ($op_destination == 1) { # addr16
+               cfw("cpu8051.pc = addr16;");
+           }
+           if ($op_destination == 2) { # A
+               cfw("cpu8051_WriteD( _ACC_, destination );");
+           }
+           if ($op_destination == 3) { # direct
+               cfw("cpu8051_WriteD( destaddr, destination );");
+           }
+           if ($op_destination == 4) { # @R0
+               cfw("cpu8051_WriteI( cpu8051_ReadD( BANKPSW + _R0_ ), destination );");
+           }
+           if ($op_destination == 5) { # @R1
+               cfw("cpu8051_WriteI( cpu8051_ReadD( BANKPSW + _R1_ ), destination );");
+           }
+           if ($op_destination == 6) { # R0
+               cfw("cpu8051_WriteD( BANKPSW + _R0_, destination );");
+           }
+           if ($op_destination == 7) { # R1
+               cfw("cpu8051_WriteD( BANKPSW + _R1_, destination );");
+           }
+           if ($op_destination == 8) { # R2
+               cfw("cpu8051_WriteD( BANKPSW + _R2_, destination );");
+           }
+           if ($op_destination == 9) { # R3
+               cfw("cpu8051_WriteD( BANKPSW + _R3_, destination );");
+           }
+           if ($op_destination == 10) { # R4
+               cfw("cpu8051_WriteD( BANKPSW + _R4_, destination );");
+           }
+           if ($op_destination == 11) { # R5
+               cfw("cpu8051_WriteD( BANKPSW + _R5_, destination );");
+           }
+           if ($op_destination == 12) { # R6
+               cfw("cpu8051_WriteD( BANKPSW + _R6_, destination );");
+           }
+           if ($op_destination == 13) { # R7
+               cfw("cpu8051_WriteD( BANKPSW + _R7_, destination );");
+           }
+
+           if ($op_destination == 14) { # bitaddr
+               cfw("cpu8051_WriteB( dstbitaddr, destination );");
+           }
+           if ($op_destination == 17) { # C
+               cfw("psw_write_cy(destination);");
+           }
+           if ($op_destination == 21) { # DPTR
+               cfw("memory_sfr_write_dptr(destination);");
+           }
+           if ($op_destination == 23) { # /bitaddr
+               cfw("cpu8051_WriteB( dstbitaddr, destination );");
+           }
+           if ($op_destination == 24) { # @DPTR
+               cfw("cpu8051_WriteI(memory_sfr_read_dptr(), destination);");
+           }
+       }
+
+       if ($modifysrc == 1) {
+           if ($instargs[$i*4] > 1) {
+               $op_source=$instargs[$i*4+2];
+               if ($op_source == 0) { # addr11
+                   cfw("cpu8051.pc = ( cpu8051.pc & 0xF800 ) | addr11;");
+               }
+               if ($op_source == 1) { # addr16
+                   cfw("cpu8051.pc = addr16;");
+               }
+               if ($op_source == 2) { # A
+                   cfw("cpu8051_WriteD( _ACC_, source );");
+               }
+               if ($op_source == 3) { # direct
+                   cfw("cpu8051_WriteD( srcaddr, source );");
+               }
+               if ($op_source == 4) { # @R0
+                   cfw("cpu8051_WriteI( cpu8051_ReadD( BANKPSW + _R0_ ), source );");
+               }
+               if ($op_source == 5) { # @R1
+                   cfw("cpu8051_WriteI( cpu8051_ReadD( BANKPSW + _R1_ ), source );");
+               }
+               if ($op_source == 6) { # R0
+                   cfw("cpu8051_WriteD( BANKPSW + _R0_, source );");
+               }
+               if ($op_source == 7) { # R1
+                   cfw("cpu8051_WriteD( BANKPSW + _R1_, source );");
+               }
+               if ($op_source == 8) { # R2
+                   cfw("cpu8051_WriteD( BANKPSW + _R2_, source );");
+               }
+               if ($op_source == 9) { # R3
+                   cfw("cpu8051_WriteD( BANKPSW + _R3_, source );");
+               }
+               if ($op_source == 10) { # R4
+                   cfw("cpu8051_WriteD( BANKPSW + _R4_, source );");
+               }
+               if ($op_source == 11) { # R5
+                   cfw("cpu8051_WriteD( BANKPSW + _R5_, source );");
+               }
+               if ($op_source == 12) { # R6
+                   cfw("cpu8051_WriteD( BANKPSW + _R6_, source );");
+               }
+               if ($op_source == 13) { # R7
+                   cfw("cpu8051_WriteD( BANKPSW + _R7_, source );");
+               }
+               if ($op_source == 14) { # bitaddr
+                   cfw("cpu8051_WriteB( srcbitaddr, source );");
+               }
+               if ($op_source == 17) { # C
+                   cfw("psw_write_cy(source);");
+               }
+               if ($op_source == 21) { # DPTR
+                    cfw("memory_sfr_write_dptr(source);");
+               }
+               if ($op_source == 23) { # /bitaddr
+                   cfw("cpu8051_WriteB( srcbitaddr, source );");
+               }
+               if ($op_source == 24) { # @DPTR
+                   cfw("cpu8051_WriteI(memory_sfr_read_dptr(), source);");
+               }
+           }
+       }
+    }
+    cfw("return $a_cycles[$i];");
+    print INST_IMP "}\n";
+    print INST_IMP "\n";
+}
+# ------------------------------------------------------------------------------
+
+
+# Header for instructions_8051.h
+print INST_DEF "/*\n";
+print INST_DEF " * instructions_8051.h\n";
+write_header(INST_DEF);
+print INST_DEF "#ifndef INSTRUCTIONS_8051_H\n";
+print INST_DEF "#define INSTRUCTIONS_8051_H 1\n\n\n";
+print INST_DEF "#define BANKPSW (cpu8051_ReadD(_PSW_) & 0x18)\n\n";
+print INST_DEF "typedef int (*OPCODE_FP)(void);\n\n\n";
+for( $i=0; $i<256; $i++ ) {
+    print INST_DEF "int\n";
+    print INST_DEF "cpu8051_OP_$a_opcodehex[$i](void);\n\n";
+}
+print INST_DEF "\n";
+print INST_DEF "/* Exported variables. */\n";
+print INST_DEF "#ifdef INSTRUCTIONS_8051_M\n";
+print INST_DEF "OPCODE_FP opcode_table[256] = {\n";
+for( $i=0; $i<256; $i++ ) {
+    $ifunc=substr($instfunction[$i], 9);
+    if( $i < 255 ) {
+       print INST_DEF "  cpu8051_$ifunc,\n";
+    }
+    else {
+       print INST_DEF "  cpu8051_$ifunc\n";
+       print INST_DEF "};\n";
+    }
+}
+
+print INST_DEF "#else\n";
+print INST_DEF "OPCODE_FP opcode_table[256];\n";
+print INST_DEF "#endif\n\n\n";
+
+print INST_DEF "#endif /* INSTRUCTIONS_8051_H */\n";
+
+print DISASM_H "#endif /* DISASM_H */\n";
+
+close DISASM_H;
+close OPCODELST;
+close INST_DEF;
+close INST_IMP;
diff --git a/src/common/opcodes.lst b/src/common/opcodes.lst
new file mode 100644 (file)
index 0000000..1494258
--- /dev/null
@@ -0,0 +1,258 @@
+Opcode(bin)    Opcode  Instruction             Bytes   Cycles
+--------------------------------------------------------------
+00000000       00      NOP                     1       1
+00000001       01      AJMP addr11             2       2
+00000010       02      LJMP addr16             3       2
+00000011       03      RR A                    1       1
+00000100       04      INC A                   1       1
+00000101       05      INC direct              2       1
+00000110       06      INC @R0                 1       1
+00000111       07      INC @R1                 1       1
+00001000       08      INC R0                  1       1
+00001001       09      INC R1                  1       1
+00001010       0A      INC R2                  1       1
+00001011       0B      INC R3                  1       1
+00001100       0C      INC R4                  1       1
+00001101       0D      INC R5                  1       1
+00001110       0E      INC R6                  1       1
+00001111       0F      INC R7                  1       1
+00010000       10      JBC bitaddr,reladdr     3       2
+00010001       11      ACALL addr11            2       2
+00010010       12      LCALL addr16            3       2
+00010011       13      RRC A                   1       1
+00010100       14      DEC A                   1       1
+00010101       15      DEC direct              2       1
+00010110       16      DEC @R0                 1       1
+00010111       17      DEC @R1                 1       1
+00011000       18      DEC R0                  1       1
+00011001       19      DEC R1                  1       1
+00011010       1A      DEC R2                  1       1
+00011011       1B      DEC R3                  1       1
+00011100       1C      DEC R4                  1       1
+00011101       1D      DEC R5                  1       1
+00011110       1E      DEC R6                  1       1
+00011111       1F      DEC R7                  1       1
+00100000       20      JB bitaddr,reladdr      3       2
+00100001       21      AJMP addr11             2       2       
+00100010       22      RET                     1       2
+00100011       23      RL A                    1       1
+00100100       24      ADD A,#data             2       1
+00100101       25      ADD A,direct            2       1
+00100110       26      ADD A,@R0               1       1
+00100111       27      ADD A,@R1               1       1
+00101000       28      ADD A,R0                1       1
+00101001       29      ADD A,R1                1       1
+00101010       2A      ADD A,R2                1       1
+00101011       2B      ADD A,R3                1       1
+00101100       2C      ADD A,R4                1       1
+00101101       2D      ADD A,R5                1       1
+00101110       2E      ADD A,R6                1       1
+00101111       2F      ADD A,R7                1       1
+00110000       30      JNB bitaddr,reladdr     3       2
+00110001       31      ACALL addr11            2       2
+00110010       32      RETI                    1       2
+00110011       33      RLC A                   1       1
+00110100       34      ADDC A,#data            2       1
+00110101       35      ADDC A,direct           2       1
+00110110       36      ADDC A,@R0              1       1
+00110111       37      ADDC A,@R1              1       1
+00111000       38      ADDC A,R0               1       1
+00111001       39      ADDC A,R1               1       1
+00111010       3A      ADDC A,R2               1       1
+00111011       3B      ADDC A,R3               1       1
+00111100       3C      ADDC A,R4               1       1
+00111101       3D      ADDC A,R5               1       1
+00111110       3E      ADDC A,R6               1       1
+00111111       3F      ADDC A,R7               1       1
+01000000       40      JC reladdr              2       2
+01000001       41      AJMP addr11             2       2       
+01000010       42      ORL direct,A            2       1
+01000011       43      ORL direct,#data        3       2
+01000100       44      ORL A,#data             2       1
+01000101       45      ORL A,direct            2       1
+01000110       46      ORL A,@R0               1       1
+01000111       47      ORL A,@R1               1       1
+01001000       48      ORL A,R0                1       1
+01001001       49      ORL A,R1                1       1
+01001010       4A      ORL A,R2                1       1
+01001011       4B      ORL A,R3                1       1
+01001100       4C      ORL A,R4                1       1
+01001101       4D      ORL A,R5                1       1
+01001110       4E      ORL A,R6                1       1
+01001111       4F      ORL A,R7                1       1
+01010000       50      JNC reladdr             2       2
+01010001       51      ACALL addr11            2       2
+01010010       52      ANL direct,A            2       1
+01010011       53      ANL direct,#data        3       2
+01010100       54      ANL A,#data             2       1
+01010101       55      ANL A,direct            2       1
+01010110       56      ANL A,@R0               1       1
+01010111       57      ANL A,@R1               1       1
+01011000       58      ANL A,R0                1       1
+01011001       59      ANL A,R1                1       1
+01011010       5A      ANL A,R2                1       1
+01011011       5B      ANL A,R3                1       1
+01011100       5C      ANL A,R4                1       1
+01011101       5D      ANL A,R5                1       1
+01011110       5E      ANL A,R6                1       1
+01011111       5F      ANL A,R7                1       1
+01100000       60      JZ reladdr              2       2
+01100001       61      AJMP addr11             2       2       
+01100010       62      XRL direct,A            2       1
+01100011       63      XRL direct,#data        3       2
+01100100       64      XRL A,#data             2       1
+01100101       65      XRL A,direct            2       1
+01100110       66      XRL A,@R0               1       1
+01100111       67      XRL A,@R1               1       1
+01101000       68      XRL A,R0                1       1
+01101001       69      XRL A,R1                1       1
+01101010       6A      XRL A,R2                1       1
+01101011       6B      XRL A,R3                1       1
+01101100       6C      XRL A,R4                1       1
+01101101       6D      XRL A,R5                1       1
+01101110       6E      XRL A,R6                1       1
+01101111       6F      XRL A,R7                1       1
+01110000       70      JNZ reladdr             2       2
+01110001       71      ACALL addr11            2       2
+01110010       72      ORL C,bitaddr           2       2
+01110011       73      JMP @A+DPTR             1       2
+01110100       74      MOV A,#data             2       1
+01110101       75      MOV direct,#data        3       2
+01110110       76      MOV @R0,#data           2       1
+01110111       77      MOV @R1,#data           2       1
+01111000       78      MOV R0,#data            2       1
+01111001       79      MOV R1,#data            2       1
+01111010       7A      MOV R2,#data            2       1
+01111011       7B      MOV R3,#data            2       1
+01111100       7C      MOV R4,#data            2       1
+01111101       7D      MOV R5,#data            2       1
+01111110       7E      MOV R6,#data            2       1
+01111111       7F      MOV R7,#data            2       1
+10000000       80      SJMP reladdr            2       2
+10000001       81      AJMP addr11             2       2
+10000010       82      ANL C,bitaddr           2       1
+10000011       83      MOVC A,@A+PC            1       1
+10000100       84      DIV AB                  1       4
+10000101       85      MOV direct,direct       3       1
+10000110       86      MOV direct,@R0          2       2
+10000111       87      MOV direct,@R1          2       2
+10001000       88      MOV direct,R0           2       2
+10001001       89      MOV direct,R1           2       2
+10001010       8A      MOV direct,R2           2       2
+10001011       8B      MOV direct,R3           2       2
+10001100       8C      MOV direct,R4           2       2
+10001101       8D      MOV direct,R5           2       2
+10001110       8E      MOV direct,R6           2       2
+10001111       8F      MOV direct,R7           2       2
+10010000       90      MOV DPTR,#data16        3       2
+10010001       91      ACALL addr11            2       2
+10010010       92      MOV bitaddr,C           2       2
+10010011       93      MOVC A,@A+DPTR          1       2
+10010100       94      SUBB A,#data            2       1
+10010101       95      SUBB A,direct           2       1
+10010110       96      SUBB A,@R0              1       1
+10010111       97      SUBB A,@R1              1       1
+10011000       98      SUBB A,R0               1       1
+10011001       99      SUBB A,R1               1       1
+10011010       9A      SUBB A,R2               1       1
+10011011       9B      SUBB A,R3               1       1
+10011100       9C      SUBB A,R4               1       1
+10011101       9D      SUBB A,R5               1       1
+10011110       9E      SUBB A,R6               1       1
+10011111       9F      SUBB A,R7               1       1
+10100000       A0      ORL C,/bitaddr          2       1
+10100001       A1      AJMP addr11             2       2
+10100010       A2      MOV C,bitaddr           2       1
+10100011       A3      INC DPTR                1       2
+10100100       A4      MUL AB                  1       4
+10100101       A5      INVALID                 1       1
+10100110       A6      MOV @R0,direct          2       2
+10100111       A7      MOV @R1,direct          2       2
+10101000       A8      MOV R0,direct           2       2
+10101001       A9      MOV R1,direct           2       2
+10101010       AA      MOV R2,direct           2       2
+10101011       AB      MOV R3,direct           2       2
+10101100       AC      MOV R4,direct           2       2
+10101101       AD      MOV R5,direct           2       2
+10101110       AE      MOV R6,direct           2       2
+10101111       AF      MOV R7,direct           2       2
+10110000       B0      ANL C,/bitaddr          2       1
+10110001       B1      ACALL addr11            2       2
+10110010       B2      CPL bitaddr             2       1
+10110011       B3      CPL C                   1       1
+10110100       B4      CJNE A,#data,reladdr    3       2
+10110101       B5      CJNE A,direct,reladdr   3       2
+10110110       B6      CJNE @R0,#data,reladdr  3       2
+10110111       B7      CJNE @R1,#data,reladdr  3       2
+10111000       B8      CJNE R0,#data,reladdr   3       2
+10111001       B9      CJNE R1,#data,reladdr   3       2
+10111010       BA      CJNE R2,#data,reladdr   3       2
+10111011       BB      CJNE R3,#data,reladdr   3       2
+10111100       BC      CJNE R4,#data,reladdr   3       2
+10111101       BD      CJNE R5,#data,reladdr   3       2
+10111110       BE      CJNE R6,#data,reladdr   3       2
+10111111       BF      CJNE R7,#data,reladdr   3       2
+11000000       C0      PUSH direct             2       2
+11000001       C1      AJMP addr11             2       2       
+11000010       C2      CLR bitaddr             2       1
+11000011       C3      CLR C                   1       1
+11000100       C4      SWAP A                  1       1
+11000101       C5      XCH A,direct            2       1
+11000110       C6      XCH A,@R0               1       1
+11000111       C7      XCH A,@R1               1       1
+11001000       C8      XCH A,R0                1       1
+11001001       C9      XCH A,R1                1       1
+11001010       CA      XCH A,R2                1       1
+11001011       CB      XCH A,R3                1       1
+11001100       CC      XCH A,R4                1       1
+11001101       CD      XCH A,R5                1       1
+11001110       CE      XCH A,R6                1       1
+11001111       CF      XCH A,R7                1       1
+11010000       D0      POP direct              2       2
+11010001       D1      ACALL addr11            2       2
+11010010       D2      SETB bitaddr            2       1
+11010011       D3      SETB C                  1       1
+11010100       D4      DA A                    1       1
+11010101       D5      DJNZ direct,reladdr     3       2
+11010110       D6      XCHD A,@R0              1       1
+11010111       D7      XCHD A,@R1              1       1
+11011000       D8      DJNZ R0,reladdr         2       2
+11011001       D9      DJNZ R1,reladdr         2       2
+11011010       DA      DJNZ R2,reladdr         2       2
+11011011       DB      DJNZ R3,reladdr         2       2
+11011100       DC      DJNZ R4,reladdr         2       2
+11011101       DD      DJNZ R5,reladdr         2       2
+11011110       DE      DJNZ R6,reladdr         2       2
+11011111       DF      DJNZ R7,reladdr         2       2
+11100000       E0      MOVX A,@DPTR            1       2
+11100001       E1      AJMP addr11             2       2       
+11100010       E2      MOVX A,@R0              1       2
+11100011       E3      MOVX A,@R1              1       2
+11100100       E4      CLR A                   1       1
+11100101       E5      MOV A,direct            2       1
+11100110       E6      MOV A,@R0               1       1
+11100111       E7      MOV A,@R1               1       1
+11101000       E8      MOV A,R0                1       1
+11101001       E9      MOV A,R1                1       1
+11101010       EA      MOV A,R2                1       1
+11101011       EB      MOV A,R3                1       1
+11101100       EC      MOV A,R4                1       1
+11101101       ED      MOV A,R5                1       1
+11101110       EE      MOV A,R6                1       1
+11101111       EF      MOV A,R7                1       1
+11110000       F0      MOVX @DPTR,A            1       2
+11110001       F1      ACALL addr11            2       2
+11110010       F2      MOVX @R0,A              1       2
+11110011       F3      MOVX @R1,A              1       2
+11110100       F4      CPL A                   1       1
+11110101       F5      MOV direct,A            2       1
+11110110       F6      MOV @R0,A               1       1
+11110111       F7      MOV @R1,A               1       1
+11111000       F8      MOV R0,A                1       1
+11111001       F9      MOV R1,A                1       1
+11111010       FA      MOV R2,A                1       1
+11111011       FB      MOV R3,A                1       1
+11111100       FC      MOV R4,A                1       1
+11111101       FD      MOV R5,A                1       1
+11111110       FE      MOV R6,A                1       1
+11111111       FF      MOV R7,A                1       1
diff --git a/src/common/options.c b/src/common/options.c
new file mode 100644 (file)
index 0000000..420cc85
--- /dev/null
@@ -0,0 +1,184 @@
+/*
+ * options.c -- functions for processing command-line options and arguments
+ *
+ * Copyright (C) 2011 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.
+ */
+
+#if HAVE_CONFIG_H
+#  include "config.h"
+#endif
+
+#include <unistd.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <argp.h>
+
+#if STDC_HEADERS
+#  include <string.h>
+#elif HAVE_STRINGS_H
+#  include <strings.h>
+#endif
+
+#include "common.h"
+#include "options.h"
+#include "memory.h"
+
+const char *argp_program_version = PACKAGE_VERSION;
+const char *argp_program_bug_address = PACKAGE_BUGREPORT;
+
+#define PACKAGE_DOC_LENGTH 128
+
+/* Program documentation. */
+static char str_doc[PACKAGE_DOC_LENGTH];
+
+/* How many arguments we accept. */
+#define ARGS_COUNT 1
+
+/* A description of the arguments we accept. */
+static const char args_doc[] = "[FILENAME]";
+
+/* The options we understand. */
+static struct argp_option argp_options[] = {
+       {"debug", 'd', "level", 0,  "Produce debugging output" },
+       {"pram",  'p', "size",  0,  "Set program memory size" },
+       {"xram",  'x', "size",  0,  "Set external ram size (default is 1024)" },
+       {"stop",  's', "addr",  0,  "Automatically run program and stop at address" },
+       { 0 }
+};
+
+struct options_t options;
+
+const char *
+get_package_description(void)
+{
+       return "Emulator for 8051 family microcontrollers";
+}
+
+static void
+decode_debug_option(char *arg, struct argp_state *state)
+{
+       char *endptr;
+       int log_level;
+
+       log_level = strtol(arg, &endptr, 0);
+
+       if (*endptr != '\0') {
+               log_err("Invalid log level");
+               argp_usage(state);
+       }
+
+       if (log_level > LOG_LEVEL_DEBUG) {
+               log_err("Invalid log level (0 to 3)");
+               argp_usage(state);
+       }
+
+       options.log = log_level;
+}
+
+static void
+decode_memory_size(char *arg, struct argp_state *state, int memid)
+{
+       char *endptr;
+       int *dest;
+
+       if (memid == PGM_MEM_ID)
+               dest = &options.pram_size;
+       else if (memid == INT_MEM_ID)
+               dest = &options.iram_size;
+       else if (memid == EXT_MEM_ID)
+               dest = &options.xram_size;
+       else
+               exit(1); /* Programming error. */
+
+       /*
+        * Sizes versus max memory sizes will be checked when calling
+        * memory_init().
+        */
+       *dest = strtol(arg, &endptr, 0);
+
+       if (*endptr != '\0') {
+               log_err("Invalid memory size");
+               argp_usage(state);
+       }
+}
+
+static void
+decode_address(char *arg, struct argp_state *state, uint16_t *dest)
+{
+       char *endptr;
+
+       *dest = strtol(arg, &endptr, 0);
+
+       if (*endptr != '\0') {
+               log_err("Invalid address");
+               argp_usage(state);
+       }
+}
+
+/* Parse a single option. */
+static error_t
+parse_opt(int key, char *arg, struct argp_state *state)
+{
+       switch (key) {
+       case 'd':
+               decode_debug_option(arg, state);
+               break;
+       case 'i':
+               decode_memory_size(arg, state, INT_MEM_ID);
+               break;
+       case 'p':
+               decode_memory_size(arg, state, PGM_MEM_ID);
+               break;
+       case 's':
+               decode_address(arg, state, &options.stop_address);
+               break;
+       case 'x':
+               decode_memory_size(arg, state, EXT_MEM_ID);
+               break;
+       case ARGP_KEY_ARG:
+               if (state->arg_num >= ARGS_COUNT) {
+                       /* Too many arguments. */
+                       argp_usage(state);
+               }
+
+               options.filename = arg;
+               break;
+       case ARGP_KEY_END:
+               if (state->arg_num < ARGS_COUNT) {
+                       /* Not enough arguments, but the filename is optional.
+                          So no error. */
+               }
+               break;
+       default:
+               return ARGP_ERR_UNKNOWN;
+       }
+
+       return 0;
+}
+
+/* Our argp parser. */
+static struct argp argp = { argp_options, parse_opt, args_doc, str_doc };
+
+/* Initializes the different options passed as arguments on the command line. */
+void
+parse_command_line_options(int argc, char *argv[])
+{
+       snprintf(str_doc, PACKAGE_DOC_LENGTH, "%s -- %s", PACKAGE_NAME,
+                get_package_description());
+
+       /* Setting default values. */
+       options.filename = NULL;
+       options.pram_size = PGM_MEM_DEFAULT_SIZE;
+       options.iram_size = INT_MEM_MAX_SIZE;
+       options.xram_size = EXT_MEM_DEFAULT_SIZE;
+       options.log = LOG_LEVEL_ERR;
+       options.stop_address = 0; /* 0 means stop address is disabled. */
+
+       /* Parse our arguments. */
+       argp_parse(&argp, argc, argv, 0, 0, NULL);
+}
diff --git a/src/common/options.h b/src/common/options.h
new file mode 100644 (file)
index 0000000..589c2d5
--- /dev/null
@@ -0,0 +1,45 @@
+/*
+ * options.h
+ *
+ * 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 OPTIONS_H
+#define OPTIONS_H 1
+
+#define COMMAND_LINE_OPTIONS \
+  "Usage: " PACKAGE " [OPTION]... [FILENAME]\n" \
+  "Simulator/emulator for 8051 family microcontrollers.\n\n" \
+  "  -h                    display this help and exit\n" \
+  "  -version              display version information and exit\n"
+
+struct options_t {
+       int pram_size; /* Maximum program memory size. */
+       int iram_size; /* Maximum internal ram size. */
+       int xram_size; /* Maximum external ram size. */
+       char *filename;
+       int log;
+       uint16_t stop_address; /* Run program up to that adress and exit. */
+} options_t;
+
+void
+parse_command_line_options(int argc, char *argv[]);
+
+const char *
+get_package_description(void);
+
+#endif /* OPTIONS_H */
diff --git a/src/common/psw.c b/src/common/psw.c
new file mode 100644 (file)
index 0000000..09352ad
--- /dev/null
@@ -0,0 +1,137 @@
+/*
+ * psw.c
+ *
+ * Copyright (C) 2013 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.
+ */
+
+#include "common.h"
+#include "reg8051.h"
+#include "memory.h"
+
+/* Returns 0 or 1 */
+int
+psw_read_bit(int bit)
+{
+       return (memory_read8(INT_MEM_ID, _PSW_) >> bit) & 0x01;
+}
+
+void
+psw_write_bit(int bit, int val)
+{
+       u_int8_t psw = memory_read8(INT_MEM_ID, _PSW_);
+
+       if (val)
+               psw |= (1 << bit);  /* Set */
+       else
+               psw &= ~(1 << bit); /* Clear */
+
+       memory_write8(INT_MEM_ID, _PSW_, psw); /* Save updated value */
+}
+
+/* Returns 0 or 1 */
+int
+psw_read_cy(void)
+{
+       return psw_read_bit(PSW_BIT_CY);
+}
+
+void
+psw_write_cy(int cy)
+{
+       psw_write_bit(PSW_BIT_CY, cy);
+}
+
+void
+psw_set_cy(void)
+{
+       psw_write_bit(PSW_BIT_CY, 1);
+}
+
+void
+psw_clr_cy(void)
+{
+       psw_write_bit(PSW_BIT_CY, 0);
+}
+
+/* Returns 0 or 1 */
+int
+psw_read_ac(void)
+{
+       return psw_read_bit(PSW_BIT_AC);
+}
+
+void
+psw_write_ac(int ac)
+{
+       psw_write_bit(PSW_BIT_AC, ac);
+}
+
+void
+psw_set_ac(void)
+{
+       psw_write_bit(PSW_BIT_AC, 1);
+}
+
+void
+psw_clr_ac(void)
+{
+       psw_write_bit(PSW_BIT_AC, 0);
+}
+
+/* Returns 0 or 1 */
+int
+psw_read_ov(void)
+{
+       return psw_read_bit(PSW_BIT_OV);
+}
+
+void
+psw_write_ov(int ov)
+{
+       psw_write_bit(PSW_BIT_OV, ov);
+}
+
+void
+psw_set_ov(void)
+{
+       psw_write_bit(PSW_BIT_OV, 1);
+}
+
+void
+psw_clr_ov(void)
+{
+       psw_write_bit(PSW_BIT_OV, 0);
+}
+
+/*
+ * Compute parity of bits in accumulator:
+ *   parity = 0: even number of ones in accumulator
+ *   parity = 1: odd  number of ones in accumulator
+ */
+void
+psw_compute_parity_bit(void)
+{
+       int parity = 0;
+       uint8_t acc = memory_read8(INT_MEM_ID, _ACC_);
+
+       while (acc) {
+               parity = !parity;
+               acc = acc & (acc - 1);
+       }
+
+       psw_write_bit(PSW_BIT_P, parity);
+}
diff --git a/src/common/psw.h b/src/common/psw.h
new file mode 100644 (file)
index 0000000..f2c09ba
--- /dev/null
@@ -0,0 +1,71 @@
+/*
+ * psw.h
+ *
+ * Copyright (C) 2013 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 PSW_H
+#define PSW_H 1
+
+#include <sys/types.h>
+
+int
+psw_read_bit(int bit);
+
+void
+psw_write_bit(int bit, int val);
+
+int
+psw_read_cy(void);
+
+void
+psw_write_cy(int cy);
+
+void
+psw_clr_cy(void);
+
+void
+psw_set_cy(void);
+
+int
+psw_read_ac(void);
+
+void
+psw_write_ac(int ac);
+
+void
+psw_clr_ac(void);
+
+void
+psw_set_ac(void);
+
+int
+psw_read_ov(void);
+
+void
+psw_write_ov(int ov);
+
+void
+psw_clr_ov(void);
+
+void
+psw_set_ov(void);
+
+void
+psw_compute_parity_bit(void);
+
+#endif /* PSW_H */
diff --git a/src/common/reg8051.h b/src/common/reg8051.h
new file mode 100644 (file)
index 0000000..b484246
--- /dev/null
@@ -0,0 +1,75 @@
+/*
+ * reg8051.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 REG8051_H
+#define REG8051_H 1
+
+/* SFR Registers ( $80 - $FF ) */
+#define _ACC_       0xE0
+#define _B_         0xF0
+#define _PSW_       0xD0
+#define _SP_        0x81
+#define _DPTRLOW_   _DPL_
+#define _DPTRHIGH_  _DPH_
+#define _DPL_       0x82
+#define _DPH_       0x83
+#define _P0_        0x80
+#define _P1_        0x90
+#define _P2_        0xA0
+#define _P3_        0xB0
+#define _IP_        0xB8
+#define _IE_        0xA8
+#define _TMOD_      0x89
+#define _TCON_      0x88
+#define _TH0_       0x8C
+#define _TL0_       0x8A
+#define _TH1_       0x8D
+#define _TL1_       0x8B
+#define _SCON_      0x98
+#define _SBUF_      0x99
+#define _PCON_      0x87
+#define _T2CON_     0xC8
+
+#define _R0_        0x00
+#define _R1_        0x01
+#define _R2_        0x02
+#define _R3_        0x03
+#define _R4_        0x04
+#define _R5_        0x05
+#define _R6_        0x06
+#define _R7_        0x07
+
+#define _BANK0_     0x00
+#define _BANK1_     0x08
+#define _BANK2_     0x10
+#define _BANK3_     0x18
+
+#define PSW_BIT_CY 7
+#define PSW_BIT_AC 6
+#define PSW_BIT_OV 2
+#define PSW_BIT_P  0
+
+#define PSW_FLAG_CY (1 << PSW_BIT_CY)
+#define PSW_FLAG_AC (1 << PSW_BIT_AC)
+#define PSW_FLAG_OV (1 << PSW_BIT_OV)
+#define PSW_FLAG_P  (1 << PSW_BIT_P)
+
+#endif /* REG8051_H */
diff --git a/src/common/sfr.c b/src/common/sfr.c
new file mode 100644 (file)
index 0000000..1bbeb8e
--- /dev/null
@@ -0,0 +1,345 @@
+/*
+ * sfr.c
+ *
+ * Copyright (C) 2013 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 "common.h"
+#include "reg8051.h"
+#include "cpu8051.h"
+#include "sfr.h"
+#include "memory.h"
+#include "instructions_8051.h"
+
+#define HEX_DIGITS_2 2
+#define HEX_DIGITS_4 4
+
+/* Specific read/write functions for special registers. */
+
+static unsigned int
+regwin_read_pc(int dummy)
+{
+       return cpu8051.pc;
+}
+
+static void
+regwin_write_pc(int param, int val)
+{
+       cpu8051.pc = (u_int16_t) val;
+}
+
+static unsigned int
+regwin_read_timer(int timer_low_addr)
+{
+       return (memory_sfr_read8(timer_low_addr + 2) << 8) |
+               memory_sfr_read8(timer_low_addr);
+}
+
+static void
+regwin_write_timer(int timer_low_addr, int val)
+{
+       memory_sfr_write8(timer_low_addr + 2, (u_int8_t) ((val & 0x0000FFFF) >> 8));
+       memory_sfr_write8(timer_low_addr, (u_int8_t) val);
+}
+
+static u_int8_t
+regwin_read_bank_offset(void)
+{
+       return memory_sfr_read8(_PSW_) & 0x18;
+}
+
+static unsigned int
+regwin_read_bank(int dummy)
+{
+       return regwin_read_bank_offset() >> 3;
+}
+
+static void
+regwin_write_bank(int param, int bank_number)
+{
+       u_int8_t psw = memory_sfr_read8(_PSW_);
+
+       if ((bank_number < 0) || (bank_number > 3)) {
+               log_info("Error: invalid bank number: %d", bank_number);
+               bank_number = 0;
+       }
+
+       memory_sfr_write8(_PSW_, (psw & ~0x18) | (bank_number << 3));
+}
+
+/* Indirect read of R0 - R7 in current bank from internal memory. */
+static unsigned int
+regwin_read_rx(int offset)
+{
+       return memory_read8(INT_MEM_ID, regwin_read_bank_offset() + offset);
+}
+
+/* Indirect write to R0 - R7 in current bank to internal memory. */
+static void
+regwin_write_rx(int offset, int val)
+{
+       memory_write8(INT_MEM_ID, regwin_read_bank_offset() + offset, (u_int8_t) val);
+}
+
+/* This array defines how to read value for each register. */
+static struct regwin_infos_t regwin_infos[SFR_REGS] = {
+       {
+               "PC",
+               HEX_DIGITS_4,
+               regwin_read_pc, regwin_write_pc,
+               0, /* Dummy */
+       },
+       {
+               "SP",
+               HEX_DIGITS_2,
+               NULL, NULL,
+               _SP_,
+       },
+       {
+               "PSW",
+               HEX_DIGITS_2,
+               NULL, NULL,
+               _PSW_,
+       },
+       {
+               "A",
+               HEX_DIGITS_2,
+               NULL, NULL,
+               _ACC_,
+       },
+       {
+               "B",
+               HEX_DIGITS_2,
+               NULL, NULL,
+               _B_,
+       },
+       {
+               "DPTR",
+               HEX_DIGITS_4,
+               NULL, NULL,
+               _DPL_,
+       },
+       {
+               "P0",
+               HEX_DIGITS_2,
+               NULL, NULL,
+               _P0_,
+       },
+       {
+               "P1",
+               HEX_DIGITS_2,
+               NULL, NULL,
+               _P1_,
+       },
+       {
+               "P2",
+               HEX_DIGITS_2,
+               NULL, NULL,
+               _P2_,
+       },
+       {
+               "P3",
+               HEX_DIGITS_2,
+               NULL, NULL,
+               _P3_,
+       },
+       {
+               "TCON",
+               HEX_DIGITS_2,
+               NULL, NULL,
+               _TCON_,
+       },
+       {
+               "TMOD",
+               HEX_DIGITS_2,
+               NULL, NULL,
+               _TMOD_,
+       },
+       {
+               "TIMER0",
+               HEX_DIGITS_4,
+               regwin_read_timer, regwin_write_timer,
+               _TL0_,
+       },
+       {
+               "TIMER1",
+               HEX_DIGITS_4,
+               regwin_read_timer, regwin_write_timer,
+               _TL1_,
+       },
+       {
+               "SCON",
+               HEX_DIGITS_2,
+               NULL, NULL,
+               _SCON_,
+       },
+       {
+               "IE",
+               HEX_DIGITS_2,
+               NULL, NULL,
+               _IE_,
+       },
+       {
+               "IP",
+               HEX_DIGITS_2,
+               NULL, NULL,
+               _IP_,
+       },
+       {
+               "BANK",
+               HEX_DIGITS_2,
+               regwin_read_bank, regwin_write_bank,
+               0, /* Dummy */
+       },
+       /* R0-R7 Registers in current Bank */
+       {
+               "R0",
+               HEX_DIGITS_2,
+               regwin_read_rx, regwin_write_rx,
+               _R0_,
+       },
+       {
+               "R1",
+               HEX_DIGITS_2,
+               regwin_read_rx, regwin_write_rx,
+               _R1_,
+       },
+       {
+               "R2",
+               HEX_DIGITS_2,
+               regwin_read_rx, regwin_write_rx,
+               _R2_,
+       },
+       {
+               "R3",
+               HEX_DIGITS_2,
+               regwin_read_rx, regwin_write_rx,
+               _R3_,
+       },
+       {
+               "R4",
+               HEX_DIGITS_2,
+               regwin_read_rx, regwin_write_rx,
+               _R4_,
+       },
+       {
+               "R5",
+               HEX_DIGITS_2,
+               regwin_read_rx, regwin_write_rx,
+               _R5_,
+       },
+       {
+               "R6",
+               HEX_DIGITS_2,
+               regwin_read_rx, regwin_write_rx,
+               _R6_,
+       },
+       {
+               "R7",
+               HEX_DIGITS_2,
+               regwin_read_rx, regwin_write_rx,
+               _R7_,
+       },
+};
+
+/* Generic read/write functions */
+static unsigned int
+regwin_read_generic(int addr, int width)
+{
+       if (width == 2)
+               return memory_sfr_read8(addr);
+       else if (width == 4) {
+               /* Address is low address. */
+               return (memory_sfr_read8(addr + 1) << 8) |
+                       memory_sfr_read8(addr);
+       } else
+               return 0xFFFFFFFF;
+}
+
+static void
+regwin_write_generic(int addr, int val, int width)
+{
+       if (width == 2)
+               memory_sfr_write8(addr, (u_int8_t) val);
+       else if (width == 4) {
+               /* Address is low address. */
+               memory_sfr_write8(addr + 1, (u_int8_t) ((val & 0x0000FFFF) >> 8));
+               memory_sfr_write8(addr, (u_int8_t) val);
+       }
+};
+
+int
+regwin_read(int row)
+{
+       int val;
+
+       if (regwin_infos[row].read_func == NULL) {
+               /*
+                * Read register value using generic 8 or 16 bits read
+                * function, depending on width.
+                */
+               val = regwin_read_generic(regwin_infos[row].param,
+                                         regwin_infos[row].w);
+       } else {
+               /* Read register value using custom function pointer. */
+               val = regwin_infos[row].read_func(
+                       regwin_infos[row].param);
+       }
+
+       return val;
+}
+
+void
+regwin_write(struct regwin_infos_t *p, int new)
+{
+       if (p->write_func == NULL) {
+               /*
+                * Write register value using generic 8 or 16 bits write
+                * function, depending on width.
+                */
+               regwin_write_generic(p->param, new, p->w);
+       } else {
+               /* Write register value using custom function pointer. */
+               p->write_func(p->param, new);
+       }
+}
+
+struct regwin_infos_t *
+sfr_get_infos(const char *regname)
+{
+       int row;
+
+       for (row = 0; row < SFR_REGS; row++) {
+               if (strcmp(regwin_infos[row].name, regname) == 0)
+                       return &regwin_infos[row];
+       }
+
+       return NULL; /* Programming error. */
+}
+
+struct regwin_infos_t *
+sfr_get_infos_from_row(int row)
+{
+       return &regwin_infos[row];
+}
+
diff --git a/src/common/sfr.h b/src/common/sfr.h
new file mode 100644 (file)
index 0000000..fe552dd
--- /dev/null
@@ -0,0 +1,46 @@
+/*
+ * sfr.h
+ *
+ * Copyright (C) 2013 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 SFR_H
+#define SFR_H 1
+
+#define SFR_REGS 26
+
+struct regwin_infos_t {
+       char *name; /* Register name */
+       int w; /* Number of hex digits to display */
+       unsigned int (*read_func)(int addr); /* Function to read value */
+       void (*write_func)(int param, int val); /* Function to write value */
+       int param; /* Optional parameter to pass to read function. */
+};
+
+int
+regwin_read(int row);
+
+void
+regwin_write(struct regwin_infos_t *p, int new);
+
+struct regwin_infos_t *
+sfr_get_infos(const char *regname);
+
+struct regwin_infos_t *
+sfr_get_infos_from_row(int row);
+
+#endif /* SFR_H */
diff --git a/src/common/timers.c b/src/common/timers.c
new file mode 100644 (file)
index 0000000..68a92bc
--- /dev/null
@@ -0,0 +1,144 @@
+/*
+ * timers.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.
+ */
+
+#include <stdio.h>
+#include <stdbool.h>
+#include <stdint.h>
+#include "config.h"
+
+#include "common.h"
+#include "reg8051.h"
+#include "cpu8051.h"
+#include "memory.h"
+#include "psw.h"
+#include "options.h"
+#include "instructions_8051.h"
+
+extern struct options_t options;
+
+static void
+timer_increment_check_overflow(uint8_t counter_address, uint8_t tf_mask)
+{
+       unsigned int tmp;
+
+       tmp = cpu8051_ReadD(counter_address);
+       tmp++;
+       tmp &= 0xFF;
+       if (tmp == 0) {
+               /* If overflow set TFx */
+               cpu8051_WriteD(_TCON_, cpu8051_ReadD(_TCON_) | tf_mask);
+       }
+
+       cpu8051_WriteD(counter_address, tmp); /* Save new value. */
+}
+
+static void
+timer_with_prescaler(uint8_t tl, uint8_t th, uint8_t tf_mask, int prescaler_width)
+{
+       unsigned int prescaler;
+
+       prescaler = cpu8051_ReadD(tl);
+       prescaler++;
+
+       prescaler &= (1 << prescaler_width) - 1; /* Keep only required bits */
+       cpu8051_WriteD(tl, prescaler);
+
+       if (prescaler == 0)
+               timer_increment_check_overflow(th, tf_mask);
+}
+
+static void
+process_timer(uint8_t tl, uint8_t th, uint8_t tf_mask, uint8_t TR, uint8_t mode,
+             uint8_t GATE, uint32_t TimerCounter)
+{
+       unsigned int tmp;
+
+       switch (mode) {
+       case 0:
+               /* Mode 0, 8-bit timer "TH" with "TL" as 5-bit prescaler. */
+               timer_with_prescaler(tl, th, tf_mask, 5);
+               break;
+       case 1:
+               /* Mode 1, 16-bits counter */
+               timer_with_prescaler(tl, th, tf_mask, 8);
+               break;
+       case 2:
+               /* Mode 2, 8-bits counter with Auto-Reload */
+               tmp = cpu8051_ReadD(tl);
+               tmp++;
+               tmp &= 0xFF;
+               if (tmp == 0) {
+                       /* If overflow -> reload and set TF0 */
+                       cpu8051_WriteD(_TCON_, cpu8051_ReadD(_TCON_) | tf_mask);
+                       cpu8051_WriteD(tl, cpu8051_ReadD(th));
+               } else
+                       cpu8051_WriteD(tl, tmp);
+               break;
+       case 3:
+               /*
+                * Mode 3:
+                *   inactive mode for timer 1
+                *   2 independents 8-bits timers for timer 0.
+                */
+
+               if (tl == _TL1_)
+                       break;
+
+               if (TR && !GATE && !TimerCounter)
+                       timer_increment_check_overflow(tl, tf_mask);
+
+               /* TH0 uses TR1 et TF1. */
+               TR = cpu8051_ReadD(_TCON_) & 0x40;
+
+               if (TR)
+                       timer_increment_check_overflow(th, 0x80);
+
+               break;
+       }
+}
+
+/* Run timers */
+void
+timers_check(void)
+{
+       unsigned int TR;
+       unsigned int MODE;
+       unsigned int GATE;
+       unsigned int TimerCounter;
+
+       /* Timer 0 */
+       TR = cpu8051_ReadD(_TCON_) & 0x10;
+       MODE = cpu8051_ReadD(_TMOD_) & 0x03;
+       GATE = cpu8051_ReadD(_TMOD_) & 0x08;
+       TimerCounter = cpu8051_ReadD(_TMOD_) & 0x04;
+
+       if ((TR && !GATE && !TimerCounter) || (MODE == 3))
+               process_timer(_TL0_, _TH0_, 0x20, TR, MODE, GATE, TimerCounter);
+
+       /* Timer 1 */
+       TR = cpu8051_ReadD(_TCON_) & 0x40;
+       MODE = (cpu8051_ReadD(_TMOD_) & 0x30) >> 4 ;
+       GATE = cpu8051_ReadD(_TMOD_) & 0x80;
+       TimerCounter = cpu8051_ReadD(_TMOD_) & 0x40;
+
+       if (TR && !GATE && !TimerCounter)
+               process_timer(_TL1_, _TH1_, 0x80, TR, MODE, GATE, TimerCounter);
+}
diff --git a/src/common/timers.h b/src/common/timers.h
new file mode 100644 (file)
index 0000000..932ace4
--- /dev/null
@@ -0,0 +1,29 @@
+/*
+ * timers.h
+ *
+ * Copyright (C) 2013 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 TIMERS_H
+#define TIMERS_H 1
+
+#include <stdint.h>
+
+int
+timers_check(void);
+
+#endif /* TIMERS_H */
diff --git a/src/cpu8051.c b/src/cpu8051.c
deleted file mode 100644 (file)
index bf7bd99..0000000
+++ /dev/null
@@ -1,651 +0,0 @@
-/*
- * cpu8051.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.
- */
-
-/* Define only here, for not having extern scope on local variables. */
-#define CPU8051_M 1
-
-#include <stdio.h>
-#include <stdint.h>
-
-#include "reg8051.h"
-#include "cpu8051.h"
-#include "memory.h"
-#include "psw.h"
-#include "timers.h"
-#include "disasm.h"
-#include "options.h"
-#include "instructions_8051.h"
-
-extern struct options_t options;
-
-/* Check if the address is a breakpoint */
-int
-IsBreakpoint(unsigned int address)
-{
-       int k;
-
-       for (k = 0; k < cpu8051.bp_count; k++) {
-               if (cpu8051.bp[k] == address)
-                       return 1;
-       }
-
-       /* The address was not found in the list of breakpoints */
-       return 0;
-}
-
-/* Check if the address is a stop point */
-int
-IsStoppoint(unsigned int address)
-{
-       if ((options.stop_address != 0) && (options.stop_address == address))
-               return 1;
-       else
-               return 0;
-}
-
-/* Show Breakpoints list */
-void
-ShowBreakpoints(void)
-{
-       int k;
-
-       for (k = 0; k < cpu8051.bp_count; k++)
-               printf("Breakpoint at address = %.4X\n", cpu8051.bp[k]);
-}
-
-/* Set Breakpoint at address at the end of the breakpoint list */
-void
-SetBreakpoint(unsigned int address)
-{
-       if (IsBreakpoint(address))
-               return; /* Already a breakpoint */
-
-       if (cpu8051.bp_count < MAXBP)
-               cpu8051.bp[cpu8051.bp_count++] = address;
-}
-
-/* Clear Breakpoint at Address from list */
-void
-ClearBreakpoint(unsigned int address)
-{
-       int k;
-
-       for (k = 0; k < cpu8051.bp_count; k++) {
-               if (cpu8051.bp[k] == address) {
-                       /* Fill removed breakpoint slot with last entry */
-                       cpu8051.bp[k] = cpu8051.bp[cpu8051.bp_count - 1];
-                       cpu8051.bp_count--;
-               }
-       }
-}
-
-/* Toggle the breakpoint at Address. */
-void
-ToggleBreakpoint(unsigned int address)
-{
-       if (IsBreakpoint(address))
-               ClearBreakpoint(address);
-       else
-               SetBreakpoint(address);
-}
-
-void
-cpu8051_init(void)
-{
-       memory_init();
-
-       cpu8051.pc = 0;
-       cpu8051.clock = 0;
-       cpu8051.active_priority = -1;
-       cpu8051.bp_count = 0;
-}
-
-/* Reset the registers and CPU state */
-void
-cpu8051_Reset(void)
-{
-       cpu8051.pc = 0;
-       cpu8051.clock = 0;
-       cpu8051.active_priority = -1;
-
-       /* Clear IRAM and SFR. */
-       memory_clear(INT_MEM_ID);
-
-       memory_sfr_write8(_P0_, 0xFF);
-       memory_sfr_write8(_P1_, 0xFF);
-       memory_sfr_write8(_P2_, 0xFF);
-       memory_sfr_write8(_P3_, 0xFF);
-
-       /* The default value of SP (after system reset) is 07 */
-       memory_sfr_write8(_SP_, 0x07);
-}
-
-static void
-cpu8051_convert_bit_address(uint8_t bit_address, uint8_t *byte_address,
-                           uint8_t *bit_number)
-{
-       if (bit_address > 0x7F) {
-               /* SFR 80-FF */
-               *byte_address = bit_address & 0xF8;
-               *bit_number = bit_address & 0x07;
-       } else {
-               /* 20-2F */
-               *byte_address = (bit_address >> 3) + 0x20;
-               *bit_number = bit_address & 0x07;
-       }
-}
-
-/* Write with a direct addressing mode at Address the new Value */
-void
-cpu8051_WriteD(unsigned int Address, unsigned char Value)
-{
-       memory_write8(INT_MEM_ID, Address, Value);
-}
-
-/* Write with an indirect addressing mode at Address the new Value */
-void
-cpu8051_WriteI(unsigned int Address, unsigned char Value)
-{
-       if (Address > 0x7F) {
-               memory_write8(EXT_MEM_ID, Address, Value);
-               return;
-       }
-
-       memory_write8(INT_MEM_ID, Address, Value);
-}
-
-/* Write with a bit addressing mode at BitAddress the new Value */
-void
-cpu8051_WriteB(uint8_t bit_address, uint8_t value)
-{
-       uint8_t byte_address;
-       uint8_t bit_number;
-       unsigned char ByteValue, ByteMask;
-
-       cpu8051_convert_bit_address(bit_address, &byte_address, &bit_number);
-
-       ByteMask = ((1 << bit_number) ^ 0xFF);
-       ByteValue = cpu8051_ReadD(byte_address) & ByteMask;
-       ByteValue += value << bit_number;
-       cpu8051_WriteD(byte_address, ByteValue);
-}
-
-/* Read with a direct addressing mode at Address */
-unsigned char
-cpu8051_ReadD(unsigned int Address)
-{
-       if (Address > 0xFF)
-               return memory_read8(EXT_MEM_ID, Address);
-       else
-               return memory_read8(INT_MEM_ID, Address);
-}
-
-/* Read with a indirect addressing mode at Address */
-unsigned char
-cpu8051_ReadI(unsigned int Address)
-{
-       if (Address > 0x7F)
-               return memory_read8(EXT_MEM_ID, Address);
-       else
-               return memory_read8(INT_MEM_ID, Address);
-}
-
-/* Read with a bit addressing mode at BitAddress */
-unsigned char
-cpu8051_ReadB(uint8_t bit_address)
-{
-       uint8_t byte_address;
-       uint8_t bit_number;
-       unsigned char BitValue;
-
-       cpu8051_convert_bit_address(bit_address, &byte_address, &bit_number);
-
-       BitValue = (cpu8051_ReadD(byte_address) >> bit_number);
-       BitValue &= 1;
-       return BitValue;
-}
-
-static int
-cpu8051_interrupt_fire(int interrupt_no, int priority)
-{
-       if (cpu8051_ReadD(_IP_) & INTERRUPT_MASK(interrupt_no))
-               return priority;
-       else
-               return !priority;
-}
-
-static int
-cpu8051_interrupt_enabled(int interrupt_no)
-{
-       return (cpu8051_ReadD(_IE_) & INTERRUPT_MASK(interrupt_no)) ? 1 : 0;
-}
-
-static void
-cpu8051_process_interrupt(int pc, int pri)
-{
-       stack_push16(cpu8051.pc);
-       cpu8051.pc = pc;
-       cpu8051.active_priority = pri;
-}
-
-
-/* Check interrupts state and process them as needed */
-static void
-cpu8051_CheckInterrupts(void)
-{
-       int i;
-
-       if ((cpu8051_ReadD(_IE_) & 0x80) == 0)
-               return;
-
-       for (i = INTERRUPT_PRIORITY_HIGH; i >= INTERRUPT_PRIORITY_LOW; i--) {
-               if (cpu8051.active_priority < i) {
-                       /* Interrupt timer 0 */
-                       if (cpu8051_interrupt_enabled(INTERRUPT_1) &&
-                           cpu8051_interrupt_fire(INTERRUPT_1, i) &&
-                            (cpu8051_ReadD(_TCON_) & 0x20)) {
-                               cpu8051_WriteD(_TCON_,
-                                              cpu8051_ReadD(_TCON_) & 0xDF);
-                               cpu8051_process_interrupt(0x0B, i);
-                               return;
-                       }
-                       /* Interrupt timer 1 */
-                       if (cpu8051_interrupt_enabled(INTERRUPT_3) &&
-                           cpu8051_interrupt_fire(INTERRUPT_3, i) &&
-                           (cpu8051_ReadD(_TCON_) & 0x80)) {
-                               cpu8051_WriteD(_TCON_,
-                                              cpu8051_ReadD(_TCON_) & 0x7F);
-                               cpu8051_process_interrupt(0x1B, i);
-                               return;
-                       }
-                       /* Serial Interrupts */
-                       if (cpu8051_interrupt_enabled(INTERRUPT_4) &&
-                           cpu8051_interrupt_fire(INTERRUPT_4, i) &&
-                           (cpu8051_ReadD(_SCON_) & 0x03)) {
-                               cpu8051_process_interrupt(0x23, i);
-                               return;
-                       }
-                       /* Interrupt timer 2 */
-                       if (cpu8051_interrupt_enabled(INTERRUPT_5) &&
-                           cpu8051_interrupt_fire(INTERRUPT_5, i) &&
-                           (cpu8051_ReadD(_T2CON_) & 0x80)) {
-                               cpu8051_process_interrupt(0x2B, i);
-                               return;
-                       }
-               }
-       }
-}
-
-/* Execute at address cpu8051.pc from PGMMem */
-void
-cpu8051_Exec(void)
-{
-       int i;
-       unsigned char opcode;
-       int insttiming;
-
-       opcode = memory_read8(PGM_MEM_ID, cpu8051.pc);
-       cpu8051.pc++;
-       insttiming = (*opcode_table[opcode])(); /* Function callback. */
-
-       /*
-        * Parity bit (p): is automatically set or cleared in each machine
-        * cycle to establish even parity in the accumulator.
-        */
-       psw_compute_parity_bit();
-
-       for (i = 0; i < insttiming; i++) {
-               cpu8051_CheckInterrupts();
-               timers_check();
-               cpu8051.clock++;
-       }
-}
-
-/*
- * Addressing modes defined in the order as they appear in disasm.h
- * from table argstext[]
- */
-#define ADDR11 0
-#define ADDR16 1
-#define DIRECT 3
-#define BITADDR 14
-#define RELADDR 15
-#define DATAIMM 16
-#define DATA16 22
-#define CBITADDR 23
-
-/*
- * SFR Memory map [80h - FFh]
- * ---------------------------------------------------------------
- * F8 |      |      |      |      |      |      |      |      | FF
- * F0 |   B  |      |      |      |      |      |      |      | F7
- * E8 |      |      |      |      |      |      |      |      | EF
- * E0 |  ACC |      |      |      |      |      |      |      | E7
- * D8 |      |      |      |      |      |      |      |      | DF
- * D0 |  PSW |      |      |      |      |      |      |      | D7
- * C8 | T2CON|      |RCAP2L|RCAP2H|  TL2 |  TH2 |      |      | CF
- * C0 |      |      |      |      |      |      |      |      | C7
- * B8 |  IP  |      |      |      |      |      |      |      | BF
- * B0 |  P3  |      |      |      |      |      |      |      | B7
- * A8 |  IE  |      |      |      |      |      |      |      | AF
- * A0 |  P2  |      |      |      |      |      |      |      | A7
- * 98 | SCON | SBUF |      |      |      |      |      |      | 9F
- * 90 |  P1  |      |      |      |      |      |      |      | 97
- * 88 | TCON | TMOD |  TL0 |  TL1 |  TH0 |  TH1 |      |      | 8F
- * 80 |  P0  |  SP  |  DPL |  DPH |      |      |      | PCON | 87
- * ---------------------------------------------------------------
- */
-
-/* Return as Text the name of the SFR register at Address if any */
-static int
-cpu8051_SFRMemInfo(unsigned int Address, char *Text)
-{
-       switch (Address) {
-       case 0x80: return sprintf(Text, "P0");
-       case 0x81: return sprintf(Text, "SP");
-       case 0x82: return sprintf(Text, "DPL");
-       case 0x83: return sprintf(Text, "DPH");
-       case 0x87: return sprintf(Text, "PCON");
-       case 0x88: return sprintf(Text, "TCON");
-       case 0x89: return sprintf(Text, "TMOD");
-       case 0x8A: return sprintf(Text, "TL0");
-       case 0x8B: return sprintf(Text, "TL1");
-       case 0x8C: return sprintf(Text, "TH0");
-       case 0x8D: return sprintf(Text, "TH1");
-       case 0x90: return sprintf(Text, "P1");
-       case 0x98: return sprintf(Text, "SCON");
-       case 0x99: return sprintf(Text, "SBUF");
-       case 0xA0: return sprintf(Text, "P2");
-       case 0xA8: return sprintf(Text, "IE");
-       case 0xB0: return sprintf(Text, "P3");
-       case 0xB8: return sprintf(Text, "IP");
-       case 0xC8: return sprintf(Text, "T2CON");
-       case 0xCA: return sprintf(Text, "RCAP2L");
-       case 0xCB: return sprintf(Text, "RCAP2H");
-       case 0xCC: return sprintf(Text, "TL2");
-       case 0xCD: return sprintf(Text, "TH2");
-       case 0xD0: return sprintf(Text, "PSW");
-       case 0xE0: return sprintf(Text, "ACC");
-       case 0xF0: return sprintf(Text, "B");
-       default: return sprintf(Text, "%.2XH", Address);
-       }
-}
-
-/* Return as Text the decoded BitAddress */
-static void
-cpu8051_IntMemBitInfo(uint8_t bit_address, char *text)
-{
-       uint8_t byte_address;
-       uint8_t bit_number;
-       int len;
-
-       cpu8051_convert_bit_address(bit_address, &byte_address, &bit_number);
-
-       len = cpu8051_SFRMemInfo(byte_address, text);
-       sprintf(&text[len], ".%X", bit_address);
-}
-
-/* Get instruction size from opcode */
-int
-cpu8051_get_instruction_size(unsigned char opcode)
-{
-       return InstSizesTbl[opcode];
-}
-
-/* Display instruction mnemonic. */
-void
-cpu8051_disasm_mnemonic(unsigned char OpCode, char *buf)
-{
-       sprintf(buf, "%s", InstTextTbl[InstTypesTbl[OpCode]]);
-}
-
-/* Disasm instruction arguments starting at address into a text string */
-void
-cpu8051_disasm_args(unsigned int address, char *buf)
-{
-       int len = 0;
-       char TextTmp[20];
-       unsigned char OpCode;
-       int ArgTblOfs;
-       int i;
-
-       OpCode = memory_read8(PGM_MEM_ID, address);
-       ArgTblOfs = OpCode << 2;
-       address++;
-
-       /*
-        * MOV direct, direct (OpCode 85h) is peculiar, the operands
-        * are inverted
-        */
-       if (OpCode == 0x85) {
-               cpu8051_SFRMemInfo(memory_read8(PGM_MEM_ID, address + 1),
-                                  TextTmp);
-               len += sprintf(&buf[len], "%s,", TextTmp);
-               cpu8051_SFRMemInfo(memory_read8(PGM_MEM_ID, address),
-                                  TextTmp);
-               len += sprintf(&buf[len], "%s", TextTmp);
-               address += 2;
-               return;
-       }
-
-       for (i = 1; i <= InstArgTbl[ArgTblOfs]; i++) {
-               switch (InstArgTbl[ArgTblOfs + i]) {
-               case ADDR11: {
-                       len += sprintf(&buf[len],
-                                      "%.4XH", ((OpCode << 3) & 0xF00) +
-                                      (memory_read8(PGM_MEM_ID, address)));
-                       address++;
-                       break;
-               }
-               case ADDR16: {
-                       len += sprintf(
-                               &buf[len], "%.4XH",
-                               ((memory_read8(PGM_MEM_ID, address) << 8) +
-                                memory_read8(PGM_MEM_ID, address + 1)));
-                       address += 2;
-                       break;
-               }
-               case DIRECT: {
-                       cpu8051_SFRMemInfo(memory_read8(PGM_MEM_ID, address),
-                                          TextTmp);
-                       len += sprintf(&buf[len], "%s", TextTmp);
-                       address++;
-                       break;
-               }
-               case BITADDR: {
-                       cpu8051_IntMemBitInfo(
-                               (memory_read8(PGM_MEM_ID, address) & 0xF8),
-                               TextTmp);
-                       len += sprintf(&buf[len], "%s.%X" , TextTmp,
-                                      (memory_read8(PGM_MEM_ID, address) & 7));
-                       address++;
-                       break;
-               }
-               case RELADDR: {
-                       address++;
-                       len += sprintf(&buf[len], "%.4XH", (address & 0xFF00) +
-                                      (((address & 0xFF) +
-                                        memory_read8(PGM_MEM_ID,
-                                                     address - 1)) & 0xFF));
-                       break;
-               }
-               case DATAIMM: {
-                       len += sprintf(&buf[len], "#%.2XH",
-                                      memory_read8(PGM_MEM_ID, address));
-                       address++;
-                       break;
-               }
-               case DATA16: {
-                       len += sprintf(&buf[len], "#%.4XH",
-                                      ((memory_read8(PGM_MEM_ID,
-                                                     address) << 8) +
-                                       memory_read8(PGM_MEM_ID, address+1)));
-                       address += 2;
-                       break;
-               }
-               case CBITADDR: {
-                       cpu8051_IntMemBitInfo((memory_read8(PGM_MEM_ID,
-                                                           address) & 0xF8),
-                                             TextTmp);
-                       len += sprintf(&buf[len], "/%s.%X", TextTmp,
-                                      (memory_read8(PGM_MEM_ID, address) & 7));
-                       address++;
-                       break;
-               }
-               default: {
-                       len += sprintf(&buf[len], "%s",
-                                      ArgsTextTbl[InstArgTbl[ArgTblOfs + i]]);
-               }
-               }
-               if (i < InstArgTbl[ArgTblOfs])
-                       len += sprintf(&buf[len], ",");
-       }
-}
-
-/* Disasm one instruction at Address into a Text string */
-int
-cpu8051_Disasm(unsigned int Address, char *Text)
-{
-       int len = 0;
-       char TextTmp[20];
-       unsigned char OpCode;
-       int ArgTblOfs;
-       int InstSize;
-       int i;
-
-       /* Display address. */
-       len += sprintf(Text, " %.4X ", Address);
-
-       OpCode = memory_read8(PGM_MEM_ID, Address);
-       InstSize = InstSizesTbl[OpCode];
-
-       /* Display hex bytes. */
-       for (i = 0; i < InstSize; i++)
-               len += sprintf(&Text[len], " %.2X",
-                                     memory_read8(PGM_MEM_ID, Address + i));
-
-       Address++;
-
-       /* Padd remaining area with spaces. */
-       for (; len < 17;)
-               len += sprintf(&Text[len], " ");
-
-       /* Display instruction mnemonic. */
-       len += sprintf(&Text[len], "%s ",
-                             InstTextTbl[InstTypesTbl[OpCode]]);
-       ArgTblOfs = OpCode << 2;
-
-       /* Padd remaining area with spaces. */
-       for (; len < 25;)
-               len += sprintf(&Text[len], " ");
-
-       /* Display instruction arguments. */
-
-       /*
-        * MOV direct, direct (OpCode 85h) is peculiar, the operands
-        * are inverted
-        */
-       if (OpCode == 0x85) {
-               cpu8051_SFRMemInfo(memory_read8(PGM_MEM_ID, Address + 1),
-                                  TextTmp);
-               len += sprintf(&Text[len], "%s,", TextTmp);
-               cpu8051_SFRMemInfo(memory_read8(PGM_MEM_ID, Address),
-                                  TextTmp);
-               len += sprintf(&Text[len], "%s", TextTmp);
-               Address += 2;
-               return InstSize;
-       }
-
-       for (i = 1; i <= InstArgTbl[ArgTblOfs]; i++) {
-               switch (InstArgTbl[ArgTblOfs + i]) {
-               case ADDR11: {
-                       len += sprintf(&Text[len],
-                                      "%.4XH", ((OpCode << 3) & 0xF00) +
-                                      (memory_read8(PGM_MEM_ID, Address)));
-                       Address++;
-                       break;
-               }
-               case ADDR16: {
-                       len += sprintf(
-                               &Text[len], "%.4XH",
-                               ((memory_read8(PGM_MEM_ID, Address) << 8) +
-                                memory_read8(PGM_MEM_ID, Address + 1)));
-                       Address += 2;
-                       break;
-               }
-               case DIRECT: {
-                       cpu8051_SFRMemInfo(memory_read8(PGM_MEM_ID, Address),
-                                          TextTmp);
-                       len += sprintf(&Text[len], "%s", TextTmp);
-                       Address++;
-                       break;
-               }
-               case BITADDR: {
-                       cpu8051_IntMemBitInfo(
-                               (memory_read8(PGM_MEM_ID, Address) & 0xF8),
-                               TextTmp);
-                       len += sprintf(&Text[len], "%s.%X" , TextTmp,
-                                      (memory_read8(PGM_MEM_ID, Address) & 7));
-                       Address++;
-                       break;
-               }
-               case RELADDR: {
-                       Address++;
-                       len += sprintf(&Text[len], "%.4XH", (Address & 0xFF00) +
-                                      (((Address & 0xFF) +
-                                        memory_read8(PGM_MEM_ID,
-                                                     Address - 1)) & 0xFF));
-                       break;
-               }
-               case DATAIMM: {
-                       len += sprintf(&Text[len], "#%.2XH",
-                                      memory_read8(PGM_MEM_ID, Address));
-                       Address++;
-                       break;
-               }
-               case DATA16: {
-                       len += sprintf(&Text[len], "#%.4XH",
-                                      ((memory_read8(PGM_MEM_ID,
-                                                     Address) << 8) +
-                                       memory_read8(PGM_MEM_ID, Address+1)));
-                       Address += 2;
-                       break;
-               }
-               case CBITADDR: {
-                       cpu8051_IntMemBitInfo((memory_read8(PGM_MEM_ID,
-                                                           Address) & 0xF8),
-                                             TextTmp);
-                       len += sprintf(&Text[len], "/%s.%X", TextTmp,
-                                      (memory_read8(PGM_MEM_ID, Address) & 7));
-                       Address++;
-                       break;
-               }
-               default: {
-                       len += sprintf(&Text[len], "%s",
-                                      ArgsTextTbl[InstArgTbl[ArgTblOfs + i]]);
-               }
-               }
-               if (i < InstArgTbl[ArgTblOfs])
-                       len += sprintf(&Text[len], ",");
-       }
-
-       return InstSize;
-}
diff --git a/src/cpu8051.h b/src/cpu8051.h
deleted file mode 100644 (file)
index adb96c8..0000000
+++ /dev/null
@@ -1,116 +0,0 @@
-/*
- * cpu8051.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 CPU8051_H
-#define CPU8051_H 1
-
-#include <stdint.h>
-
-/* Maximum number of BreakPoints */
-#define MAXBP 32
-
-#define INTERRUPT_0 (0)
-#define INTERRUPT_1 (1)
-#define INTERRUPT_2 (2)
-#define INTERRUPT_3 (3)
-#define INTERRUPT_4 (4)
-#define INTERRUPT_5 (5)
-#define INTERRUPT_MASK(n) (1 << n)
-
-#define INTERRUPT_PRIORITY_HIGH     (1)
-#define INTERRUPT_PRIORITY_LOW      (0)
-
-struct cpu8051_t {
-       unsigned int pc; /* Program counter */
-       unsigned long clock;
-       int active_priority;
-       int bp_count;
-       unsigned int bp[MAXBP]; /* List of breakpoints */
-};
-
-/* Exported variables */
-#undef _SCOPE_
-#ifdef CPU8051_M
-#  define _SCOPE_ /**/
-#else
-#  define _SCOPE_ extern
-#endif
-
-_SCOPE_ struct cpu8051_t cpu8051;
-
-int
-IsBreakpoint(unsigned int Address);
-
-int
-IsStoppoint(unsigned int address);
-
-void
-ShowBreakpoints(void);
-
-void
-SetBreakpoint(unsigned int Address);
-
-void
-ClearBreakpoint(unsigned int Address);
-
-void
-ToggleBreakpoint(unsigned int Address);
-
-void
-cpu8051_init(void);
-
-void
-cpu8051_Exec(void);
-
-void
-cpu8051_Reset(void);
-
-void
-cpu8051_WriteD(unsigned int Address, unsigned char Value);
-
-void
-cpu8051_WriteI(unsigned int Address, unsigned char Value);
-
-void
-cpu8051_WriteB(uint8_t bit_address, uint8_t value);
-
-unsigned char
-cpu8051_ReadD(unsigned int Address);
-
-unsigned char
-cpu8051_ReadI(unsigned int Address);
-
-unsigned char
-cpu8051_ReadB(uint8_t bit_address);
-
-int
-cpu8051_get_instruction_size(unsigned char opcode);
-
-void
-cpu8051_disasm_mnemonic(unsigned char OpCode, char *buf);
-
-void
-cpu8051_disasm_args(unsigned int address, char *buf);
-
-int
-cpu8051_Disasm(unsigned int Address, char *Text);
-
-#endif /* CPU8051_H */
diff --git a/src/emuconsole.c b/src/emuconsole.c
deleted file mode 100644 (file)
index f29146d..0000000
+++ /dev/null
@@ -1,518 +0,0 @@
-/*
- * emuconsole.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.
- */
-
-#define _GNU_SOURCE /* For getline() */
-#include <stdio.h>
-#include <string.h>
-#include <ctype.h> /* For isblank, toupper() */
-#include "config.h"
-
-#include "common.h"
-#include "cpu8051.h"
-#include "reg8051.h"
-#include "sfr.h"
-#include "memory.h"
-#include "options.h"
-#include "hexfile.h"
-#include "keyboard.h"
-
-extern struct options_t options;
-
-/* Capitalize all letters in buffer */
-static void
-Capitalize(char *buffer)
-{
-       int k;
-
-       for (k = 0; k < strlen(buffer); k++)
-               buffer[k] = toupper(buffer[k]);
-}
-
-/* Remove leading spaces from string in buffer */
-static void
-RemoveSpaces(char *buffer)
-{
-       int k = 0;
-
-       while ((k < strlen(buffer)) && isblank(buffer[k]))
-               k++;
-
-       if (k != 0)
-               strcpy(buffer, &buffer[k]);
-}
-
-/* CPU exec and Console UI update */
-static void
-console_exec(char *Address, char *NumberInst)
-{
-       int NbInst = -1; /* -1 is infinity */
-       if (strlen(Address) == 0) {
-               log_err("Invalid address");
-               return;
-       }
-
-       if (!STREQ(Address, "PC"))
-               cpu8051.pc = Ascii2Hex(Address, strlen(Address));
-
-       if (NumberInst)
-               if (strlen(NumberInst) != 0)
-                       NbInst = Ascii2Hex(NumberInst, strlen(NumberInst));
-
-       InitUnixKB();
-
-       log_info("Program executing...");
-
-       do {
-               cpu8051_Exec();
-               if (NbInst > 0)
-                       NbInst--;
-       } while (!IsBreakpoint(cpu8051.pc) && !IsStoppoint(cpu8051.pc) &&
-                (NbInst != 0) && !kbhit());
-       if (kbhit()) {
-               (void) getch(); /* Flush key */
-               log_info("Caught break signal!");
-       }
-       if (NbInst == 0)
-               log_info("Number of instructions reached! Stopping!");
-       if (IsBreakpoint(cpu8051.pc))
-               log_info("Breakpoint hit at %.4X! Stopping!", cpu8051.pc);
-       if (IsStoppoint(cpu8051.pc))
-               log_info("Stoppoint hit at %.4X! Stopping!", cpu8051.pc);
-
-       ResetUnixKB();
-}
-
-/* Disassemble NumberInst instructions at Address */
-static void
-DisasmN(unsigned int Address, int NumberInst)
-{
-       char TextTmp[255];
-       int Row;
-
-       for (Row = 0; Row < NumberInst ; Row++) {
-               Address += cpu8051_Disasm(Address, TextTmp);
-               printf("%s\n", TextTmp);
-
-               if (Address > 0xFFFF)
-                       return;
-       }
-}
-
-/* Disassemble 16 instructions at Address */
-static void
-Disasm(char *Address, char *NumberInst)
-{
-       unsigned int MemAddress, NbInst;
-
-       if ((strlen(Address) == 0) || (STREQ(Address, "PC")))
-               MemAddress = cpu8051.pc;
-       else
-               MemAddress = Ascii2Hex(Address, strlen(Address));
-
-       if (strlen(NumberInst) == 0)
-               NumberInst = "10";
-       NbInst = Ascii2Hex(NumberInst, strlen(NumberInst));
-       DisasmN(MemAddress, NbInst);
-}
-
-/* Set NewValue to Register */
-static void
-SetRegister(char *Register, char *NewValue)
-{
-       if (STREQ(Register, "PC"))
-               cpu8051.pc = Ascii2Hex(NewValue, 4);
-       else if (STREQ(Register, "A"))
-               cpu8051_WriteD(_ACC_, Ascii2Hex(NewValue, 2));
-       else if (STREQ(Register, "B"))
-               cpu8051_WriteD(_B_, Ascii2Hex(NewValue, 2));
-       else if (STREQ(Register, "SP"))
-               cpu8051_WriteD(_SP_, Ascii2Hex(NewValue, 2));
-       else {
-               printf("\nInvalid register name!\n");
-               printf("Valid registers are A, B, PC and SP.\n");
-       }
-}
-
-/* Show CPU registers, one per line */
-static void
-console_dump_sfr_registers_detailed(void)
-{
-       int k;
-
-       for (k = 0; k < SFR_REGS; k++) {
-               struct regwin_infos_t *regwin_infos;
-               int val;
-
-               regwin_infos = sfr_get_infos_from_row(k);
-
-               printf("%s = ", regwin_infos->name);
-
-               val = regwin_read(k);
-               if (regwin_infos->w == 2)
-                       printf("$%02X", val);
-               else if (regwin_infos->w == 4)
-                       printf("$%04X", val);
-
-               printf("\n");
-       }
-}
-
-/* Show CPU registers, compact format */
-static void
-console_dump_sfr_registers_compact(void)
-{
-       unsigned char PSW = cpu8051_ReadD(_PSW_);
-       int BankSelect = (PSW & 0x18);
-
-       printf("---------------------------------------------------------------"
-              "-------\n");
-       printf("|  PC  | SP | DPTR | ACC |  B | PSW:  CY  AC  F0 RS1 RS0  OV"
-              "   -   P |\n");
-       printf("| %.4X | %.2X | %.4X |  %.2X | %.2X |", cpu8051.pc,
-              cpu8051_ReadD(_SP_),
-              memory_sfr_read_dptr(),
-              cpu8051_ReadD(_ACC_), cpu8051_ReadD(_B_));
-       printf("        %d   %d   %d   %d   %d   %d   %d   %d |",
-              (PSW >> 7) & 1, (PSW >> 6) & 1, (PSW >> 5) & 1, (PSW >> 4) & 1,
-              (PSW >> 3) & 1, (PSW >> 2) & 1, (PSW >> 1) & 1, PSW & 1);
-       printf("\n");
-       printf("---------------------------------------------------------------"
-              "-------\n");
-
-       printf("| TCON | TMOD | IE | IP | R0 | R1 | R2 | R3 | R4 | R5 | R6 | R7"
-              " |    |\n");
-       printf("|   %.2X |   %.2X | %.2X | %.2X ", cpu8051_ReadD(_TCON_),
-              cpu8051_ReadD(_TMOD_), cpu8051_ReadD(_IE_), cpu8051_ReadD(_IP_));
-       printf("| %.2X | %.2X | %.2X | %.2X ",
-              cpu8051_ReadD(BankSelect + _R0_),
-              cpu8051_ReadD(BankSelect + _R1_),
-              cpu8051_ReadD(BankSelect + _R2_),
-              cpu8051_ReadD(BankSelect + _R3_));
-       printf("| %.2X | %.2X | %.2X | %.2X ",
-              cpu8051_ReadD(BankSelect + _R4_),
-              cpu8051_ReadD(BankSelect + _R5_),
-              cpu8051_ReadD(BankSelect + _R6_),
-              cpu8051_ReadD(BankSelect + _R7_));
-       printf("|    |\n");
-       printf("---------------------------------------------------------------"
-              "-------\n");
-}
-
-/* Show CPU registers */
-static void
-console_show_registers(void)
-{
-       if (options.stop_address != 0)
-               console_dump_sfr_registers_detailed();
-       else
-               console_dump_sfr_registers_compact();
-}
-
-/* CPU reset and Console UI update */
-static void
-console_reset(void)
-{
-       log_info("Resetting...");
-       cpu8051_Reset();
-       log_info("Done");
-}
-
-/* CPU trace and Console UI update */
-static void
-console_trace(char *Address)
-{
-       if (strlen(Address) != 0)
-               cpu8051.pc = Ascii2Hex(Address, strlen(Address));
-       cpu8051_Exec();
-       console_show_registers();
-       DisasmN(cpu8051.pc, 1);
-}
-
-/* EmuConsole main loop */
-static void
-console_main(void)
-{
-       unsigned int Index;
-       char *line = NULL;
-       int QuitRequest = 0;
-       char prompt[] = "-> ";
-
-       char *Title[] = { "      *******************",
-                         "      *  8051 Emulator  *",
-                         "      *******************",
-                         "", 0 };
-
-       char *Menu[] = {
-               "      Available commands, [ ] = options",
-               "",
-               "  Set Breakpoint.............. SB [address]",
-               "  Remove Breakpoint........... RB [address]",
-               "  Display Breakpoint(s)....... DB",
-               "  Dump External Data Memory... DE [address] [size]",
-               "  Dump Internal Data Memory... DI [address] [size]",
-               "  Dump Program Memory......... DP [address] [size]",
-               "  Display Registers content... DR",
-               "  Execute..................... EM [address"
-               " [number of instructions]]",
-               "  Help........................ H or ?",
-               "  Modify External Data Memory. ME address value",
-               "  Modify Internal Data Memory. MI address value",
-               "  Modify Program Memory....... MP address value",
-               "  Modify Register............. MR register value",
-               "  Quit Emulator............... Q",
-               "  Trace mode.................. T [address]",
-               "  Unassemble.................. U [address]"
-               " [number of instructions]",
-               "  Reset processor............. Z", 0 };
-
-       console_reset();
-
-       if (options.stop_address != 0) {
-               /* Automatically run program and stop at specified address. */
-               console_exec("0x0000", NULL);
-               console_show_registers();
-               QuitRequest = 1;
-       } else {
-               Index = 0;
-               while (Title[Index] != 0)
-                       printf("%s\n", Title[Index++]);
-
-               Index = 0;
-               while (Menu[Index] != 0)
-                       printf("%s\n", Menu[Index++]);
-
-               console_show_registers();
-       }
-
-       while (!QuitRequest) {
-               int slen;
-               size_t len = 0;
-               char Command[256];
-               char Args[256];
-               char Parameter1[256];
-               char Parameter2[256];
-
-               Parameter1[0] = '\0';
-               Parameter2[0] = '\0';
-
-               printf(prompt);
-               (void) getline(&line, &len, stdin);
-               Capitalize(line);
-               RemoveSpaces(line);
-
-               /* Strip trailing newline */
-               slen = strlen(line);
-               if (line[slen - 1] == '\n')
-                       line[slen - 1] = '\0';
-
-               /* Find command-arguments delimiter */
-               for (Index = 0; Index < strlen(line); Index++) {
-                       if (isblank(line[Index]))
-                               break;
-               }
-
-               /* Keep only the Command part from the input line */
-               memcpy(Command, &line[0], Index);
-               Command[Index] = '\0';
-
-               /* Keep only the arguments part from the input line */
-               if (Index < strlen(line)) {
-                       slen = strlen(line) - Index;
-                       memcpy(Args, &line[Index + 1], slen);
-               } else {
-                       slen = 0;
-               }
-               Args[slen] = '\0';
-               RemoveSpaces(Args);
-
-               /* Find multi-arguments delimiter */
-               for (Index = 0; Index < strlen(Args); Index++) {
-                       if (isblank(Args[Index]))
-                               break;
-               }
-
-               memcpy(Parameter1, &Args[0], Index);
-               Parameter1[Index] = '\0';
-
-               if (Index < strlen(Args)) {
-                       slen = strlen(Args) - Index;
-                       memcpy(Parameter2, &Args[Index + 1], slen);
-               } else {
-                       slen = 0;
-               }
-               Parameter2[slen] = '\0';
-               RemoveSpaces(Parameter2);
-
-               if (strlen(Command) == 0) {
-                       goto syntax_error;
-                       continue;
-               }
-
-               if ((strlen(Parameter1) > 4) || (strlen(Parameter2) > 4)) {
-                       printf("Invalid Parameter Format!\n");
-                       continue;
-               }
-
-               switch (Command[0]) {
-               case 'D':
-                       if (STREQ(Command, "DB") &&
-                           (strlen(Parameter1) == 0))
-                               ShowBreakpoints();
-                       else if (STREQ(Command, "DE"))
-                               DumpMem(Parameter1, Parameter2, EXT_MEM_ID);
-                       else if (STREQ(Command, "DI"))
-                               DumpMem(Parameter1, Parameter2, INT_MEM_ID);
-                       else if (STREQ(Command, "DP")) {
-                               if ((strlen(Parameter1) == 0))
-                                       strcpy(Parameter1, "PC");
-                               DumpMem(Parameter1, Parameter2, PGM_MEM_ID);
-                       } else if (STREQ(Command, "DR") &&
-                                  (strlen(Parameter1) == 0))
-                               console_show_registers();
-                       else
-                               goto syntax_error;
-                       break;
-               case 'E':
-                       if (STREQ(Command, "EM"))
-                               console_exec(Parameter1, Parameter2);
-                       else
-                               goto syntax_error;
-                       break;
-               case 'H':
-               case '?':
-                       if ((STREQ(Command, "H") || STREQ(Command, "?")) &&
-                           (strlen(Parameter1) == 0) &&
-                           (strlen(Parameter2) == 0)) {
-                               Index = 0;
-                               while (Menu[Index] != 0)
-                                       printf("%s\n", Menu[Index++]);
-                       } else
-                               goto syntax_error;
-                       break;
-               case 'M':
-                       if ((strlen(Parameter1) == 0) ||
-                           (strlen(Parameter2) == 0))
-                               printf("Missing Parameter!\n");
-                       else if (STREQ(Command, "ME")) {
-                               unsigned int adresse = Ascii2Hex(Parameter1, 4);
-                               unsigned char valeur = Ascii2Hex(Parameter2, 2);
-                               memory_write8(EXT_MEM_ID, adresse, valeur);
-                       } else if (STREQ(Command, "MI")) {
-                               unsigned int adresse = Ascii2Hex(Parameter1, 2);
-                               unsigned char valeur = Ascii2Hex(Parameter2, 2);
-                               memory_write8(INT_MEM_ID, adresse, valeur);
-                       } else if (STREQ(Command, "MP")) {
-                               unsigned int adresse = Ascii2Hex(Parameter1, 4);
-                               unsigned char valeur = Ascii2Hex(Parameter2, 2);
-                               memory_write8(PGM_MEM_ID, adresse, valeur);
-                       } else if (STREQ(Command, "MR"))
-                               SetRegister(Parameter1, Parameter2);
-                       else
-                               goto syntax_error;
-                       break;
-               case 'Q':
-                       if (STREQ(Command, "Q") && (strlen(Parameter1) == 0) &&
-                           (strlen(Parameter2) == 0))
-                               QuitRequest = 1;
-                       else
-                               goto syntax_error;
-                       break;
-               case 'R':
-                       if (strlen(Parameter2) != 0)
-                               goto TooMuchParameters;
-                       if (STREQ(Command, "RB")) {
-                               if (strlen(Parameter1) == 0)
-                                       ClearBreakpoint(cpu8051.pc);
-                               else
-                                       ClearBreakpoint(
-                                               Ascii2Hex(Parameter1, 4));
-                       } else
-                               goto syntax_error;
-                       break;
-               case 'S':
-                       if (strlen(Parameter2) != 0)
-                               goto TooMuchParameters;
-
-                       if (STREQ(Command, "SB")) {
-                               if (strlen(Parameter1) == 0)
-                                       SetBreakpoint(cpu8051.pc);
-                               else
-                                       SetBreakpoint(Ascii2Hex(Parameter1, 4));
-                       } else
-                               goto syntax_error;
-                       break;
-               case 'T':
-                       if (strlen(Parameter2) != 0)
-                               printf("Wrong Number of Parameters!\n");
-
-                       if (STREQ(Command, "T"))
-                               console_trace(Parameter1);
-                       else
-                               goto syntax_error;
-                       break;
-               case 'U':
-                       if (STREQ(Command, "U"))
-                               Disasm(Parameter1, Parameter2);
-                       else
-                               goto syntax_error;
-                       break;
-               case 'Z':
-                       if (STREQ(Command, "Z") && (strlen(Parameter1) == 0) &&
-                           (strlen(Parameter2) == 0))
-                               cpu8051_Reset();
-                       else
-                               goto syntax_error;
-                       break;
-               case '\n':
-                       break;
-               default:
-                       goto syntax_error;
-               }
-               continue;
-
-syntax_error:
-               printf("Syntax Error!\n");
-               continue;
-TooMuchParameters:
-               printf("Wrong Number of Parameters!\n");
-               continue;
-       }
-
-       if (line)
-               free(line);
-}
-
-int
-main(int argc, char **argv)
-{
-       parse_command_line_options(argc, argv);
-
-       cpu8051_init();
-
-       if (options.filename != NULL)
-               LoadHexFile(options.filename);
-
-       console_main();
-
-       log_info("Terminate");
-
-       return 0;
-}
diff --git a/src/emugtk.c b/src/emugtk.c
deleted file mode 100644 (file)
index b5ef13f..0000000
+++ /dev/null
@@ -1,528 +0,0 @@
-/*
- * emugtk.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.
- */
-
-#include <stdio.h>
-#include "config.h"
-
-#include <stdint.h>
-#include <stdbool.h>
-
-#include <gtk/gtk.h>
-
-#include "common.h"
-#include "cpu8051.h"
-#include "memory.h"
-#include "options.h"
-#include "hexfile.h"
-
-#include "emugtk.h"
-#include "reset.xpm"
-#include "run.xpm"
-#include "stop.xpm"
-#include "step.xpm"
-#include "filemenu.h"
-#include "viewmenu.h"
-#include "helpmenu.h"
-#include "regwin.h"
-#include "pgmwin.h"
-#include "memwin.h"
-#include "pswwin.h"
-#include "app-config.h"
-
-#define BUTTONS_BORDER 2
-
-static int running;
-static int running_function_tag;
-static int restart_gui = true;
-
-GtkWidget *mainwin;
-
-extern struct app_config_t *cfg;
-extern struct options_t options;
-
-void
-emugtk_UpdateDisplay(void)
-{
-       log_debug("UpdateDisplay()");
-       regwin_refresh();
-       pgmwin_refresh();
-       pswwin_refresh();
-
-       if (cfg->view_int_memory)
-               memwin_refresh(INT_MEM_ID);
-
-       if (cfg->view_ext_memory)
-               memwin_refresh(EXT_MEM_ID);
-}
-
-/* Step out of running state */
-static void
-emugtk_stop_running()
-{
-       if (running) {
-               log_info("StopRunning()");
-               g_source_remove(running_function_tag);
-               running = 0;
-               emugtk_UpdateDisplay();
-       }
-}
-
-/* Running function called when idle from gtk_main */
-static gboolean
-emugtk_running(gpointer data)
-{
-       cpu8051_Exec();
-       if (IsBreakpoint(cpu8051.pc)) {
-               log_info("Breakpoint Hit");
-               emugtk_stop_running();
-       }
-
-       return TRUE;
-}
-
-/* Get in the running state */
-static void
-emugtk_start_running(void)
-{
-       if (!running) {
-               log_info("StartRunning()");
-               running_function_tag = g_idle_add(emugtk_running, 0);
-               running = 1;
-       }
-}
-
-/* Taken from the Gxine source code. */
-static GtkWidget *
-button_add_pix(GtkWidget *box, char **xpm)
-{
-       GtkWidget *button, *icon;
-
-       button = gtk_button_new();
-       gtk_button_set_relief(GTK_BUTTON(button), GTK_RELIEF_NORMAL);
-
-       icon = gtk_image_new_from_pixbuf(
-               gdk_pixbuf_new_from_xpm_data((const char **) xpm));
-       gtk_container_add(GTK_CONTAINER(button), icon);
-
-       gtk_box_pack_start(GTK_BOX(box), button, FALSE, FALSE, BUTTONS_BORDER);
-
-       return button;
-}
-
-/* CPU reset and Gtk UI update */
-static void
-emugtk_Reset(void)
-{
-       cpu8051_Reset();
-       emugtk_UpdateDisplay();
-}
-
-/* Signal ResetEvent (ResetButton) */
-static void
-emugtk_ResetEvent(GtkWidget *widget, GdkEvent *event, gpointer data)
-{
-       log_info("ResetEvent()");
-       emugtk_stop_running();
-       emugtk_Reset();
-}
-
-/* CPU Step and Gtk UI update */
-static void
-emugtk_Step(void)
-{
-       cpu8051_Exec();
-       emugtk_UpdateDisplay();
-}
-
-/* Signal RunEvent (RunButton) */
-static void
-emugtk_RunEvent(GtkWidget *widget, GdkEvent *event, gpointer data)
-{
-       log_info("RunEvent()");
-
-       if (running)
-               emugtk_stop_running();
-       else
-               emugtk_start_running();
-}
-
-/* Signal StopEvent (StopButton) */
-static void
-emugtk_StopEvent(GtkWidget *widget, GdkEvent *event, gpointer data)
-{
-       log_info("StopEvent()");
-       emugtk_stop_running();
-}
-
-/* Signal StepEvent (StepButton) */
-static void
-emugtk_StepEvent(GtkWidget *widget, GdkEvent *event, gpointer data)
-{
-       log_info("StepEvent()");
-       emugtk_stop_running();
-       emugtk_Step();
-}
-
-/* Creates the Reset, Run, Stop and Step buttons. */
-static GtkWidget *
-AddButtons(void)
-{
-       GtkWidget *button_hbox;
-       GtkWidget *button;
-
-       /* The buttons of the hbox are NOT given equal space in the box. */
-       button_hbox = gtk_hbox_new(FALSE, 0);
-
-       /* Creating the RESET button. */
-       button = button_add_pix(button_hbox, reset_xpm);
-       g_signal_connect(button, "clicked",
-                        G_CALLBACK(emugtk_ResetEvent),
-                        NULL);
-
-       /* Creating the RUN button. */
-       button = button_add_pix(button_hbox, run_xpm);
-       g_signal_connect(button, "clicked",
-                        G_CALLBACK(emugtk_RunEvent),
-                        NULL);
-
-       /* Creating STOP button. */
-       button = button_add_pix(button_hbox, stop_xpm);
-       g_signal_connect(GTK_OBJECT(button), "clicked",
-                        G_CALLBACK(emugtk_StopEvent),
-                        NULL);
-
-       /* Creating STEP button. */
-       button = button_add_pix(button_hbox, step_xpm);
-       g_signal_connect(GTK_OBJECT(button), "clicked",
-                        G_CALLBACK(emugtk_StepEvent),
-                        NULL);
-
-       return button_hbox;
-}
-
-static GtkWidget *
-AddMenu(void)
-{
-       GtkWidget *menu_bar;
-
-       /* Creating menu item. */
-       menu_bar = gtk_menu_bar_new();
-
-       /* Adding the 'File' submenu */
-       FileAddMenu(menu_bar);
-
-       /* Adding the 'View' submenu */
-       ViewAddMenu(menu_bar);
-
-       /* Adding the 'Help' submenu */
-       HelpAddMenu(menu_bar);
-
-       return menu_bar;
-}
-
-static int
-mainwin_configure_event(GtkWindow *window, GdkEvent *event, gpointer data)
-{
-       cfg->win_width = event->configure.width;
-       cfg->win_height = event->configure.height;
-
-       /*
-        * Important:
-        * Returning false allows event to propagate to children. If not, they
-        * will not be resized when we resize the main window.
-        */
-       return FALSE;
-}
-
-static void
-hpaned_notify_event(GtkWindow *window, GdkEvent *event, gpointer data)
-{
-       GtkWidget *paned = data;
-
-       cfg->hpane_pos = gtk_paned_get_position(GTK_PANED(paned));
-}
-
-static void
-vpaned_notify_event(GtkWindow *window, GdkEvent *event, gpointer data)
-{
-       GtkWidget *paned = data;
-
-       cfg->vpane_pos = gtk_paned_get_position(GTK_PANED(paned));
-}
-
-static void
-main_paned_notify_event(GtkWindow *window, GdkEvent *event, gpointer data)
-{
-       GtkWidget *paned = data;
-
-       cfg->main_pane_pos = gtk_paned_get_position(GTK_PANED(paned));
-}
-
-void
-emugtk_restart_gui(void)
-{
-       emugtk_stop_running();
-
-       gtk_widget_destroy(mainwin);
-
-       restart_gui = true;
-}
-
-void
-emugtk_quit_gui(void)
-{
-       gtk_main_quit();
-
-       restart_gui = false;
-}
-
-static GtkWidget *
-emugtk_create_memory_paned(void)
-{
-       GtkWidget *vpaned;
-       GtkWidget *scrollwin;
-
-       /* Create vpaned (memory windows) only if necessary. */
-       if (cfg->view_int_memory || cfg->view_ext_memory) {
-               vpaned = gtk_vpaned_new();
-               gtk_paned_set_position(GTK_PANED(vpaned), cfg->vpane_pos);
-               g_signal_connect(G_OBJECT(vpaned), "notify::position",
-                                G_CALLBACK(vpaned_notify_event), vpaned);
-
-               /* Internal memory dump frame. */
-               if (cfg->view_int_memory) {
-                       scrollwin = memwin_init("Internal memory (IRAM)",
-                                               INT_MEM_ID);
-                       gtk_paned_pack1(GTK_PANED(vpaned), scrollwin,
-                                       FALSE, FALSE);
-               }
-
-               /* External memory dump frame. */
-               if (cfg->view_ext_memory) {
-                       scrollwin = memwin_init("External memory (XRAM)",
-                                               EXT_MEM_ID);
-                       gtk_paned_pack2(GTK_PANED(vpaned), scrollwin,
-                                       TRUE, FALSE);
-               }
-
-               return vpaned;
-       } else
-               return NULL;
-}
-
-/*
- *  mainwin
- * +---------------------------------------------------------------------+
- * |                                                                     |
- * |  vbox                                                               |
- * |  +---------------------------------------------------------------+  |
- * |  |                                                               |  |
- * |  |  menu_bar                                                     |  |
- * |  |  +----------------------+                                     |  |
- * |  |  | File  View  Help     |                                     |  |
- * |  |  +----------------------+                                     |  |
- * |  |                                                               |  |
- * |  |---------------------------------------------------------------|  |
- * |  |                                                               |  |
- * |  |  buttons_bar                                                  |  |
- * |  |  +-----------------------+                                    |  |
- * |  |  | RST  RUN  STOP  STEP  |                                    |  |
- * |  |  +-----------------------+                                    |  |
- * |  |                                                               |  |
- * |  |---------------------------------------------------------------|  |
- * |  |                                                               |  |
- * |  |  main_paned                                                   |  |
- * |  |  +---------------------------------------------------------+  |  |
- * |  |  |                                                         |  |  |
- * |  |  |  hpaned                                                 |  |  |
- * |  |  |  +---------------------------------------------------+  |  |  |
- * |  |  |  |                        |                          |  |  |  |
- * |  |  |  |  scrollwin             |  scrollwin               |  |  |  |
- * |  |  |  |  +------------------+  *  +--------------------+  |  |  |  |
- * |  |  |  |  | REGISTERS window |  *  | Disassembly window |  |  |  |  |
- * |  |  |  |  +------------------+  |  +--------------------+  |  |  |  |
- * |  |  |  |                        |                          |  |  |  |
- * |  |  |  +---------------------------------------------------+  |  |  |
- * |  |  |                                                         |  |  |
- * |  |  |--------------------------***-----------------------------  |  |
- * |  |  |                                                         |  |  |
- * |  |  |  vpaned                                                 |  |  |
- * |  |  |  +---------------------------------------------------+  |  |  |
- * |  |  |  |                                                   |  |  |  |
- * |  |  |  |  scrollwin                                        |  |  |  |
- * |  |  |  |  +---------------------------------------------+  |  |  |  |
- * |  |  |  |  | Internal memory window                      |  |  |  |  |
- * |  |  |  |  +---------------------------------------------+  |  |  |  |
- * |  |  |  |                                                   |  |  |  |
- * |  |  |  +-----------------------***-------------------------|  |  |  |
- * |  |  |  |                                                   |  |  |  |
- * |  |  |  |  scrollwin                                        |  |  |  |
- * |  |  |  |  +---------------------------------------------+  |  |  |  |
- * |  |  |  |  | External memory window                      |  |  |  |  |
- * |  |  |  |  +---------------------------------------------+  |  |  |  |
- * |  |  |  |                                                   |  |  |  |
- * |  |  |  +---------------------------------------------------+  |  |  |
- * |  |  |                                                         |  |  |
- * |  |  +---------------------------------------------------------+  |  |
- * |  |                                                               |  |
- * |  |                                                               |  |
- * |  +---------------------------------------------------------------+  |
- * |                                                                     |
- * |                                                                     |
- * +---------------------------------------------------------------------+
- */
-static void
-emugtk_window_init(void)
-{
-       GtkWidget *vbox;
-       GtkWidget *menu_bar;
-       GtkWidget *buttons_bar;
-       GtkWidget *scrollwin;
-       GtkWidget *hpaned;
-       GtkWidget *vpaned;
-       GtkWidget *main_paned;
-
-       mainwin = gtk_window_new(GTK_WINDOW_TOPLEVEL);
-       gtk_window_set_title(GTK_WINDOW(mainwin), PACKAGE);
-       gtk_window_set_default_size(GTK_WINDOW(mainwin),
-                                   cfg->win_width, cfg->win_height);
-       gtk_container_set_border_width(GTK_CONTAINER(mainwin), 0);
-
-       /* Window DESTROY event. */
-       g_signal_connect(mainwin, "destroy",
-                        G_CALLBACK(gtk_main_quit), NULL);
-
-       g_signal_connect(G_OBJECT(mainwin), "configure-event",
-                        G_CALLBACK(mainwin_configure_event), NULL);
-
-       /* Creating the menu bar. */
-       menu_bar = AddMenu();
-
-       /* Creating the buttons bar. */
-       buttons_bar = AddButtons();
-
-       scrollwin = pswwin_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);
-       g_signal_connect(G_OBJECT(hpaned), "notify::position",
-                        G_CALLBACK(hpaned_notify_event), hpaned);
-
-       /* 8051 registers frame. */
-       scrollwin = regwin_init();
-       gtk_paned_pack1(GTK_PANED(hpaned), scrollwin, FALSE, FALSE);
-
-       /* Program disassembly frame. */
-       scrollwin = pgmwin_init();
-       gtk_paned_pack2(GTK_PANED(hpaned), scrollwin, TRUE, FALSE);
-
-       /*
-        * main_paned will contain two groups:
-        *   group1:    registers and disassembly windows.
-        *   group2:    memory windows
-        */
-       if (cfg->layout == UI_LAYOUT1)
-               main_paned = gtk_vpaned_new();
-       else
-               main_paned = gtk_hpaned_new();
-
-       gtk_paned_set_position(GTK_PANED(main_paned), cfg->main_pane_pos);
-       g_signal_connect(G_OBJECT(main_paned), "notify::position",
-                        G_CALLBACK(main_paned_notify_event), main_paned);
-       gtk_paned_pack1(GTK_PANED(main_paned), hpaned, FALSE, FALSE);
-
-       vpaned = emugtk_create_memory_paned();
-       if (vpaned != NULL)
-               gtk_paned_pack2(GTK_PANED(main_paned), vpaned,
-                               TRUE, FALSE);
-
-       /*
-        * vbox contains the menu bar and body_vbox (for all remaining
-        * items).
-        */
-       vbox = gtk_vbox_new(FALSE, 1);
-       gtk_box_pack_start(GTK_BOX(vbox), menu_bar, FALSE, FALSE, 1);
-       gtk_box_pack_start(GTK_BOX(vbox), buttons_bar, FALSE, FALSE, 1);
-       gtk_box_pack_start(GTK_BOX(vbox), main_paned, true, true, 1);
-
-       /* Adding the vbox to the main window. */
-       gtk_container_add(GTK_CONTAINER(mainwin), vbox);
-
-       g_signal_connect(mainwin, "destroy", G_CALLBACK(emugtk_quit_gui), NULL);
-
-       gtk_widget_show_all(mainwin);
-}
-
-void
-AddMenuSeparator(GtkWidget *menu)
-{
-       GtkWidget *item;
-
-       item = gtk_menu_item_new();
-       gtk_menu_shell_append(GTK_MENU_SHELL(menu), item);
-}
-
-void
-emugtk_new_file(char *file)
-{
-       emugtk_stop_running();
-
-       LoadHexFile(file);
-
-       if (cfg->clear_ram_on_file_load)
-               emugtk_Reset();
-
-       emugtk_UpdateDisplay();
-}
-
-int
-main(int argc, char **argv)
-{
-       parse_command_line_options(argc, argv);
-       app_config_load();
-
-       cpu8051_init();
-
-       running = 0;
-
-       gtk_init(&argc, &argv);
-
-       if (options.filename != NULL)
-               LoadHexFile(options.filename);
-
-       cpu8051_Reset();
-
-       while (restart_gui == true) {
-               log_info("Init GUI");
-
-               emugtk_window_init();
-               emugtk_UpdateDisplay();
-               gtk_main();
-       }
-
-       log_info("Terminate");
-
-       app_config_save();
-
-       return EXIT_SUCCESS;
-}
diff --git a/src/emugtk.h b/src/emugtk.h
deleted file mode 100644 (file)
index 8e47427..0000000
+++ /dev/null
@@ -1,42 +0,0 @@
-/*
- * emugtk.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 EMUGTK_H
-#define EMUGTK_H 1
-
-#include <gtk/gtk.h>
-
-void
-AddMenuSeparator(GtkWidget *menu);
-
-void
-emugtk_new_file(char *file);
-
-void
-emugtk_UpdateDisplay(void);
-
-void
-emugtk_restart_gui(void);
-
-void
-emugtk_quit_gui(void);
-
-#endif /* EMUGTK_H */
diff --git a/src/filemenu.c b/src/filemenu.c
deleted file mode 100644 (file)
index d2dae9c..0000000
+++ /dev/null
@@ -1,139 +0,0 @@
-/*
- * filemenu.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 <unistd.h>  /* UNIX standard function definitions */
-#include <pwd.h>
-#include <gtk/gtk.h>
-
-#include "common.h"
-#include "emugtk.h"
-#include "messagebox.h"
-#include "filemenu.h"
-
-#define FILENAME_DESCRIPTION "Open Intel Hex file"
-
-static char previous_folder[MAX_FILENAME_LENGTH + 1];
-
-static void
-remember_current_folder(GtkFileChooser *chooser)
-{
-       char *folder;
-
-       folder = gtk_file_chooser_get_current_folder(chooser);
-
-       if (folder != NULL) {
-               if (strlen(folder) >= MAX_FILENAME_LENGTH) {
-                       /* Non-critical error */
-                       log_warn("current folder name too long for buffer");
-               } else {
-                       log_info("current folder = %s", folder);
-                       strncpy(previous_folder, folder, MAX_FILENAME_LENGTH);
-               }
-
-               g_free(folder);
-       }
-}
-
-void
-FileOpenEvent(GtkObject *object, gpointer data)
-{
-       GtkWidget *file_dialog;
-       char *dir;
-       char *cwd = NULL;
-
-       log_info("FileOpenEvent()");
-
-       /* Create a new file selection widget. */
-       file_dialog = gtk_file_chooser_dialog_new(
-               FILENAME_DESCRIPTION, NULL, GTK_FILE_CHOOSER_ACTION_OPEN,
-               GTK_STOCK_CANCEL, GTK_RESPONSE_CANCEL,
-               GTK_STOCK_OPEN, GTK_RESPONSE_ACCEPT, NULL);
-
-       if (strlen(previous_folder) == 0) {
-               /* Opening file chooser to current working directory. */
-               cwd = g_get_current_dir();
-               dir = cwd;
-       } else {
-               /* Opening file chooser to previous opened directory. */
-               dir = previous_folder;
-       }
-
-       gtk_file_chooser_set_current_folder(GTK_FILE_CHOOSER(file_dialog), dir);
-
-       if (cwd)
-               g_free(cwd);
-
-       if (gtk_dialog_run(GTK_DIALOG(file_dialog)) == GTK_RESPONSE_ACCEPT) {
-               char *selected_file;
-
-               selected_file = gtk_file_chooser_get_filename(
-                       GTK_FILE_CHOOSER(file_dialog));
-
-               if (selected_file != NULL) {
-                       log_info("emugtk_File = %s", selected_file);
-
-                       remember_current_folder(GTK_FILE_CHOOSER(file_dialog));
-
-                       emugtk_new_file(selected_file);
-                       g_free(selected_file);
-               }
-       }
-
-       gtk_widget_destroy(file_dialog);
-}
-
-static void
-FileQuitEvent(gchar *string)
-{
-       emugtk_quit_gui();
-}
-
-void
-FileAddMenu(GtkWidget *menu_bar)
-{
-       GtkWidget *item;
-       GtkWidget *menu;
-
-       menu = gtk_menu_new();
-
-       /* Create the 'open' item. */
-       item = gtk_menu_item_new_with_label(FILENAME_DESCRIPTION);
-       gtk_menu_shell_append(GTK_MENU_SHELL(menu), item);
-       /* Attach the callback functions to the activate signal. */
-       g_signal_connect(item, "activate", G_CALLBACK(FileOpenEvent), NULL);
-
-       AddMenuSeparator(menu);
-
-       item = gtk_menu_item_new_with_label("Exit");
-       gtk_menu_shell_append(GTK_MENU_SHELL(menu), item);
-       /* We can attach the Quit menu item to our exit function */
-       g_signal_connect(item, "activate", G_CALLBACK(FileQuitEvent),
-                        (gpointer) "file.quit");
-
-       /* Adding submenu title. */
-       item = gtk_menu_item_new_with_label("File");
-       gtk_menu_item_set_submenu(GTK_MENU_ITEM(item), menu);
-       gtk_menu_shell_append((GtkMenuShell *) menu_bar, item);
-}
diff --git a/src/filemenu.h b/src/filemenu.h
deleted file mode 100644 (file)
index fe9688a..0000000
+++ /dev/null
@@ -1,36 +0,0 @@
-/*
- * filemenu.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 FILEMENU_H
-#define FILEMENU_H 1
-
-#include <gtk/gtk.h>
-
-void
-FileOpenEvent(GtkObject *object, gpointer data);
-
-void
-FileResetEvent(GtkObject *object, gpointer data);
-
-void
-FileAddMenu(GtkWidget *menu_bar);
-
-#endif /* FILEMENU_H */
diff --git a/src/gtk/Makefile.am b/src/gtk/Makefile.am
new file mode 100644 (file)
index 0000000..22bb895
--- /dev/null
@@ -0,0 +1,38 @@
+# This file is processed by GNU automake to generate Makefile.in
+
+AM_CPPFLAGS = \
+    -Wall \
+    -I@top_srcdir@ \
+    -I@top_srcdir@/src/common \
+    -I$(top_srcdir)/pixmaps \
+    @GTK_CFLAGS@ \
+    @GLIB_CFLAGS@ \
+    -DDATADIR=\"$(datadir)\" \
+    -DGDK_PIXBUF_DISABLE_DEPRECATED \
+    -DGDK_DISABLE_DEPRECATED \
+    -DGTK_DISABLE_DEPRECATED
+
+LDADD = \
+    $(top_builddir)/src/common/libemu8051.a \
+    @GTK_LIBS@ \
+    @GLIB_LIBS@
+
+bin_PROGRAMS = emu8051-gtk
+
+emu8051_gtk_SOURCES = \
+    emugtk.c emugtk.h \
+    app-config.c app-config.h \
+    memwin.c memwin.h \
+    pgmwin.c pgmwin.h \
+    regwin.c regwin.h \
+    pswwin.c pswwin.h \
+    filemenu.c filemenu.h \
+    viewmenu.c viewmenu.h \
+    helpmenu.c helpmenu.h \
+    messagebox.c messagebox.h
+
+EXTRA_DIST =
+
+CLEANFILES = *~
+
+MAINTAINERCLEANFILES = Makefile.in
diff --git a/src/gtk/app-config.c b/src/gtk/app-config.c
new file mode 100644 (file)
index 0000000..90022f2
--- /dev/null
@@ -0,0 +1,218 @@
+/*
+ * Handle loading and saving of application configuration settings
+ *
+ * Copyright (C) 2013 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 <stdint.h>
+#include <stdbool.h>
+#include <unistd.h>
+#include <stdio.h>
+#include <stdlib.h>
+
+#if STDC_HEADERS
+#  include <string.h>
+#elif HAVE_STRINGS_H
+#  include <strings.h>
+#endif
+
+#include <glib.h>
+
+#include "common.h"
+#include "app-config.h"
+
+static const char profile_name[] = "default";
+static struct app_config_t app_config;
+
+struct app_config_t *cfg = &app_config;
+
+static void
+app_config_init(void)
+{
+       /* Emulation options */
+       cfg->clear_ram_on_file_load = false;
+
+       /* UI settings */
+       cfg->win_width = 640;
+       cfg->win_height = 480;
+       cfg->hpane_pos = 100;
+       cfg->vpane_pos = 200;
+       cfg->main_pane_pos = 200;
+
+       /* View menu options */
+       cfg->layout = UI_LAYOUT1;
+       cfg->view_int_memory = 1;
+       cfg->view_sfr_memory = 1;
+       cfg->view_ext_memory = 1;
+       cfg->bits_per_row = 16; /* 8 or 16 */
+}
+
+static int
+app_config_key_file_get_int(GKeyFile *kf, const char *grp, const char *key, int *value)
+{
+    char *str = g_key_file_get_value(kf, grp, key, NULL);
+
+    log_debug("key: %s", key);
+
+    if (G_LIKELY(str)) {
+           *value = atoi(str);
+           log_debug("  value = %d", *value);
+           g_free(str);
+    }
+
+    return str != NULL;
+}
+
+static void
+app_config_load_from_key_file(GKeyFile *kf)
+{
+       /* Emulation options */
+       app_config_key_file_get_int(kf, "emulation", "clear_ram_on_file_load",
+                                   &cfg->clear_ram_on_file_load);
+
+       /* ui */
+       app_config_key_file_get_int(kf, "ui", "win_width",  &cfg->win_width);
+       app_config_key_file_get_int(kf, "ui", "win_height", &cfg->win_height);
+       app_config_key_file_get_int(kf, "ui", "hpane_pos",  &cfg->hpane_pos);
+       app_config_key_file_get_int(kf, "ui", "vpane_pos",  &cfg->vpane_pos);
+       app_config_key_file_get_int(kf, "ui", "main_pane_pos",
+                                   &cfg->main_pane_pos);
+
+       /* View */
+       app_config_key_file_get_int(kf, "view", "layout",  &cfg->layout);
+       if ((cfg->layout != UI_LAYOUT1) && (cfg->layout != UI_LAYOUT2)) {
+               log_err("Invalid layout, defaulting to layout 1");
+               cfg->layout = UI_LAYOUT1;
+       }
+       app_config_key_file_get_int(kf, "view", "int_memory",
+                                   &cfg->view_int_memory);
+       app_config_key_file_get_int(kf, "view", "sfr_memory",
+                                   &cfg->view_sfr_memory);
+       app_config_key_file_get_int(kf, "view", "ext_memory",
+                                   &cfg->view_ext_memory);
+       app_config_key_file_get_int(kf, "view", "bits_per_row",
+                                   &cfg->bits_per_row);
+}
+
+static char *
+app_config_get_dir_path(void)
+{
+       char *dir_path;
+
+       dir_path = g_build_filename(g_get_user_config_dir(), PACKAGE,
+                                   profile_name, NULL);
+
+       return dir_path;
+}
+
+static char *
+app_config_get_file_path(void)
+{
+       char *file_path;
+       char *dir_path;
+       char file[MAX_FILENAME_LENGTH];
+
+       sprintf(file, "%s.conf", PACKAGE);
+
+       dir_path = app_config_get_dir_path();
+
+       file_path = g_build_filename(dir_path, file, NULL);
+
+       log_info("app. config file = %s", file_path);
+
+       g_free(dir_path);
+
+       return file_path;
+}
+
+int
+app_config_load(void)
+{
+       char *file_path;
+       GKeyFile *kf;
+
+       /* Load default values before config file */
+       app_config_init();
+
+       kf = g_key_file_new();
+
+       file_path = app_config_get_file_path();
+
+       if (g_key_file_load_from_file(kf, file_path, 0, NULL))
+               app_config_load_from_key_file(kf);
+
+       g_free(file_path);
+
+       g_key_file_free(kf);
+
+       /* ??? */
+       return 0;
+}
+
+int
+app_config_save(void)
+{
+       char *dir_path;
+
+       dir_path = app_config_get_dir_path();
+
+       if (g_mkdir_with_parents(dir_path, 0700) != -1)
+       {
+               char *file_path;
+               GString* buf = g_string_sized_new(1024);
+
+               g_string_append(buf, "\n[emulation]\n");
+
+               g_string_append_printf(buf, "clear_ram_on_file_load=%d\n",
+                                      cfg->clear_ram_on_file_load);
+
+               g_string_append(buf, "\n[ui]\n");
+
+               g_string_append_printf(buf, "win_width=%d\n", cfg->win_width);
+               g_string_append_printf(buf, "win_height=%d\n", cfg->win_height);
+               g_string_append_printf(buf, "hpane_pos=%d\n", cfg->hpane_pos);
+               g_string_append_printf(buf, "vpane_pos=%d\n", cfg->vpane_pos);
+               g_string_append_printf(buf, "main_pane_pos=%d\n",
+                                      cfg->main_pane_pos);
+
+               g_string_append(buf, "\n[view]\n");
+               g_string_append_printf(buf, "layout=%d\n", cfg->layout);
+               g_string_append_printf(buf, "int_memory=%d\n",
+                                      cfg->view_int_memory);
+               g_string_append_printf(buf, "sfr_memory=%d\n",
+                                      cfg->view_sfr_memory);
+               g_string_append_printf(buf, "ext_memory=%d\n",
+                                      cfg->view_ext_memory);
+               g_string_append_printf(buf, "bits_per_row=%d\n",
+                                      cfg->bits_per_row);
+
+               file_path = app_config_get_file_path();
+
+               g_file_set_contents(file_path, buf->str, buf->len, NULL);
+               g_string_free(buf, TRUE);
+               g_free(file_path);
+       }
+
+       g_free(dir_path);
+
+       /* ??? */
+       return 0;
+}
diff --git a/src/gtk/app-config.h b/src/gtk/app-config.h
new file mode 100644 (file)
index 0000000..1c418b5
--- /dev/null
@@ -0,0 +1,64 @@
+/*
+ * app_config.h
+ *
+ * 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 APP_CONFIG_H
+#define APP_CONFIG_H 1
+
+/*
+ *    Layout1:              Layout2:
+ *
+ * REGS | PROGRAM           |         | IRAM
+ * --------------      REGS | PROGRAM | ----
+ *     IRAM                 |         | XRAM
+ * --------------
+ *     XRAM
+ */
+enum layout_t {
+       UI_LAYOUT1 = 1,
+       UI_LAYOUT2,
+};
+
+struct app_config_t
+{
+       /* Emulation options */
+       int clear_ram_on_file_load;
+
+       /* UI settings */
+       int win_width;
+       int win_height;
+       int hpane_pos;     /* For registers and program windows. */
+       int vpane_pos; /* For internal and external memory windows. */
+       int main_pane_pos; /* Between hpane and vpane. */
+
+       /* View menu options */
+       int layout; /* UI Layout 1 or 2 */
+       int view_int_memory;
+       int view_sfr_memory;
+       int view_ext_memory;
+       int bits_per_row; /* 8 or 16 */
+};
+
+int
+app_config_load(void);
+
+int
+app_config_save(void);
+
+#endif /* APP_CONFIG_H */
diff --git a/src/gtk/emugtk.c b/src/gtk/emugtk.c
new file mode 100644 (file)
index 0000000..b5ef13f
--- /dev/null
@@ -0,0 +1,528 @@
+/*
+ * emugtk.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.
+ */
+
+#include <stdio.h>
+#include "config.h"
+
+#include <stdint.h>
+#include <stdbool.h>
+
+#include <gtk/gtk.h>
+
+#include "common.h"
+#include "cpu8051.h"
+#include "memory.h"
+#include "options.h"
+#include "hexfile.h"
+
+#include "emugtk.h"
+#include "reset.xpm"
+#include "run.xpm"
+#include "stop.xpm"
+#include "step.xpm"
+#include "filemenu.h"
+#include "viewmenu.h"
+#include "helpmenu.h"
+#include "regwin.h"
+#include "pgmwin.h"
+#include "memwin.h"
+#include "pswwin.h"
+#include "app-config.h"
+
+#define BUTTONS_BORDER 2
+
+static int running;
+static int running_function_tag;
+static int restart_gui = true;
+
+GtkWidget *mainwin;
+
+extern struct app_config_t *cfg;
+extern struct options_t options;
+
+void
+emugtk_UpdateDisplay(void)
+{
+       log_debug("UpdateDisplay()");
+       regwin_refresh();
+       pgmwin_refresh();
+       pswwin_refresh();
+
+       if (cfg->view_int_memory)
+               memwin_refresh(INT_MEM_ID);
+
+       if (cfg->view_ext_memory)
+               memwin_refresh(EXT_MEM_ID);
+}
+
+/* Step out of running state */
+static void
+emugtk_stop_running()
+{
+       if (running) {
+               log_info("StopRunning()");
+               g_source_remove(running_function_tag);
+               running = 0;
+               emugtk_UpdateDisplay();
+       }
+}
+
+/* Running function called when idle from gtk_main */
+static gboolean
+emugtk_running(gpointer data)
+{
+       cpu8051_Exec();
+       if (IsBreakpoint(cpu8051.pc)) {
+               log_info("Breakpoint Hit");
+               emugtk_stop_running();
+       }
+
+       return TRUE;
+}
+
+/* Get in the running state */
+static void
+emugtk_start_running(void)
+{
+       if (!running) {
+               log_info("StartRunning()");
+               running_function_tag = g_idle_add(emugtk_running, 0);
+               running = 1;
+       }
+}
+
+/* Taken from the Gxine source code. */
+static GtkWidget *
+button_add_pix(GtkWidget *box, char **xpm)
+{
+       GtkWidget *button, *icon;
+
+       button = gtk_button_new();
+       gtk_button_set_relief(GTK_BUTTON(button), GTK_RELIEF_NORMAL);
+
+       icon = gtk_image_new_from_pixbuf(
+               gdk_pixbuf_new_from_xpm_data((const char **) xpm));
+       gtk_container_add(GTK_CONTAINER(button), icon);
+
+       gtk_box_pack_start(GTK_BOX(box), button, FALSE, FALSE, BUTTONS_BORDER);
+
+       return button;
+}
+
+/* CPU reset and Gtk UI update */
+static void
+emugtk_Reset(void)
+{
+       cpu8051_Reset();
+       emugtk_UpdateDisplay();
+}
+
+/* Signal ResetEvent (ResetButton) */
+static void
+emugtk_ResetEvent(GtkWidget *widget, GdkEvent *event, gpointer data)
+{
+       log_info("ResetEvent()");
+       emugtk_stop_running();
+       emugtk_Reset();
+}
+
+/* CPU Step and Gtk UI update */
+static void
+emugtk_Step(void)
+{
+       cpu8051_Exec();
+       emugtk_UpdateDisplay();
+}
+
+/* Signal RunEvent (RunButton) */
+static void
+emugtk_RunEvent(GtkWidget *widget, GdkEvent *event, gpointer data)
+{
+       log_info("RunEvent()");
+
+       if (running)
+               emugtk_stop_running();
+       else
+               emugtk_start_running();
+}
+
+/* Signal StopEvent (StopButton) */
+static void
+emugtk_StopEvent(GtkWidget *widget, GdkEvent *event, gpointer data)
+{
+       log_info("StopEvent()");
+       emugtk_stop_running();
+}
+
+/* Signal StepEvent (StepButton) */
+static void
+emugtk_StepEvent(GtkWidget *widget, GdkEvent *event, gpointer data)
+{
+       log_info("StepEvent()");
+       emugtk_stop_running();
+       emugtk_Step();
+}
+
+/* Creates the Reset, Run, Stop and Step buttons. */
+static GtkWidget *
+AddButtons(void)
+{
+       GtkWidget *button_hbox;
+       GtkWidget *button;
+
+       /* The buttons of the hbox are NOT given equal space in the box. */
+       button_hbox = gtk_hbox_new(FALSE, 0);
+
+       /* Creating the RESET button. */
+       button = button_add_pix(button_hbox, reset_xpm);
+       g_signal_connect(button, "clicked",
+                        G_CALLBACK(emugtk_ResetEvent),
+                        NULL);
+
+       /* Creating the RUN button. */
+       button = button_add_pix(button_hbox, run_xpm);
+       g_signal_connect(button, "clicked",
+                        G_CALLBACK(emugtk_RunEvent),
+                        NULL);
+
+       /* Creating STOP button. */
+       button = button_add_pix(button_hbox, stop_xpm);
+       g_signal_connect(GTK_OBJECT(button), "clicked",
+                        G_CALLBACK(emugtk_StopEvent),
+                        NULL);
+
+       /* Creating STEP button. */
+       button = button_add_pix(button_hbox, step_xpm);
+       g_signal_connect(GTK_OBJECT(button), "clicked",
+                        G_CALLBACK(emugtk_StepEvent),
+                        NULL);
+
+       return button_hbox;
+}
+
+static GtkWidget *
+AddMenu(void)
+{
+       GtkWidget *menu_bar;
+
+       /* Creating menu item. */
+       menu_bar = gtk_menu_bar_new();
+
+       /* Adding the 'File' submenu */
+       FileAddMenu(menu_bar);
+
+       /* Adding the 'View' submenu */
+       ViewAddMenu(menu_bar);
+
+       /* Adding the 'Help' submenu */
+       HelpAddMenu(menu_bar);
+
+       return menu_bar;
+}
+
+static int
+mainwin_configure_event(GtkWindow *window, GdkEvent *event, gpointer data)
+{
+       cfg->win_width = event->configure.width;
+       cfg->win_height = event->configure.height;
+
+       /*
+        * Important:
+        * Returning false allows event to propagate to children. If not, they
+        * will not be resized when we resize the main window.
+        */
+       return FALSE;
+}
+
+static void
+hpaned_notify_event(GtkWindow *window, GdkEvent *event, gpointer data)
+{
+       GtkWidget *paned = data;
+
+       cfg->hpane_pos = gtk_paned_get_position(GTK_PANED(paned));
+}
+
+static void
+vpaned_notify_event(GtkWindow *window, GdkEvent *event, gpointer data)
+{
+       GtkWidget *paned = data;
+
+       cfg->vpane_pos = gtk_paned_get_position(GTK_PANED(paned));
+}
+
+static void
+main_paned_notify_event(GtkWindow *window, GdkEvent *event, gpointer data)
+{
+       GtkWidget *paned = data;
+
+       cfg->main_pane_pos = gtk_paned_get_position(GTK_PANED(paned));
+}
+
+void
+emugtk_restart_gui(void)
+{
+       emugtk_stop_running();
+
+       gtk_widget_destroy(mainwin);
+
+       restart_gui = true;
+}
+
+void
+emugtk_quit_gui(void)
+{
+       gtk_main_quit();
+
+       restart_gui = false;
+}
+
+static GtkWidget *
+emugtk_create_memory_paned(void)
+{
+       GtkWidget *vpaned;
+       GtkWidget *scrollwin;
+
+       /* Create vpaned (memory windows) only if necessary. */
+       if (cfg->view_int_memory || cfg->view_ext_memory) {
+               vpaned = gtk_vpaned_new();
+               gtk_paned_set_position(GTK_PANED(vpaned), cfg->vpane_pos);
+               g_signal_connect(G_OBJECT(vpaned), "notify::position",
+                                G_CALLBACK(vpaned_notify_event), vpaned);
+
+               /* Internal memory dump frame. */
+               if (cfg->view_int_memory) {
+                       scrollwin = memwin_init("Internal memory (IRAM)",
+                                               INT_MEM_ID);
+                       gtk_paned_pack1(GTK_PANED(vpaned), scrollwin,
+                                       FALSE, FALSE);
+               }
+
+               /* External memory dump frame. */
+               if (cfg->view_ext_memory) {
+                       scrollwin = memwin_init("External memory (XRAM)",
+                                               EXT_MEM_ID);
+                       gtk_paned_pack2(GTK_PANED(vpaned), scrollwin,
+                                       TRUE, FALSE);
+               }
+
+               return vpaned;
+       } else
+               return NULL;
+}
+
+/*
+ *  mainwin
+ * +---------------------------------------------------------------------+
+ * |                                                                     |
+ * |  vbox                                                               |
+ * |  +---------------------------------------------------------------+  |
+ * |  |                                                               |  |
+ * |  |  menu_bar                                                     |  |
+ * |  |  +----------------------+                                     |  |
+ * |  |  | File  View  Help     |                                     |  |
+ * |  |  +----------------------+                                     |  |
+ * |  |                                                               |  |
+ * |  |---------------------------------------------------------------|  |
+ * |  |                                                               |  |
+ * |  |  buttons_bar                                                  |  |
+ * |  |  +-----------------------+                                    |  |
+ * |  |  | RST  RUN  STOP  STEP  |                                    |  |
+ * |  |  +-----------------------+                                    |  |
+ * |  |                                                               |  |
+ * |  |---------------------------------------------------------------|  |
+ * |  |                                                               |  |
+ * |  |  main_paned                                                   |  |
+ * |  |  +---------------------------------------------------------+  |  |
+ * |  |  |                                                         |  |  |
+ * |  |  |  hpaned                                                 |  |  |
+ * |  |  |  +---------------------------------------------------+  |  |  |
+ * |  |  |  |                        |                          |  |  |  |
+ * |  |  |  |  scrollwin             |  scrollwin               |  |  |  |
+ * |  |  |  |  +------------------+  *  +--------------------+  |  |  |  |
+ * |  |  |  |  | REGISTERS window |  *  | Disassembly window |  |  |  |  |
+ * |  |  |  |  +------------------+  |  +--------------------+  |  |  |  |
+ * |  |  |  |                        |                          |  |  |  |
+ * |  |  |  +---------------------------------------------------+  |  |  |
+ * |  |  |                                                         |  |  |
+ * |  |  |--------------------------***-----------------------------  |  |
+ * |  |  |                                                         |  |  |
+ * |  |  |  vpaned                                                 |  |  |
+ * |  |  |  +---------------------------------------------------+  |  |  |
+ * |  |  |  |                                                   |  |  |  |
+ * |  |  |  |  scrollwin                                        |  |  |  |
+ * |  |  |  |  +---------------------------------------------+  |  |  |  |
+ * |  |  |  |  | Internal memory window                      |  |  |  |  |
+ * |  |  |  |  +---------------------------------------------+  |  |  |  |
+ * |  |  |  |                                                   |  |  |  |
+ * |  |  |  +-----------------------***-------------------------|  |  |  |
+ * |  |  |  |                                                   |  |  |  |
+ * |  |  |  |  scrollwin                                        |  |  |  |
+ * |  |  |  |  +---------------------------------------------+  |  |  |  |
+ * |  |  |  |  | External memory window                      |  |  |  |  |
+ * |  |  |  |  +---------------------------------------------+  |  |  |  |
+ * |  |  |  |                                                   |  |  |  |
+ * |  |  |  +---------------------------------------------------+  |  |  |
+ * |  |  |                                                         |  |  |
+ * |  |  +---------------------------------------------------------+  |  |
+ * |  |                                                               |  |
+ * |  |                                                               |  |
+ * |  +---------------------------------------------------------------+  |
+ * |                                                                     |
+ * |                                                                     |
+ * +---------------------------------------------------------------------+
+ */
+static void
+emugtk_window_init(void)
+{
+       GtkWidget *vbox;
+       GtkWidget *menu_bar;
+       GtkWidget *buttons_bar;
+       GtkWidget *scrollwin;
+       GtkWidget *hpaned;
+       GtkWidget *vpaned;
+       GtkWidget *main_paned;
+
+       mainwin = gtk_window_new(GTK_WINDOW_TOPLEVEL);
+       gtk_window_set_title(GTK_WINDOW(mainwin), PACKAGE);
+       gtk_window_set_default_size(GTK_WINDOW(mainwin),
+                                   cfg->win_width, cfg->win_height);
+       gtk_container_set_border_width(GTK_CONTAINER(mainwin), 0);
+
+       /* Window DESTROY event. */
+       g_signal_connect(mainwin, "destroy",
+                        G_CALLBACK(gtk_main_quit), NULL);
+
+       g_signal_connect(G_OBJECT(mainwin), "configure-event",
+                        G_CALLBACK(mainwin_configure_event), NULL);
+
+       /* Creating the menu bar. */
+       menu_bar = AddMenu();
+
+       /* Creating the buttons bar. */
+       buttons_bar = AddButtons();
+
+       scrollwin = pswwin_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);
+       g_signal_connect(G_OBJECT(hpaned), "notify::position",
+                        G_CALLBACK(hpaned_notify_event), hpaned);
+
+       /* 8051 registers frame. */
+       scrollwin = regwin_init();
+       gtk_paned_pack1(GTK_PANED(hpaned), scrollwin, FALSE, FALSE);
+
+       /* Program disassembly frame. */
+       scrollwin = pgmwin_init();
+       gtk_paned_pack2(GTK_PANED(hpaned), scrollwin, TRUE, FALSE);
+
+       /*
+        * main_paned will contain two groups:
+        *   group1:    registers and disassembly windows.
+        *   group2:    memory windows
+        */
+       if (cfg->layout == UI_LAYOUT1)
+               main_paned = gtk_vpaned_new();
+       else
+               main_paned = gtk_hpaned_new();
+
+       gtk_paned_set_position(GTK_PANED(main_paned), cfg->main_pane_pos);
+       g_signal_connect(G_OBJECT(main_paned), "notify::position",
+                        G_CALLBACK(main_paned_notify_event), main_paned);
+       gtk_paned_pack1(GTK_PANED(main_paned), hpaned, FALSE, FALSE);
+
+       vpaned = emugtk_create_memory_paned();
+       if (vpaned != NULL)
+               gtk_paned_pack2(GTK_PANED(main_paned), vpaned,
+                               TRUE, FALSE);
+
+       /*
+        * vbox contains the menu bar and body_vbox (for all remaining
+        * items).
+        */
+       vbox = gtk_vbox_new(FALSE, 1);
+       gtk_box_pack_start(GTK_BOX(vbox), menu_bar, FALSE, FALSE, 1);
+       gtk_box_pack_start(GTK_BOX(vbox), buttons_bar, FALSE, FALSE, 1);
+       gtk_box_pack_start(GTK_BOX(vbox), main_paned, true, true, 1);
+
+       /* Adding the vbox to the main window. */
+       gtk_container_add(GTK_CONTAINER(mainwin), vbox);
+
+       g_signal_connect(mainwin, "destroy", G_CALLBACK(emugtk_quit_gui), NULL);
+
+       gtk_widget_show_all(mainwin);
+}
+
+void
+AddMenuSeparator(GtkWidget *menu)
+{
+       GtkWidget *item;
+
+       item = gtk_menu_item_new();
+       gtk_menu_shell_append(GTK_MENU_SHELL(menu), item);
+}
+
+void
+emugtk_new_file(char *file)
+{
+       emugtk_stop_running();
+
+       LoadHexFile(file);
+
+       if (cfg->clear_ram_on_file_load)
+               emugtk_Reset();
+
+       emugtk_UpdateDisplay();
+}
+
+int
+main(int argc, char **argv)
+{
+       parse_command_line_options(argc, argv);
+       app_config_load();
+
+       cpu8051_init();
+
+       running = 0;
+
+       gtk_init(&argc, &argv);
+
+       if (options.filename != NULL)
+               LoadHexFile(options.filename);
+
+       cpu8051_Reset();
+
+       while (restart_gui == true) {
+               log_info("Init GUI");
+
+               emugtk_window_init();
+               emugtk_UpdateDisplay();
+               gtk_main();
+       }
+
+       log_info("Terminate");
+
+       app_config_save();
+
+       return EXIT_SUCCESS;
+}
diff --git a/src/gtk/emugtk.h b/src/gtk/emugtk.h
new file mode 100644 (file)
index 0000000..8e47427
--- /dev/null
@@ -0,0 +1,42 @@
+/*
+ * emugtk.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 EMUGTK_H
+#define EMUGTK_H 1
+
+#include <gtk/gtk.h>
+
+void
+AddMenuSeparator(GtkWidget *menu);
+
+void
+emugtk_new_file(char *file);
+
+void
+emugtk_UpdateDisplay(void);
+
+void
+emugtk_restart_gui(void);
+
+void
+emugtk_quit_gui(void);
+
+#endif /* EMUGTK_H */
diff --git a/src/gtk/filemenu.c b/src/gtk/filemenu.c
new file mode 100644 (file)
index 0000000..d2dae9c
--- /dev/null
@@ -0,0 +1,139 @@
+/*
+ * filemenu.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 <unistd.h>  /* UNIX standard function definitions */
+#include <pwd.h>
+#include <gtk/gtk.h>
+
+#include "common.h"
+#include "emugtk.h"
+#include "messagebox.h"
+#include "filemenu.h"
+
+#define FILENAME_DESCRIPTION "Open Intel Hex file"
+
+static char previous_folder[MAX_FILENAME_LENGTH + 1];
+
+static void
+remember_current_folder(GtkFileChooser *chooser)
+{
+       char *folder;
+
+       folder = gtk_file_chooser_get_current_folder(chooser);
+
+       if (folder != NULL) {
+               if (strlen(folder) >= MAX_FILENAME_LENGTH) {
+                       /* Non-critical error */
+                       log_warn("current folder name too long for buffer");
+               } else {
+                       log_info("current folder = %s", folder);
+                       strncpy(previous_folder, folder, MAX_FILENAME_LENGTH);
+               }
+
+               g_free(folder);
+       }
+}
+
+void
+FileOpenEvent(GtkObject *object, gpointer data)
+{
+       GtkWidget *file_dialog;
+       char *dir;
+       char *cwd = NULL;
+
+       log_info("FileOpenEvent()");
+
+       /* Create a new file selection widget. */
+       file_dialog = gtk_file_chooser_dialog_new(
+               FILENAME_DESCRIPTION, NULL, GTK_FILE_CHOOSER_ACTION_OPEN,
+               GTK_STOCK_CANCEL, GTK_RESPONSE_CANCEL,
+               GTK_STOCK_OPEN, GTK_RESPONSE_ACCEPT, NULL);
+
+       if (strlen(previous_folder) == 0) {
+               /* Opening file chooser to current working directory. */
+               cwd = g_get_current_dir();
+               dir = cwd;
+       } else {
+               /* Opening file chooser to previous opened directory. */
+               dir = previous_folder;
+       }
+
+       gtk_file_chooser_set_current_folder(GTK_FILE_CHOOSER(file_dialog), dir);
+
+       if (cwd)
+               g_free(cwd);
+
+       if (gtk_dialog_run(GTK_DIALOG(file_dialog)) == GTK_RESPONSE_ACCEPT) {
+               char *selected_file;
+
+               selected_file = gtk_file_chooser_get_filename(
+                       GTK_FILE_CHOOSER(file_dialog));
+
+               if (selected_file != NULL) {
+                       log_info("emugtk_File = %s", selected_file);
+
+                       remember_current_folder(GTK_FILE_CHOOSER(file_dialog));
+
+                       emugtk_new_file(selected_file);
+                       g_free(selected_file);
+               }
+       }
+
+       gtk_widget_destroy(file_dialog);
+}
+
+static void
+FileQuitEvent(gchar *string)
+{
+       emugtk_quit_gui();
+}
+
+void
+FileAddMenu(GtkWidget *menu_bar)
+{
+       GtkWidget *item;
+       GtkWidget *menu;
+
+       menu = gtk_menu_new();
+
+       /* Create the 'open' item. */
+       item = gtk_menu_item_new_with_label(FILENAME_DESCRIPTION);
+       gtk_menu_shell_append(GTK_MENU_SHELL(menu), item);
+       /* Attach the callback functions to the activate signal. */
+       g_signal_connect(item, "activate", G_CALLBACK(FileOpenEvent), NULL);
+
+       AddMenuSeparator(menu);
+
+       item = gtk_menu_item_new_with_label("Exit");
+       gtk_menu_shell_append(GTK_MENU_SHELL(menu), item);
+       /* We can attach the Quit menu item to our exit function */
+       g_signal_connect(item, "activate", G_CALLBACK(FileQuitEvent),
+                        (gpointer) "file.quit");
+
+       /* Adding submenu title. */
+       item = gtk_menu_item_new_with_label("File");
+       gtk_menu_item_set_submenu(GTK_MENU_ITEM(item), menu);
+       gtk_menu_shell_append((GtkMenuShell *) menu_bar, item);
+}
diff --git a/src/gtk/filemenu.h b/src/gtk/filemenu.h
new file mode 100644 (file)
index 0000000..fe9688a
--- /dev/null
@@ -0,0 +1,36 @@
+/*
+ * filemenu.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 FILEMENU_H
+#define FILEMENU_H 1
+
+#include <gtk/gtk.h>
+
+void
+FileOpenEvent(GtkObject *object, gpointer data);
+
+void
+FileResetEvent(GtkObject *object, gpointer data);
+
+void
+FileAddMenu(GtkWidget *menu_bar);
+
+#endif /* FILEMENU_H */
diff --git a/src/gtk/helpmenu.c b/src/gtk/helpmenu.c
new file mode 100644 (file)
index 0000000..4a8d9dc
--- /dev/null
@@ -0,0 +1,119 @@
+/*
+ * helpmenu.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 <stdbool.h>
+
+#if STDC_HEADERS
+#  include <string.h>
+#elif HAVE_STRINGS_H
+#  include <strings.h>
+#endif
+
+#include <gtk/gtk.h>
+
+#include "common.h"
+#include "options.h"
+#include "emugtk.h"
+#include "messagebox.h"
+#include "helpmenu.h"
+
+#define PACKAGE_COPYRIGHT "(c) Hugo Villeneuve"
+
+static void
+HelpCommandsEvent(gchar *string)
+{
+       ShowMessage("Command Line Options", COMMAND_LINE_OPTIONS,
+                   GTK_JUSTIFY_LEFT, MESSAGE_DIALOG_FIXED_FONT);
+}
+
+static void
+HelpAboutEvent(GtkWidget *widget, gpointer data)
+{
+       const char *authors[] = {
+               "Hugo Villeneuve <hugo@hugovil.com>",
+               "Jonathan St-André",
+               "Pascal Fecteau",
+               "Jimmy Ringuette",
+               NULL,
+       };
+
+       const char *license =
+               "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.\n\n"
+               "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.\n\n"
+               "You should have received a copy of the GNU General Public"
+               " License along with this program. If not, see\n"
+               "   <http://www.gnu.org/licenses/>";
+
+       gtk_show_about_dialog(
+               NULL,
+               "name", PACKAGE_NAME,
+               "title", "About Dialog",
+               "version", PACKAGE_VERSION,
+               "logo-icon-name", PACKAGE_TARNAME,
+               "comments", get_package_description(),
+               "authors", authors,
+               "website", PACKAGE_URL,
+               "copyright", PACKAGE_COPYRIGHT,
+               "license", license,
+               "wrap-license", true,
+               NULL);
+}
+
+void
+HelpAddMenu(GtkWidget *menu_bar)
+{
+       GtkWidget *item;
+       GtkWidget *menu;
+
+       menu = gtk_menu_new();
+
+       /* Create the 'Help Command Line Options' item. */
+       item = gtk_menu_item_new_with_label("Command Line Options");
+       gtk_menu_shell_append(GTK_MENU_SHELL(menu), item);
+       /* Attach the callback functions to the activate signal. */
+       g_signal_connect(item, "activate", G_CALLBACK(HelpCommandsEvent), NULL);
+
+       AddMenuSeparator(menu);
+
+       /* Create the 'Help About' item. */
+       item = gtk_menu_item_new_with_label("About " PACKAGE);
+       gtk_menu_shell_append(GTK_MENU_SHELL(menu), item);
+       /* Attach the callback functions to the activate signal. */
+       g_signal_connect(item, "activate", G_CALLBACK(HelpAboutEvent), NULL);
+
+       /* Adding submenu title. */
+       item = gtk_menu_item_new_with_label("Help");
+       gtk_menu_item_set_submenu(GTK_MENU_ITEM(item), menu);
+       gtk_menu_shell_append((GtkMenuShell *) menu_bar, item);
+}
diff --git a/src/gtk/helpmenu.h b/src/gtk/helpmenu.h
new file mode 100644 (file)
index 0000000..63908dd
--- /dev/null
@@ -0,0 +1,30 @@
+/*
+ * helpmenu.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 HELPMENU_H
+#define HELPMENU_H 1
+
+#include <gtk/gtk.h>
+
+void
+HelpAddMenu(GtkWidget *menu_bar);
+
+#endif /* HELPMENU_H */
diff --git a/src/gtk/memwin.c b/src/gtk/memwin.c
new file mode 100644 (file)
index 0000000..58ce1d2
--- /dev/null
@@ -0,0 +1,346 @@
+/*
+ * memwin.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 <ctype.h> /* For isprint */
+
+#include "common.h"
+#include "memory.h"
+#include "hexfile.h"
+#include "cpu8051.h"
+#include "regwin.h"
+#include "memwin.h"
+#include "emugtk.h"
+#include "options.h"
+#include "app-config.h"
+
+extern struct app_config_t *cfg;
+extern struct options_t options;
+
+static int COL_ASCII;
+static int N_COLUMNS;
+
+enum
+{
+       COL_ADDRESS = 0,
+       COL_DATA0,
+};
+
+static GtkWidget *memlist_internal;
+static GtkWidget *memlist_external;
+
+/* Creating a model */
+static GtkListStore *
+memwin_init_store(int data_rows)
+{
+       GtkTreeIter iter;
+       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);
+
+       /* Add rows. */
+       for (row = 0; row < data_rows; row++)
+               gtk_list_store_append(store, &iter);
+
+       return store;
+}
+
+static void
+memwin_cell_edited(GtkCellRendererText *cell, gchar *path_string,
+                  gchar *new_str, gpointer model)
+{
+       guint column;
+       guint memory_id;
+       gpointer columnptr;
+       gpointer memory_id_ptr;
+       GtkTreeIter iter;
+       int address;
+       u_int8_t old;
+       int new;
+       char *str;
+
+       if (!model) {
+               g_error("Unable to get model from cell renderer");
+       }
+
+       /* Column number is passed as renderer object data */
+        columnptr = g_object_get_data(G_OBJECT(cell), "column");
+        column = GPOINTER_TO_UINT(columnptr);
+
+       /* Memory ID  is passed as renderer object data */
+       memory_id_ptr = g_object_get_data(G_OBJECT(cell), "memory_id");
+       memory_id = GPOINTER_TO_UINT(memory_id_ptr);
+
+       /* Get the iterator */
+        gtk_tree_model_get_iter_from_string(model, &iter, path_string);
+
+       /* Get base address. */
+       gtk_tree_model_get(model, &iter, COL_ADDRESS, &str, -1);
+       address = asciihex2int(str);
+
+       /* Convert column number (1, 2, 3...) to index (0, 1, 2...) */
+       address += (column - COL_DATA0);
+       old = memory_read8(memory_id, address);
+
+       log_info("Address: $%02X", address);
+       log_info("  old value: $%02X", old);
+
+       /* Convert new value (asciihex) to integer. */
+       new = asciihex2int(new_str);
+       if ((new < 0) || (new > 255)) {
+               log_info("  new value: out of range");
+               new = old; /* Put back old value... */
+       } else {
+               log_info("  new value: $%02X", new);
+       }
+
+       /* Store new value in emulator memory. */
+       memory_write8(memory_id, address, new);
+
+       /* Convert to text. */
+       int2asciihex(new, str, 2);
+
+       /* Store new value in gtk model. */
+        gtk_list_store_set(GTK_LIST_STORE(model), &iter, column, str, -1);
+
+       /*
+        * Make sure to update all registers and memory.
+        * For example, BANKed registers depends on internal memory.
+        */
+       emugtk_UpdateDisplay();
+};
+
+static void
+memwin_init_columns(GtkWidget *listview, int memory_id)
+{
+       int i;
+       GtkCellRenderer *renderer;
+       GtkTreeViewColumn *column;
+
+       /* Columns and cell renderers */
+       renderer = gtk_cell_renderer_text_new();
+
+       /* Add address column */
+       column = gtk_tree_view_column_new_with_attributes(
+               "Address", renderer, "text", COL_ADDRESS, NULL);
+       gtk_tree_view_column_set_sizing(column, GTK_TREE_VIEW_COLUMN_AUTOSIZE);
+       gtk_tree_view_append_column(GTK_TREE_VIEW(listview), column);
+
+       for (i = COL_DATA0; i < (COL_DATA0 + cfg->bits_per_row); i++) {
+               char col_name[8];
+
+               /* Create new renderer for each editable cell. */
+               renderer = gtk_cell_renderer_text_new();
+
+               /* Allow edition, align to left side. */
+               g_object_set(renderer, "editable", TRUE, "xalign", 0, NULL);
+
+               g_signal_connect(renderer, "edited",
+                                G_CALLBACK(memwin_cell_edited),
+                                gtk_tree_view_get_model(
+                                        GTK_TREE_VIEW(listview)));
+
+               /* Add column index and memory_id, used when editing the cell. */
+               g_object_set_data(G_OBJECT(renderer), "column",
+                                 GUINT_TO_POINTER(i));
+               g_object_set_data(G_OBJECT(renderer), "memory_id",
+                                 GUINT_TO_POINTER(memory_id));
+
+               /* Use two digits only if DATA_ROWS > 10 */
+               if (cfg->bits_per_row < 10)
+                       sprintf(col_name, "B%1d", i - COL_DATA0);
+               else
+                       sprintf(col_name, "B%02d", i - COL_DATA0);
+
+               column = gtk_tree_view_column_new_with_attributes(
+                       col_name, renderer, "text", i, NULL);
+               gtk_tree_view_column_set_sizing(column,
+                                               GTK_TREE_VIEW_COLUMN_AUTOSIZE);
+               gtk_tree_view_append_column(GTK_TREE_VIEW(listview), column);
+       }
+
+       /* Add ASCII column, using fixed-font. */
+       renderer = gtk_cell_renderer_text_new();
+       g_object_set(renderer, "family", "Monospace", NULL);
+       column = gtk_tree_view_column_new_with_attributes(
+               "ASCII", renderer, "text", COL_ASCII, NULL);
+       gtk_tree_view_column_set_sizing(column, GTK_TREE_VIEW_COLUMN_AUTOSIZE);
+       gtk_tree_view_append_column(GTK_TREE_VIEW(listview), column);
+}
+
+static int
+compute_data_rows(int memory_id)
+{
+       int data_rows;
+
+       if (memory_id == INT_MEM_ID) {
+               data_rows = options.iram_size / cfg->bits_per_row;
+       } else if (memory_id == EXT_MEM_ID) {
+               data_rows = options.xram_size / cfg->bits_per_row;
+       } else {
+               log_fail("Invalid memory type");
+               exit(1);
+       }
+
+       return data_rows;
+}
+
+GtkWidget *
+memwin_init(char *title, int memory_id)
+{
+       GtkWidget *frame;
+       GtkWidget *scrollwin;
+       GtkListStore *store;
+       GtkWidget *memlist;
+       int data_rows;
+
+       COL_ASCII = cfg->bits_per_row + 1;
+       N_COLUMNS = COL_ASCII + 1;
+
+       frame = gtk_frame_new(title);
+
+       scrollwin = gtk_scrolled_window_new(NULL, NULL);
+       gtk_scrolled_window_set_shadow_type(GTK_SCROLLED_WINDOW(scrollwin),
+                                           GTK_SHADOW_ETCHED_OUT);
+
+       /* Automatically add scrollbars when necessary. */
+       gtk_scrolled_window_set_policy(GTK_SCROLLED_WINDOW(scrollwin),
+                                      GTK_POLICY_AUTOMATIC,
+                                      GTK_POLICY_AUTOMATIC);
+
+       gtk_container_add(GTK_CONTAINER(frame), scrollwin);
+
+       data_rows = compute_data_rows(memory_id);
+
+       /* Creating a model */
+       store = memwin_init_store(data_rows);
+
+       /* Creating the view component */
+       memlist = gtk_tree_view_new_with_model(GTK_TREE_MODEL(store));
+       gtk_tree_view_set_headers_visible(GTK_TREE_VIEW(memlist), TRUE);
+       gtk_container_add(GTK_CONTAINER(scrollwin), memlist);
+
+       if (memory_id == INT_MEM_ID) {
+               memlist_internal = memlist;
+       } else if (memory_id == EXT_MEM_ID) {
+               memlist_external = memlist;
+       } else {
+               log_fail("Invalid memory type");
+               exit(1);
+       }
+
+       memwin_init_columns(memlist, memory_id);
+
+       /*
+        * The tree view has acquired its own reference to the model, so we can
+        * drop ours. That way the model will be freed automatically when the
+        * tree view is destroyed.
+        */
+       g_object_unref(store);
+
+       return frame;
+}
+
+/* Dump internal or external memory. */
+void
+memwin_refresh(int memory_id)
+{
+       int row;
+       unsigned int Address;
+       GtkListStore *store;
+       GtkWidget *memlist;
+       int data_rows;
+
+       Address = 0;
+
+       data_rows = compute_data_rows(memory_id);
+
+       if (memory_id == INT_MEM_ID) {
+               memlist = memlist_internal;
+       } else if (memory_id == EXT_MEM_ID) {
+               memlist = memlist_external;
+       } else {
+               log_fail("Invalid memory type");
+               exit(1);
+       }
+
+       store = GTK_LIST_STORE(gtk_tree_view_get_model(GTK_TREE_VIEW(memlist)));
+
+       for (row = 0; row < data_rows; 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;
+
+               if (row == 0) {
+                       /* Get first row in list store */
+                       valid = gtk_tree_model_get_iter_first(
+                               GTK_TREE_MODEL(store), &iter);
+               } else {
+                       /* Get next row in list store */
+                       valid = gtk_tree_model_iter_next(
+                               GTK_TREE_MODEL(store), &iter);
+               }
+
+               if (!valid) {
+                       printf("Invalid iter...\n");
+                       return;
+               }
+
+               /* Display base address. */
+               int2asciihex(Address, str, 4);
+
+               gtk_list_store_set(store, &iter, COL_ADDRESS, str, -1);
+
+               for (col = 0; col < cfg->bits_per_row; col++) {
+                       u_int8_t data;
+
+                       data = memory_read8(memory_id, Address + col);
+
+                       /* Display hex data */
+                       int2asciihex(data, str, 2);
+
+                       gtk_list_store_set(store, &iter, col + 1, str, -1);
+
+                       /* Append to ASCII string (if applicable). */
+                       if (!isprint(data))
+                               data = '.';
+                       sprintf(&ascii_str[col], "%c", data);
+               }
+
+               /* Display ASCII characters. */
+               gtk_list_store_set(store, &iter, COL_ASCII, ascii_str, -1);
+
+               Address += cfg->bits_per_row;
+       }
+}
diff --git a/src/gtk/memwin.h b/src/gtk/memwin.h
new file mode 100644 (file)
index 0000000..ccb528d
--- /dev/null
@@ -0,0 +1,33 @@
+/*
+ * memwin.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 MEMWIN_H
+#define MEMWIN_H 1
+
+#include <gtk/gtk.h>
+
+GtkWidget *
+memwin_init(char *title, int memory_id);
+
+void
+memwin_refresh(int memory_id);
+
+#endif /* MEMWIN_H */
diff --git a/src/gtk/messagebox.c b/src/gtk/messagebox.c
new file mode 100644 (file)
index 0000000..c4d3723
--- /dev/null
@@ -0,0 +1,98 @@
+/*
+ * messagebox.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 <gtk/gtk.h>
+
+#include "common.h"
+#include "messagebox.h"
+
+#define MESSAGE_DIALOG_BORDER 25
+
+#define BUTTON_TEXT_BORDER 3
+
+extern GtkWidget *mainwin;
+
+void
+ShowMessage(gchar *title, gchar *message, int justification, int font_style)
+{
+       GtkWidget *dialog;
+       GtkWidget *label;
+       GtkWidget *label_window;
+
+       /* Keep the dialog on top of the main window, and centered. */
+       dialog = gtk_dialog_new_with_buttons(
+               title, GTK_WINDOW(mainwin),
+               GTK_DIALOG_MODAL | GTK_DIALOG_DESTROY_WITH_PARENT, GTK_STOCK_OK,
+               GTK_RESPONSE_NONE, NULL);
+
+       /*
+        * The GtkLabel widget is one of a few GTK+ widgets that don't create
+        * their own window to render themselves into. Instead, they draw
+        * themselves directly onto their parents window. This means that in
+        * order to set a property for a GtkLabel widget, you need to change the
+        * property of its parent, i.e. the object that you pack it into.
+        * Another solution (short term workaround) is to put the label widget
+        * inside another widget that does get its own window, like the
+        * 'ViewPort' or 'EventBox' widget.
+        */
+
+       /*
+        * Using workaround described above to set the border width of 'label'
+        * widget.
+        */
+       label_window = gtk_event_box_new();
+
+       /* Creating our label. */
+       label = gtk_label_new(message);
+       gtk_label_set_justify(GTK_LABEL(label), justification);
+
+       if (font_style == MESSAGE_DIALOG_FIXED_FONT) {
+               PangoFontDescription *pango_font;
+
+               pango_font = pango_font_description_from_string(FIXED_FONT);
+               gtk_widget_modify_font(label, pango_font);
+       }
+
+       /* Adding label widget to label_window widget. */
+       gtk_container_add(GTK_CONTAINER(label_window), label);
+
+       /*
+        * Changing border width of the label widget by way of label_window
+        * widget.
+        */
+       gtk_container_set_border_width(GTK_CONTAINER(label_window),
+                                      MESSAGE_DIALOG_BORDER);
+
+       /* Ensure that the dialog box is destroyed when the user responds */
+       g_signal_connect_swapped(dialog, "response",
+                                G_CALLBACK(gtk_widget_destroy), dialog);
+
+       /* Add the label_window to the dialog window. */
+       gtk_container_add(GTK_CONTAINER(GTK_DIALOG(dialog)->vbox),
+                         label_window);
+
+       /* Show everything we've added to the dialog. */
+       gtk_widget_show_all(dialog);
+}
diff --git a/src/gtk/messagebox.h b/src/gtk/messagebox.h
new file mode 100644 (file)
index 0000000..991e758
--- /dev/null
@@ -0,0 +1,33 @@
+/*
+ * messagebox.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 MESSAGEBOX_H
+#define MESSAGEBOX_H 1
+
+#include <gtk/gtk.h>
+
+#define MESSAGE_DIALOG_NORMAL_FONT 0
+#define MESSAGE_DIALOG_FIXED_FONT  1
+
+void
+ShowMessage(gchar *title, gchar *message, int justification, int font_style);
+
+#endif /* MESSAGEBOX_H */
diff --git a/src/gtk/pgmwin.c b/src/gtk/pgmwin.c
new file mode 100644 (file)
index 0000000..0e8961b
--- /dev/null
@@ -0,0 +1,299 @@
+/*
+ * pgmwin.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 "common.h"
+#include "memory.h"
+#include "cpu8051.h"
+#include "pgmwin.h"
+#include "hexfile.h"
+
+static GtkWidget *pgmlist;
+
+#define LIST_VIEW_NAME "Program"
+#define DATA_ROWS 100
+
+enum
+{
+       COL_BREAKPT = 0,
+       COL_ADDR,
+       COL_B0,
+       COL_B1,
+       COL_B2,
+       COL_INST,
+       COL_ARGS,
+       COL_COLOR,
+       N_COLUMNS,
+};
+
+static char *col_names[N_COLUMNS] = {
+       "BPT",
+       "Address",
+       "B0",
+       "B1",
+       "B2",
+       "Mnemonic",
+       "Arguments",
+       "COLOR", /* Not displayed, used to set foreground color of cell. */
+};
+
+/* Creating a model */
+static GtkListStore *
+pgmwin_init_store(void)
+{
+       GtkTreeIter iter;
+       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);
+
+       /* 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;
+}
+
+static void
+pgmwin_init_columns(void)
+{
+       int k;
+       GtkCellRenderer *renderer;
+
+       /* Create renderer */
+       renderer = gtk_cell_renderer_text_new();
+
+       /* Add columns, except for last one (COL_COLOR). */
+       for (k = 0; k < COL_COLOR; k++) {
+               GtkTreeViewColumn *col;
+
+               /* 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);
+       }
+}
+
+/* Mouse button pressed in the window. */
+static gint
+pgmwin_sel_changed_event(GtkWidget *widget, GdkEvent *event, gpointer data)
+{
+       GtkTreeSelection *selection;
+       GtkTreeModel     *model;
+       GtkTreeIter       iter;
+
+       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));
+
+       if (gtk_tree_selection_get_selected(selection, &model, &iter)) {
+               char *str_addr;
+               int val;
+
+               gtk_tree_model_get(model, &iter, COL_ADDR, &str_addr, -1);
+
+               /* Convert hex address in ASCII to integer. */
+               val = asciihex2int(str_addr);
+
+               log_debug("  row address is: $%04X", val);
+
+               ToggleBreakpoint(val);
+               pgmwin_refresh();
+
+               g_free(str_addr);
+       } else {
+               log_debug("  no row selected");
+       }
+
+       return FALSE;
+}
+
+GtkWidget *
+pgmwin_init(void)
+{
+       GtkWidget *frame;
+       GtkWidget *scrollwin;
+       GtkListStore *store;
+       GtkTreeSelection *selection;
+
+       frame = gtk_frame_new(LIST_VIEW_NAME);
+
+       scrollwin = gtk_scrolled_window_new(NULL, NULL);
+       gtk_scrolled_window_set_shadow_type(GTK_SCROLLED_WINDOW(scrollwin),
+                                           GTK_SHADOW_ETCHED_OUT);
+
+       /* Automatically add scrollbars when necessary. */
+       gtk_scrolled_window_set_policy(GTK_SCROLLED_WINDOW(scrollwin),
+                                      GTK_POLICY_AUTOMATIC,
+                                      GTK_POLICY_AUTOMATIC);
+
+       gtk_container_add(GTK_CONTAINER(frame), scrollwin);
+
+       /* Creating a model */
+       store = pgmwin_init_store();
+
+       /* Creating the view component */
+       pgmlist = gtk_tree_view_new_with_model(GTK_TREE_MODEL(store));
+       gtk_tree_view_set_headers_visible(GTK_TREE_VIEW(pgmlist), TRUE);
+       gtk_container_add(GTK_CONTAINER(scrollwin), pgmlist);
+
+       selection = gtk_tree_view_get_selection(GTK_TREE_VIEW(pgmlist));
+
+       /* Only one row can be selected at a time. */
+       gtk_tree_selection_set_mode(selection, GTK_SELECTION_BROWSE);
+
+       g_signal_connect(selection, "changed",
+               G_CALLBACK(pgmwin_sel_changed_event), NULL);
+
+       pgmwin_init_columns();
+
+       /*
+        * The tree view has acquired its own reference to the model, so we can
+        * drop ours. That way the model will be freed automatically when the
+        * tree view is destroyed.
+        */
+       g_object_unref(store);
+
+       return frame;
+}
+
+/* Show disassembled program. */
+void
+pgmwin_refresh(void)
+{
+       int row;
+       GtkListStore *store;
+       unsigned int Address;
+
+       Address = cpu8051.pc;
+
+       store = GTK_LIST_STORE(gtk_tree_view_get_model(GTK_TREE_VIEW(pgmlist)));
+
+       for (row = 0; row < DATA_ROWS; row++) {
+               int valid;
+               GtkTreeIter iter;
+               char str[128];
+               int k;
+               int col_id;
+               int InstSize;
+               unsigned char OpCode;
+
+               if (row == 0) {
+                       /* Get first row in list store */
+                       valid = gtk_tree_model_get_iter_first(
+                               GTK_TREE_MODEL(store), &iter);
+               } else {
+                       /* Get next row in list store */
+                       valid = gtk_tree_model_iter_next(
+                               GTK_TREE_MODEL(store), &iter);
+               }
+
+               if (!valid) {
+                       printf("Invalid iter...\n");
+                       return;
+               }
+
+               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);
+
+                       /* Display base address. */
+                       int2asciihex(Address, str, 4);
+
+                       gtk_list_store_set(store, &iter, COL_ADDR, str, -1);
+
+                       OpCode = memory_read8(PGM_MEM_ID, Address);
+                       InstSize = cpu8051_get_instruction_size(OpCode);
+
+                       /* 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';
+
+                               gtk_list_store_set(store, &iter, col_id, str, -1);
+                       }
+
+                       /* 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;
+               }
+       }
+}
diff --git a/src/gtk/pgmwin.h b/src/gtk/pgmwin.h
new file mode 100644 (file)
index 0000000..952d931
--- /dev/null
@@ -0,0 +1,36 @@
+/*
+ * pgmwin.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 PGMWIN_H
+#define PGMWIN_H 1
+
+#include <gtk/gtk.h>
+
+GtkWidget *
+pgmwin_init(void);
+
+void
+pgmwin_refresh(void);
+
+int
+pgmwin_IsBreakpoint(unsigned int address);
+
+#endif /* PGMWIN_H */
diff --git a/src/gtk/pswwin.c b/src/gtk/pswwin.c
new file mode 100644 (file)
index 0000000..94f733c
--- /dev/null
@@ -0,0 +1,247 @@
+/*
+ * pswwin.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 "common.h"
+#include "reg8051.h"
+#include "cpu8051.h"
+#include "memory.h"
+#include "pswwin.h"
+#include "memwin.h"
+#include "pgmwin.h"
+#include "psw.h"
+#include "instructions_8051.h"
+#include "hexfile.h"
+#include "emugtk.h"
+
+static GtkWidget *pswlist;
+
+#define DATA_ROWS 1
+#define LIST_VIEW_NAME "PSW"
+enum
+{
+       COL_CY = 0,
+       COL_AC,
+       COL_F0,
+       COL_RS1,
+       COL_RS0,
+       COL_OV,
+       COL_RESERVED,
+       COL_P,
+       N_COLUMNS,
+};
+
+static char *col_names[N_COLUMNS] = {
+       "CY",
+       "AC",
+       "F0",
+       "RS1",
+       "RS0",
+       "OV",
+       "-",
+       "P",
+};
+
+/* Creating a model */
+static GtkListStore *
+pswwin_init_store(void)
+{
+       GtkTreeIter iter;
+       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);
+
+       /* Add rows. */
+       for (row = 0; row < DATA_ROWS; row++)
+               gtk_list_store_append(store, &iter);
+
+       return store;
+}
+
+static void
+pswwin_cell_edited(GtkCellRendererText *cell, gchar *path_string,
+                  gchar *new_str, gpointer model)
+{
+       guint column;
+       gpointer columnptr;
+       GtkTreeIter iter;
+       u_int8_t old;
+       int new;
+       char str[10];
+       int bit_index;
+
+       if (!model) {
+               g_error("Unable to get model from cell renderer");
+       }
+
+       /* Column number is passed as renderer object data */
+        columnptr = g_object_get_data(G_OBJECT(cell), "column");
+        column = GPOINTER_TO_UINT(columnptr);
+
+       log_info("column = $%02X", column);
+
+       /* Get the iterator */
+        gtk_tree_model_get_iter_from_string(model, &iter, path_string);
+
+       bit_index = 7 - column;
+
+       old = psw_read_bit(bit_index);
+
+       log_info("  old value: %d", old);
+
+       /* Convert new value (asciihex) to integer. */
+       new = asciihex2int(new_str);
+
+       if ((new != 0) && (new != 1)) {
+               log_info("  new value: out of range");
+               new = old; /* Put back old value... */
+       } else {
+               log_info("  new value: %d", new);
+       }
+
+       /* Store new value in emulator memory. */
+       psw_write_bit(bit_index, new);
+
+       /* Convert to text. */
+       int2asciihex(new, str, 1);
+
+       /* Store new value in gtk model. */
+        gtk_list_store_set(GTK_LIST_STORE(model), &iter, column, str, -1);
+
+       /*
+        * Make sure to update all registers and memory.
+        * For example, BANKed registers depends on internal memory.
+        */
+       emugtk_UpdateDisplay();
+};
+
+static void
+pswwin_init_columns(void)
+{
+       int k;
+
+       /* Add column for each bit in PSW. */
+       for (k = 0; k < N_COLUMNS; k++) {
+               GtkCellRenderer *renderer;
+               GtkTreeViewColumn *column;
+
+               /* Create new renderer for value column (editable). */
+               renderer = gtk_cell_renderer_text_new();
+
+               /* Allow edition, align to center. */
+               g_object_set(renderer, "editable", TRUE, "xalign", 0.5, NULL);
+
+               g_signal_connect(renderer, "edited",
+                                G_CALLBACK(pswwin_cell_edited),
+                                gtk_tree_view_get_model(GTK_TREE_VIEW(pswlist)));
+
+               /* Add column index, used when editing the cell. */
+               g_object_set_data(G_OBJECT(renderer), "column",
+                                 GUINT_TO_POINTER(k));
+
+               column = gtk_tree_view_column_new_with_attributes(
+                       col_names[k], renderer, "text", k, NULL);
+
+               /* Center column name */
+               g_object_set(column, "alignment", 0.5, NULL);
+
+               /* Hardcoded width... */
+               gtk_tree_view_column_set_sizing(column, GTK_TREE_VIEW_COLUMN_FIXED);
+               gtk_tree_view_column_set_fixed_width(column, 35);
+
+               gtk_tree_view_append_column(GTK_TREE_VIEW(pswlist), column);
+       }
+}
+
+GtkWidget *
+pswwin_init(void)
+{
+       GtkWidget *frame;
+       GtkListStore *store;
+
+       frame = gtk_frame_new(LIST_VIEW_NAME);
+
+       /* Creating a model */
+       store = pswwin_init_store();
+
+       /* Creating the view component */
+       pswlist = gtk_tree_view_new_with_model(GTK_TREE_MODEL(store));
+
+       gtk_tree_view_set_grid_lines(GTK_TREE_VIEW(pswlist), GTK_TREE_VIEW_GRID_LINES_BOTH);
+
+       gtk_tree_view_set_headers_visible(GTK_TREE_VIEW(pswlist), TRUE);
+       gtk_container_add(GTK_CONTAINER(frame), pswlist);
+
+       pswwin_init_columns();
+
+       /*
+        * The tree view has acquired its own reference to the model, so we can
+        * drop ours. That way the model will be freed automatically when the
+        * tree view is destroyed.
+        */
+       g_object_unref(store);
+
+       return frame;
+}
+
+/* Show registers. */
+void
+pswwin_refresh(void)
+{
+       GtkListStore *store;
+       int valid;
+       GtkTreeIter iter;
+       int k;
+
+       store = GTK_LIST_STORE(gtk_tree_view_get_model(GTK_TREE_VIEW(pswlist)));
+
+       /* Get first row in list store */
+       valid = gtk_tree_model_get_iter_first(
+               GTK_TREE_MODEL(store), &iter);
+
+       if (!valid) {
+               printf("Invalid iter...\n");
+               return;
+       }
+
+       /* Display bit values. */
+       for (k = 0; k < N_COLUMNS; k++) {
+               char str[4];
+               int bit_index;
+
+               bit_index = 7 - k;
+
+               int2asciihex(psw_read_bit(bit_index), str, 1);
+               gtk_list_store_set(store, &iter, k, str, -1);
+       }
+}
diff --git a/src/gtk/pswwin.h b/src/gtk/pswwin.h
new file mode 100644 (file)
index 0000000..84d34dd
--- /dev/null
@@ -0,0 +1,33 @@
+/*
+ * pswwin.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 PSWWIN_H
+#define PSWWIN_H 1
+
+#include <gtk/gtk.h>
+
+GtkWidget *
+pswwin_init(void);
+
+void
+pswwin_refresh(void);
+
+#endif /* PSWWIN_H */
diff --git a/src/gtk/regwin.c b/src/gtk/regwin.c
new file mode 100644 (file)
index 0000000..8c4cd4d
--- /dev/null
@@ -0,0 +1,256 @@
+/*
+ * regwin.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 "common.h"
+#include "reg8051.h"
+#include "cpu8051.h"
+#include "sfr.h"
+#include "memory.h"
+#include "regwin.h"
+#include "memwin.h"
+#include "pgmwin.h"
+#include "instructions_8051.h"
+#include "hexfile.h"
+#include "emugtk.h"
+
+static GtkWidget *reglist;
+
+#define LIST_VIEW_NAME "Registers"
+#define DATA_ROWS SFR_REGS
+
+enum
+{
+       COL_NAME = 0,
+       COL_VAL,
+       N_COLUMNS,
+};
+
+/* Creating a model */
+static GtkListStore *
+regwin_init_store(void)
+{
+       GtkTreeIter iter;
+       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);
+
+       /* Add rows. */
+       for (row = 0; row < DATA_ROWS; row++)
+               gtk_list_store_append(store, &iter);
+
+       return store;
+}
+
+static void
+regwin_cell_edited(GtkCellRendererText *cell, gchar *path_string,
+                  gchar *new_str, gpointer model)
+{
+       GtkTreeIter iter;
+       int old;
+       int new;
+       char *str;
+       struct regwin_infos_t *regwin_infos;
+
+       if (!model) {
+               g_error("Unable to get model from cell renderer");
+       }
+
+       /* Get the iterator */
+        gtk_tree_model_get_iter_from_string(model, &iter, path_string);
+
+       /* Get register name. */
+       gtk_tree_model_get(model, &iter, COL_NAME, &str, -1);
+
+       log_info("Register: %s", str);
+       regwin_infos = sfr_get_infos(str);
+
+       /* Read current (old) value. */
+       gtk_tree_model_get(model, &iter, COL_VAL, &str, -1);
+
+       old = asciihex2int(str);
+
+       if (regwin_infos->w == 2)
+               log_info("  old value: $%02X", old);
+       else if (regwin_infos->w == 4)
+               log_info("  old value: $%04X", old);
+
+       new = asciihex2int(new_str);
+
+       if (regwin_infos->w == 2) {
+               if ((new < 0) || (new > 0xFF)) {
+                       log_info("  new value: out of range");
+                       new = old; /* Put back old value... */
+               } else {
+                       log_info("  new value: $%02X", new);
+               }
+       } else if (regwin_infos->w == 4) {
+               if ((new < 0) || (new > 0xFFFF)) {
+                       log_info("  new value: out of range");
+                       new = old; /* Put back old value... */
+               } else {
+                       log_info("  new value: $%04X", new);
+               }
+       }
+
+       /* Store new value in emulator register. */
+       regwin_write(regwin_infos, new);
+
+       /* Store new value in gtk model. */
+       int2asciihex(new, str, regwin_infos->w);
+        gtk_list_store_set(GTK_LIST_STORE(model), &iter, COL_VAL, str, -1);
+
+       /*
+        * Make sure to update all windows.
+        * For example, R0-R7 values depends on internal memory values.
+        */
+       emugtk_UpdateDisplay();
+};
+
+static void
+regwin_init_columns(void)
+{
+       GtkCellRenderer *renderer;
+       GtkTreeViewColumn *column;
+
+       /* Columns and cell renderers */
+       renderer = gtk_cell_renderer_text_new();
+
+       /* Add Register column */
+       column = gtk_tree_view_column_new_with_attributes(
+               "Name", renderer, "text", COL_NAME, NULL);
+       gtk_tree_view_column_set_sizing(column, GTK_TREE_VIEW_COLUMN_AUTOSIZE);
+       gtk_tree_view_append_column(GTK_TREE_VIEW(reglist), column);
+
+       /* Add Value column */
+
+       /* Create new renderer for value column (editable). */
+       renderer = gtk_cell_renderer_text_new();
+
+       /* Allow edition, align to right side. */
+       g_object_set(renderer, "editable", TRUE, "xalign", 1.0, NULL);
+
+       g_signal_connect(renderer, "edited",
+                        G_CALLBACK(regwin_cell_edited),
+                        gtk_tree_view_get_model(GTK_TREE_VIEW(reglist)));
+
+       column = gtk_tree_view_column_new_with_attributes(
+               "Value", renderer, "text", COL_VAL, NULL);
+       gtk_tree_view_column_set_sizing(column, GTK_TREE_VIEW_COLUMN_AUTOSIZE);
+       gtk_tree_view_append_column(GTK_TREE_VIEW(reglist), column);
+}
+
+GtkWidget *
+regwin_init(void)
+{
+       GtkWidget *frame;
+       GtkWidget *scrollwin;
+       GtkListStore *store;
+
+       frame = gtk_frame_new(LIST_VIEW_NAME);
+
+       scrollwin = gtk_scrolled_window_new(NULL, NULL);
+       gtk_scrolled_window_set_shadow_type(GTK_SCROLLED_WINDOW(scrollwin),
+                                           GTK_SHADOW_ETCHED_OUT);
+
+       /* Automatically add scrollbars when necessary. */
+       gtk_scrolled_window_set_policy(GTK_SCROLLED_WINDOW(scrollwin),
+                                      GTK_POLICY_AUTOMATIC,
+                                      GTK_POLICY_AUTOMATIC);
+
+       gtk_container_add(GTK_CONTAINER(frame), scrollwin);
+
+       /* Creating a model */
+       store = regwin_init_store();
+
+       /* Creating the view component */
+       reglist = gtk_tree_view_new_with_model(GTK_TREE_MODEL(store));
+       gtk_tree_view_set_headers_visible(GTK_TREE_VIEW(reglist), TRUE);
+       gtk_container_add(GTK_CONTAINER(scrollwin), reglist);
+
+       regwin_init_columns();
+
+       /*
+        * The tree view has acquired its own reference to the model, so we can
+        * drop ours. That way the model will be freed automatically when the
+        * tree view is destroyed.
+        */
+       g_object_unref(store);
+
+       return frame;
+}
+
+/* Show registers. */
+void
+regwin_refresh(void)
+{
+       int row;
+       GtkListStore *store;
+
+       store = GTK_LIST_STORE(gtk_tree_view_get_model(GTK_TREE_VIEW(reglist)));
+
+       for (row = 0; row < DATA_ROWS; row++) {
+               int valid;
+               GtkTreeIter iter;
+               int val;
+               char str[8];
+               struct regwin_infos_t *regwin_infos;
+
+               if (row == 0) {
+                       /* Get first row in list store */
+                       valid = gtk_tree_model_get_iter_first(
+                               GTK_TREE_MODEL(store), &iter);
+               } else {
+                       /* Get next row in list store */
+                       valid = gtk_tree_model_iter_next(
+                               GTK_TREE_MODEL(store), &iter);
+               }
+
+               if (!valid) {
+                       printf("Invalid iter...\n");
+                       return;
+               }
+
+               regwin_infos = sfr_get_infos_from_row(row);
+
+               val = regwin_read(row);
+
+               /* Convert to specified number of hex digits. */
+               int2asciihex(val, str, regwin_infos->w);
+
+               gtk_list_store_set(store, &iter,
+                                  COL_NAME, regwin_infos->name,
+                                  COL_VAL, str,
+                                  -1);
+       }
+}
diff --git a/src/gtk/regwin.h b/src/gtk/regwin.h
new file mode 100644 (file)
index 0000000..a526f6f
--- /dev/null
@@ -0,0 +1,33 @@
+/*
+ * regwin.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 REGWIN_H
+#define REGWIN_H 1
+
+#include <gtk/gtk.h>
+
+GtkWidget *
+regwin_init(void);
+
+void
+regwin_refresh(void);
+
+#endif /* REGWIN_H */
diff --git a/src/gtk/viewmenu.c b/src/gtk/viewmenu.c
new file mode 100644 (file)
index 0000000..3377329
--- /dev/null
@@ -0,0 +1,208 @@
+/*
+ * viewmenu.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 <gtk/gtk.h>
+
+#include "common.h"
+#include "emugtk.h" /* For AddMenuSeparator() function. */
+#include "messagebox.h"
+#include "viewmenu.h"
+#include "app-config.h"
+
+extern struct app_config_t *cfg;
+
+void toggle_layout(GtkWidget *widget, gpointer data)
+{
+       int id;
+
+        id = GPOINTER_TO_UINT(data);
+
+       if (gtk_check_menu_item_get_active(GTK_CHECK_MENU_ITEM(widget))) {
+               log_info("  Switching to layout %d", id);
+               cfg->layout = id;
+               emugtk_restart_gui();
+       }
+}
+
+void toggle_bits_per_row(GtkWidget *widget, gpointer data)
+{
+       int bits_per_row;
+
+        bits_per_row = GPOINTER_TO_UINT(data);
+
+       if (gtk_check_menu_item_get_active(GTK_CHECK_MENU_ITEM(widget))) {
+               log_info("  Bits per row = %d", bits_per_row);
+               cfg->bits_per_row = bits_per_row;
+               emugtk_restart_gui();
+       }
+}
+
+void toggle_int_memory(GtkWidget *widget, gpointer data)
+{
+       if (gtk_check_menu_item_get_active(GTK_CHECK_MENU_ITEM(widget))) {
+               log_info("  View internal memory");
+               cfg->view_int_memory = 1;
+       } else {
+               cfg->view_int_memory = 0;
+       }
+
+       emugtk_restart_gui();
+}
+
+void toggle_sfr_memory(GtkWidget *widget, gpointer data)
+{
+       if (gtk_check_menu_item_get_active(GTK_CHECK_MENU_ITEM(widget))) {
+               log_info("  View SFR memory");
+               cfg->view_sfr_memory = 1;
+       } else {
+               cfg->view_sfr_memory = 0;
+       }
+
+       emugtk_restart_gui();
+}
+
+void toggle_ext_memory(GtkWidget *widget, gpointer data)
+{
+       if (gtk_check_menu_item_get_active(GTK_CHECK_MENU_ITEM(widget))) {
+               log_info("  View external memory");
+               cfg->view_ext_memory = 1;
+       } else {
+               cfg->view_ext_memory = 0;
+       }
+
+       emugtk_restart_gui();
+}
+
+void
+view_add_layout_submenu(GtkWidget *parent)
+{
+       GtkWidget *submenu;
+       GtkWidget *layout;
+       GtkWidget *layout1;
+       GtkWidget *layout2;
+       GSList *group = NULL;
+
+       submenu = gtk_menu_new();
+
+       layout  = gtk_menu_item_new_with_label("Layout");
+
+       layout1 = gtk_radio_menu_item_new_with_label(group, "Layout1");
+       group = gtk_radio_menu_item_get_group(GTK_RADIO_MENU_ITEM(layout1));
+       layout2 = gtk_radio_menu_item_new_with_label(group, "Layout2");
+
+       if (cfg->layout == UI_LAYOUT1)
+               gtk_check_menu_item_set_active(GTK_CHECK_MENU_ITEM(layout1), TRUE);
+       else
+               gtk_check_menu_item_set_active(GTK_CHECK_MENU_ITEM(layout2), TRUE);
+
+       g_signal_connect(G_OBJECT(layout1), "activate",
+                        G_CALLBACK(toggle_layout), (gpointer) UI_LAYOUT1);
+       g_signal_connect(G_OBJECT(layout2), "activate",
+                        G_CALLBACK(toggle_layout), (gpointer) UI_LAYOUT2);
+
+       gtk_menu_item_set_submenu(GTK_MENU_ITEM(layout), submenu);
+       gtk_menu_shell_append(GTK_MENU_SHELL(submenu), layout1);
+       gtk_menu_shell_append(GTK_MENU_SHELL(submenu), layout2);
+       gtk_menu_shell_append(GTK_MENU_SHELL(parent), layout);
+}
+
+void
+view_add_bits_per_row_submenu(GtkWidget *parent)
+{
+       GtkWidget *submenu;
+       GtkWidget *item;
+       GtkWidget *item1;
+       GtkWidget *item2;
+       GSList *group = NULL;
+
+       submenu = gtk_menu_new();
+
+       item  = gtk_menu_item_new_with_label("Bits per row");
+
+       item1 = gtk_radio_menu_item_new_with_label(group, "8");
+       group = gtk_radio_menu_item_get_group(GTK_RADIO_MENU_ITEM(item1));
+       item2 = gtk_radio_menu_item_new_with_label(group, "16");
+
+       if (cfg->bits_per_row == 8)
+               gtk_check_menu_item_set_active(GTK_CHECK_MENU_ITEM(item1), TRUE);
+       else
+               gtk_check_menu_item_set_active(GTK_CHECK_MENU_ITEM(item2), TRUE);
+
+       g_signal_connect(G_OBJECT(item1), "activate",
+                        G_CALLBACK(toggle_bits_per_row), (gpointer) 8);
+       g_signal_connect(G_OBJECT(item2), "activate",
+                        G_CALLBACK(toggle_bits_per_row), (gpointer) 16);
+
+       gtk_menu_item_set_submenu(GTK_MENU_ITEM(item), submenu);
+       gtk_menu_shell_append(GTK_MENU_SHELL(submenu), item1);
+       gtk_menu_shell_append(GTK_MENU_SHELL(submenu), item2);
+       gtk_menu_shell_append(GTK_MENU_SHELL(parent), item);
+}
+
+void
+ViewAddMenu(GtkWidget *menu_bar)
+{
+       GtkWidget *item;
+       GtkWidget *menu;
+       GtkWidget *view;
+
+       menu = gtk_menu_new();
+
+       view = gtk_menu_item_new_with_label("View");
+
+       item = gtk_check_menu_item_new_with_label("Internal Memory");
+       gtk_menu_shell_append(GTK_MENU_SHELL(menu), item);
+       gtk_check_menu_item_set_active(GTK_CHECK_MENU_ITEM(item),
+                                      cfg->view_int_memory);
+       g_signal_connect(G_OBJECT(item), "activate",
+                        G_CALLBACK(toggle_int_memory), NULL);
+
+       item = gtk_check_menu_item_new_with_label("SFR Memory");
+       gtk_menu_shell_append(GTK_MENU_SHELL(menu), item);
+       gtk_check_menu_item_set_active(GTK_CHECK_MENU_ITEM(item),
+                                      cfg->view_sfr_memory);
+       g_signal_connect(G_OBJECT(item), "activate",
+                        G_CALLBACK(toggle_sfr_memory), NULL);
+
+       item = gtk_check_menu_item_new_with_label("External Memory");
+       gtk_menu_shell_append(GTK_MENU_SHELL(menu), item);
+       gtk_check_menu_item_set_active(GTK_CHECK_MENU_ITEM(item),
+                                      cfg->view_ext_memory);
+       g_signal_connect(G_OBJECT(item), "activate",
+                        G_CALLBACK(toggle_ext_memory), NULL);
+
+       AddMenuSeparator(menu);
+
+       /* Add layout submenu */
+       view_add_layout_submenu(menu);
+
+       AddMenuSeparator(menu);
+
+       /* Add bits per row submenu */
+       view_add_bits_per_row_submenu(menu);
+
+       gtk_menu_item_set_submenu(GTK_MENU_ITEM(view), menu);
+       gtk_menu_shell_append(GTK_MENU_SHELL(menu_bar), view);
+}
diff --git a/src/gtk/viewmenu.h b/src/gtk/viewmenu.h
new file mode 100644 (file)
index 0000000..bf78564
--- /dev/null
@@ -0,0 +1,30 @@
+/*
+ * viewmenu.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 VIEWMENU_H
+#define VIEWMENU_H 1
+
+#include <gtk/gtk.h>
+
+void
+ViewAddMenu(GtkWidget *menu_bar);
+
+#endif /* VIEWMENU_H */
diff --git a/src/helpmenu.c b/src/helpmenu.c
deleted file mode 100644 (file)
index 4a8d9dc..0000000
+++ /dev/null
@@ -1,119 +0,0 @@
-/*
- * helpmenu.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 <stdbool.h>
-
-#if STDC_HEADERS
-#  include <string.h>
-#elif HAVE_STRINGS_H
-#  include <strings.h>
-#endif
-
-#include <gtk/gtk.h>
-
-#include "common.h"
-#include "options.h"
-#include "emugtk.h"
-#include "messagebox.h"
-#include "helpmenu.h"
-
-#define PACKAGE_COPYRIGHT "(c) Hugo Villeneuve"
-
-static void
-HelpCommandsEvent(gchar *string)
-{
-       ShowMessage("Command Line Options", COMMAND_LINE_OPTIONS,
-                   GTK_JUSTIFY_LEFT, MESSAGE_DIALOG_FIXED_FONT);
-}
-
-static void
-HelpAboutEvent(GtkWidget *widget, gpointer data)
-{
-       const char *authors[] = {
-               "Hugo Villeneuve <hugo@hugovil.com>",
-               "Jonathan St-André",
-               "Pascal Fecteau",
-               "Jimmy Ringuette",
-               NULL,
-       };
-
-       const char *license =
-               "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.\n\n"
-               "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.\n\n"
-               "You should have received a copy of the GNU General Public"
-               " License along with this program. If not, see\n"
-               "   <http://www.gnu.org/licenses/>";
-
-       gtk_show_about_dialog(
-               NULL,
-               "name", PACKAGE_NAME,
-               "title", "About Dialog",
-               "version", PACKAGE_VERSION,
-               "logo-icon-name", PACKAGE_TARNAME,
-               "comments", get_package_description(),
-               "authors", authors,
-               "website", PACKAGE_URL,
-               "copyright", PACKAGE_COPYRIGHT,
-               "license", license,
-               "wrap-license", true,
-               NULL);
-}
-
-void
-HelpAddMenu(GtkWidget *menu_bar)
-{
-       GtkWidget *item;
-       GtkWidget *menu;
-
-       menu = gtk_menu_new();
-
-       /* Create the 'Help Command Line Options' item. */
-       item = gtk_menu_item_new_with_label("Command Line Options");
-       gtk_menu_shell_append(GTK_MENU_SHELL(menu), item);
-       /* Attach the callback functions to the activate signal. */
-       g_signal_connect(item, "activate", G_CALLBACK(HelpCommandsEvent), NULL);
-
-       AddMenuSeparator(menu);
-
-       /* Create the 'Help About' item. */
-       item = gtk_menu_item_new_with_label("About " PACKAGE);
-       gtk_menu_shell_append(GTK_MENU_SHELL(menu), item);
-       /* Attach the callback functions to the activate signal. */
-       g_signal_connect(item, "activate", G_CALLBACK(HelpAboutEvent), NULL);
-
-       /* Adding submenu title. */
-       item = gtk_menu_item_new_with_label("Help");
-       gtk_menu_item_set_submenu(GTK_MENU_ITEM(item), menu);
-       gtk_menu_shell_append((GtkMenuShell *) menu_bar, item);
-}
diff --git a/src/helpmenu.h b/src/helpmenu.h
deleted file mode 100644 (file)
index 63908dd..0000000
+++ /dev/null
@@ -1,30 +0,0 @@
-/*
- * helpmenu.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 HELPMENU_H
-#define HELPMENU_H 1
-
-#include <gtk/gtk.h>
-
-void
-HelpAddMenu(GtkWidget *menu_bar);
-
-#endif /* HELPMENU_H */
diff --git a/src/hexfile.c b/src/hexfile.c
deleted file mode 100644 (file)
index 6411166..0000000
+++ /dev/null
@@ -1,186 +0,0 @@
-/*
- * Functions for loading an Intel HEX file.
- *
- * 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 <unistd.h>
-#include <stdio.h>
-#include <stdlib.h>
-
-#if STDC_HEADERS
-#  include <string.h>
-#elif HAVE_STRINGS_H
-#  include <strings.h>
-#endif
-
-#include "common.h"
-#include "memory.h"
-
-/* Convert integer to ASCII hex string. */
-void
-int2asciihex(int val, char *str, int width)
-{
-       if (width == 1)
-               sprintf(str , "%.1X", (u_int8_t) val);
-       else if (width == 2)
-               sprintf(str , "%.2X", (u_int8_t) val);
-       else if (width == 4)
-               sprintf(str , "%.4X", (u_int16_t) val);
-       else
-               sprintf(str , "Err");
-}
-
-/* Convert ASCII hex string to integer. */
-int
-asciihex2int(char *str)
-{
-       int val;
-
-       sscanf(str, "%X", &val);
-
-       return val;
-}
-
-/* Convert an ascii string to an hexadecimal number. */
-unsigned int
-Ascii2Hex(char *istring, int length)
-{
-       unsigned int result = 0;
-       int i, ascii_code;
-
-       if (!length || (length > (int) strlen(istring)))
-               length = strlen(istring);
-
-       for (i = 0; i < length; i++) {
-               ascii_code = istring[i];
-               if (ascii_code > 0x39)
-                       ascii_code &= 0xDF;
-
-               if ((ascii_code >= 0x30 && ascii_code <= 0x39) ||
-                    (ascii_code >= 0x41 && ascii_code <= 0x46)) {
-                       ascii_code -= 0x30;
-                       if (ascii_code > 9)
-                               ascii_code -= 7;
-
-                       result <<= 4;
-                       result += ascii_code;
-               } else {
-                       printf("%s: In Ascii2Hex(), syntax error.\n", PACKAGE);
-                       printf("  str=%s, length=%d\n", istring, length);
-               }
-       }
-       return result;
-}
-
-void
-LoadHexFile(const char *filename)
-{
-       int i, j, RecLength, LoadOffset, RecType, Data, Checksum;
-
-#define LINE_BUFFER_LEN 256
-       FILE *fp;
-       int status;
-       char line[LINE_BUFFER_LEN];
-
-       if (filename == NULL) {
-               printf("%s: No file specified\n", PACKAGE);
-               exit(EXIT_FAILURE);
-       }
-
-       /* Trying to open the file. */
-       fp = fopen(filename, "r");
-       if (fp == NULL) {
-               perror(filename);
-               /*ErrorLocation(__FILE__, __LINE__);*/
-               exit(EXIT_FAILURE);
-       }
-
-       /* Reading one line of data from the hex file. */
-       /* char *fgets(char *s, int size, FILE *stream);
-          Reading stops after an EOF or a newline. If a newline is read, it is
-          stored into the buffer.  A '\0'  is  stored after the last character
-          in the buffer.
-       */
-       while (fgets(line, LINE_BUFFER_LEN, fp) != NULL) {
-               i = 0;
-               Checksum = 0;
-
-               if (line[i++] != ':') {
-                       printf("%s: line not beginning with \":\"\n", PACKAGE);
-                       goto close_file;
-               }
-
-               RecLength = Ascii2Hex(&line[i], 2);
-               i += 2;
-               Checksum += RecLength;
-
-               LoadOffset = Ascii2Hex(&line[i], 4);
-               Checksum += LoadOffset / 256;
-               Checksum += LoadOffset % 256;
-               i += 4;
-
-               RecType = Ascii2Hex(&line[i], 2);
-               i += 2;
-               Checksum += RecType;
-
-               if (RecType == 1) {
-                       Checksum += Ascii2Hex(&line[i], 2);
-                       Checksum &= 0x000000FF;
-
-                       if (Checksum) {
-                               /* Error. */
-                               printf("%s: Invalid format\n", PACKAGE);
-                               goto close_file;
-                       } else {
-                               /* OK */
-                               goto close_file;
-                       }
-               }
-
-               for (j = 0; j < RecLength; j++) {
-                       Data = Ascii2Hex(&line[i], 2);
-                       memory_write8(PGM_MEM_ID,
-                                     (unsigned int)(LoadOffset + j),
-                                     (unsigned char)Data);
-                       i += 2;
-                       Checksum += Data;
-               }
-
-               RecType = Ascii2Hex(&line[i], 2);
-               Checksum += RecType;
-               Checksum &= 0x000000FF;
-
-               if (Checksum) {
-                       printf("%s: Invalid format\n", PACKAGE);
-                       goto close_file;
-               }
-       }
-
-close_file:
-       status = fclose(fp);
-       if (status != EXIT_SUCCESS) {
-               fprintf(stderr, "%s: Error closing hex file.\n", PACKAGE);
-               /*ErrorLocation(__FILE__, __LINE__);*/
-               exit(EXIT_FAILURE);
-       }
-}
diff --git a/src/hexfile.h b/src/hexfile.h
deleted file mode 100644 (file)
index 0f46527..0000000
+++ /dev/null
@@ -1,37 +0,0 @@
-/*
- * hexfile.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 HEXFILE_H
-#define HEXFILE_H 1
-
-void
-int2asciihex(int val, char *str, int width);
-
-int
-asciihex2int(char *str);
-
-unsigned int
-Ascii2Hex(char *istring, int length);
-
-void
-LoadHexFile(const char *filename);
-
-#endif /* HEXFILE_H */
diff --git a/src/keyboard.c b/src/keyboard.c
deleted file mode 100644 (file)
index 654087e..0000000
+++ /dev/null
@@ -1,77 +0,0 @@
-/*
- * keyboard.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.
- */
-
-#include <termios.h>
-#include <unistd.h>
-
-static struct termios orig, newtio;
-static int peek = -1;
-
-int
-kbhit(void)
-{
-       char ch;
-       int nread;
-       if (peek != -1)
-               return 1;
-       newtio.c_cc[VMIN] = 0;
-       tcsetattr(0, TCSANOW, &newtio);
-       nread = read(0, &ch, 1);
-       newtio.c_cc[VMIN] = 1;
-       tcsetattr(0, TCSANOW, &newtio);
-       if (nread == 1) {
-               peek = ch;
-               return 1;
-       }
-       return 0;
-}
-
-int
-getch(void)
-{
-       char ch;
-       if (peek != -1) {
-               ch = peek;
-               peek = -1;
-               return ch;
-       }
-       read(0, &ch, 1);
-       return ch;
-}
-
-void
-InitUnixKB(void)
-{
-       tcgetattr(0, &orig);
-       newtio = orig;
-       newtio.c_lflag &= ~ICANON;
-       newtio.c_lflag &= ~ECHO;
-       newtio.c_lflag &= ~ISIG;
-       newtio.c_cc[VMIN] = 1;
-       newtio.c_cc[VTIME] = 0;
-       tcsetattr(0, TCSANOW, &newtio);
-}
-
-void
-ResetUnixKB(void)
-{
-       tcsetattr(0, TCSANOW, &orig);
-}
diff --git a/src/keyboard.h b/src/keyboard.h
deleted file mode 100644 (file)
index 8660616..0000000
+++ /dev/null
@@ -1,37 +0,0 @@
-/*
- * keyboard.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 _KEYBOARD_H_
-#define _KEYBOARD_H_
-
-int
-kbhit(void);
-
-int
-getch(void);
-
-void
-InitUnixKB(void);
-
-void
-ResetUnixKB(void);
-
-#endif /* _KEYBOARD_H_ */
diff --git a/src/log.c b/src/log.c
deleted file mode 100644 (file)
index b378575..0000000
--- a/src/log.c
+++ /dev/null
@@ -1,130 +0,0 @@
-/*
- * log.c -- debug functions for logging.
- *
- * Copyright (C) 2011 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.
- */
-
-#include "config.h"
-
-#include <unistd.h>
-#include <stdio.h>
-#include <stdlib.h>
-#include <stdarg.h>
-#include <string.h>
-
-#include "common.h"
-#include "options.h"
-
-#define PREFIX_PACKAGE_NAME 1
-#define ADD_LINEFEED        1
-
-extern struct options_t options;
-
-static void
-log_prefix_package_name(FILE *stream, const char *severity)
-{
-#if PREFIX_PACKAGE_NAME
-       /* Printing the name of the program first if desired. */
-       fprintf(stream, "%s %s: ", PACKAGE_NAME, severity);
-#endif /* PREFIX_PACKAGE_NAME */
-}
-
-static void
-log_suffix_newline(FILE *stream)
-{
-#if ADD_LINEFEED
-       fprintf(stream, "\n");
-#endif /* ADD_LINEFEED */
-}
-
-void
-log_debug(const char *format, ...)
-{
-       FILE *stream = stdout;
-
-       if (options.log >= LOG_LEVEL_DEBUG) {
-               va_list ap;
-
-               log_prefix_package_name(stream, "debug");
-
-               va_start(ap, format);
-               vfprintf(stream, format, ap);
-               va_end(ap);
-
-               log_suffix_newline(stream);
-       }
-}
-
-void
-log_info(const char *format, ...)
-{
-       FILE *stream = stdout;
-
-       if (options.log >= LOG_LEVEL_INFO) {
-               va_list ap;
-
-               log_prefix_package_name(stream, "info");
-
-               va_start(ap, format);
-               vfprintf(stream, format, ap);
-               va_end(ap);
-
-               log_suffix_newline(stream);
-       }
-}
-
-void
-log_warn(const char *format, ...)
-{
-       FILE *stream = stderr;
-
-       if (options.log >= LOG_LEVEL_WARN) {
-               va_list ap;
-
-               log_prefix_package_name(stream, "warn");
-
-               va_start(ap, format);
-               vfprintf(stream, format, ap);
-               va_end(ap);
-
-               log_suffix_newline(stream);
-       }
-}
-
-void
-log_err(const char *format, ...)
-{
-       FILE *stream = stderr;
-       va_list ap;
-
-       log_prefix_package_name(stream, "error");
-
-       va_start(ap, format);
-       vfprintf(stream, format, ap);
-       va_end(ap);
-
-       log_suffix_newline(stream);
-}
-
-/* Log error message and exits with error code. */
-void
-log_fail(const char *format, ...)
-{
-       FILE *stream = stderr;
-       va_list ap;
-
-       log_prefix_package_name(stream, "error");
-
-       va_start(ap, format);
-       vfprintf(stream, format, ap);
-       va_end(ap);
-
-       log_suffix_newline(stream);
-
-       exit(EXIT_FAILURE);
-}
diff --git a/src/log.h b/src/log.h
deleted file mode 100644 (file)
index 6b3e2e9..0000000
--- a/src/log.h
+++ /dev/null
@@ -1,46 +0,0 @@
-/*
- * log.h
- *
- * Copyright (C) 2011 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.
- */
-
-#ifndef LOG_H
-#define LOG_H 1
-
-#include <stdio.h>
-#include <stdlib.h>
-#include <stdint.h>
-#include <errno.h>
-#include <string.h>
-
-#include "common.h"
-
-enum LOG_LEVEL {
-       LOG_LEVEL_ERR = 0, /* Display only errors */
-       LOG_LEVEL_WARN,    /* Display warnings */
-       LOG_LEVEL_INFO,    /* Display information messages */
-       LOG_LEVEL_DEBUG,   /* Display all messages */
-};
-
-void
-log_debug(const char *format, ...);
-
-void
-log_info(const char *format, ...);
-
-void
-log_warn(const char *format, ...);
-
-void
-log_err(const char *format, ...);
-
-/* Log error message and exits with error code. */
-void
-log_fail(const char *format, ...);
-
-#endif /* LOG_H */
diff --git a/src/memory.c b/src/memory.c
deleted file mode 100644 (file)
index c5b2acf..0000000
+++ /dev/null
@@ -1,245 +0,0 @@
-/*
- * memory.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.
- */
-
-#include <stdio.h>
-#include <string.h>
-
-#include "common.h"
-#include "cpu8051.h"
-#include "reg8051.h"
-#include "hexfile.h"
-#include "memory.h"
-#include "options.h"
-
-struct mem_infos_t {
-       int size;
-       int max_size;
-       u_int8_t *buf;
-};
-
-struct mem_infos_t mem_infos[MEM_ID_COUNT];
-
-extern struct options_t options;
-
-/* Init each 8051 memory sections. */
-void
-memory_init(void)
-{
-       int k;
-       struct mem_infos_t *m;
-
-       /* Set desired and maximum allowable sizes for each memory type. */
-       mem_infos[PGM_MEM_ID].size = options.pram_size;
-       mem_infos[PGM_MEM_ID].max_size = PGM_MEM_MAX_SIZE;
-
-       mem_infos[INT_MEM_ID].size = options.iram_size;
-       mem_infos[INT_MEM_ID].max_size = INT_MEM_MAX_SIZE;
-
-       mem_infos[EXT_MEM_ID].size = options.xram_size;
-       mem_infos[EXT_MEM_ID].max_size = EXT_MEM_MAX_SIZE;
-
-       /* Verify if desired sizes are valid, and if so allocate memory. */
-       for (k = 0; k < MEM_ID_COUNT; k++) {
-               m = &mem_infos[k];
-
-               if (m->size > m->max_size) {
-                       log_err("Memory size invalid (max = %d)", m->max_size);
-                       exit(1);
-               }
-
-               m->buf = malloc(m->size);
-               if (m->buf == NULL) {
-                       log_err("%s", strerror(errno));
-                       exit(1);
-               }
-
-               memset(m->buf, 0x00, m->size);
-       }
-}
-
-void
-memory_clear(enum mem_id_t id)
-{
-       memset(mem_infos[id].buf, 0, mem_infos[id].size);
-}
-
-void
-memory_write8(enum mem_id_t id, unsigned long address, u_int8_t value)
-{
-       if (address >= mem_infos[id].max_size) {
-               printf("Error writing to memory ID: %d\n", id);
-               printf("  Address (%lu) greater than maximum memory size\n",
-                      address);
-               return;
-       } else
-               mem_infos[id].buf[address] = value;
-}
-
-void
-memory_sfr_write8(unsigned long address, u_int8_t value)
-{
-       /* SFR registers are from addresses $80 to $FF. */
-       memory_write8(INT_MEM_ID, address, value);
-}
-
-void
-memory_sfr_write_dptr(u_int16_t value)
-{
-       memory_write8(INT_MEM_ID, _DPTRHIGH_, value >> 8);
-       memory_write8(INT_MEM_ID, _DPTRLOW_, (uint8_t) value);
-}
-
-u_int8_t
-memory_read8(enum mem_id_t id, unsigned long address)
-{
-       if (address >= mem_infos[id].max_size) {
-               printf("Error reading from memory ID: %d\n", id);
-               printf("  Address (%lu) greater than maximum memory size\n",
-                      address);
-               return 0;
-       } else
-               return mem_infos[id].buf[address];
-}
-
-u_int8_t
-memory_sfr_read8(unsigned long address)
-{
-       /* SFR registers are from addresses $80 to $FF. */
-       return memory_read8(INT_MEM_ID, address);
-}
-
-u_int16_t
-memory_sfr_read_dptr(void)
-{
-       return (memory_read8(INT_MEM_ID, _DPTRHIGH_) << 8) +
-               memory_read8(INT_MEM_ID, _DPTRLOW_);
-}
-
-void
-stack_push8(uint8_t value)
-{
-       uint8_t sp;
-
-       sp = memory_read8(INT_MEM_ID, _SP_);
-
-       memory_write8(INT_MEM_ID, ++sp, value);
-       memory_write8(INT_MEM_ID, _SP_, sp); /* Save new stack pointer */
-}
-
-void
-stack_push16(uint16_t value)
-{
-       uint8_t sp;
-
-       sp = memory_read8(INT_MEM_ID, _SP_);
-
-       memory_write8(INT_MEM_ID, ++sp, (uint8_t) value); /* Write LSB */
-       memory_write8(INT_MEM_ID, ++sp, value >> 8);      /* Write MSB */
-       memory_write8(INT_MEM_ID, _SP_, sp); /* Save new stack pointer */
-}
-
-uint8_t
-stack_pop8(void)
-{
-       uint8_t sp;
-       uint8_t value;
-
-       sp = memory_read8(INT_MEM_ID, _SP_);
-
-       value = memory_read8(INT_MEM_ID, sp--);
-       memory_write8(INT_MEM_ID, _SP_, sp); /* Save new stack pointer */
-
-       return value;
-}
-
-uint16_t
-stack_pop16(void)
-{
-       uint8_t sp;
-       uint16_t value;
-
-       sp = memory_read8(INT_MEM_ID, _SP_);
-
-       value = memory_read8(INT_MEM_ID, sp--) << 8; /* Read MSB */
-       value |= memory_read8(INT_MEM_ID, sp--);     /* Read LSB */
-       memory_write8(INT_MEM_ID, _SP_, sp); /* Save new stack pointer */
-
-       return value;
-}
-
-/* Read a 16-bit address from PGM memory, starting at <base> offset */
-uint16_t
-pgm_read_addr16(uint16_t base)
-{
-       uint16_t addr;
-
-       addr = memory_read8(PGM_MEM_ID, base) << 8; /* MSB */
-       addr |= memory_read8(PGM_MEM_ID, base + 1); /* LSB */
-
-       return addr;
-}
-
-/* Dump memory */
-void
-DumpMem(char *Address, char *Asize, int memory_id)
-{
-       unsigned int MemAddress;
-       int size;
-       int Offset, Column;
-
-       if (strlen(Address) != 0) {
-               if (STREQ(Address, "PC"))
-                       MemAddress = cpu8051.pc;
-               else
-                       MemAddress = Ascii2Hex(Address, strlen(Address));
-       } else {
-               MemAddress = 0;
-       }
-
-       if (strlen(Asize) != 0) {
-               size = Ascii2Hex(Asize, strlen(Asize));
-       } else {
-               size = 256; /* Default size if not specified. */
-       }
-
-       for (Offset = 0; Offset < size; Offset += 16) {
-               unsigned char data[16];
-
-               printf("%.4X ", MemAddress + Offset);
-
-               for (Column = 0; Column < 16; Column++) {
-                       data[Column] = memory_read8(memory_id, MemAddress +
-                                                   Offset + Column);
-                       printf(" %.2X", (int) data[Column]);
-               }
-               printf("  ");
-
-               /* Display any ASCII characters */
-               for (Column = 0; Column < 16; Column++) {
-                       if ((int) data[Column] >= 32 &&
-                           (int) data[Column] <= 126) {
-                               printf("%c", data[Column]);
-                       } else
-                               printf(".");
-               }
-               printf("\n");
-       }
-}
diff --git a/src/memory.h b/src/memory.h
deleted file mode 100644 (file)
index fee41a6..0000000
+++ /dev/null
@@ -1,88 +0,0 @@
-/*
- * memory.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 MEMORY_H
-#define MEMORY_H 1
-
-#include <sys/types.h>
-
-#define PGM_MEM_MAX_SIZE 65536
-/*
- *   Direct addressing $00 to $7F = IRAM (8051)
- *   Direct addressing $80 to $FF = SFR  (8051)
- * Indirect addressing $80 to $FF = IRAM (8052)
- */
-#define INT_MEM_MAX_SIZE   256
-#define EXT_MEM_MAX_SIZE 65536
-
-#define PGM_MEM_DEFAULT_SIZE 8192
-#define EXT_MEM_DEFAULT_SIZE 1024
-
-enum mem_id_t {
-       PGM_MEM_ID,
-       INT_MEM_ID,
-       EXT_MEM_ID,
-       MEM_ID_COUNT
-};
-
-void
-memory_init(void);
-
-void
-memory_clear(enum mem_id_t id);
-
-void
-memory_write8(enum mem_id_t id, unsigned long address, u_int8_t value);
-
-void
-memory_sfr_write8(unsigned long address, u_int8_t value);
-
-void
-memory_sfr_write_dptr(u_int16_t value);
-
-u_int8_t
-memory_read8(enum mem_id_t id, unsigned long address);
-
-u_int8_t
-memory_sfr_read8(unsigned long address);
-
-u_int16_t
-memory_sfr_read_dptr(void);
-
-void
-stack_push8(uint8_t value);
-
-void
-stack_push16(uint16_t value);
-
-uint8_t
-stack_pop8(void);
-
-uint16_t
-stack_pop16(void);
-
-uint16_t
-pgm_read_addr16(uint16_t base);
-
-void
-DumpMem(char *Address, char *Asize, int memory_id);
-
-#endif /* MEMORY_H */
diff --git a/src/memwin.c b/src/memwin.c
deleted file mode 100644 (file)
index 58ce1d2..0000000
+++ /dev/null
@@ -1,346 +0,0 @@
-/*
- * memwin.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 <ctype.h> /* For isprint */
-
-#include "common.h"
-#include "memory.h"
-#include "hexfile.h"
-#include "cpu8051.h"
-#include "regwin.h"
-#include "memwin.h"
-#include "emugtk.h"
-#include "options.h"
-#include "app-config.h"
-
-extern struct app_config_t *cfg;
-extern struct options_t options;
-
-static int COL_ASCII;
-static int N_COLUMNS;
-
-enum
-{
-       COL_ADDRESS = 0,
-       COL_DATA0,
-};
-
-static GtkWidget *memlist_internal;
-static GtkWidget *memlist_external;
-
-/* Creating a model */
-static GtkListStore *
-memwin_init_store(int data_rows)
-{
-       GtkTreeIter iter;
-       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);
-
-       /* Add rows. */
-       for (row = 0; row < data_rows; row++)
-               gtk_list_store_append(store, &iter);
-
-       return store;
-}
-
-static void
-memwin_cell_edited(GtkCellRendererText *cell, gchar *path_string,
-                  gchar *new_str, gpointer model)
-{
-       guint column;
-       guint memory_id;
-       gpointer columnptr;
-       gpointer memory_id_ptr;
-       GtkTreeIter iter;
-       int address;
-       u_int8_t old;
-       int new;
-       char *str;
-
-       if (!model) {
-               g_error("Unable to get model from cell renderer");
-       }
-
-       /* Column number is passed as renderer object data */
-        columnptr = g_object_get_data(G_OBJECT(cell), "column");
-        column = GPOINTER_TO_UINT(columnptr);
-
-       /* Memory ID  is passed as renderer object data */
-       memory_id_ptr = g_object_get_data(G_OBJECT(cell), "memory_id");
-       memory_id = GPOINTER_TO_UINT(memory_id_ptr);
-
-       /* Get the iterator */
-        gtk_tree_model_get_iter_from_string(model, &iter, path_string);
-
-       /* Get base address. */
-       gtk_tree_model_get(model, &iter, COL_ADDRESS, &str, -1);
-       address = asciihex2int(str);
-
-       /* Convert column number (1, 2, 3...) to index (0, 1, 2...) */
-       address += (column - COL_DATA0);
-       old = memory_read8(memory_id, address);
-
-       log_info("Address: $%02X", address);
-       log_info("  old value: $%02X", old);
-
-       /* Convert new value (asciihex) to integer. */
-       new = asciihex2int(new_str);
-       if ((new < 0) || (new > 255)) {
-               log_info("  new value: out of range");
-               new = old; /* Put back old value... */
-       } else {
-               log_info("  new value: $%02X", new);
-       }
-
-       /* Store new value in emulator memory. */
-       memory_write8(memory_id, address, new);
-
-       /* Convert to text. */
-       int2asciihex(new, str, 2);
-
-       /* Store new value in gtk model. */
-        gtk_list_store_set(GTK_LIST_STORE(model), &iter, column, str, -1);
-
-       /*
-        * Make sure to update all registers and memory.
-        * For example, BANKed registers depends on internal memory.
-        */
-       emugtk_UpdateDisplay();
-};
-
-static void
-memwin_init_columns(GtkWidget *listview, int memory_id)
-{
-       int i;
-       GtkCellRenderer *renderer;
-       GtkTreeViewColumn *column;
-
-       /* Columns and cell renderers */
-       renderer = gtk_cell_renderer_text_new();
-
-       /* Add address column */
-       column = gtk_tree_view_column_new_with_attributes(
-               "Address", renderer, "text", COL_ADDRESS, NULL);
-       gtk_tree_view_column_set_sizing(column, GTK_TREE_VIEW_COLUMN_AUTOSIZE);
-       gtk_tree_view_append_column(GTK_TREE_VIEW(listview), column);
-
-       for (i = COL_DATA0; i < (COL_DATA0 + cfg->bits_per_row); i++) {
-               char col_name[8];
-
-               /* Create new renderer for each editable cell. */
-               renderer = gtk_cell_renderer_text_new();
-
-               /* Allow edition, align to left side. */
-               g_object_set(renderer, "editable", TRUE, "xalign", 0, NULL);
-
-               g_signal_connect(renderer, "edited",
-                                G_CALLBACK(memwin_cell_edited),
-                                gtk_tree_view_get_model(
-                                        GTK_TREE_VIEW(listview)));
-
-               /* Add column index and memory_id, used when editing the cell. */
-               g_object_set_data(G_OBJECT(renderer), "column",
-                                 GUINT_TO_POINTER(i));
-               g_object_set_data(G_OBJECT(renderer), "memory_id",
-                                 GUINT_TO_POINTER(memory_id));
-
-               /* Use two digits only if DATA_ROWS > 10 */
-               if (cfg->bits_per_row < 10)
-                       sprintf(col_name, "B%1d", i - COL_DATA0);
-               else
-                       sprintf(col_name, "B%02d", i - COL_DATA0);
-
-               column = gtk_tree_view_column_new_with_attributes(
-                       col_name, renderer, "text", i, NULL);
-               gtk_tree_view_column_set_sizing(column,
-                                               GTK_TREE_VIEW_COLUMN_AUTOSIZE);
-               gtk_tree_view_append_column(GTK_TREE_VIEW(listview), column);
-       }
-
-       /* Add ASCII column, using fixed-font. */
-       renderer = gtk_cell_renderer_text_new();
-       g_object_set(renderer, "family", "Monospace", NULL);
-       column = gtk_tree_view_column_new_with_attributes(
-               "ASCII", renderer, "text", COL_ASCII, NULL);
-       gtk_tree_view_column_set_sizing(column, GTK_TREE_VIEW_COLUMN_AUTOSIZE);
-       gtk_tree_view_append_column(GTK_TREE_VIEW(listview), column);
-}
-
-static int
-compute_data_rows(int memory_id)
-{
-       int data_rows;
-
-       if (memory_id == INT_MEM_ID) {
-               data_rows = options.iram_size / cfg->bits_per_row;
-       } else if (memory_id == EXT_MEM_ID) {
-               data_rows = options.xram_size / cfg->bits_per_row;
-       } else {
-               log_fail("Invalid memory type");
-               exit(1);
-       }
-
-       return data_rows;
-}
-
-GtkWidget *
-memwin_init(char *title, int memory_id)
-{
-       GtkWidget *frame;
-       GtkWidget *scrollwin;
-       GtkListStore *store;
-       GtkWidget *memlist;
-       int data_rows;
-
-       COL_ASCII = cfg->bits_per_row + 1;
-       N_COLUMNS = COL_ASCII + 1;
-
-       frame = gtk_frame_new(title);
-
-       scrollwin = gtk_scrolled_window_new(NULL, NULL);
-       gtk_scrolled_window_set_shadow_type(GTK_SCROLLED_WINDOW(scrollwin),
-                                           GTK_SHADOW_ETCHED_OUT);
-
-       /* Automatically add scrollbars when necessary. */
-       gtk_scrolled_window_set_policy(GTK_SCROLLED_WINDOW(scrollwin),
-                                      GTK_POLICY_AUTOMATIC,
-                                      GTK_POLICY_AUTOMATIC);
-
-       gtk_container_add(GTK_CONTAINER(frame), scrollwin);
-
-       data_rows = compute_data_rows(memory_id);
-
-       /* Creating a model */
-       store = memwin_init_store(data_rows);
-
-       /* Creating the view component */
-       memlist = gtk_tree_view_new_with_model(GTK_TREE_MODEL(store));
-       gtk_tree_view_set_headers_visible(GTK_TREE_VIEW(memlist), TRUE);
-       gtk_container_add(GTK_CONTAINER(scrollwin), memlist);
-
-       if (memory_id == INT_MEM_ID) {
-               memlist_internal = memlist;
-       } else if (memory_id == EXT_MEM_ID) {
-               memlist_external = memlist;
-       } else {
-               log_fail("Invalid memory type");
-               exit(1);
-       }
-
-       memwin_init_columns(memlist, memory_id);
-
-       /*
-        * The tree view has acquired its own reference to the model, so we can
-        * drop ours. That way the model will be freed automatically when the
-        * tree view is destroyed.
-        */
-       g_object_unref(store);
-
-       return frame;
-}
-
-/* Dump internal or external memory. */
-void
-memwin_refresh(int memory_id)
-{
-       int row;
-       unsigned int Address;
-       GtkListStore *store;
-       GtkWidget *memlist;
-       int data_rows;
-
-       Address = 0;
-
-       data_rows = compute_data_rows(memory_id);
-
-       if (memory_id == INT_MEM_ID) {
-               memlist = memlist_internal;
-       } else if (memory_id == EXT_MEM_ID) {
-               memlist = memlist_external;
-       } else {
-               log_fail("Invalid memory type");
-               exit(1);
-       }
-
-       store = GTK_LIST_STORE(gtk_tree_view_get_model(GTK_TREE_VIEW(memlist)));
-
-       for (row = 0; row < data_rows; 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;
-
-               if (row == 0) {
-                       /* Get first row in list store */
-                       valid = gtk_tree_model_get_iter_first(
-                               GTK_TREE_MODEL(store), &iter);
-               } else {
-                       /* Get next row in list store */
-                       valid = gtk_tree_model_iter_next(
-                               GTK_TREE_MODEL(store), &iter);
-               }
-
-               if (!valid) {
-                       printf("Invalid iter...\n");
-                       return;
-               }
-
-               /* Display base address. */
-               int2asciihex(Address, str, 4);
-
-               gtk_list_store_set(store, &iter, COL_ADDRESS, str, -1);
-
-               for (col = 0; col < cfg->bits_per_row; col++) {
-                       u_int8_t data;
-
-                       data = memory_read8(memory_id, Address + col);
-
-                       /* Display hex data */
-                       int2asciihex(data, str, 2);
-
-                       gtk_list_store_set(store, &iter, col + 1, str, -1);
-
-                       /* Append to ASCII string (if applicable). */
-                       if (!isprint(data))
-                               data = '.';
-                       sprintf(&ascii_str[col], "%c", data);
-               }
-
-               /* Display ASCII characters. */
-               gtk_list_store_set(store, &iter, COL_ASCII, ascii_str, -1);
-
-               Address += cfg->bits_per_row;
-       }
-}
diff --git a/src/memwin.h b/src/memwin.h
deleted file mode 100644 (file)
index ccb528d..0000000
+++ /dev/null
@@ -1,33 +0,0 @@
-/*
- * memwin.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 MEMWIN_H
-#define MEMWIN_H 1
-
-#include <gtk/gtk.h>
-
-GtkWidget *
-memwin_init(char *title, int memory_id);
-
-void
-memwin_refresh(int memory_id);
-
-#endif /* MEMWIN_H */
diff --git a/src/messagebox.c b/src/messagebox.c
deleted file mode 100644 (file)
index c4d3723..0000000
+++ /dev/null
@@ -1,98 +0,0 @@
-/*
- * messagebox.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 <gtk/gtk.h>
-
-#include "common.h"
-#include "messagebox.h"
-
-#define MESSAGE_DIALOG_BORDER 25
-
-#define BUTTON_TEXT_BORDER 3
-
-extern GtkWidget *mainwin;
-
-void
-ShowMessage(gchar *title, gchar *message, int justification, int font_style)
-{
-       GtkWidget *dialog;
-       GtkWidget *label;
-       GtkWidget *label_window;
-
-       /* Keep the dialog on top of the main window, and centered. */
-       dialog = gtk_dialog_new_with_buttons(
-               title, GTK_WINDOW(mainwin),
-               GTK_DIALOG_MODAL | GTK_DIALOG_DESTROY_WITH_PARENT, GTK_STOCK_OK,
-               GTK_RESPONSE_NONE, NULL);
-
-       /*
-        * The GtkLabel widget is one of a few GTK+ widgets that don't create
-        * their own window to render themselves into. Instead, they draw
-        * themselves directly onto their parents window. This means that in
-        * order to set a property for a GtkLabel widget, you need to change the
-        * property of its parent, i.e. the object that you pack it into.
-        * Another solution (short term workaround) is to put the label widget
-        * inside another widget that does get its own window, like the
-        * 'ViewPort' or 'EventBox' widget.
-        */
-
-       /*
-        * Using workaround described above to set the border width of 'label'
-        * widget.
-        */
-       label_window = gtk_event_box_new();
-
-       /* Creating our label. */
-       label = gtk_label_new(message);
-       gtk_label_set_justify(GTK_LABEL(label), justification);
-
-       if (font_style == MESSAGE_DIALOG_FIXED_FONT) {
-               PangoFontDescription *pango_font;
-
-               pango_font = pango_font_description_from_string(FIXED_FONT);
-               gtk_widget_modify_font(label, pango_font);
-       }
-
-       /* Adding label widget to label_window widget. */
-       gtk_container_add(GTK_CONTAINER(label_window), label);
-
-       /*
-        * Changing border width of the label widget by way of label_window
-        * widget.
-        */
-       gtk_container_set_border_width(GTK_CONTAINER(label_window),
-                                      MESSAGE_DIALOG_BORDER);
-
-       /* Ensure that the dialog box is destroyed when the user responds */
-       g_signal_connect_swapped(dialog, "response",
-                                G_CALLBACK(gtk_widget_destroy), dialog);
-
-       /* Add the label_window to the dialog window. */
-       gtk_container_add(GTK_CONTAINER(GTK_DIALOG(dialog)->vbox),
-                         label_window);
-
-       /* Show everything we've added to the dialog. */
-       gtk_widget_show_all(dialog);
-}
diff --git a/src/messagebox.h b/src/messagebox.h
deleted file mode 100644 (file)
index 991e758..0000000
+++ /dev/null
@@ -1,33 +0,0 @@
-/*
- * messagebox.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 MESSAGEBOX_H
-#define MESSAGEBOX_H 1
-
-#include <gtk/gtk.h>
-
-#define MESSAGE_DIALOG_NORMAL_FONT 0
-#define MESSAGE_DIALOG_FIXED_FONT  1
-
-void
-ShowMessage(gchar *title, gchar *message, int justification, int font_style);
-
-#endif /* MESSAGEBOX_H */
diff --git a/src/opcode2c.pl b/src/opcode2c.pl
deleted file mode 100755 (executable)
index 035c718..0000000
+++ /dev/null
@@ -1,851 +0,0 @@
-#!/usr/bin/perl
-#
-# 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.
-
-open INST_DEF, ">instructions_8051.h" or die "Error creating <instructions_8051.h> : $!\n";
-open INST_IMP, ">instructions_8051.c" or die "Error creating <instructions_8051.c> : $!\n";
-open OPCODELST, "opcodes.lst" or die "Error opening <opcodes.lst> : $!\n";
-open DISASM_H, ">disasm.h" or die "Error creating <disasm.h> : $!\n";
-
-# Write GPL license
-# Argument 0 is file descriptor
-sub write_header
-{
-    my $fd = $_[0];
-
-    print $fd " *\n";
-    print $fd " * Do not modify this file directly, as it was created by opcode2c.pl\n";
-    print $fd " * Any modifications made directly to this file will be lost.\n";
-    print $fd " *\n";
-    print $fd " * Copyright (C) 1999 Jonathan St-André\n";
-    print $fd " * Copyright (C) 1999 Hugo Villeneuve <hugo@hugovil.com>\n";
-    print $fd " *\n";
-    print $fd " * This program is free software; you can redistribute it and/or modify\n";
-    print $fd " * it under the terms of the GNU General Public License as published by\n";
-    print $fd " * the Free Software Foundation; either version 2 of the License, or\n";
-    print $fd " * (at your option) any later version.\n";
-    print $fd " *\n";
-    print $fd " * This program is distributed in the hope that it will be useful,\n";
-    print $fd " * but WITHOUT ANY WARRANTY; without even the implied warranty of\n";
-    print $fd " * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n";
-    print $fd " * GNU General Public License for more details.\n";
-    print $fd " *\n";
-    print $fd " * You should have received a copy of the GNU General Public License\n";
-    print $fd " * along with this program; if not, write to the Free Software\n";
-    print $fd " * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA.\n";
-    print $fd " */\n\n";
-}
-
-# Write C function source code line to INST_IMP file.
-# Prefix each line with a tab (indentation) and add newline character at the end.
-sub cfw
-{
-    print INST_IMP "\t",$_[0],"\n";
-}
-
-# Header for instructions_8051.c
-print INST_IMP "/*\n";
-print INST_IMP " * instructions_8051.c\n";
-write_header(INST_IMP);
-print INST_IMP "/* Define only here, for not having extern scope on local variables. */\n";
-print INST_IMP "#define INSTRUCTIONS_8051_M 1\n\n\n";
-print INST_IMP "#include \"reg8051.h\"\n";
-print INST_IMP "#include \"cpu8051.h\"\n";
-print INST_IMP "#include \"memory.h\"\n";
-print INST_IMP "#include \"psw.h\"\n";
-print INST_IMP "#include \"instructions_8051.h\"\n\n\n";
-
-# Header for disasm.h
-print DISASM_H "/*\n";
-print DISASM_H " * disasm.h\n";
-write_header(DISASM_H);
-print DISASM_H "#ifndef DISASM_H\n";
-print DISASM_H "#define DISASM_H 1\n\n";
-
-$nbinst=0;
-$nbaddr=0;
-$nbargs=0;
-$instnumb=0;
-
-$ligne=<OPCODELST>;
-$ligne=<OPCODELST>;
-while($ligne=<OPCODELST>) {
-    chop $ligne;
-    if (length $ligne < 2) {next;}
-    @wordlist=split ' ',$ligne;
-    $nbword=@wordlist;
-    $instruction=$wordlist[2];
-    for($i=3;$i<($nbword-2);$i++) {$instruction="$instruction $wordlist[$i]";}
-
-    $a_instruction[$instnumb]=$instruction;
-    $a_bytes[$instnumb]=$wordlist[$nbword-2];
-    $a_cycles[$instnumb]=$wordlist[$nbword-1];
-    $a_opcodehex[$instnumb]=$wordlist[1];
-    $a_opcodebin[$instnumb]=$wordlist[0];
-
-    $instfunction[$instnumb]="CPU8051::OP_$wordlist[1]";
-
-    $instargs[$instnumb << 2]=$instargs[($instnumb << 2) + 1]=$instargs[($instnumb << 2) + 2]=$instargs[($instnumb << 2) + 3]=0;
-    if ($nbword > 5) {
-       @argslist=split /\,/,$wordlist[3];
-       $argslistsize=@argslist;
-       $instargs[$instnumb << 2]=$argslistsize;
-       for ($i=0;$i<$argslistsize;$i++) {
-           if (not exists $argstypes{$argslist[$i]}) {
-               $argstypes[$nbargs]=$argslist[$i];
-               $argstypes{$argslist[$i]}=$nbargs++;
-           }
-           $instargs[($instnumb << 2) + $i + 1]=$argstypes{$argslist[$i]};
-       }
-    }
-
-    if (not exists $insttext{$wordlist[2]}) {
-       $insttext[$nbinst]=$wordlist[2];
-       $insttext{$wordlist[2]}=$nbinst++;
-    }
-
-    $insttype[$instnumb]=$insttext{$wordlist[2]};
-
-    if ( not exists $addrmode{$wordlist[3]}) {
-       $addrmode[$nbaddr]=$wordlist[3];
-       $addrmode{$wordlist[3]}=$nbaddr++;
-    }
-
-    $nbbytes[$instnumb]=$wordlist[$nbword-2];
-
-    $instaddr[$instnumb]=$addrmode{$wordlist[3]};
-
-    $instnumb++;
-}
-# ------------------------------------------------------------------------------
-print DISASM_H "/*\n";
-print DISASM_H " * For all 256 opcodes, the value in this table gives the instruction type\n";
-print DISASM_H " * ex.: MOV, INC, CLR, CPL,...\n";
-print DISASM_H " * To know what is the instruction type, use\n";
-print DISASM_H " * the number as an offset in the InstTextTbl[]\n";
-print DISASM_H " */\n";
-print DISASM_H "static int InstTypesTbl[] = {\n";
-for($i=0;$i<256;$i++) {
-    print DISASM_H " $insttype[$i]";
-    ($i != 255) and print DISASM_H ",";
-    if (($i+1) % 16 == 0) { print DISASM_H "\n"; }
-}
-print DISASM_H "};\n";
-print DISASM_H "\n";
-# ------------------------------------------------------------------------------
-print DISASM_H "/* Size(in bytes) of each instruction (offset in table is instruction opcode) */\n";
-print DISASM_H "static int InstSizesTbl[] = {\n";
-for($i=0;$i<256;$i++) {
-    print DISASM_H " $nbbytes[$i]";
-    ($i != 255) and print DISASM_H ",";
-    if (($i+1) % 16 == 0) { print DISASM_H "\n"; }
-}
-print DISASM_H "};\n";
-print DISASM_H "\n";
-# ------------------------------------------------------------------------------
-print DISASM_H "/* List of instructions types referenced by InstTypesTbl[] */\n";
-$nbelement=@insttext;
-print DISASM_H "\#define InstTextTblLength $nbelement\n";
-$elementnb=0;
-print DISASM_H "static char *InstTextTbl[] = {\n";
-foreach $instruc (@insttext) {
-    print DISASM_H " \"$instruc\"";
-    ($elementnb++ < $nbelement-1) and print DISASM_H ",";
-    print DISASM_H "\n";
-}
-print DISASM_H "};\n";
-print DISASM_H "\n";
-# ------------------------------------------------------------------------------
-print DISASM_H "/*\n";
-print DISASM_H " * Table describing all arguments types of an instruction\n";
-print DISASM_H " * The table is indexed InstArgTbl[ opcode * 4]\n";
-print DISASM_H " * InstArgTbl[opcode*4 + 1] gives the number of arguments the instruction has\n";
-print DISASM_H " * InstArgTbl[opcode*4 + i] for i=1,2 and 3 give the type of each argument\n";
-print DISASM_H " * for most instructions, the 3rd argument isn't used\n";
-print DISASM_H " * the argument type is referecing to ArgsTextTbl[]\n";
-print DISASM_H " */\n";
-print DISASM_H "\#define InstArgTblLength 256\n";
-print DISASM_H "static int InstArgTbl[] = {\n";
-for($i=0;$i<1024;$i++) {
-    print DISASM_H " $instargs[$i]";
-    ($i != 1023) and print DISASM_H ",";
-    if (($i+1) % 16 == 0) { print DISASM_H "\n"; }
-}
-print DISASM_H "};\n";
-print DISASM_H "\n";
-# ------------------------------------------------------------------------------
-print DISASM_H "/*\n";
-print DISASM_H " * List all types of arguments available to instructions\n";
-print DISASM_H " * Referenced by InstArgsTbl[]\n";
-print DISASM_H " */\n";
-$nbelement=@argstypes;
-print DISASM_H "\#define ArgsTextTblLength $nbelement\n";
-$elementnb=0;
-print DISASM_H "static char *ArgsTextTbl[] = {\n";
-foreach $args (@argstypes) {
-    print DISASM_H " \"$args\"";
-    ($elementnb++ < $nbelement-1) and print DISASM_H ",";
-    print DISASM_H "\n";
-}
-print DISASM_H "};\n";
-print DISASM_H "\n";
-
-# ------------------------------------------------------------------------------
-for ($i=0 ; $i< 256; $i++) {
-    print INST_IMP "/*","*"x76,"\n";
-    print INST_IMP " * Instruction \"$a_instruction[$i]\" takes $a_cycles[$i] cycle(s) and $a_bytes[$i] byte(s).\n";
-    print INST_IMP " ","*"x76,"/\n";
-    print INST_IMP "int\n";
-    print INST_IMP "cpu8051_OP_$a_opcodehex[$i](void)\n";
-    print INST_IMP "{\n";
-
-    if( $i == 0x85 ) {
-       # Cas particulier pour MOV direct,direct -> src et dest sont inverses dans la memoire
-        print INST_IMP "  unsigned char srcaddr = memory_read8( PGM_MEM_ID, cpu8051.pc++ );\n";
-       print INST_IMP "  unsigned char source = cpu8051_ReadD( srcaddr );\n";
-       print INST_IMP "  unsigned char destaddr = memory_read8( PGM_MEM_ID, cpu8051.pc++ );\n";
-       print INST_IMP "  unsigned char destination = cpu8051_ReadD( destaddr );\n";
-       print INST_IMP "  destination = source;\n";
-       print INST_IMP "  cpu8051_WriteD( destaddr, destination );\n";
-    }
-    else {
-       if ($instargs[$i*4] > 0) {
-           $op_destination=$instargs[$i*4+1];
-           if ($op_destination == 0) { # addr11
-               cfw("unsigned int addr11 = ( ( memory_read8( PGM_MEM_ID, cpu8051.pc - 1 ) << 3 ) & 0xF00 ) + memory_read8( PGM_MEM_ID, cpu8051.pc );");
-               cfw("cpu8051.pc++;");
-           }
-           if ($op_destination == 1) { # addr16
-               cfw("uint16_t addr16 = pgm_read_addr16(cpu8051.pc);");
-               cfw("cpu8051.pc += 2;");
-           }
-           if ($op_destination == 2) { # A
-               cfw("unsigned char destination = cpu8051_ReadD( _ACC_ );");
-           }
-           if ($op_destination == 3) { # direct
-               cfw("unsigned char destaddr = memory_read8( PGM_MEM_ID, cpu8051.pc++ );");
-               cfw("unsigned char destination = cpu8051_ReadD( destaddr );");
-           }
-           if ($op_destination == 4) { # @R0
-               cfw("unsigned char destination = cpu8051_ReadI ( cpu8051_ReadD( BANKPSW + _R0_ ) );");
-           }
-           if ($op_destination == 5) { # @R1
-               cfw("unsigned char destination = cpu8051_ReadI ( cpu8051_ReadD( BANKPSW + _R1_ ) );");
-           }
-           if ($op_destination == 6) { # R0
-               cfw("unsigned char destination = cpu8051_ReadD( BANKPSW + _R0_ );");
-           }
-           if ($op_destination == 7) { # R1
-               cfw("unsigned char destination = cpu8051_ReadD( BANKPSW + _R1_ );");
-           }
-           if ($op_destination == 8) { # R2
-               cfw("unsigned char destination = cpu8051_ReadD( BANKPSW + _R2_ );");
-           }
-           if ($op_destination == 9) { # R3
-               cfw("unsigned char destination = cpu8051_ReadD( BANKPSW + _R3_ );");
-           }
-           if ($op_destination == 10) { # R4
-               cfw("unsigned char destination = cpu8051_ReadD( BANKPSW + _R4_ );");
-           }
-           if ($op_destination == 11) { # R5
-               cfw("unsigned char destination = cpu8051_ReadD( BANKPSW + _R5_ );");
-           }
-           if ($op_destination == 12) { # R6
-               cfw("unsigned char destination = cpu8051_ReadD( BANKPSW + _R6_ );");
-           }
-           if ($op_destination == 13) { # R7
-               cfw("unsigned char destination = cpu8051_ReadD( BANKPSW + _R7_ );");
-           }
-           if ($op_destination == 14) { # bitaddr
-               cfw("unsigned char destination, dstbitaddr = memory_read8( PGM_MEM_ID, cpu8051.pc++ );");
-               cfw("destination = cpu8051_ReadB( dstbitaddr );");
-           }
-           if ($op_destination == 15) { # reladdr
-               cfw("cpu8051.pc++;");
-               cfw("unsigned int destination = ((char) memory_read8(PGM_MEM_ID, cpu8051.pc - 1)) + cpu8051.pc;");
-           }
-           if ($op_destination == 16) { # #data
-               cfw("unsigned char destination = memory_read8( PGM_MEM_ID, cpu8051.pc++ );");
-           }
-           if ($op_destination == 17) { # C
-               cfw("unsigned char destination = psw_read_cy();");
-           }
-           if ($op_destination == 18) { # @A+DPTR
-               cfw("unsigned int destination = cpu8051_ReadD( _ACC_ ) + memory_sfr_read_dptr();");
-           }
-            if ($op_destination == 20) { # AB
-                cfw("unsigned char destination = cpu8051_ReadD( _ACC_ );");
-                cfw("unsigned char source = cpu8051_ReadD( _B_ );");
-            }
-           if ($op_destination == 21) { # DPTR
-               cfw("unsigned int destination = memory_sfr_read_dptr();");
-           }
-           if ($op_destination == 23) { # /bitaddr
-               cfw("unsigned char destination, dstbitaddr = memory_read8( PGM_MEM_ID, (cpu8051.pc)++ );");
-               cfw("destination = ( cpu8051_ReadB( dstbitaddr ) ^ 1 );");
-           }
-           if ($op_destination == 24) { # @DPTR
-               cfw("unsigned char destination = cpu8051_ReadI(memory_sfr_read_dptr());");
-           }
-       }
-
-       if ($instargs[$i*4] > 1) {
-           $op_source=$instargs[$i*4+2];
-           if ($op_source == 0) { # addr11
-               cfw("unsigned int addr11 = ( ( memory_read8( PGM_MEM_ID, cpu8051.pc - 1 ) << 3 ) & 0xF00 ) + memory_read8( PGM_MEM_ID, (cpu8051.pc)++ );");
-           }
-           if ($op_source == 1) { # addr16
-               cfw("uint16_t addr16 = pgm_read_addr16(cpu8051.pc);");
-               cfw("cpu8051.pc += 2;");
-           }
-           if ($op_source == 2) { # A
-               cfw("unsigned char source = cpu8051_ReadD( _ACC_ );");
-           }
-           if ($op_source == 3) { # direct
-               cfw("unsigned char srcaddr = memory_read8( PGM_MEM_ID, (cpu8051.pc)++ );");
-               cfw("unsigned char source = cpu8051_ReadD( srcaddr );");
-           }
-           if ($op_source == 4) { # @R0
-               cfw("unsigned char source = cpu8051_ReadI ( cpu8051_ReadD( BANKPSW + _R0_ ) );");
-           }
-           if ($op_source == 5) { # @R1
-               cfw("unsigned char source = cpu8051_ReadI ( cpu8051_ReadD( BANKPSW + _R1_ ) );");
-           }
-           if ($op_source == 6) { # R0
-               cfw("unsigned char source = cpu8051_ReadD( BANKPSW + _R0_ );");
-           }
-           if ($op_source == 7) { # R1
-               cfw("unsigned char source = cpu8051_ReadD( BANKPSW + _R1_ );");
-           }
-           if ($op_source == 8) { # R2
-               cfw("unsigned char source = cpu8051_ReadD( BANKPSW + _R2_ );");
-           }
-           if ($op_source == 9) { # R3
-               cfw("unsigned char source = cpu8051_ReadD( BANKPSW + _R3_ );");
-           }
-           if ($op_source == 10) { # R4
-               cfw("unsigned char source = cpu8051_ReadD( BANKPSW + _R4_ );");
-           }
-           if ($op_source == 11) { # R5
-               cfw("unsigned char source = cpu8051_ReadD( BANKPSW + _R5_ );");
-           }
-           if ($op_source == 12) { # R6
-               cfw("unsigned char source = cpu8051_ReadD( BANKPSW + _R6_ );");
-           }
-           if ($op_source == 13) { # R7
-               cfw("unsigned char source = cpu8051_ReadD( BANKPSW + _R7_ );");
-           }
-
-           if ($op_source == 14) { # bitaddr
-               cfw("unsigned char source, srcbitaddr = memory_read8( PGM_MEM_ID, (cpu8051.pc)++ );");
-               cfw("source = cpu8051_ReadB( srcbitaddr );");
-           }
-           if ($op_source == 15) { # reladdr
-               cfw("(cpu8051.pc)++;");
-               cfw("unsigned int source = ((char) memory_read8(PGM_MEM_ID, cpu8051.pc - 1)) + cpu8051.pc;");
-           }
-           if ($op_source == 16) { # #data
-               cfw("unsigned char source = memory_read8( PGM_MEM_ID, (cpu8051.pc)++ );");
-           }
-           if ($op_source == 17) { # C
-               cfw("unsigned char source = psw_read_cy();");
-           }
-           if ($op_source == 18) { # @A+DPTR
-               cfw("unsigned char source = memory_read8( PGM_MEM_ID, cpu8051_ReadD( _ACC_ ) + memory_sfr_read_dptr());");
-           }
-           if ($op_source == 19) { # @A+PC
-               cfw("unsigned char source = memory_read8( PGM_MEM_ID, cpu8051_ReadD( _ACC_ ) + ( ++cpu8051.pc ) );");
-           }
-           if ($op_source == 21) { # DPTR
-               cfw("unsigned int source = memory_sfr_read_dptr();");
-           }
-           if ($op_source == 22) { # #data16
-               cfw("uint16_t source = pgm_read_addr16(cpu8051.pc);");
-               cfw("cpu8051.pc += 2;");
-           }
-           if ($op_source == 23) { # /bitaddr
-               cfw("unsigned char source, srcbitaddr = memory_read8( PGM_MEM_ID, (cpu8051.pc)++ );");
-               cfw("source = ( cpu8051_ReadB( srcbitaddr ) ^ 1 );");
-           }
-           if ($op_source == 24) { # @DPTR
-               cfw("unsigned char source = cpu8051_ReadI(memory_sfr_read_dptr());");
-           }
-       }
-
-##############################################################################
-       $modifysrc=0;
-
-       # RR
-       if ($insttype[$i] == 3) {
-           cfw("destination = ( destination >> 1 ) | ( destination << 7 );");
-       }
-
-       # INC
-       if ($insttype[$i] == 4) {
-           cfw("destination++;");
-       }
-
-       # JBC
-       if ($insttype[$i] == 5) {
-           cfw("if ( destination == 1 ) { cpu8051.pc = source; destination = 0; }");
-       }
-
-       # ACALL
-       if ($insttype[$i] == 6) {
-           cfw("stack_push16(cpu8051.pc);");
-       }
-
-       # LCALL
-       if ($insttype[$i] == 7) {
-           cfw("stack_push16(cpu8051.pc);");
-       }
-
-       # RRC
-       if ($insttype[$i] == 8) {
-           cfw("unsigned char new_cy = destination & 0x01;");
-           cfw("destination = ( destination >> 1 ) | (psw_read_cy() << 7);");
-           cfw("psw_write_cy(new_cy);");
-       }
-
-       # DEC
-       if ($insttype[$i] == 9) {
-           cfw("destination--;");
-       }
-
-       # JB
-       if ($insttype[$i] == 10) {
-           cfw("if ( destination == 1 ) { cpu8051.pc = source; }");
-       }
-
-       # RET
-       if ($insttype[$i] == 11) {
-            cfw("cpu8051.pc = stack_pop16();");
-       }
-
-       # RL
-       if ($insttype[$i] == 12) {
-           cfw("destination = ( destination << 1 ) | ( destination >> 7 );");
-       }
-
-       # ADD
-       if ($insttype[$i] == 13) {
-           cfw("psw_clr_cy();");
-           cfw("psw_clr_ac();");
-           cfw("psw_clr_ov();");
-            # The Overflow (OV) bit is set if there is a carry-out of bit 6 or
-            # out of bit 7, but not both. In other words, if the addition of the
-            # Accumulator, operand and (in the case of ADDC) the Carry flag
-            # treated as signed values results in a value that is out of the
-            # range of a signed byte (-128 through +127) the Overflow flag is
-            # set. Otherwise, the Overflow flag is cleared.
-           cfw("if ( destination + source > 0xFF ) {");
-            # Carry from bit 7
-           cfw("   psw_set_cy();");
-            # If no carry from bit 6, set OV
-           cfw("   if (((destination & 0x7F) + (source & 0x7F)) < 0x80)");
-           cfw("       psw_set_ov();");
-            # If no carry from bit 7, but caary from bit 6, set OV
-           cfw("} else if (((destination & 0x7F) + (source & 0x7F)) > 0x7F )  psw_set_ov();");
-           cfw("if (((destination & 0x0F) + (source & 0x0F)) > 0x0F)  psw_set_ac();");
-           cfw("destination += source;");
-       }
-
-       # JNB
-       if ($insttype[$i] == 14) {
-           cfw("if ( destination == 0 ) { cpu8051.pc = source; }");
-       }
-
-       # RETI
-       if ($insttype[$i] == 15) {
-           cfw("cpu8051.active_priority = -1;");
-            cfw("cpu8051.pc = stack_pop16();");
-       }
-
-       # RLC
-       if ($insttype[$i] == 16) {
-           cfw("unsigned char new_cy = destination & 0x80;");
-           cfw("destination = ( destination << 1 ) | psw_read_cy();");
-           cfw("psw_write_cy(new_cy);");
-       }
-
-       # ADDC
-       if ($insttype[$i] == 17) {
-           cfw("unsigned char carryflag = psw_read_cy();");
-           cfw("psw_clr_cy();");
-           cfw("psw_clr_ac();");
-           cfw("psw_clr_ov();");
-           cfw("if ( destination + source + carryflag > 0xFF ) {");
-           cfw("   psw_set_cy();");
-           cfw("   if (((destination & 0x7F) + (source & 0x7F) + carryflag) < 0x80);");
-           cfw("       psw_set_ov();");
-           cfw("} else if (((destination & 0x7F) + (source & 0x7F) + carryflag) > 0x7F)  psw_set_ov();");
-           cfw("if (((destination & 0x0F) + (source & 0x0F) + carryflag) > 0x0F)  psw_set_ac();");
-           cfw("destination += source;");
-       }
-
-       # JC
-       if ($insttype[$i] == 18) {
-           cfw("if (psw_read_cy()) { cpu8051.pc = destination; }");
-       }
-
-       # ORL
-       if ($insttype[$i] == 19) {
-            cfw("destination |= source;");
-       }
-
-       # JNC
-       if ($insttype[$i] == 20) {
-           cfw("if (psw_read_cy() == 0) { cpu8051.pc = destination; }");
-       }
-
-       # ANL
-       if ($insttype[$i] == 21) {
-            cfw("destination &= source;");
-       }
-
-       # JZ
-       if ($insttype[$i] == 22) {
-           cfw("if ( cpu8051_ReadD( _ACC_ ) == 0 ) { cpu8051.pc = destination; }");
-       }
-
-       # XRL
-       if ($insttype[$i] == 23) {
-           cfw("destination ^= source;");
-       }
-
-       # JNZ
-       if ($insttype[$i] == 24) {
-           cfw("if ( cpu8051_ReadD( _ACC_ ) != 0 ) { cpu8051.pc = destination; }");
-       }
-
-       # JMP
-       if ($insttype[$i] == 25) {
-           cfw("cpu8051.pc = destination;");
-       }
-
-       # MOV
-       if ($insttype[$i] == 26) {
-           cfw("destination = source;");
-       }
-
-       # SJMP
-       if ($insttype[$i] == 27) {
-           cfw("cpu8051.pc = destination;");
-       }
-
-       # MOVC
-       if ($insttype[$i] == 28) {
-           cfw("destination = source;");
-       }
-
-       # DIV
-       if ($insttype[$i] == 29) {
-            # A = destination
-            # B = source
-           cfw("psw_clr_cy();");
-            # If B is zero, the OV flag will be set indicating a
-            # division-by-zero error
-           cfw("if (source != 0) {");
-           cfw("    cpu8051_WriteD(_ACC_, destination/source);");
-            cfw("    cpu8051_WriteD( _B_, destination%source);");
-           cfw("    psw_clr_ov();");
-           cfw("} else {");
-           cfw("    psw_set_ov();");
-           cfw("}");
-       }
-
-       # SUBB
-       if ($insttype[$i] == 30) {
-           cfw("unsigned char carryflag = psw_read_cy();");
-           cfw("psw_clr_cy();");
-           cfw("psw_clr_ac();");
-           cfw("psw_clr_ov();");
-           cfw("if ( destination < ( source + carryflag ) ) {");
-           cfw("  psw_set_cy();");
-           cfw("  if ((destination & 0x7F) > ((source + carryflag) & 0x7F))  psw_set_ov();");
-           cfw("} else if ((destination & 0x7F) < ((source + carryflag) & 0x7F))   psw_set_ov();");
-           cfw("if ((destination & 0x0F) < ((source + carryflag) & 0x0F))   psw_set_ac();");
-           cfw("destination -= source + carryflag;");
-       }
-
-       # MUL
-       if ($insttype[$i] == 31) {
-            # A = destination
-            # B = source
-           cfw("psw_clr_cy();");
-           cfw("cpu8051_WriteD(_ACC_, destination * source);");
-            cfw("cpu8051_WriteD(_B_, (destination * source) / 0x100);");
-           cfw("if (cpu8051_ReadD(_B_) > 0)");
-           cfw("    psw_set_ov();");
-           cfw("else");
-           cfw("    psw_clr_ov();");
-       }
-
-       # CPL
-       if ($insttype[$i] == 33) {
-           if ($instargs[$i*4+1] == 2) { cfw("destination ^= 0xFF;"); }
-           else { cfw("destination ^= 0x01;"); }
-       }
-
-       # CJNE
-       if ($insttype[$i] == 34) {
-           cfw("unsigned int reladdr = ((char) memory_read8(PGM_MEM_ID, cpu8051.pc)) + (cpu8051.pc + 1);");
-           cfw("psw_clr_cy();");
-           cfw("if ( destination < source ) psw_set_cy();");
-           cfw("if ( destination != source ) cpu8051.pc = reladdr; else cpu8051.pc++;");
-       }
-
-       # PUSH
-       if ($insttype[$i] == 35) {
-           cfw("stack_push8(destination);");
-       }
-
-       # CLR
-       if ($insttype[$i] == 36) {
-           cfw("destination = 0;");
-       }
-
-       # SWAP
-       if ($insttype[$i] == 37) {
-           cfw("destination = ( destination << 4 ) + ( destination >> 4 );");
-       }
-
-       # XCH
-       if ($insttype[$i] == 38) {
-           cfw("unsigned char tmpval = destination;");
-           cfw("destination = source; source = tmpval;");
-           $modifysrc=1;
-       }
-
-       # POP
-       if ($insttype[$i] == 39) {
-            cfw("destination = stack_pop8();");
-       }
-
-       # SETB
-       if ($insttype[$i] == 40) {
-           cfw("destination = 1;");
-       }
-
-       # DA
-       if ($insttype[$i] == 41) {
-           cfw("if (((destination & 0x0F) > 9) || psw_read_ac()) {");
-           cfw("   if ( ( destination + 6 ) > 0xFF)  psw_set_cy();");
-           cfw("   destination += 6;");
-           cfw("}");
-           cfw("if ( psw_read_cy() || ( ( destination & 0xF0 ) > 0x90 ) ) {");
-           cfw("   if ( ( destination + 0x60 ) > 0xFF ) psw_set_cy();");
-           cfw("   destination += 0x60;");
-           cfw("}");
-       }
-
-       # DJNZ
-       if ($insttype[$i] == 42) {
-           cfw("destination--;");
-           cfw("if ( destination != 0 ) cpu8051.pc = source;");
-       }
-
-       # XCHD
-       if ($insttype[$i] == 43) {
-           cfw("unsigned char tmpval = ( destination & 0x0F );");
-           cfw("destination = ( destination & 0xF0 ) + ( source & 0x0F );");
-           cfw("source = ( source & 0xF0 ) + tmpval;");
-           $modifysrc=1;
-       }
-
-       # MOVX
-       if ($insttype[$i] == 44) {
-           cfw("destination = source;");
-       }
-
-
-
-##############################################################################
-
-
-       if ($instargs[$i*4] > 0) {
-           $op_destination=$instargs[$i*4+1];
-           if ($op_destination == 0) { # addr11
-               cfw("cpu8051.pc = ( cpu8051.pc & 0xF800 ) | addr11;");
-           }
-           if ($op_destination == 1) { # addr16
-               cfw("cpu8051.pc = addr16;");
-           }
-           if ($op_destination == 2) { # A
-               cfw("cpu8051_WriteD( _ACC_, destination );");
-           }
-           if ($op_destination == 3) { # direct
-               cfw("cpu8051_WriteD( destaddr, destination );");
-           }
-           if ($op_destination == 4) { # @R0
-               cfw("cpu8051_WriteI( cpu8051_ReadD( BANKPSW + _R0_ ), destination );");
-           }
-           if ($op_destination == 5) { # @R1
-               cfw("cpu8051_WriteI( cpu8051_ReadD( BANKPSW + _R1_ ), destination );");
-           }
-           if ($op_destination == 6) { # R0
-               cfw("cpu8051_WriteD( BANKPSW + _R0_, destination );");
-           }
-           if ($op_destination == 7) { # R1
-               cfw("cpu8051_WriteD( BANKPSW + _R1_, destination );");
-           }
-           if ($op_destination == 8) { # R2
-               cfw("cpu8051_WriteD( BANKPSW + _R2_, destination );");
-           }
-           if ($op_destination == 9) { # R3
-               cfw("cpu8051_WriteD( BANKPSW + _R3_, destination );");
-           }
-           if ($op_destination == 10) { # R4
-               cfw("cpu8051_WriteD( BANKPSW + _R4_, destination );");
-           }
-           if ($op_destination == 11) { # R5
-               cfw("cpu8051_WriteD( BANKPSW + _R5_, destination );");
-           }
-           if ($op_destination == 12) { # R6
-               cfw("cpu8051_WriteD( BANKPSW + _R6_, destination );");
-           }
-           if ($op_destination == 13) { # R7
-               cfw("cpu8051_WriteD( BANKPSW + _R7_, destination );");
-           }
-
-           if ($op_destination == 14) { # bitaddr
-               cfw("cpu8051_WriteB( dstbitaddr, destination );");
-           }
-           if ($op_destination == 17) { # C
-               cfw("psw_write_cy(destination);");
-           }
-           if ($op_destination == 21) { # DPTR
-               cfw("memory_sfr_write_dptr(destination);");
-           }
-           if ($op_destination == 23) { # /bitaddr
-               cfw("cpu8051_WriteB( dstbitaddr, destination );");
-           }
-           if ($op_destination == 24) { # @DPTR
-               cfw("cpu8051_WriteI(memory_sfr_read_dptr(), destination);");
-           }
-       }
-
-       if ($modifysrc == 1) {
-           if ($instargs[$i*4] > 1) {
-               $op_source=$instargs[$i*4+2];
-               if ($op_source == 0) { # addr11
-                   cfw("cpu8051.pc = ( cpu8051.pc & 0xF800 ) | addr11;");
-               }
-               if ($op_source == 1) { # addr16
-                   cfw("cpu8051.pc = addr16;");
-               }
-               if ($op_source == 2) { # A
-                   cfw("cpu8051_WriteD( _ACC_, source );");
-               }
-               if ($op_source == 3) { # direct
-                   cfw("cpu8051_WriteD( srcaddr, source );");
-               }
-               if ($op_source == 4) { # @R0
-                   cfw("cpu8051_WriteI( cpu8051_ReadD( BANKPSW + _R0_ ), source );");
-               }
-               if ($op_source == 5) { # @R1
-                   cfw("cpu8051_WriteI( cpu8051_ReadD( BANKPSW + _R1_ ), source );");
-               }
-               if ($op_source == 6) { # R0
-                   cfw("cpu8051_WriteD( BANKPSW + _R0_, source );");
-               }
-               if ($op_source == 7) { # R1
-                   cfw("cpu8051_WriteD( BANKPSW + _R1_, source );");
-               }
-               if ($op_source == 8) { # R2
-                   cfw("cpu8051_WriteD( BANKPSW + _R2_, source );");
-               }
-               if ($op_source == 9) { # R3
-                   cfw("cpu8051_WriteD( BANKPSW + _R3_, source );");
-               }
-               if ($op_source == 10) { # R4
-                   cfw("cpu8051_WriteD( BANKPSW + _R4_, source );");
-               }
-               if ($op_source == 11) { # R5
-                   cfw("cpu8051_WriteD( BANKPSW + _R5_, source );");
-               }
-               if ($op_source == 12) { # R6
-                   cfw("cpu8051_WriteD( BANKPSW + _R6_, source );");
-               }
-               if ($op_source == 13) { # R7
-                   cfw("cpu8051_WriteD( BANKPSW + _R7_, source );");
-               }
-               if ($op_source == 14) { # bitaddr
-                   cfw("cpu8051_WriteB( srcbitaddr, source );");
-               }
-               if ($op_source == 17) { # C
-                   cfw("psw_write_cy(source);");
-               }
-               if ($op_source == 21) { # DPTR
-                    cfw("memory_sfr_write_dptr(source);");
-               }
-               if ($op_source == 23) { # /bitaddr
-                   cfw("cpu8051_WriteB( srcbitaddr, source );");
-               }
-               if ($op_source == 24) { # @DPTR
-                   cfw("cpu8051_WriteI(memory_sfr_read_dptr(), source);");
-               }
-           }
-       }
-    }
-    cfw("return $a_cycles[$i];");
-    print INST_IMP "}\n";
-    print INST_IMP "\n";
-}
-# ------------------------------------------------------------------------------
-
-
-# Header for instructions_8051.h
-print INST_DEF "/*\n";
-print INST_DEF " * instructions_8051.h\n";
-write_header(INST_DEF);
-print INST_DEF "#ifndef INSTRUCTIONS_8051_H\n";
-print INST_DEF "#define INSTRUCTIONS_8051_H 1\n\n\n";
-print INST_DEF "#define BANKPSW (cpu8051_ReadD(_PSW_) & 0x18)\n\n";
-print INST_DEF "typedef int (*OPCODE_FP)(void);\n\n\n";
-for( $i=0; $i<256; $i++ ) {
-    print INST_DEF "int\n";
-    print INST_DEF "cpu8051_OP_$a_opcodehex[$i](void);\n\n";
-}
-print INST_DEF "\n";
-print INST_DEF "/* Exported variables. */\n";
-print INST_DEF "#ifdef INSTRUCTIONS_8051_M\n";
-print INST_DEF "OPCODE_FP opcode_table[256] = {\n";
-for( $i=0; $i<256; $i++ ) {
-    $ifunc=substr($instfunction[$i], 9);
-    if( $i < 255 ) {
-       print INST_DEF "  cpu8051_$ifunc,\n";
-    }
-    else {
-       print INST_DEF "  cpu8051_$ifunc\n";
-       print INST_DEF "};\n";
-    }
-}
-
-print INST_DEF "#else\n";
-print INST_DEF "OPCODE_FP opcode_table[256];\n";
-print INST_DEF "#endif\n\n\n";
-
-print INST_DEF "#endif /* INSTRUCTIONS_8051_H */\n";
-
-print DISASM_H "#endif /* DISASM_H */\n";
-
-close DISASM_H;
-close OPCODELST;
-close INST_DEF;
-close INST_IMP;
diff --git a/src/opcodes.lst b/src/opcodes.lst
deleted file mode 100644 (file)
index 1494258..0000000
+++ /dev/null
@@ -1,258 +0,0 @@
-Opcode(bin)    Opcode  Instruction             Bytes   Cycles
---------------------------------------------------------------
-00000000       00      NOP                     1       1
-00000001       01      AJMP addr11             2       2
-00000010       02      LJMP addr16             3       2
-00000011       03      RR A                    1       1
-00000100       04      INC A                   1       1
-00000101       05      INC direct              2       1
-00000110       06      INC @R0                 1       1
-00000111       07      INC @R1                 1       1
-00001000       08      INC R0                  1       1
-00001001       09      INC R1                  1       1
-00001010       0A      INC R2                  1       1
-00001011       0B      INC R3                  1       1
-00001100       0C      INC R4                  1       1
-00001101       0D      INC R5                  1       1
-00001110       0E      INC R6                  1       1
-00001111       0F      INC R7                  1       1
-00010000       10      JBC bitaddr,reladdr     3       2
-00010001       11      ACALL addr11            2       2
-00010010       12      LCALL addr16            3       2
-00010011       13      RRC A                   1       1
-00010100       14      DEC A                   1       1
-00010101       15      DEC direct              2       1
-00010110       16      DEC @R0                 1       1
-00010111       17      DEC @R1                 1       1
-00011000       18      DEC R0                  1       1
-00011001       19      DEC R1                  1       1
-00011010       1A      DEC R2                  1       1
-00011011       1B      DEC R3                  1       1
-00011100       1C      DEC R4                  1       1
-00011101       1D      DEC R5                  1       1
-00011110       1E      DEC R6                  1       1
-00011111       1F      DEC R7                  1       1
-00100000       20      JB bitaddr,reladdr      3       2
-00100001       21      AJMP addr11             2       2       
-00100010       22      RET                     1       2
-00100011       23      RL A                    1       1
-00100100       24      ADD A,#data             2       1
-00100101       25      ADD A,direct            2       1
-00100110       26      ADD A,@R0               1       1
-00100111       27      ADD A,@R1               1       1
-00101000       28      ADD A,R0                1       1
-00101001       29      ADD A,R1                1       1
-00101010       2A      ADD A,R2                1       1
-00101011       2B      ADD A,R3                1       1
-00101100       2C      ADD A,R4                1       1
-00101101       2D      ADD A,R5                1       1
-00101110       2E      ADD A,R6                1       1
-00101111       2F      ADD A,R7                1       1
-00110000       30      JNB bitaddr,reladdr     3       2
-00110001       31      ACALL addr11            2       2
-00110010       32      RETI                    1       2
-00110011       33      RLC A                   1       1
-00110100       34      ADDC A,#data            2       1
-00110101       35      ADDC A,direct           2       1
-00110110       36      ADDC A,@R0              1       1
-00110111       37      ADDC A,@R1              1       1
-00111000       38      ADDC A,R0               1       1
-00111001       39      ADDC A,R1               1       1
-00111010       3A      ADDC A,R2               1       1
-00111011       3B      ADDC A,R3               1       1
-00111100       3C      ADDC A,R4               1       1
-00111101       3D      ADDC A,R5               1       1
-00111110       3E      ADDC A,R6               1       1
-00111111       3F      ADDC A,R7               1       1
-01000000       40      JC reladdr              2       2
-01000001       41      AJMP addr11             2       2       
-01000010       42      ORL direct,A            2       1
-01000011       43      ORL direct,#data        3       2
-01000100       44      ORL A,#data             2       1
-01000101       45      ORL A,direct            2       1
-01000110       46      ORL A,@R0               1       1
-01000111       47      ORL A,@R1               1       1
-01001000       48      ORL A,R0                1       1
-01001001       49      ORL A,R1                1       1
-01001010       4A      ORL A,R2                1       1
-01001011       4B      ORL A,R3                1       1
-01001100       4C      ORL A,R4                1       1
-01001101       4D      ORL A,R5                1       1
-01001110       4E      ORL A,R6                1       1
-01001111       4F      ORL A,R7                1       1
-01010000       50      JNC reladdr             2       2
-01010001       51      ACALL addr11            2       2
-01010010       52      ANL direct,A            2       1
-01010011       53      ANL direct,#data        3       2
-01010100       54      ANL A,#data             2       1
-01010101       55      ANL A,direct            2       1
-01010110       56      ANL A,@R0               1       1
-01010111       57      ANL A,@R1               1       1
-01011000       58      ANL A,R0                1       1
-01011001       59      ANL A,R1                1       1
-01011010       5A      ANL A,R2                1       1
-01011011       5B      ANL A,R3                1       1
-01011100       5C      ANL A,R4                1       1
-01011101       5D      ANL A,R5                1       1
-01011110       5E      ANL A,R6                1       1
-01011111       5F      ANL A,R7                1       1
-01100000       60      JZ reladdr              2       2
-01100001       61      AJMP addr11             2       2       
-01100010       62      XRL direct,A            2       1
-01100011       63      XRL direct,#data        3       2
-01100100       64      XRL A,#data             2       1
-01100101       65      XRL A,direct            2       1
-01100110       66      XRL A,@R0               1       1
-01100111       67      XRL A,@R1               1       1
-01101000       68      XRL A,R0                1       1
-01101001       69      XRL A,R1                1       1
-01101010       6A      XRL A,R2                1       1
-01101011       6B      XRL A,R3                1       1
-01101100       6C      XRL A,R4                1       1
-01101101       6D      XRL A,R5                1       1
-01101110       6E      XRL A,R6                1       1
-01101111       6F      XRL A,R7                1       1
-01110000       70      JNZ reladdr             2       2
-01110001       71      ACALL addr11            2       2
-01110010       72      ORL C,bitaddr           2       2
-01110011       73      JMP @A+DPTR             1       2
-01110100       74      MOV A,#data             2       1
-01110101       75      MOV direct,#data        3       2
-01110110       76      MOV @R0,#data           2       1
-01110111       77      MOV @R1,#data           2       1
-01111000       78      MOV R0,#data            2       1
-01111001       79      MOV R1,#data            2       1
-01111010       7A      MOV R2,#data            2       1
-01111011       7B      MOV R3,#data            2       1
-01111100       7C      MOV R4,#data            2       1
-01111101       7D      MOV R5,#data            2       1
-01111110       7E      MOV R6,#data            2       1
-01111111       7F      MOV R7,#data            2       1
-10000000       80      SJMP reladdr            2       2
-10000001       81      AJMP addr11             2       2
-10000010       82      ANL C,bitaddr           2       1
-10000011       83      MOVC A,@A+PC            1       1
-10000100       84      DIV AB                  1       4
-10000101       85      MOV direct,direct       3       1
-10000110       86      MOV direct,@R0          2       2
-10000111       87      MOV direct,@R1          2       2
-10001000       88      MOV direct,R0           2       2
-10001001       89      MOV direct,R1           2       2
-10001010       8A      MOV direct,R2           2       2
-10001011       8B      MOV direct,R3           2       2
-10001100       8C      MOV direct,R4           2       2
-10001101       8D      MOV direct,R5           2       2
-10001110       8E      MOV direct,R6           2       2
-10001111       8F      MOV direct,R7           2       2
-10010000       90      MOV DPTR,#data16        3       2
-10010001       91      ACALL addr11            2       2
-10010010       92      MOV bitaddr,C           2       2
-10010011       93      MOVC A,@A+DPTR          1       2
-10010100       94      SUBB A,#data            2       1
-10010101       95      SUBB A,direct           2       1
-10010110       96      SUBB A,@R0              1       1
-10010111       97      SUBB A,@R1              1       1
-10011000       98      SUBB A,R0               1       1
-10011001       99      SUBB A,R1               1       1
-10011010       9A      SUBB A,R2               1       1
-10011011       9B      SUBB A,R3               1       1
-10011100       9C      SUBB A,R4               1       1
-10011101       9D      SUBB A,R5               1       1
-10011110       9E      SUBB A,R6               1       1
-10011111       9F      SUBB A,R7               1       1
-10100000       A0      ORL C,/bitaddr          2       1
-10100001       A1      AJMP addr11             2       2
-10100010       A2      MOV C,bitaddr           2       1
-10100011       A3      INC DPTR                1       2
-10100100       A4      MUL AB                  1       4
-10100101       A5      INVALID                 1       1
-10100110       A6      MOV @R0,direct          2       2
-10100111       A7      MOV @R1,direct          2       2
-10101000       A8      MOV R0,direct           2       2
-10101001       A9      MOV R1,direct           2       2
-10101010       AA      MOV R2,direct           2       2
-10101011       AB      MOV R3,direct           2       2
-10101100       AC      MOV R4,direct           2       2
-10101101       AD      MOV R5,direct           2       2
-10101110       AE      MOV R6,direct           2       2
-10101111       AF      MOV R7,direct           2       2
-10110000       B0      ANL C,/bitaddr          2       1
-10110001       B1      ACALL addr11            2       2
-10110010       B2      CPL bitaddr             2       1
-10110011       B3      CPL C                   1       1
-10110100       B4      CJNE A,#data,reladdr    3       2
-10110101       B5      CJNE A,direct,reladdr   3       2
-10110110       B6      CJNE @R0,#data,reladdr  3       2
-10110111       B7      CJNE @R1,#data,reladdr  3       2
-10111000       B8      CJNE R0,#data,reladdr   3       2
-10111001       B9      CJNE R1,#data,reladdr   3       2
-10111010       BA      CJNE R2,#data,reladdr   3       2
-10111011       BB      CJNE R3,#data,reladdr   3       2
-10111100       BC      CJNE R4,#data,reladdr   3       2
-10111101       BD      CJNE R5,#data,reladdr   3       2
-10111110       BE      CJNE R6,#data,reladdr   3       2
-10111111       BF      CJNE R7,#data,reladdr   3       2
-11000000       C0      PUSH direct             2       2
-11000001       C1      AJMP addr11             2       2       
-11000010       C2      CLR bitaddr             2       1
-11000011       C3      CLR C                   1       1
-11000100       C4      SWAP A                  1       1
-11000101       C5      XCH A,direct            2       1
-11000110       C6      XCH A,@R0               1       1
-11000111       C7      XCH A,@R1               1       1
-11001000       C8      XCH A,R0                1       1
-11001001       C9      XCH A,R1                1       1
-11001010       CA      XCH A,R2                1       1
-11001011       CB      XCH A,R3                1       1
-11001100       CC      XCH A,R4                1       1
-11001101       CD      XCH A,R5                1       1
-11001110       CE      XCH A,R6                1       1
-11001111       CF      XCH A,R7                1       1
-11010000       D0      POP direct              2       2
-11010001       D1      ACALL addr11            2       2
-11010010       D2      SETB bitaddr            2       1
-11010011       D3      SETB C                  1       1
-11010100       D4      DA A                    1       1
-11010101       D5      DJNZ direct,reladdr     3       2
-11010110       D6      XCHD A,@R0              1       1
-11010111       D7      XCHD A,@R1              1       1
-11011000       D8      DJNZ R0,reladdr         2       2
-11011001       D9      DJNZ R1,reladdr         2       2
-11011010       DA      DJNZ R2,reladdr         2       2
-11011011       DB      DJNZ R3,reladdr         2       2
-11011100       DC      DJNZ R4,reladdr         2       2
-11011101       DD      DJNZ R5,reladdr         2       2
-11011110       DE      DJNZ R6,reladdr         2       2
-11011111       DF      DJNZ R7,reladdr         2       2
-11100000       E0      MOVX A,@DPTR            1       2
-11100001       E1      AJMP addr11             2       2       
-11100010       E2      MOVX A,@R0              1       2
-11100011       E3      MOVX A,@R1              1       2
-11100100       E4      CLR A                   1       1
-11100101       E5      MOV A,direct            2       1
-11100110       E6      MOV A,@R0               1       1
-11100111       E7      MOV A,@R1               1       1
-11101000       E8      MOV A,R0                1       1
-11101001       E9      MOV A,R1                1       1
-11101010       EA      MOV A,R2                1       1
-11101011       EB      MOV A,R3                1       1
-11101100       EC      MOV A,R4                1       1
-11101101       ED      MOV A,R5                1       1
-11101110       EE      MOV A,R6                1       1
-11101111       EF      MOV A,R7                1       1
-11110000       F0      MOVX @DPTR,A            1       2
-11110001       F1      ACALL addr11            2       2
-11110010       F2      MOVX @R0,A              1       2
-11110011       F3      MOVX @R1,A              1       2
-11110100       F4      CPL A                   1       1
-11110101       F5      MOV direct,A            2       1
-11110110       F6      MOV @R0,A               1       1
-11110111       F7      MOV @R1,A               1       1
-11111000       F8      MOV R0,A                1       1
-11111001       F9      MOV R1,A                1       1
-11111010       FA      MOV R2,A                1       1
-11111011       FB      MOV R3,A                1       1
-11111100       FC      MOV R4,A                1       1
-11111101       FD      MOV R5,A                1       1
-11111110       FE      MOV R6,A                1       1
-11111111       FF      MOV R7,A                1       1
diff --git a/src/options.c b/src/options.c
deleted file mode 100644 (file)
index 420cc85..0000000
+++ /dev/null
@@ -1,184 +0,0 @@
-/*
- * options.c -- functions for processing command-line options and arguments
- *
- * Copyright (C) 2011 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.
- */
-
-#if HAVE_CONFIG_H
-#  include "config.h"
-#endif
-
-#include <unistd.h>
-#include <stdio.h>
-#include <stdlib.h>
-#include <argp.h>
-
-#if STDC_HEADERS
-#  include <string.h>
-#elif HAVE_STRINGS_H
-#  include <strings.h>
-#endif
-
-#include "common.h"
-#include "options.h"
-#include "memory.h"
-
-const char *argp_program_version = PACKAGE_VERSION;
-const char *argp_program_bug_address = PACKAGE_BUGREPORT;
-
-#define PACKAGE_DOC_LENGTH 128
-
-/* Program documentation. */
-static char str_doc[PACKAGE_DOC_LENGTH];
-
-/* How many arguments we accept. */
-#define ARGS_COUNT 1
-
-/* A description of the arguments we accept. */
-static const char args_doc[] = "[FILENAME]";
-
-/* The options we understand. */
-static struct argp_option argp_options[] = {
-       {"debug", 'd', "level", 0,  "Produce debugging output" },
-       {"pram",  'p', "size",  0,  "Set program memory size" },
-       {"xram",  'x', "size",  0,  "Set external ram size (default is 1024)" },
-       {"stop",  's', "addr",  0,  "Automatically run program and stop at address" },
-       { 0 }
-};
-
-struct options_t options;
-
-const char *
-get_package_description(void)
-{
-       return "Emulator for 8051 family microcontrollers";
-}
-
-static void
-decode_debug_option(char *arg, struct argp_state *state)
-{
-       char *endptr;
-       int log_level;
-
-       log_level = strtol(arg, &endptr, 0);
-
-       if (*endptr != '\0') {
-               log_err("Invalid log level");
-               argp_usage(state);
-       }
-
-       if (log_level > LOG_LEVEL_DEBUG) {
-               log_err("Invalid log level (0 to 3)");
-               argp_usage(state);
-       }
-
-       options.log = log_level;
-}
-
-static void
-decode_memory_size(char *arg, struct argp_state *state, int memid)
-{
-       char *endptr;
-       int *dest;
-
-       if (memid == PGM_MEM_ID)
-               dest = &options.pram_size;
-       else if (memid == INT_MEM_ID)
-               dest = &options.iram_size;
-       else if (memid == EXT_MEM_ID)
-               dest = &options.xram_size;
-       else
-               exit(1); /* Programming error. */
-
-       /*
-        * Sizes versus max memory sizes will be checked when calling
-        * memory_init().
-        */
-       *dest = strtol(arg, &endptr, 0);
-
-       if (*endptr != '\0') {
-               log_err("Invalid memory size");
-               argp_usage(state);
-       }
-}
-
-static void
-decode_address(char *arg, struct argp_state *state, uint16_t *dest)
-{
-       char *endptr;
-
-       *dest = strtol(arg, &endptr, 0);
-
-       if (*endptr != '\0') {
-               log_err("Invalid address");
-               argp_usage(state);
-       }
-}
-
-/* Parse a single option. */
-static error_t
-parse_opt(int key, char *arg, struct argp_state *state)
-{
-       switch (key) {
-       case 'd':
-               decode_debug_option(arg, state);
-               break;
-       case 'i':
-               decode_memory_size(arg, state, INT_MEM_ID);
-               break;
-       case 'p':
-               decode_memory_size(arg, state, PGM_MEM_ID);
-               break;
-       case 's':
-               decode_address(arg, state, &options.stop_address);
-               break;
-       case 'x':
-               decode_memory_size(arg, state, EXT_MEM_ID);
-               break;
-       case ARGP_KEY_ARG:
-               if (state->arg_num >= ARGS_COUNT) {
-                       /* Too many arguments. */
-                       argp_usage(state);
-               }
-
-               options.filename = arg;
-               break;
-       case ARGP_KEY_END:
-               if (state->arg_num < ARGS_COUNT) {
-                       /* Not enough arguments, but the filename is optional.
-                          So no error. */
-               }
-               break;
-       default:
-               return ARGP_ERR_UNKNOWN;
-       }
-
-       return 0;
-}
-
-/* Our argp parser. */
-static struct argp argp = { argp_options, parse_opt, args_doc, str_doc };
-
-/* Initializes the different options passed as arguments on the command line. */
-void
-parse_command_line_options(int argc, char *argv[])
-{
-       snprintf(str_doc, PACKAGE_DOC_LENGTH, "%s -- %s", PACKAGE_NAME,
-                get_package_description());
-
-       /* Setting default values. */
-       options.filename = NULL;
-       options.pram_size = PGM_MEM_DEFAULT_SIZE;
-       options.iram_size = INT_MEM_MAX_SIZE;
-       options.xram_size = EXT_MEM_DEFAULT_SIZE;
-       options.log = LOG_LEVEL_ERR;
-       options.stop_address = 0; /* 0 means stop address is disabled. */
-
-       /* Parse our arguments. */
-       argp_parse(&argp, argc, argv, 0, 0, NULL);
-}
diff --git a/src/options.h b/src/options.h
deleted file mode 100644 (file)
index 589c2d5..0000000
+++ /dev/null
@@ -1,45 +0,0 @@
-/*
- * options.h
- *
- * 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 OPTIONS_H
-#define OPTIONS_H 1
-
-#define COMMAND_LINE_OPTIONS \
-  "Usage: " PACKAGE " [OPTION]... [FILENAME]\n" \
-  "Simulator/emulator for 8051 family microcontrollers.\n\n" \
-  "  -h                    display this help and exit\n" \
-  "  -version              display version information and exit\n"
-
-struct options_t {
-       int pram_size; /* Maximum program memory size. */
-       int iram_size; /* Maximum internal ram size. */
-       int xram_size; /* Maximum external ram size. */
-       char *filename;
-       int log;
-       uint16_t stop_address; /* Run program up to that adress and exit. */
-} options_t;
-
-void
-parse_command_line_options(int argc, char *argv[]);
-
-const char *
-get_package_description(void);
-
-#endif /* OPTIONS_H */
diff --git a/src/pgmwin.c b/src/pgmwin.c
deleted file mode 100644 (file)
index 0e8961b..0000000
+++ /dev/null
@@ -1,299 +0,0 @@
-/*
- * pgmwin.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 "common.h"
-#include "memory.h"
-#include "cpu8051.h"
-#include "pgmwin.h"
-#include "hexfile.h"
-
-static GtkWidget *pgmlist;
-
-#define LIST_VIEW_NAME "Program"
-#define DATA_ROWS 100
-
-enum
-{
-       COL_BREAKPT = 0,
-       COL_ADDR,
-       COL_B0,
-       COL_B1,
-       COL_B2,
-       COL_INST,
-       COL_ARGS,
-       COL_COLOR,
-       N_COLUMNS,
-};
-
-static char *col_names[N_COLUMNS] = {
-       "BPT",
-       "Address",
-       "B0",
-       "B1",
-       "B2",
-       "Mnemonic",
-       "Arguments",
-       "COLOR", /* Not displayed, used to set foreground color of cell. */
-};
-
-/* Creating a model */
-static GtkListStore *
-pgmwin_init_store(void)
-{
-       GtkTreeIter iter;
-       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);
-
-       /* 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;
-}
-
-static void
-pgmwin_init_columns(void)
-{
-       int k;
-       GtkCellRenderer *renderer;
-
-       /* Create renderer */
-       renderer = gtk_cell_renderer_text_new();
-
-       /* Add columns, except for last one (COL_COLOR). */
-       for (k = 0; k < COL_COLOR; k++) {
-               GtkTreeViewColumn *col;
-
-               /* 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);
-       }
-}
-
-/* Mouse button pressed in the window. */
-static gint
-pgmwin_sel_changed_event(GtkWidget *widget, GdkEvent *event, gpointer data)
-{
-       GtkTreeSelection *selection;
-       GtkTreeModel     *model;
-       GtkTreeIter       iter;
-
-       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));
-
-       if (gtk_tree_selection_get_selected(selection, &model, &iter)) {
-               char *str_addr;
-               int val;
-
-               gtk_tree_model_get(model, &iter, COL_ADDR, &str_addr, -1);
-
-               /* Convert hex address in ASCII to integer. */
-               val = asciihex2int(str_addr);
-
-               log_debug("  row address is: $%04X", val);
-
-               ToggleBreakpoint(val);
-               pgmwin_refresh();
-
-               g_free(str_addr);
-       } else {
-               log_debug("  no row selected");
-       }
-
-       return FALSE;
-}
-
-GtkWidget *
-pgmwin_init(void)
-{
-       GtkWidget *frame;
-       GtkWidget *scrollwin;
-       GtkListStore *store;
-       GtkTreeSelection *selection;
-
-       frame = gtk_frame_new(LIST_VIEW_NAME);
-
-       scrollwin = gtk_scrolled_window_new(NULL, NULL);
-       gtk_scrolled_window_set_shadow_type(GTK_SCROLLED_WINDOW(scrollwin),
-                                           GTK_SHADOW_ETCHED_OUT);
-
-       /* Automatically add scrollbars when necessary. */
-       gtk_scrolled_window_set_policy(GTK_SCROLLED_WINDOW(scrollwin),
-                                      GTK_POLICY_AUTOMATIC,
-                                      GTK_POLICY_AUTOMATIC);
-
-       gtk_container_add(GTK_CONTAINER(frame), scrollwin);
-
-       /* Creating a model */
-       store = pgmwin_init_store();
-
-       /* Creating the view component */
-       pgmlist = gtk_tree_view_new_with_model(GTK_TREE_MODEL(store));
-       gtk_tree_view_set_headers_visible(GTK_TREE_VIEW(pgmlist), TRUE);
-       gtk_container_add(GTK_CONTAINER(scrollwin), pgmlist);
-
-       selection = gtk_tree_view_get_selection(GTK_TREE_VIEW(pgmlist));
-
-       /* Only one row can be selected at a time. */
-       gtk_tree_selection_set_mode(selection, GTK_SELECTION_BROWSE);
-
-       g_signal_connect(selection, "changed",
-               G_CALLBACK(pgmwin_sel_changed_event), NULL);
-
-       pgmwin_init_columns();
-
-       /*
-        * The tree view has acquired its own reference to the model, so we can
-        * drop ours. That way the model will be freed automatically when the
-        * tree view is destroyed.
-        */
-       g_object_unref(store);
-
-       return frame;
-}
-
-/* Show disassembled program. */
-void
-pgmwin_refresh(void)
-{
-       int row;
-       GtkListStore *store;
-       unsigned int Address;
-
-       Address = cpu8051.pc;
-
-       store = GTK_LIST_STORE(gtk_tree_view_get_model(GTK_TREE_VIEW(pgmlist)));
-
-       for (row = 0; row < DATA_ROWS; row++) {
-               int valid;
-               GtkTreeIter iter;
-               char str[128];
-               int k;
-               int col_id;
-               int InstSize;
-               unsigned char OpCode;
-
-               if (row == 0) {
-                       /* Get first row in list store */
-                       valid = gtk_tree_model_get_iter_first(
-                               GTK_TREE_MODEL(store), &iter);
-               } else {
-                       /* Get next row in list store */
-                       valid = gtk_tree_model_iter_next(
-                               GTK_TREE_MODEL(store), &iter);
-               }
-
-               if (!valid) {
-                       printf("Invalid iter...\n");
-                       return;
-               }
-
-               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);
-
-                       /* Display base address. */
-                       int2asciihex(Address, str, 4);
-
-                       gtk_list_store_set(store, &iter, COL_ADDR, str, -1);
-
-                       OpCode = memory_read8(PGM_MEM_ID, Address);
-                       InstSize = cpu8051_get_instruction_size(OpCode);
-
-                       /* 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';
-
-                               gtk_list_store_set(store, &iter, col_id, str, -1);
-                       }
-
-                       /* 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;
-               }
-       }
-}
diff --git a/src/pgmwin.h b/src/pgmwin.h
deleted file mode 100644 (file)
index 952d931..0000000
+++ /dev/null
@@ -1,36 +0,0 @@
-/*
- * pgmwin.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 PGMWIN_H
-#define PGMWIN_H 1
-
-#include <gtk/gtk.h>
-
-GtkWidget *
-pgmwin_init(void);
-
-void
-pgmwin_refresh(void);
-
-int
-pgmwin_IsBreakpoint(unsigned int address);
-
-#endif /* PGMWIN_H */
diff --git a/src/psw.c b/src/psw.c
deleted file mode 100644 (file)
index 09352ad..0000000
--- a/src/psw.c
+++ /dev/null
@@ -1,137 +0,0 @@
-/*
- * psw.c
- *
- * Copyright (C) 2013 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.
- */
-
-#include "common.h"
-#include "reg8051.h"
-#include "memory.h"
-
-/* Returns 0 or 1 */
-int
-psw_read_bit(int bit)
-{
-       return (memory_read8(INT_MEM_ID, _PSW_) >> bit) & 0x01;
-}
-
-void
-psw_write_bit(int bit, int val)
-{
-       u_int8_t psw = memory_read8(INT_MEM_ID, _PSW_);
-
-       if (val)
-               psw |= (1 << bit);  /* Set */
-       else
-               psw &= ~(1 << bit); /* Clear */
-
-       memory_write8(INT_MEM_ID, _PSW_, psw); /* Save updated value */
-}
-
-/* Returns 0 or 1 */
-int
-psw_read_cy(void)
-{
-       return psw_read_bit(PSW_BIT_CY);
-}
-
-void
-psw_write_cy(int cy)
-{
-       psw_write_bit(PSW_BIT_CY, cy);
-}
-
-void
-psw_set_cy(void)
-{
-       psw_write_bit(PSW_BIT_CY, 1);
-}
-
-void
-psw_clr_cy(void)
-{
-       psw_write_bit(PSW_BIT_CY, 0);
-}
-
-/* Returns 0 or 1 */
-int
-psw_read_ac(void)
-{
-       return psw_read_bit(PSW_BIT_AC);
-}
-
-void
-psw_write_ac(int ac)
-{
-       psw_write_bit(PSW_BIT_AC, ac);
-}
-
-void
-psw_set_ac(void)
-{
-       psw_write_bit(PSW_BIT_AC, 1);
-}
-
-void
-psw_clr_ac(void)
-{
-       psw_write_bit(PSW_BIT_AC, 0);
-}
-
-/* Returns 0 or 1 */
-int
-psw_read_ov(void)
-{
-       return psw_read_bit(PSW_BIT_OV);
-}
-
-void
-psw_write_ov(int ov)
-{
-       psw_write_bit(PSW_BIT_OV, ov);
-}
-
-void
-psw_set_ov(void)
-{
-       psw_write_bit(PSW_BIT_OV, 1);
-}
-
-void
-psw_clr_ov(void)
-{
-       psw_write_bit(PSW_BIT_OV, 0);
-}
-
-/*
- * Compute parity of bits in accumulator:
- *   parity = 0: even number of ones in accumulator
- *   parity = 1: odd  number of ones in accumulator
- */
-void
-psw_compute_parity_bit(void)
-{
-       int parity = 0;
-       uint8_t acc = memory_read8(INT_MEM_ID, _ACC_);
-
-       while (acc) {
-               parity = !parity;
-               acc = acc & (acc - 1);
-       }
-
-       psw_write_bit(PSW_BIT_P, parity);
-}
diff --git a/src/psw.h b/src/psw.h
deleted file mode 100644 (file)
index f2c09ba..0000000
--- a/src/psw.h
+++ /dev/null
@@ -1,71 +0,0 @@
-/*
- * psw.h
- *
- * Copyright (C) 2013 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 PSW_H
-#define PSW_H 1
-
-#include <sys/types.h>
-
-int
-psw_read_bit(int bit);
-
-void
-psw_write_bit(int bit, int val);
-
-int
-psw_read_cy(void);
-
-void
-psw_write_cy(int cy);
-
-void
-psw_clr_cy(void);
-
-void
-psw_set_cy(void);
-
-int
-psw_read_ac(void);
-
-void
-psw_write_ac(int ac);
-
-void
-psw_clr_ac(void);
-
-void
-psw_set_ac(void);
-
-int
-psw_read_ov(void);
-
-void
-psw_write_ov(int ov);
-
-void
-psw_clr_ov(void);
-
-void
-psw_set_ov(void);
-
-void
-psw_compute_parity_bit(void);
-
-#endif /* PSW_H */
diff --git a/src/pswwin.c b/src/pswwin.c
deleted file mode 100644 (file)
index 94f733c..0000000
+++ /dev/null
@@ -1,247 +0,0 @@
-/*
- * pswwin.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 "common.h"
-#include "reg8051.h"
-#include "cpu8051.h"
-#include "memory.h"
-#include "pswwin.h"
-#include "memwin.h"
-#include "pgmwin.h"
-#include "psw.h"
-#include "instructions_8051.h"
-#include "hexfile.h"
-#include "emugtk.h"
-
-static GtkWidget *pswlist;
-
-#define DATA_ROWS 1
-#define LIST_VIEW_NAME "PSW"
-enum
-{
-       COL_CY = 0,
-       COL_AC,
-       COL_F0,
-       COL_RS1,
-       COL_RS0,
-       COL_OV,
-       COL_RESERVED,
-       COL_P,
-       N_COLUMNS,
-};
-
-static char *col_names[N_COLUMNS] = {
-       "CY",
-       "AC",
-       "F0",
-       "RS1",
-       "RS0",
-       "OV",
-       "-",
-       "P",
-};
-
-/* Creating a model */
-static GtkListStore *
-pswwin_init_store(void)
-{
-       GtkTreeIter iter;
-       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);
-
-       /* Add rows. */
-       for (row = 0; row < DATA_ROWS; row++)
-               gtk_list_store_append(store, &iter);
-
-       return store;
-}
-
-static void
-pswwin_cell_edited(GtkCellRendererText *cell, gchar *path_string,
-                  gchar *new_str, gpointer model)
-{
-       guint column;
-       gpointer columnptr;
-       GtkTreeIter iter;
-       u_int8_t old;
-       int new;
-       char str[10];
-       int bit_index;
-
-       if (!model) {
-               g_error("Unable to get model from cell renderer");
-       }
-
-       /* Column number is passed as renderer object data */
-        columnptr = g_object_get_data(G_OBJECT(cell), "column");
-        column = GPOINTER_TO_UINT(columnptr);
-
-       log_info("column = $%02X", column);
-
-       /* Get the iterator */
-        gtk_tree_model_get_iter_from_string(model, &iter, path_string);
-
-       bit_index = 7 - column;
-
-       old = psw_read_bit(bit_index);
-
-       log_info("  old value: %d", old);
-
-       /* Convert new value (asciihex) to integer. */
-       new = asciihex2int(new_str);
-
-       if ((new != 0) && (new != 1)) {
-               log_info("  new value: out of range");
-               new = old; /* Put back old value... */
-       } else {
-               log_info("  new value: %d", new);
-       }
-
-       /* Store new value in emulator memory. */
-       psw_write_bit(bit_index, new);
-
-       /* Convert to text. */
-       int2asciihex(new, str, 1);
-
-       /* Store new value in gtk model. */
-        gtk_list_store_set(GTK_LIST_STORE(model), &iter, column, str, -1);
-
-       /*
-        * Make sure to update all registers and memory.
-        * For example, BANKed registers depends on internal memory.
-        */
-       emugtk_UpdateDisplay();
-};
-
-static void
-pswwin_init_columns(void)
-{
-       int k;
-
-       /* Add column for each bit in PSW. */
-       for (k = 0; k < N_COLUMNS; k++) {
-               GtkCellRenderer *renderer;
-               GtkTreeViewColumn *column;
-
-               /* Create new renderer for value column (editable). */
-               renderer = gtk_cell_renderer_text_new();
-
-               /* Allow edition, align to center. */
-               g_object_set(renderer, "editable", TRUE, "xalign", 0.5, NULL);
-
-               g_signal_connect(renderer, "edited",
-                                G_CALLBACK(pswwin_cell_edited),
-                                gtk_tree_view_get_model(GTK_TREE_VIEW(pswlist)));
-
-               /* Add column index, used when editing the cell. */
-               g_object_set_data(G_OBJECT(renderer), "column",
-                                 GUINT_TO_POINTER(k));
-
-               column = gtk_tree_view_column_new_with_attributes(
-                       col_names[k], renderer, "text", k, NULL);
-
-               /* Center column name */
-               g_object_set(column, "alignment", 0.5, NULL);
-
-               /* Hardcoded width... */
-               gtk_tree_view_column_set_sizing(column, GTK_TREE_VIEW_COLUMN_FIXED);
-               gtk_tree_view_column_set_fixed_width(column, 35);
-
-               gtk_tree_view_append_column(GTK_TREE_VIEW(pswlist), column);
-       }
-}
-
-GtkWidget *
-pswwin_init(void)
-{
-       GtkWidget *frame;
-       GtkListStore *store;
-
-       frame = gtk_frame_new(LIST_VIEW_NAME);
-
-       /* Creating a model */
-       store = pswwin_init_store();
-
-       /* Creating the view component */
-       pswlist = gtk_tree_view_new_with_model(GTK_TREE_MODEL(store));
-
-       gtk_tree_view_set_grid_lines(GTK_TREE_VIEW(pswlist), GTK_TREE_VIEW_GRID_LINES_BOTH);
-
-       gtk_tree_view_set_headers_visible(GTK_TREE_VIEW(pswlist), TRUE);
-       gtk_container_add(GTK_CONTAINER(frame), pswlist);
-
-       pswwin_init_columns();
-
-       /*
-        * The tree view has acquired its own reference to the model, so we can
-        * drop ours. That way the model will be freed automatically when the
-        * tree view is destroyed.
-        */
-       g_object_unref(store);
-
-       return frame;
-}
-
-/* Show registers. */
-void
-pswwin_refresh(void)
-{
-       GtkListStore *store;
-       int valid;
-       GtkTreeIter iter;
-       int k;
-
-       store = GTK_LIST_STORE(gtk_tree_view_get_model(GTK_TREE_VIEW(pswlist)));
-
-       /* Get first row in list store */
-       valid = gtk_tree_model_get_iter_first(
-               GTK_TREE_MODEL(store), &iter);
-
-       if (!valid) {
-               printf("Invalid iter...\n");
-               return;
-       }
-
-       /* Display bit values. */
-       for (k = 0; k < N_COLUMNS; k++) {
-               char str[4];
-               int bit_index;
-
-               bit_index = 7 - k;
-
-               int2asciihex(psw_read_bit(bit_index), str, 1);
-               gtk_list_store_set(store, &iter, k, str, -1);
-       }
-}
diff --git a/src/pswwin.h b/src/pswwin.h
deleted file mode 100644 (file)
index 84d34dd..0000000
+++ /dev/null
@@ -1,33 +0,0 @@
-/*
- * pswwin.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 PSWWIN_H
-#define PSWWIN_H 1
-
-#include <gtk/gtk.h>
-
-GtkWidget *
-pswwin_init(void);
-
-void
-pswwin_refresh(void);
-
-#endif /* PSWWIN_H */
diff --git a/src/reg8051.h b/src/reg8051.h
deleted file mode 100644 (file)
index b484246..0000000
+++ /dev/null
@@ -1,75 +0,0 @@
-/*
- * reg8051.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 REG8051_H
-#define REG8051_H 1
-
-/* SFR Registers ( $80 - $FF ) */
-#define _ACC_       0xE0
-#define _B_         0xF0
-#define _PSW_       0xD0
-#define _SP_        0x81
-#define _DPTRLOW_   _DPL_
-#define _DPTRHIGH_  _DPH_
-#define _DPL_       0x82
-#define _DPH_       0x83
-#define _P0_        0x80
-#define _P1_        0x90
-#define _P2_        0xA0
-#define _P3_        0xB0
-#define _IP_        0xB8
-#define _IE_        0xA8
-#define _TMOD_      0x89
-#define _TCON_      0x88
-#define _TH0_       0x8C
-#define _TL0_       0x8A
-#define _TH1_       0x8D
-#define _TL1_       0x8B
-#define _SCON_      0x98
-#define _SBUF_      0x99
-#define _PCON_      0x87
-#define _T2CON_     0xC8
-
-#define _R0_        0x00
-#define _R1_        0x01
-#define _R2_        0x02
-#define _R3_        0x03
-#define _R4_        0x04
-#define _R5_        0x05
-#define _R6_        0x06
-#define _R7_        0x07
-
-#define _BANK0_     0x00
-#define _BANK1_     0x08
-#define _BANK2_     0x10
-#define _BANK3_     0x18
-
-#define PSW_BIT_CY 7
-#define PSW_BIT_AC 6
-#define PSW_BIT_OV 2
-#define PSW_BIT_P  0
-
-#define PSW_FLAG_CY (1 << PSW_BIT_CY)
-#define PSW_FLAG_AC (1 << PSW_BIT_AC)
-#define PSW_FLAG_OV (1 << PSW_BIT_OV)
-#define PSW_FLAG_P  (1 << PSW_BIT_P)
-
-#endif /* REG8051_H */
diff --git a/src/regwin.c b/src/regwin.c
deleted file mode 100644 (file)
index 8c4cd4d..0000000
+++ /dev/null
@@ -1,256 +0,0 @@
-/*
- * regwin.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 "common.h"
-#include "reg8051.h"
-#include "cpu8051.h"
-#include "sfr.h"
-#include "memory.h"
-#include "regwin.h"
-#include "memwin.h"
-#include "pgmwin.h"
-#include "instructions_8051.h"
-#include "hexfile.h"
-#include "emugtk.h"
-
-static GtkWidget *reglist;
-
-#define LIST_VIEW_NAME "Registers"
-#define DATA_ROWS SFR_REGS
-
-enum
-{
-       COL_NAME = 0,
-       COL_VAL,
-       N_COLUMNS,
-};
-
-/* Creating a model */
-static GtkListStore *
-regwin_init_store(void)
-{
-       GtkTreeIter iter;
-       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);
-
-       /* Add rows. */
-       for (row = 0; row < DATA_ROWS; row++)
-               gtk_list_store_append(store, &iter);
-
-       return store;
-}
-
-static void
-regwin_cell_edited(GtkCellRendererText *cell, gchar *path_string,
-                  gchar *new_str, gpointer model)
-{
-       GtkTreeIter iter;
-       int old;
-       int new;
-       char *str;
-       struct regwin_infos_t *regwin_infos;
-
-       if (!model) {
-               g_error("Unable to get model from cell renderer");
-       }
-
-       /* Get the iterator */
-        gtk_tree_model_get_iter_from_string(model, &iter, path_string);
-
-       /* Get register name. */
-       gtk_tree_model_get(model, &iter, COL_NAME, &str, -1);
-
-       log_info("Register: %s", str);
-       regwin_infos = sfr_get_infos(str);
-
-       /* Read current (old) value. */
-       gtk_tree_model_get(model, &iter, COL_VAL, &str, -1);
-
-       old = asciihex2int(str);
-
-       if (regwin_infos->w == 2)
-               log_info("  old value: $%02X", old);
-       else if (regwin_infos->w == 4)
-               log_info("  old value: $%04X", old);
-
-       new = asciihex2int(new_str);
-
-       if (regwin_infos->w == 2) {
-               if ((new < 0) || (new > 0xFF)) {
-                       log_info("  new value: out of range");
-                       new = old; /* Put back old value... */
-               } else {
-                       log_info("  new value: $%02X", new);
-               }
-       } else if (regwin_infos->w == 4) {
-               if ((new < 0) || (new > 0xFFFF)) {
-                       log_info("  new value: out of range");
-                       new = old; /* Put back old value... */
-               } else {
-                       log_info("  new value: $%04X", new);
-               }
-       }
-
-       /* Store new value in emulator register. */
-       regwin_write(regwin_infos, new);
-
-       /* Store new value in gtk model. */
-       int2asciihex(new, str, regwin_infos->w);
-        gtk_list_store_set(GTK_LIST_STORE(model), &iter, COL_VAL, str, -1);
-
-       /*
-        * Make sure to update all windows.
-        * For example, R0-R7 values depends on internal memory values.
-        */
-       emugtk_UpdateDisplay();
-};
-
-static void
-regwin_init_columns(void)
-{
-       GtkCellRenderer *renderer;
-       GtkTreeViewColumn *column;
-
-       /* Columns and cell renderers */
-       renderer = gtk_cell_renderer_text_new();
-
-       /* Add Register column */
-       column = gtk_tree_view_column_new_with_attributes(
-               "Name", renderer, "text", COL_NAME, NULL);
-       gtk_tree_view_column_set_sizing(column, GTK_TREE_VIEW_COLUMN_AUTOSIZE);
-       gtk_tree_view_append_column(GTK_TREE_VIEW(reglist), column);
-
-       /* Add Value column */
-
-       /* Create new renderer for value column (editable). */
-       renderer = gtk_cell_renderer_text_new();
-
-       /* Allow edition, align to right side. */
-       g_object_set(renderer, "editable", TRUE, "xalign", 1.0, NULL);
-
-       g_signal_connect(renderer, "edited",
-                        G_CALLBACK(regwin_cell_edited),
-                        gtk_tree_view_get_model(GTK_TREE_VIEW(reglist)));
-
-       column = gtk_tree_view_column_new_with_attributes(
-               "Value", renderer, "text", COL_VAL, NULL);
-       gtk_tree_view_column_set_sizing(column, GTK_TREE_VIEW_COLUMN_AUTOSIZE);
-       gtk_tree_view_append_column(GTK_TREE_VIEW(reglist), column);
-}
-
-GtkWidget *
-regwin_init(void)
-{
-       GtkWidget *frame;
-       GtkWidget *scrollwin;
-       GtkListStore *store;
-
-       frame = gtk_frame_new(LIST_VIEW_NAME);
-
-       scrollwin = gtk_scrolled_window_new(NULL, NULL);
-       gtk_scrolled_window_set_shadow_type(GTK_SCROLLED_WINDOW(scrollwin),
-                                           GTK_SHADOW_ETCHED_OUT);
-
-       /* Automatically add scrollbars when necessary. */
-       gtk_scrolled_window_set_policy(GTK_SCROLLED_WINDOW(scrollwin),
-                                      GTK_POLICY_AUTOMATIC,
-                                      GTK_POLICY_AUTOMATIC);
-
-       gtk_container_add(GTK_CONTAINER(frame), scrollwin);
-
-       /* Creating a model */
-       store = regwin_init_store();
-
-       /* Creating the view component */
-       reglist = gtk_tree_view_new_with_model(GTK_TREE_MODEL(store));
-       gtk_tree_view_set_headers_visible(GTK_TREE_VIEW(reglist), TRUE);
-       gtk_container_add(GTK_CONTAINER(scrollwin), reglist);
-
-       regwin_init_columns();
-
-       /*
-        * The tree view has acquired its own reference to the model, so we can
-        * drop ours. That way the model will be freed automatically when the
-        * tree view is destroyed.
-        */
-       g_object_unref(store);
-
-       return frame;
-}
-
-/* Show registers. */
-void
-regwin_refresh(void)
-{
-       int row;
-       GtkListStore *store;
-
-       store = GTK_LIST_STORE(gtk_tree_view_get_model(GTK_TREE_VIEW(reglist)));
-
-       for (row = 0; row < DATA_ROWS; row++) {
-               int valid;
-               GtkTreeIter iter;
-               int val;
-               char str[8];
-               struct regwin_infos_t *regwin_infos;
-
-               if (row == 0) {
-                       /* Get first row in list store */
-                       valid = gtk_tree_model_get_iter_first(
-                               GTK_TREE_MODEL(store), &iter);
-               } else {
-                       /* Get next row in list store */
-                       valid = gtk_tree_model_iter_next(
-                               GTK_TREE_MODEL(store), &iter);
-               }
-
-               if (!valid) {
-                       printf("Invalid iter...\n");
-                       return;
-               }
-
-               regwin_infos = sfr_get_infos_from_row(row);
-
-               val = regwin_read(row);
-
-               /* Convert to specified number of hex digits. */
-               int2asciihex(val, str, regwin_infos->w);
-
-               gtk_list_store_set(store, &iter,
-                                  COL_NAME, regwin_infos->name,
-                                  COL_VAL, str,
-                                  -1);
-       }
-}
diff --git a/src/regwin.h b/src/regwin.h
deleted file mode 100644 (file)
index a526f6f..0000000
+++ /dev/null
@@ -1,33 +0,0 @@
-/*
- * regwin.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 REGWIN_H
-#define REGWIN_H 1
-
-#include <gtk/gtk.h>
-
-GtkWidget *
-regwin_init(void);
-
-void
-regwin_refresh(void);
-
-#endif /* REGWIN_H */
diff --git a/src/sfr.c b/src/sfr.c
deleted file mode 100644 (file)
index 1bbeb8e..0000000
--- a/src/sfr.c
+++ /dev/null
@@ -1,345 +0,0 @@
-/*
- * sfr.c
- *
- * Copyright (C) 2013 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 "common.h"
-#include "reg8051.h"
-#include "cpu8051.h"
-#include "sfr.h"
-#include "memory.h"
-#include "instructions_8051.h"
-
-#define HEX_DIGITS_2 2
-#define HEX_DIGITS_4 4
-
-/* Specific read/write functions for special registers. */
-
-static unsigned int
-regwin_read_pc(int dummy)
-{
-       return cpu8051.pc;
-}
-
-static void
-regwin_write_pc(int param, int val)
-{
-       cpu8051.pc = (u_int16_t) val;
-}
-
-static unsigned int
-regwin_read_timer(int timer_low_addr)
-{
-       return (memory_sfr_read8(timer_low_addr + 2) << 8) |
-               memory_sfr_read8(timer_low_addr);
-}
-
-static void
-regwin_write_timer(int timer_low_addr, int val)
-{
-       memory_sfr_write8(timer_low_addr + 2, (u_int8_t) ((val & 0x0000FFFF) >> 8));
-       memory_sfr_write8(timer_low_addr, (u_int8_t) val);
-}
-
-static u_int8_t
-regwin_read_bank_offset(void)
-{
-       return memory_sfr_read8(_PSW_) & 0x18;
-}
-
-static unsigned int
-regwin_read_bank(int dummy)
-{
-       return regwin_read_bank_offset() >> 3;
-}
-
-static void
-regwin_write_bank(int param, int bank_number)
-{
-       u_int8_t psw = memory_sfr_read8(_PSW_);
-
-       if ((bank_number < 0) || (bank_number > 3)) {
-               log_info("Error: invalid bank number: %d", bank_number);
-               bank_number = 0;
-       }
-
-       memory_sfr_write8(_PSW_, (psw & ~0x18) | (bank_number << 3));
-}
-
-/* Indirect read of R0 - R7 in current bank from internal memory. */
-static unsigned int
-regwin_read_rx(int offset)
-{
-       return memory_read8(INT_MEM_ID, regwin_read_bank_offset() + offset);
-}
-
-/* Indirect write to R0 - R7 in current bank to internal memory. */
-static void
-regwin_write_rx(int offset, int val)
-{
-       memory_write8(INT_MEM_ID, regwin_read_bank_offset() + offset, (u_int8_t) val);
-}
-
-/* This array defines how to read value for each register. */
-static struct regwin_infos_t regwin_infos[SFR_REGS] = {
-       {
-               "PC",
-               HEX_DIGITS_4,
-               regwin_read_pc, regwin_write_pc,
-               0, /* Dummy */
-       },
-       {
-               "SP",
-               HEX_DIGITS_2,
-               NULL, NULL,
-               _SP_,
-       },
-       {
-               "PSW",
-               HEX_DIGITS_2,
-               NULL, NULL,
-               _PSW_,
-       },
-       {
-               "A",
-               HEX_DIGITS_2,
-               NULL, NULL,
-               _ACC_,
-       },
-       {
-               "B",
-               HEX_DIGITS_2,
-               NULL, NULL,
-               _B_,
-       },
-       {
-               "DPTR",
-               HEX_DIGITS_4,
-               NULL, NULL,
-               _DPL_,
-       },
-       {
-               "P0",
-               HEX_DIGITS_2,
-               NULL, NULL,
-               _P0_,
-       },
-       {
-               "P1",
-               HEX_DIGITS_2,
-               NULL, NULL,
-               _P1_,
-       },
-       {
-               "P2",
-               HEX_DIGITS_2,
-               NULL, NULL,
-               _P2_,
-       },
-       {
-               "P3",
-               HEX_DIGITS_2,
-               NULL, NULL,
-               _P3_,
-       },
-       {
-               "TCON",
-               HEX_DIGITS_2,
-               NULL, NULL,
-               _TCON_,
-       },
-       {
-               "TMOD",
-               HEX_DIGITS_2,
-               NULL, NULL,
-               _TMOD_,
-       },
-       {
-               "TIMER0",
-               HEX_DIGITS_4,
-               regwin_read_timer, regwin_write_timer,
-               _TL0_,
-       },
-       {
-               "TIMER1",
-               HEX_DIGITS_4,
-               regwin_read_timer, regwin_write_timer,
-               _TL1_,
-       },
-       {
-               "SCON",
-               HEX_DIGITS_2,
-               NULL, NULL,
-               _SCON_,
-       },
-       {
-               "IE",
-               HEX_DIGITS_2,
-               NULL, NULL,
-               _IE_,
-       },
-       {
-               "IP",
-               HEX_DIGITS_2,
-               NULL, NULL,
-               _IP_,
-       },
-       {
-               "BANK",
-               HEX_DIGITS_2,
-               regwin_read_bank, regwin_write_bank,
-               0, /* Dummy */
-       },
-       /* R0-R7 Registers in current Bank */
-       {
-               "R0",
-               HEX_DIGITS_2,
-               regwin_read_rx, regwin_write_rx,
-               _R0_,
-       },
-       {
-               "R1",
-               HEX_DIGITS_2,
-               regwin_read_rx, regwin_write_rx,
-               _R1_,
-       },
-       {
-               "R2",
-               HEX_DIGITS_2,
-               regwin_read_rx, regwin_write_rx,
-               _R2_,
-       },
-       {
-               "R3",
-               HEX_DIGITS_2,
-               regwin_read_rx, regwin_write_rx,
-               _R3_,
-       },
-       {
-               "R4",
-               HEX_DIGITS_2,
-               regwin_read_rx, regwin_write_rx,
-               _R4_,
-       },
-       {
-               "R5",
-               HEX_DIGITS_2,
-               regwin_read_rx, regwin_write_rx,
-               _R5_,
-       },
-       {
-               "R6",
-               HEX_DIGITS_2,
-               regwin_read_rx, regwin_write_rx,
-               _R6_,
-       },
-       {
-               "R7",
-               HEX_DIGITS_2,
-               regwin_read_rx, regwin_write_rx,
-               _R7_,
-       },
-};
-
-/* Generic read/write functions */
-static unsigned int
-regwin_read_generic(int addr, int width)
-{
-       if (width == 2)
-               return memory_sfr_read8(addr);
-       else if (width == 4) {
-               /* Address is low address. */
-               return (memory_sfr_read8(addr + 1) << 8) |
-                       memory_sfr_read8(addr);
-       } else
-               return 0xFFFFFFFF;
-}
-
-static void
-regwin_write_generic(int addr, int val, int width)
-{
-       if (width == 2)
-               memory_sfr_write8(addr, (u_int8_t) val);
-       else if (width == 4) {
-               /* Address is low address. */
-               memory_sfr_write8(addr + 1, (u_int8_t) ((val & 0x0000FFFF) >> 8));
-               memory_sfr_write8(addr, (u_int8_t) val);
-       }
-};
-
-int
-regwin_read(int row)
-{
-       int val;
-
-       if (regwin_infos[row].read_func == NULL) {
-               /*
-                * Read register value using generic 8 or 16 bits read
-                * function, depending on width.
-                */
-               val = regwin_read_generic(regwin_infos[row].param,
-                                         regwin_infos[row].w);
-       } else {
-               /* Read register value using custom function pointer. */
-               val = regwin_infos[row].read_func(
-                       regwin_infos[row].param);
-       }
-
-       return val;
-}
-
-void
-regwin_write(struct regwin_infos_t *p, int new)
-{
-       if (p->write_func == NULL) {
-               /*
-                * Write register value using generic 8 or 16 bits write
-                * function, depending on width.
-                */
-               regwin_write_generic(p->param, new, p->w);
-       } else {
-               /* Write register value using custom function pointer. */
-               p->write_func(p->param, new);
-       }
-}
-
-struct regwin_infos_t *
-sfr_get_infos(const char *regname)
-{
-       int row;
-
-       for (row = 0; row < SFR_REGS; row++) {
-               if (strcmp(regwin_infos[row].name, regname) == 0)
-                       return &regwin_infos[row];
-       }
-
-       return NULL; /* Programming error. */
-}
-
-struct regwin_infos_t *
-sfr_get_infos_from_row(int row)
-{
-       return &regwin_infos[row];
-}
-
diff --git a/src/sfr.h b/src/sfr.h
deleted file mode 100644 (file)
index fe552dd..0000000
--- a/src/sfr.h
+++ /dev/null
@@ -1,46 +0,0 @@
-/*
- * sfr.h
- *
- * Copyright (C) 2013 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 SFR_H
-#define SFR_H 1
-
-#define SFR_REGS 26
-
-struct regwin_infos_t {
-       char *name; /* Register name */
-       int w; /* Number of hex digits to display */
-       unsigned int (*read_func)(int addr); /* Function to read value */
-       void (*write_func)(int param, int val); /* Function to write value */
-       int param; /* Optional parameter to pass to read function. */
-};
-
-int
-regwin_read(int row);
-
-void
-regwin_write(struct regwin_infos_t *p, int new);
-
-struct regwin_infos_t *
-sfr_get_infos(const char *regname);
-
-struct regwin_infos_t *
-sfr_get_infos_from_row(int row);
-
-#endif /* SFR_H */
diff --git a/src/timers.c b/src/timers.c
deleted file mode 100644 (file)
index 68a92bc..0000000
+++ /dev/null
@@ -1,144 +0,0 @@
-/*
- * timers.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.
- */
-
-#include <stdio.h>
-#include <stdbool.h>
-#include <stdint.h>
-#include "config.h"
-
-#include "common.h"
-#include "reg8051.h"
-#include "cpu8051.h"
-#include "memory.h"
-#include "psw.h"
-#include "options.h"
-#include "instructions_8051.h"
-
-extern struct options_t options;
-
-static void
-timer_increment_check_overflow(uint8_t counter_address, uint8_t tf_mask)
-{
-       unsigned int tmp;
-
-       tmp = cpu8051_ReadD(counter_address);
-       tmp++;
-       tmp &= 0xFF;
-       if (tmp == 0) {
-               /* If overflow set TFx */
-               cpu8051_WriteD(_TCON_, cpu8051_ReadD(_TCON_) | tf_mask);
-       }
-
-       cpu8051_WriteD(counter_address, tmp); /* Save new value. */
-}
-
-static void
-timer_with_prescaler(uint8_t tl, uint8_t th, uint8_t tf_mask, int prescaler_width)
-{
-       unsigned int prescaler;
-
-       prescaler = cpu8051_ReadD(tl);
-       prescaler++;
-
-       prescaler &= (1 << prescaler_width) - 1; /* Keep only required bits */
-       cpu8051_WriteD(tl, prescaler);
-
-       if (prescaler == 0)
-               timer_increment_check_overflow(th, tf_mask);
-}
-
-static void
-process_timer(uint8_t tl, uint8_t th, uint8_t tf_mask, uint8_t TR, uint8_t mode,
-             uint8_t GATE, uint32_t TimerCounter)
-{
-       unsigned int tmp;
-
-       switch (mode) {
-       case 0:
-               /* Mode 0, 8-bit timer "TH" with "TL" as 5-bit prescaler. */
-               timer_with_prescaler(tl, th, tf_mask, 5);
-               break;
-       case 1:
-               /* Mode 1, 16-bits counter */
-               timer_with_prescaler(tl, th, tf_mask, 8);
-               break;
-       case 2:
-               /* Mode 2, 8-bits counter with Auto-Reload */
-               tmp = cpu8051_ReadD(tl);
-               tmp++;
-               tmp &= 0xFF;
-               if (tmp == 0) {
-                       /* If overflow -> reload and set TF0 */
-                       cpu8051_WriteD(_TCON_, cpu8051_ReadD(_TCON_) | tf_mask);
-                       cpu8051_WriteD(tl, cpu8051_ReadD(th));
-               } else
-                       cpu8051_WriteD(tl, tmp);
-               break;
-       case 3:
-               /*
-                * Mode 3:
-                *   inactive mode for timer 1
-                *   2 independents 8-bits timers for timer 0.
-                */
-
-               if (tl == _TL1_)
-                       break;
-
-               if (TR && !GATE && !TimerCounter)
-                       timer_increment_check_overflow(tl, tf_mask);
-
-               /* TH0 uses TR1 et TF1. */
-               TR = cpu8051_ReadD(_TCON_) & 0x40;
-
-               if (TR)
-                       timer_increment_check_overflow(th, 0x80);
-
-               break;
-       }
-}
-
-/* Run timers */
-void
-timers_check(void)
-{
-       unsigned int TR;
-       unsigned int MODE;
-       unsigned int GATE;
-       unsigned int TimerCounter;
-
-       /* Timer 0 */
-       TR = cpu8051_ReadD(_TCON_) & 0x10;
-       MODE = cpu8051_ReadD(_TMOD_) & 0x03;
-       GATE = cpu8051_ReadD(_TMOD_) & 0x08;
-       TimerCounter = cpu8051_ReadD(_TMOD_) & 0x04;
-
-       if ((TR && !GATE && !TimerCounter) || (MODE == 3))
-               process_timer(_TL0_, _TH0_, 0x20, TR, MODE, GATE, TimerCounter);
-
-       /* Timer 1 */
-       TR = cpu8051_ReadD(_TCON_) & 0x40;
-       MODE = (cpu8051_ReadD(_TMOD_) & 0x30) >> 4 ;
-       GATE = cpu8051_ReadD(_TMOD_) & 0x80;
-       TimerCounter = cpu8051_ReadD(_TMOD_) & 0x40;
-
-       if (TR && !GATE && !TimerCounter)
-               process_timer(_TL1_, _TH1_, 0x80, TR, MODE, GATE, TimerCounter);
-}
diff --git a/src/timers.h b/src/timers.h
deleted file mode 100644 (file)
index 932ace4..0000000
+++ /dev/null
@@ -1,29 +0,0 @@
-/*
- * timers.h
- *
- * Copyright (C) 2013 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 TIMERS_H
-#define TIMERS_H 1
-
-#include <stdint.h>
-
-int
-timers_check(void);
-
-#endif /* TIMERS_H */
diff --git a/src/viewmenu.c b/src/viewmenu.c
deleted file mode 100644 (file)
index 3377329..0000000
+++ /dev/null
@@ -1,208 +0,0 @@
-/*
- * viewmenu.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 <gtk/gtk.h>
-
-#include "common.h"
-#include "emugtk.h" /* For AddMenuSeparator() function. */
-#include "messagebox.h"
-#include "viewmenu.h"
-#include "app-config.h"
-
-extern struct app_config_t *cfg;
-
-void toggle_layout(GtkWidget *widget, gpointer data)
-{
-       int id;
-
-        id = GPOINTER_TO_UINT(data);
-
-       if (gtk_check_menu_item_get_active(GTK_CHECK_MENU_ITEM(widget))) {
-               log_info("  Switching to layout %d", id);
-               cfg->layout = id;
-               emugtk_restart_gui();
-       }
-}
-
-void toggle_bits_per_row(GtkWidget *widget, gpointer data)
-{
-       int bits_per_row;
-
-        bits_per_row = GPOINTER_TO_UINT(data);
-
-       if (gtk_check_menu_item_get_active(GTK_CHECK_MENU_ITEM(widget))) {
-               log_info("  Bits per row = %d", bits_per_row);
-               cfg->bits_per_row = bits_per_row;
-               emugtk_restart_gui();
-       }
-}
-
-void toggle_int_memory(GtkWidget *widget, gpointer data)
-{
-       if (gtk_check_menu_item_get_active(GTK_CHECK_MENU_ITEM(widget))) {
-               log_info("  View internal memory");
-               cfg->view_int_memory = 1;
-       } else {
-               cfg->view_int_memory = 0;
-       }
-
-       emugtk_restart_gui();
-}
-
-void toggle_sfr_memory(GtkWidget *widget, gpointer data)
-{
-       if (gtk_check_menu_item_get_active(GTK_CHECK_MENU_ITEM(widget))) {
-               log_info("  View SFR memory");
-               cfg->view_sfr_memory = 1;
-       } else {
-               cfg->view_sfr_memory = 0;
-       }
-
-       emugtk_restart_gui();
-}
-
-void toggle_ext_memory(GtkWidget *widget, gpointer data)
-{
-       if (gtk_check_menu_item_get_active(GTK_CHECK_MENU_ITEM(widget))) {
-               log_info("  View external memory");
-               cfg->view_ext_memory = 1;
-       } else {
-               cfg->view_ext_memory = 0;
-       }
-
-       emugtk_restart_gui();
-}
-
-void
-view_add_layout_submenu(GtkWidget *parent)
-{
-       GtkWidget *submenu;
-       GtkWidget *layout;
-       GtkWidget *layout1;
-       GtkWidget *layout2;
-       GSList *group = NULL;
-
-       submenu = gtk_menu_new();
-
-       layout  = gtk_menu_item_new_with_label("Layout");
-
-       layout1 = gtk_radio_menu_item_new_with_label(group, "Layout1");
-       group = gtk_radio_menu_item_get_group(GTK_RADIO_MENU_ITEM(layout1));
-       layout2 = gtk_radio_menu_item_new_with_label(group, "Layout2");
-
-       if (cfg->layout == UI_LAYOUT1)
-               gtk_check_menu_item_set_active(GTK_CHECK_MENU_ITEM(layout1), TRUE);
-       else
-               gtk_check_menu_item_set_active(GTK_CHECK_MENU_ITEM(layout2), TRUE);
-
-       g_signal_connect(G_OBJECT(layout1), "activate",
-                        G_CALLBACK(toggle_layout), (gpointer) UI_LAYOUT1);
-       g_signal_connect(G_OBJECT(layout2), "activate",
-                        G_CALLBACK(toggle_layout), (gpointer) UI_LAYOUT2);
-
-       gtk_menu_item_set_submenu(GTK_MENU_ITEM(layout), submenu);
-       gtk_menu_shell_append(GTK_MENU_SHELL(submenu), layout1);
-       gtk_menu_shell_append(GTK_MENU_SHELL(submenu), layout2);
-       gtk_menu_shell_append(GTK_MENU_SHELL(parent), layout);
-}
-
-void
-view_add_bits_per_row_submenu(GtkWidget *parent)
-{
-       GtkWidget *submenu;
-       GtkWidget *item;
-       GtkWidget *item1;
-       GtkWidget *item2;
-       GSList *group = NULL;
-
-       submenu = gtk_menu_new();
-
-       item  = gtk_menu_item_new_with_label("Bits per row");
-
-       item1 = gtk_radio_menu_item_new_with_label(group, "8");
-       group = gtk_radio_menu_item_get_group(GTK_RADIO_MENU_ITEM(item1));
-       item2 = gtk_radio_menu_item_new_with_label(group, "16");
-
-       if (cfg->bits_per_row == 8)
-               gtk_check_menu_item_set_active(GTK_CHECK_MENU_ITEM(item1), TRUE);
-       else
-               gtk_check_menu_item_set_active(GTK_CHECK_MENU_ITEM(item2), TRUE);
-
-       g_signal_connect(G_OBJECT(item1), "activate",
-                        G_CALLBACK(toggle_bits_per_row), (gpointer) 8);
-       g_signal_connect(G_OBJECT(item2), "activate",
-                        G_CALLBACK(toggle_bits_per_row), (gpointer) 16);
-
-       gtk_menu_item_set_submenu(GTK_MENU_ITEM(item), submenu);
-       gtk_menu_shell_append(GTK_MENU_SHELL(submenu), item1);
-       gtk_menu_shell_append(GTK_MENU_SHELL(submenu), item2);
-       gtk_menu_shell_append(GTK_MENU_SHELL(parent), item);
-}
-
-void
-ViewAddMenu(GtkWidget *menu_bar)
-{
-       GtkWidget *item;
-       GtkWidget *menu;
-       GtkWidget *view;
-
-       menu = gtk_menu_new();
-
-       view = gtk_menu_item_new_with_label("View");
-
-       item = gtk_check_menu_item_new_with_label("Internal Memory");
-       gtk_menu_shell_append(GTK_MENU_SHELL(menu), item);
-       gtk_check_menu_item_set_active(GTK_CHECK_MENU_ITEM(item),
-                                      cfg->view_int_memory);
-       g_signal_connect(G_OBJECT(item), "activate",
-                        G_CALLBACK(toggle_int_memory), NULL);
-
-       item = gtk_check_menu_item_new_with_label("SFR Memory");
-       gtk_menu_shell_append(GTK_MENU_SHELL(menu), item);
-       gtk_check_menu_item_set_active(GTK_CHECK_MENU_ITEM(item),
-                                      cfg->view_sfr_memory);
-       g_signal_connect(G_OBJECT(item), "activate",
-                        G_CALLBACK(toggle_sfr_memory), NULL);
-
-       item = gtk_check_menu_item_new_with_label("External Memory");
-       gtk_menu_shell_append(GTK_MENU_SHELL(menu), item);
-       gtk_check_menu_item_set_active(GTK_CHECK_MENU_ITEM(item),
-                                      cfg->view_ext_memory);
-       g_signal_connect(G_OBJECT(item), "activate",
-                        G_CALLBACK(toggle_ext_memory), NULL);
-
-       AddMenuSeparator(menu);
-
-       /* Add layout submenu */
-       view_add_layout_submenu(menu);
-
-       AddMenuSeparator(menu);
-
-       /* Add bits per row submenu */
-       view_add_bits_per_row_submenu(menu);
-
-       gtk_menu_item_set_submenu(GTK_MENU_ITEM(view), menu);
-       gtk_menu_shell_append(GTK_MENU_SHELL(menu_bar), view);
-}
diff --git a/src/viewmenu.h b/src/viewmenu.h
deleted file mode 100644 (file)
index bf78564..0000000
+++ /dev/null
@@ -1,30 +0,0 @@
-/*
- * viewmenu.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 VIEWMENU_H
-#define VIEWMENU_H 1
-
-#include <gtk/gtk.h>
-
-void
-ViewAddMenu(GtkWidget *menu_bar);
-
-#endif /* VIEWMENU_H */
index f6ff764..3ae17fd 100755 (executable)
@@ -12,7 +12,7 @@ name=$(basename ${test_name} .sh)
 hexfile=${name}.hex
 
 echo "Testing ${name}.hex" > ${lf}
-../src/emu8051-cli -d 2 --xram=${XRAM_SIZE} -s ${STOP_ADDRESS} ${hexfile} >> ${lf}
+../src/cli/emu8051-cli -d 2 --xram=${XRAM_SIZE} -s ${STOP_ADDRESS} ${hexfile} >> ${lf}
 if test $? -ne 0 ; then
     return 1
 fi