summaryrefslogtreecommitdiff
path: root/sim/ucsim/xa.src
diff options
context:
space:
mode:
authorXavier ASUS <xavi92psx@gmail.com>2019-10-18 00:31:54 +0200
committerXavier ASUS <xavi92psx@gmail.com>2019-10-18 00:31:54 +0200
commit268a53de823a6750d6256ee1fb1e7707b4b45740 (patch)
tree42c1799a9a82b2f7d9790ee9fe181d72a7274751 /sim/ucsim/xa.src
downloadsdcc-gas-268a53de823a6750d6256ee1fb1e7707b4b45740.tar.gz
sdcc-3.9.0 fork implementing GNU assembler syntax
This fork aims to provide better support for stm8-binutils
Diffstat (limited to 'sim/ucsim/xa.src')
-rw-r--r--sim/ucsim/xa.src/(c).125
-rw-r--r--sim/ucsim/xa.src/Makefile142
-rw-r--r--sim/ucsim/xa.src/Makefile.in142
-rw-r--r--sim/ucsim/xa.src/clean.mk26
-rw-r--r--sim/ucsim/xa.src/conf.mk10
-rw-r--r--sim/ucsim/xa.src/glob.cc452
-rw-r--r--sim/ucsim/xa.src/glob.h212
-rw-r--r--sim/ucsim/xa.src/inst.cc1191
-rw-r--r--sim/ucsim/xa.src/inst_gen.cc285
-rw-r--r--sim/ucsim/xa.src/instcl.h71
-rw-r--r--sim/ucsim/xa.src/regsxa.h285
-rw-r--r--sim/ucsim/xa.src/simxa.cc45
-rw-r--r--sim/ucsim/xa.src/simxacl.h45
-rw-r--r--sim/ucsim/xa.src/sxa.cc56
-rw-r--r--sim/ucsim/xa.src/xa.cc1190
-rw-r--r--sim/ucsim/xa.src/xacl.h400
16 files changed, 4577 insertions, 0 deletions
diff --git a/sim/ucsim/xa.src/(c).1 b/sim/ucsim/xa.src/(c).1
new file mode 100644
index 0000000..d673f9f
--- /dev/null
+++ b/sim/ucsim/xa.src/(c).1
@@ -0,0 +1,25 @@
+/*
+ * Simulator of microcontrollers (@@F@@)
+ *
+ * Copyright (C) @@S@@,@@Y@@ Drotos Daniel, Talker Bt.
+ *
+ * To contact author send email to drdani@mazsola.iit.uni-miskolc.hu
+ *
+ */
+
+/* This file is part of microcontroller simulator: ucsim.
+
+UCSIM 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.
+
+UCSIM 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 UCSIM; see the file COPYING. If not, write to the Free
+Software Foundation, 59 Temple Place - Suite 330, Boston, MA
+02111-1307, USA. */
diff --git a/sim/ucsim/xa.src/Makefile b/sim/ucsim/xa.src/Makefile
new file mode 100644
index 0000000..1414d36
--- /dev/null
+++ b/sim/ucsim/xa.src/Makefile
@@ -0,0 +1,142 @@
+#
+# uCsim xa.src/Makefile
+#
+# (c) Drotos Daniel, Talker Bt. 1997
+#
+
+STARTYEAR = 1997
+
+SHELL = /bin/sh
+CXX = g++
+CPP = gcc -E
+CXXCPP = g++ -E
+RANLIB = ranlib
+INSTALL = /usr/bin/install -c
+STRIP = strip
+MAKEDEP = g++ -MM
+
+top_builddir = ..
+top_srcdir = ..
+
+transform = s,x,x,
+
+EXEEXT =
+
+DEFS = $(subs -DHAVE_CONFIG_H,,-DHAVE_CONFIG_H)
+CPPFLAGS = -I$(srcdir) -I$(top_srcdir) -I$(top_builddir) \
+ -I$(top_srcdir)/cmd.src -I$(top_srcdir)/sim.src \
+ -I$(top_srcdir)/gui.src
+CFLAGS = -g -O2 -Wall
+CXXFLAGS = -g -O2 -g -Wall
+LDFLAGS =
+PICOPT = -fPIC -DPIC
+
+LIBS = -L$(top_builddir) -lsim -lucsimutil -lguiucsim -lcmd -lsim -lrt -lnsl
+
+prefix = /usr/local
+exec_prefix = ${prefix}
+bindir = ${exec_prefix}/bin
+libdir = ${exec_prefix}/lib
+datadir = ${datarootdir}
+datarootdir = ${prefix}/share
+includedir = ${prefix}/include
+mandir = ${datarootdir}/man
+man1dir = $(mandir)/man1
+man2dir = $(mandir)/man2
+infodir = ${datarootdir}/info
+srcdir = .
+
+
+OBJECTS = sxa.o glob.o \
+ inst.o \
+ simxa.o xa.o
+
+XAASM =
+#TEST_OBJ = test_bit.hex test_dis.hex test_mov.hex test_jmp.hex \
+# test_arith.hex
+
+
+# Compiling entire program or any subproject
+# ------------------------------------------
+all: checkconf otherlibs xa.src tests
+
+tests: $(TEST_OBJ)
+
+
+# Compiling and installing everything and runing test
+# ---------------------------------------------------
+install: all installdirs
+ $(INSTALL) sxa$(EXEEXT) $(DESTDIR)$(bindir)/`echo sxa|sed '$(transform)'`$(EXEEXT)
+ $(STRIP) $(DESTDIR)$(bindir)/`echo sxa|sed '$(transform)'`$(EXEEXT)
+
+
+# Deleting all the installed files
+# --------------------------------
+uninstall:
+ rm -f $(DESTDIR)$(bindir)/`echo sxa|sed '$(transform)'`$(EXEEXT)
+
+
+# Performing self-test
+# --------------------
+check:
+
+
+# Performing installation test
+# ----------------------------
+installcheck:
+
+
+# Creating installation directories
+# ---------------------------------
+installdirs:
+ test -d $(DESTDIR)$(bindir) || $(INSTALL) -d $(DESTDIR)$(bindir)
+
+
+# Creating dependencies
+# ---------------------
+dep: Makefile.dep
+
+Makefile.dep: $(srcdir)/*.cc $(srcdir)/*.h
+ $(MAKEDEP) $(CPPFLAGS) $(filter %.cc,$^) >Makefile.dep
+
+-include Makefile.dep
+include $(srcdir)/clean.mk
+
+# My rules
+# --------
+.SUFFIXES: .asm .hex
+
+xa.src: sxa$(EXEEXT)
+
+sxa$(EXEEXT): $(OBJECTS) $(top_builddir)/libcmd.a $(top_builddir)/libguiucsim.a $(top_builddir)/libsim.a $(top_builddir)/libucsimutil.a
+ $(CXX) $(CXXFLAGS) $(LDFLAGS) $(OBJECTS) $(LIBS) -o $@
+
+otherlibs: $(top_builddir)/libcmd.a $(top_builddir)/libguiucsim.a $(top_builddir)/libsim.a $(top_builddir)/libucsimutil.a
+
+$(top_builddir)/libcmd.a:
+ $(MAKE) -C $(top_builddir)/cmd.src all
+
+$(top_builddir)/libguiucsim.a:
+ $(MAKE) -C $(top_builddir)/gui.src checkconf ucsim_lib
+
+$(top_builddir)/libsim.a:
+ $(MAKE) -C $(top_builddir)/sim.src all
+
+$(top_builddir)/libucsimutil.a:
+ $(MAKE) -C $(top_builddir) -f main.mk
+
+.cc.o:
+ $(CXX) $(CXXFLAGS) $(PICOPT) $(CPPFLAGS) $(TARGET_ARCH) -c $< -o $@
+
+.asm.hex:
+ $(XAASM) -l $< -o $@ -e $<.lst
+
+
+# Remaking configuration
+# ----------------------
+checkconf:
+ @if [ -f $(top_builddir)/devel ]; then\
+ $(MAKE) -f $(srcdir)/conf.mk srcdir="$(srcdir)" top_builddir="$(top_builddir)" freshconf;\
+ fi
+
+# End of xa.src/Makefile.in
diff --git a/sim/ucsim/xa.src/Makefile.in b/sim/ucsim/xa.src/Makefile.in
new file mode 100644
index 0000000..6b34c29
--- /dev/null
+++ b/sim/ucsim/xa.src/Makefile.in
@@ -0,0 +1,142 @@
+#
+# uCsim xa.src/Makefile
+#
+# (c) Drotos Daniel, Talker Bt. 1997
+#
+
+STARTYEAR = 1997
+
+SHELL = /bin/sh
+CXX = @CXX@
+CPP = @CPP@
+CXXCPP = @CXXCPP@
+RANLIB = @RANLIB@
+INSTALL = @INSTALL@
+STRIP = @STRIP@
+MAKEDEP = @MAKEDEP@
+
+top_builddir = @top_builddir@
+top_srcdir = @top_srcdir@
+
+transform = @program_transform_name@
+
+EXEEXT = @EXEEXT@
+
+DEFS = $(subs -DHAVE_CONFIG_H,,@DEFS@)
+CPPFLAGS = @CPPFLAGS@ -I$(srcdir) -I$(top_srcdir) -I$(top_builddir) \
+ -I$(top_srcdir)/cmd.src -I$(top_srcdir)/sim.src \
+ -I$(top_srcdir)/gui.src
+CFLAGS = @CFLAGS@ @WALL_FLAG@
+CXXFLAGS = @CXXFLAGS@ @WALL_FLAG@
+LDFLAGS = @LDFLAGS@
+PICOPT = @PICOPT@
+
+LIBS = -L$(top_builddir) -lsim -lucsimutil -lguiucsim -lcmd -lsim @LIBS@
+
+prefix = @prefix@
+exec_prefix = @exec_prefix@
+bindir = @bindir@
+libdir = @libdir@
+datadir = @datadir@
+datarootdir = @datarootdir@
+includedir = @includedir@
+mandir = @mandir@
+man1dir = $(mandir)/man1
+man2dir = $(mandir)/man2
+infodir = @infodir@
+srcdir = @srcdir@
+VPATH = @srcdir@
+
+OBJECTS = sxa.o glob.o \
+ inst.o \
+ simxa.o xa.o
+
+XAASM =
+#TEST_OBJ = test_bit.hex test_dis.hex test_mov.hex test_jmp.hex \
+# test_arith.hex
+
+
+# Compiling entire program or any subproject
+# ------------------------------------------
+all: checkconf otherlibs xa.src tests
+
+tests: $(TEST_OBJ)
+
+
+# Compiling and installing everything and runing test
+# ---------------------------------------------------
+install: all installdirs
+ $(INSTALL) sxa$(EXEEXT) $(DESTDIR)$(bindir)/`echo sxa|sed '$(transform)'`$(EXEEXT)
+ $(STRIP) $(DESTDIR)$(bindir)/`echo sxa|sed '$(transform)'`$(EXEEXT)
+
+
+# Deleting all the installed files
+# --------------------------------
+uninstall:
+ rm -f $(DESTDIR)$(bindir)/`echo sxa|sed '$(transform)'`$(EXEEXT)
+
+
+# Performing self-test
+# --------------------
+check:
+
+
+# Performing installation test
+# ----------------------------
+installcheck:
+
+
+# Creating installation directories
+# ---------------------------------
+installdirs:
+ test -d $(DESTDIR)$(bindir) || $(INSTALL) -d $(DESTDIR)$(bindir)
+
+
+# Creating dependencies
+# ---------------------
+dep: Makefile.dep
+
+Makefile.dep: $(srcdir)/*.cc $(srcdir)/*.h
+ $(MAKEDEP) $(CPPFLAGS) $(filter %.cc,$^) >Makefile.dep
+
+-include Makefile.dep
+include $(srcdir)/clean.mk
+
+# My rules
+# --------
+.SUFFIXES: .asm .hex
+
+xa.src: sxa$(EXEEXT)
+
+sxa$(EXEEXT): $(OBJECTS) $(top_builddir)/libcmd.a $(top_builddir)/libguiucsim.a $(top_builddir)/libsim.a $(top_builddir)/libucsimutil.a
+ $(CXX) $(CXXFLAGS) $(LDFLAGS) $(OBJECTS) $(LIBS) -o $@
+
+otherlibs: $(top_builddir)/libcmd.a $(top_builddir)/libguiucsim.a $(top_builddir)/libsim.a $(top_builddir)/libucsimutil.a
+
+$(top_builddir)/libcmd.a:
+ $(MAKE) -C $(top_builddir)/cmd.src all
+
+$(top_builddir)/libguiucsim.a:
+ $(MAKE) -C $(top_builddir)/gui.src checkconf ucsim_lib
+
+$(top_builddir)/libsim.a:
+ $(MAKE) -C $(top_builddir)/sim.src all
+
+$(top_builddir)/libucsimutil.a:
+ $(MAKE) -C $(top_builddir) -f main.mk
+
+.cc.o:
+ $(CXX) $(CXXFLAGS) $(PICOPT) $(CPPFLAGS) $(TARGET_ARCH) -c $< -o $@
+
+.asm.hex:
+ $(XAASM) -l $< -o $@ -e $<.lst
+
+
+# Remaking configuration
+# ----------------------
+checkconf:
+ @if [ -f $(top_builddir)/devel ]; then\
+ $(MAKE) -f $(srcdir)/conf.mk srcdir="$(srcdir)" top_builddir="$(top_builddir)" freshconf;\
+ fi
+
+# End of xa.src/Makefile.in
diff --git a/sim/ucsim/xa.src/clean.mk b/sim/ucsim/xa.src/clean.mk
new file mode 100644
index 0000000..f7f2416
--- /dev/null
+++ b/sim/ucsim/xa.src/clean.mk
@@ -0,0 +1,26 @@
+# Deleting all files created by building the program
+# --------------------------------------------------
+clean:
+ rm -f *core *[%~] *.[oa]
+ rm -f .[a-z]*~
+ rm -f sxa$(EXEEXT)
+
+
+# Deleting all files created by configuring or building the program
+# -----------------------------------------------------------------
+distclean: clean
+ rm -f config.cache config.log config.status
+ rm -f Makefile *.dep
+
+
+# Like clean but some files may still exist
+# -----------------------------------------
+mostlyclean: clean
+
+
+# Deleting everything that can reconstructed by this Makefile. It deletes
+# everything deleted by distclean plus files created by bison, etc.
+# -----------------------------------------------------------------------
+realclean: distclean
+
+# End of xa.src/clean.mk
diff --git a/sim/ucsim/xa.src/conf.mk b/sim/ucsim/xa.src/conf.mk
new file mode 100644
index 0000000..3e4e7dd
--- /dev/null
+++ b/sim/ucsim/xa.src/conf.mk
@@ -0,0 +1,10 @@
+#
+# Makefile targets to remake configuration
+#
+
+freshconf: Makefile
+
+Makefile: $(srcdir)/Makefile.in $(top_srcdir)/configure.ac
+ cd $(top_builddir) && $(SHELL) ./config.status
+
+# End of xa.src/conf.mk
diff --git a/sim/ucsim/xa.src/glob.cc b/sim/ucsim/xa.src/glob.cc
new file mode 100644
index 0000000..0baed61
--- /dev/null
+++ b/sim/ucsim/xa.src/glob.cc
@@ -0,0 +1,452 @@
+/*
+ * Simulator of microcontrollers (glob.cc)
+ *
+ * Copyright (C) 1999,2002 Drotos Daniel, Talker Bt.
+ *
+ * To contact author send email to drdani@mazsola.iit.uni-miskolc.hu
+ * Other contributors include:
+ * Karl Bongers karl@turbobit.com,
+ * Johan Knol johan.knol@iduna.nl
+ */
+
+/* This file is part of microcontroller simulator: ucsim.
+
+UCSIM 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.
+
+UCSIM 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 UCSIM; see the file COPYING. If not, write to the Free
+Software Foundation, 59 Temple Place - Suite 330, Boston, MA
+02111-1307, USA. */
+/*@1@*/
+
+#include <stdio.h>
+
+#include "stypes.h"
+#include "glob.h"
+
+/* this needs to match enum definition in glob.h */
+const char *op_mnemonic_str[] = {
+"BAD_OPCODE",
+"ADD",
+"ADDC",
+"ADDS",
+"AND",
+"ANL",
+"ASL",
+"ASR",
+"BCC",
+"BCS",
+"BEQ",
+"BG",
+"BGE",
+"BGT",
+"BKPT",
+"BL",
+"BLE",
+"BLT",
+"BMI",
+"BNE",
+"BNV",
+"BOV",
+"BPL",
+"BR",
+"CALL",
+"CJNE",
+"CLR",
+"CMP",
+"CPL",
+"DA",
+"DIV_w",
+"DIV_d",
+"DIVU_b",
+"DIVU_w",
+"DIVU_d",
+"DJNZ",
+"FCALL",
+"FJMP",
+"JB",
+"JBC",
+"JMP",
+"JNB",
+"JNZ",
+"JZ",
+"LEA",
+"LSR",
+"MOV",
+"MOVC",
+"MOVS",
+"MOVX",
+"MUL_w",
+"MULU_b",
+"MULU_w",
+"NEG",
+"NOP",
+"NORM",
+"OR",
+"ORL",
+"POP",
+"POPU",
+"PUSH",
+"PUSHU",
+"RESET",
+"RET",
+"RETI",
+"RL",
+"RLC",
+"RR",
+"RRC",
+"SETB",
+"SEXT",
+"SUB",
+"SUBB",
+"TRAP",
+"XCH",
+"XOR",
+};
+
+/* this is junk, but we need to keep it until main ucSim code
+ is cleaned of dis_entry[] references. */
+struct dis_entry glob_disass_xa[]= {
+ { 0x0000, 0x00ff, ' ', 1, "nop" },
+ { 0x0000, 0x00, 0, 0, NULL}
+};
+
+/* plan: keep this list in same order as in User Guide(pg 106)
+ until all op-codes are defined. Figure out how to make simulation
+ lookup fast later. */
+struct xa_dis_entry disass_xa[]= {
+ {0,0x0100,0xf700,' ',2,ADD, REG_REG }, // ADD Rd, Rs 0 0 0 0 S 0 0 1 d d d d s s s s
+ {0,0x0200,0xf708,' ',2,ADD, REG_IREG }, // ADD Rd, [Rs] 0 0 0 0 S 0 1 0 d d d d 0 s s s
+ {0,0x0208,0xf708,' ',2,ADD, IREG_REG }, // ADD [Rd], Rs 0 0 0 0 S 0 1 0 s s s s 1 d d d
+ {0,0x0400,0xf708,' ',3,ADD, REG_IREGOFF8 }, // ADD Rd, [Rs+offset8] 0 0 0 0 S 1 0 0 d d d d 0 s s s
+ {0,0x0408,0xf708,' ',3,ADD, IREGOFF8_REG }, // ADD [Rd+offset8], Rs 0 0 0 0 S 1 0 0 s s s s 1 d d d
+ {0,0x0500,0xf708,' ',4,ADD, REG_IREGOFF16 }, // ADD Rd, [Rs+offset16] 0 0 0 0 S 1 0 1 d d d d 0 s s s
+ {0,0x0508,0xf708,' ',4,ADD, IREGOFF16_REG }, // ADD [Rd+offset16], Rs 0 0 0 0 S 1 0 1 s s s s 1 d d d
+ {0,0x0300,0xf708,' ',2,ADD, REG_IREGINC }, // ADD Rd, [Rs+] 0 0 0 0 S 0 1 1 d d d d 0 s s s
+ {0,0x0308,0xf708,' ',2,ADD, IREGINC_REG }, // ADD [Rd+], Rs 0 0 0 0 S 0 1 1 s s s s 1 d d d
+ {0,0x0608,0xf708,' ',3,ADD, DIRECT_REG }, // ADD direct, Rs 0 0 0 0 S 1 1 0 s s s s 1 x x x
+ {0,0x0600,0xf708,' ',3,ADD, REG_DIRECT }, // ADD Rd, direct 0 0 0 0 S 1 1 0 d d d d 0 x x x
+ {0,0x9100,0xff0f,' ',3,ADD, REG_DATA8 }, // ADD Rd, #data8 1 0 0 1 0 0 0 1 d d d d 0 0 0 0
+ {0,0x9900,0xff0f,' ',4,ADD, REG_DATA16 }, // ADD Rd, #data16 1 0 0 1 1 0 0 1 d d d d 0 0 0 0
+ {0,0x9200,0xff8f,' ',3,ADD, IREG_DATA8 }, // ADD [Rd], #data8 1 0 0 1 0 0 1 0 0 d d d 0 0 0 0
+ {0,0x9a00,0xff8f,' ',4,ADD, IREG_DATA16 }, // ADD [Rd], #data16 1 0 0 1 1 0 1 0 0 d d d 0 0 0 0
+ {0,0x9300,0xff8f,' ',3,ADD, IREGINC_DATA8 }, // ADD [Rd+], #data8 1 0 0 1 0 0 1 1 0 d d d 0 0 0 0
+ {0,0x9b00,0xff8f,' ',4,ADD, IREGINC_DATA16 }, // ADD [Rd+], #data16 1 0 0 1 1 0 1 1 0 d d d 0 0 0 0
+ {0,0x9400,0xff8f,' ',4,ADD, IREGOFF8_DATA8 }, // ADD [Rd+offset8], #data8 1 0 0 1 0 1 0 0 0 d d d 0 0 0 0
+ {0,0x9c00,0xff8f,' ',5,ADD, IREGOFF8_DATA16 }, // ADD [Rd+offset8], #data16 1 0 0 1 1 1 0 0 0 d d d 0 0 0 0
+ {0,0x9500,0xff8f,' ',5,ADD, IREGOFF16_DATA8 }, // ADD [Rd+offset16], #data8 1 0 0 1 0 1 0 1 0 d d d 0 0 0 0
+ {0,0x9d00,0xff8f,' ',6,ADD, IREGOFF16_DATA16}, // ADD [Rd+offset16], #data16 1 0 0 1 1 1 0 1 0 d d d 0 0 0 0
+ {0,0x9600,0xff8f,' ',4,ADD, DIRECT_DATA8 }, // ADD direct, #data8 1 0 0 1 0 1 1 0 0 b b b 0 0 0 0
+ {0,0x9e00,0xff8f,' ',5,ADD, DIRECT_DATA16 }, // ADD direct, #data16 1 0 0 1 1 1 1 0 0 b b b 0 0 0 0
+
+ {0,0x1100,0xf700,' ',2,ADDC,REG_REG }, //ADDC Rd, Rs 0 0 0 1 S 0 0 1 d d d d s s s s
+ {0,0x1200,0xf708,' ',2,ADDC,REG_IREG }, //ADDC Rd, [Rs] 0 0 0 1 S 0 1 0 d d d d 0 s s s
+ {0,0x1208,0xf708,' ',2,ADDC,IREG_REG }, //ADDC [Rd], Rs 0 0 0 1 S 0 1 0 s s s s 1 d d d
+ {0,0x1400,0xf708,' ',3,ADDC,REG_IREGOFF8 }, //ADDC Rd, [Rs+offset8] 0 0 0 1 S 1 0 0 d d d d 0 s s s
+ {0,0x1408,0xf708,' ',3,ADDC,IREGOFF8_REG }, //ADDC [Rd+offset8], Rs 0 0 0 1 S 1 0 0 s s s s 1 d d d
+ {0,0x1500,0xf708,' ',4,ADDC,REG_IREGOFF16 }, //ADDC Rd, [Rs+offset16] 0 0 0 1 S 1 0 1 d d d d 0 s s s
+ {0,0x1508,0xf708,' ',4,ADDC,IREGOFF16_REG }, //ADDC [Rd+offset16], Rs 0 0 0 1 S 1 0 1 s s s s 1 d d d
+ {0,0x1300,0xf708,' ',2,ADDC,REG_IREGINC }, //ADDC Rd, [Rs+] 0 0 0 1 S 0 1 1 d d d d 0 s s s
+ {0,0x1308,0xf708,' ',2,ADDC,IREGINC_REG }, //ADDC [Rd+], Rs 0 0 0 1 S 0 1 1 s s s s 1 d d d
+ {0,0x1608,0xf708,' ',3,ADDC,DIRECT_REG }, //ADDC direct, Rs 0 0 0 1 S 1 1 0 s s s s 1 x x x
+ {0,0x1600,0xf708,' ',3,ADDC,REG_DIRECT }, //ADDC Rd, direct 0 0 0 1 S 1 1 0 d d d d 0 x x x
+ {0,0x9101,0xff0f,' ',3,ADDC,REG_DATA8 }, //ADDC Rd, #data8 1 0 0 1 0 0 0 1 d d d d 0 0 0 1
+ {0,0x9901,0xff0f,' ',4,ADDC,REG_DATA16 }, //ADDC Rd, #data16 1 0 0 1 1 0 0 1 d d d d 0 0 0 1
+ {0,0x9201,0xff8f,' ',3,ADDC,IREG_DATA8 }, //ADDC [Rd], #data8 1 0 0 1 0 0 1 0 0 d d d 0 0 0 1
+ {0,0x9a01,0xff8f,' ',4,ADDC,IREG_DATA16 }, //ADDC [Rd], #data16 1 0 0 1 1 0 1 0 0 d d d 0 0 0 1
+ {0,0x9301,0xff8f,' ',3,ADDC,IREGINC_DATA8 }, //ADDC [Rd+], #data8 1 0 0 1 0 0 1 1 0 d d d 0 0 0 1
+ {0,0x9b01,0xff8f,' ',4,ADDC,IREGINC_DATA16 }, //ADDC [Rd+], #data16 1 0 0 1 1 0 1 1 0 d d d 0 0 0 1
+ {0,0x9401,0xff8f,' ',4,ADDC,IREGOFF8_DATA8 }, //ADDC [Rd+offset8], #data8 1 0 0 1 0 1 0 0 0 d d d 0 0 0 1
+ {0,0x9c01,0xff8f,' ',5,ADDC,IREGOFF8_DATA16 }, //ADDC [Rd+offset8], #data16 1 0 0 1 1 1 0 0 0 d d d 0 0 0 1
+ {0,0x9501,0xff8f,' ',5,ADDC,IREGOFF16_DATA8 }, //ADDC [Rd+offset16], #data8 1 0 0 1 0 1 0 1 0 d d d 0 0 0 1
+ {0,0x9d01,0xff8f,' ',6,ADDC,IREGOFF16_DATA16}, //ADDC [Rd+offset16], #data16 1 0 0 1 1 1 0 1 0 d d d 0 0 0 1
+ {0,0x9601,0xff8f,' ',4,ADDC,DIRECT_DATA8 }, //ADDC direct, #data8 1 0 0 1 0 1 1 0 0 b b b 0 0 0 1
+ {0,0x9e01,0xff8f,' ',5,ADDC,DIRECT_DATA16 }, //ADDC direct, #data16 1 0 0 1 1 1 1 0 0 b b b 0 0 0 1
+
+ {0,0x1408,0xf780,' ',2,ADDS, REG_DATA4 }, // ADDS Rd, #data4 1 0 1 0 S 0 0 1 d d d d #data4
+ {0,0x1408,0xf780,' ',2,ADDS, IREG_DATA4 }, // ADDS [Rd], #data4 1 0 1 0 S 0 1 0 0 d d d #data4
+ {0,0x1408,0xf780,' ',2,ADDS, IREGINC_DATA4 }, // ADDS [Rd+], #data4 1 0 1 0 S 0 1 1 0 d d d #data4
+ {0,0x1408,0xf780,' ',3,ADDS, IREGOFF8_DATA4 }, // ADDS [Rd+offset8], #data4 1 0 1 0 S 1 0 0 0 d d d #data4
+ {0,0x1408,0xf780,' ',4,ADDS, IREGOFF16_DATA4}, // ADDS [Rd+offset16], #data4 1 0 1 0 S 1 0 1 0 d d d #data4
+ {0,0x1408,0xf780,' ',3,ADDS, DIRECT_DATA4 }, // ADDS direct, #data4 1 0 1 0 S 1 1 0 0 x x x #data4
+
+ {0,0x5100,0xf700,' ',2, AND,REG_REG }, // AND Rd, Rs 0 1 0 1 S 0 0 1 d d d d s s s s
+ {0,0x5200,0xf708,' ',2, AND,REG_IREG }, // AND Rd, [Rs] 0 1 0 1 S 0 1 0 d d d d 0 s s s
+ {0,0x5208,0xf708,' ',2, AND,IREG_REG }, // AND [Rd], Rs 0 1 0 1 S 0 1 0 s s s s 1 d d d
+ {0,0x5400,0xf708,' ',3, AND,REG_IREGOFF8 }, // AND Rd, [Rs+offset8] 0 1 0 1 S 1 0 0 d d d d 0 s s s
+ {0,0x5408,0xf708,' ',3, AND,IREGOFF8_REG }, // AND [Rd+offset8], Rs 0 1 0 1 S 1 0 0 s s s s 1 d d d
+ {0,0x5500,0xf708,' ',4, AND,REG_IREGOFF16 }, // AND Rd, [Rs+offset16] 0 1 0 1 S 1 0 1 d d d d 0 s s s
+ {0,0x5508,0xf708,' ',4, AND,IREGOFF16_REG }, // AND [Rd+offset16], Rs 0 1 0 1 S 1 0 1 s s s s 1 d d d
+ {0,0x5300,0xf708,' ',2, AND,REG_IREGINC }, // AND Rd, [Rs+] 0 1 0 1 S 0 1 1 d d d d 0 s s s
+ {0,0x5308,0xf708,' ',2, AND,IREGINC_REG }, // AND [Rd+], Rs 0 1 0 1 S 0 1 1 s s s s 1 d d d
+ {0,0x5608,0xf708,' ',3, AND,DIRECT_REG }, // AND direct, Rs 0 1 0 1 S 1 1 0 s s s s 1 x x x
+ {0,0x5600,0xf708,' ',3, AND,REG_DIRECT }, // AND Rd, direct 0 1 0 1 S 1 1 0 d d d d 0 x x x
+ {0,0x9105,0xff0f,' ',3, AND,REG_DATA8 }, // AND Rd, #data8 1 0 0 1 0 0 0 1 d d d d 0 1 0 1
+ {0,0x9905,0xff0f,' ',4, AND,REG_DATA16 }, // AND Rd, #data16 1 0 0 1 1 0 0 1 d d d d 0 1 0 1
+ {0,0x9205,0xff8f,' ',3, AND,IREG_DATA8 }, // AND [Rd], #data8 1 0 0 1 0 0 1 0 0 d d d 0 1 0 1
+ {0,0x9a05,0xff8f,' ',4, AND,IREG_DATA16 }, // AND [Rd], #data16 1 0 0 1 1 0 1 0 0 d d d 0 1 0 1
+ {0,0x9305,0xff8f,' ',3, AND,IREGINC_DATA8 }, // AND [Rd+], #data8 1 0 0 1 0 0 1 1 0 d d d 0 1 0 1
+ {0,0x9b05,0xff8f,' ',4, AND,IREGINC_DATA16 }, // AND [Rd+], #data16 1 0 0 1 1 0 1 1 0 d d d 0 1 0 1
+ {0,0x9405,0xff8f,' ',4, AND,IREGOFF8_DATA8 }, // AND [Rd+offset8], #data8 1 0 0 1 0 1 0 0 0 d d d 0 1 0 1
+ {0,0x9c05,0xff8f,' ',5, AND,IREGOFF8_DATA16 }, // AND [Rd+offset8], #data16 1 0 0 1 1 1 0 0 0 d d d 0 1 0 1
+ {0,0x9505,0xff8f,' ',5, AND,IREGOFF16_DATA8 }, // AND [Rd+offset16], #data8 1 0 0 1 0 1 0 1 0 d d d 0 1 0 1
+ {0,0x9d05,0xff8f,' ',6, AND,IREGOFF16_DATA16}, // AND [Rd+offset16], #data16 1 0 0 1 1 1 0 1 0 d d d 0 1 0 1
+ {0,0x9605,0xff8f,' ',4, AND,DIRECT_DATA8 }, // AND direct, #data8 1 0 0 1 0 1 1 0 0 b b b 0 1 0 1
+ {0,0x9e05,0xff8f,' ',5, AND,DIRECT_DATA16 }, // AND direct, #data16 1 0 0 1 0 1 1 0 1 b b b 0 1 0 1
+
+ {0,0x0840,0xfffc,' ',3,ANL, CY_BIT }, // ANL C, bit 0 0 0 0 1 0 0 0 0 1 0 0 0 0 b b lsbbit
+ {0,0x0850,0xfffc,' ',3,ANL, CY_NOTBIT }, // ANL C, /bit 0 0 0 0 1 0 0 0 0 1 0 1 0 0 b b lsbbit
+ {0,0xc150,0xf300,' ',2,ASL, REG_REG }, // ASL Rd, Rs 1 1 0 0 S S 0 1 d d d d s s s s
+ {0,0xdd00,0xff00,' ',2,ASL, REG_DATA5 }, // ASL Rd, #data5 (dword) 1 1 0 1 1 1 0 1 d d d #data5
+ {0,0xd100,0xf700,' ',2,ASL, REG_DATA4 }, // ASL Rd, #data4 1 1 0 1 S S 0 1 d d d d #data4
+ {0,0xc250,0xf300,' ',2,ASR, REG_REG }, // ASR Rd, Rs 1 1 0 0 S S 1 0 d d d d s s s s
+ {0,0xde00,0xff00,' ',2,ASR, REG_DATA5 }, // ASR Rd, #data5 (dword) 1 1 0 1 1 1 1 0 d d d #data5
+ {0,0xd200,0xf700,' ',2,ASR, REG_DATA4 }, // ASR Rd, #data4 1 1 0 1 S S 1 0 d d d d #data4
+ {1,0xf000,0xff00,' ',2,BCC, REL8 }, // BCC rel8 1 1 1 1 0 0 0 0 rel8
+ {1,0xf100,0xff00,' ',2,BCS, REL8 }, // BCS rel8 1 1 1 1 0 0 0 1 rel8
+ {1,0xf300,0xff00,' ',2,BEQ, REL8 }, // BEQ rel8 1 1 1 1 0 0 1 1 rel8
+ {1,0xf800,0xff00,' ',2,BG, REL8 }, // BG rel8 1 1 1 1 1 0 0 0 rel8
+ {1,0xfa00,0xff00,' ',2,BGE, REL8 }, // BGE rel8 1 1 1 1 1 0 1 0 rel8
+ {1,0xfc00,0xff00,' ',2,BGT, REL8 }, // BGT rel8 1 1 1 1 1 1 0 0 rel8
+
+ {1,0xff00,0xff00,' ',1,BKPT, NO_OPERANDS }, // BKPT 1 1 1 1 1 1 1 1
+
+ {1,0xf900,0xff00,' ',2,BL, REL8 }, // BL rel8 1 1 1 1 1 0 0 1 rel8
+ {1,0xfd00,0xff00,' ',2,BLE, REL8 }, // BLE rel8 1 1 1 1 1 1 0 1 rel8
+ {1,0xfb00,0xff00,' ',2,BLT, REL8 }, // BLT rel8 1 1 1 1 1 0 1 1 rel8
+ {1,0xf700,0xff00,' ',2,BMI, REL8 }, // BMI rel8 1 1 1 1 0 1 1 1 rel8
+ {1,0xf200,0xff00,' ',2,BNE, REL8 }, // BNE rel8 1 1 1 1 0 0 1 0 rel8
+ {1,0xf400,0xff00,' ',2,BNV, REL8 }, // BNV rel8 1 1 1 1 0 1 0 0 rel8
+ {1,0xf500,0xff00,' ',2,BOV, REL8 }, // BOV rel8 1 1 1 1 0 1 0 1 rel8
+ {1,0xf600,0xff00,' ',2,BPL, REL8 }, // BPL rel8 1 1 1 1 0 1 1 0 rel8
+ {1,0xfe00,0xff00,' ',2,BR, REL8 }, // BR rel8 1 1 1 1 1 1 1 0 rel8
+
+ {1,0xc500,0xff00,'a',3,CALL, REL16 }, // CALL rel16 1 1 0 0 0 1 0 1 rel16
+ {0,0xc600,0xfff8,'a',2,CALL, IREG }, // CALL [Rs] 1 1 0 0 0 1 1 0 0 0 0 0 0 s s s
+
+ {0,0xe200,0xf708,' ',4,CJNE, REG_DIRECT_REL8}, // CJNE Rd, direct, rel8 1 1 1 0 S 0 1 0 d d d d 0 x x x
+ {0,0xe300,0xff0f,' ',4,CJNE, REG_DATA8_REL8}, // CJNE Rd, data8, rel8 1 1 1 0 0 0 1 1 d d d d 0 0 0 0
+ {0,0xeb00,0xff0f,' ',5,CJNE, REG_DATA16_REL8}, // CJNE Rd, data16, rel8 1 1 1 0 1 0 1 1 d d d d 0 0 0 0
+ {0,0xe308,0xff8f,' ',4,CJNE, IREG_DATA8_REL8}, // CJNE [Rd], data8, rel8 1 1 1 0 0 0 1 1 0 d d d 1 0 0 0
+ {0,0xeb08,0xff8f,' ',5,CJNE, IREG_DATA16_REL8},// CJNE [Rd], data16, rel8 1 1 1 0 1 0 1 1 0 d d d 1 0 0 0
+
+ {0,0x0800,0xfffc,' ',3,CLR, BIT_ALONE }, // CLR bit 0 0 0 0 1 0 0 0 0 0 0 0 0 0 b b
+ {0,0x4100,0xf700,' ',2,CMP, REG_REG }, // CMP Rd, Rs 0 1 0 0 S 0 0 1 d d d d s s s s
+ {0,0x4200,0xf708,' ',2,CMP, REG_IREG }, // CMP Rd, [Rs] 0 1 0 0 S 0 1 0 d d d d 0 s s s
+ {0,0x4208,0xf708,' ',2,CMP, IREG_REG }, // CMP [Rd], Rs 0 1 0 0 S 0 1 0 s s s s 1 d d d
+ {0,0x4400,0xf708,' ',3,CMP, REG_IREGOFF8 }, // CMP Rd, [Rs+offset8] 0 1 0 0 S 1 0 0 d d d d 0 s s s
+ {0,0x4408,0xf708,' ',3,CMP, IREGOFF8_REG }, // CMP [Rd+offset8], Rs 0 1 0 0 S 1 0 0 s s s s 1 d d d
+ {0,0x4500,0xf708,' ',4,CMP, REG_IREGOFF16 }, // CMP Rd, [Rs+offset16] 0 1 0 0 S 1 0 1 d d d d 0 s s s
+ {0,0x4508,0xf708,' ',4,CMP, IREGOFF16_REG }, // CMP [Rd+offset16], Rs 0 1 0 0 S 1 0 1 s s s s 1 d d d
+ {0,0x4300,0xf708,' ',2,CMP, REG_IREGINC }, // CMP Rd, [Rs+] 0 1 0 0 S 0 1 1 d d d d 0 s s s
+ {0,0x4308,0xf708,' ',2,CMP, IREGINC_REG }, // CMP [Rd+], Rs 0 1 0 0 S 0 1 1 s s s s 1 d d d
+ {0,0x4608,0xf708,' ',3,CMP, DIRECT_REG }, // CMP direct, Rs 0 1 0 0 S 1 1 0 s s s s 1 x x x
+ {0,0x4600,0xf708,' ',3,CMP, REG_DIRECT }, // CMP Rd, direct 0 1 0 0 S 1 1 0 d d d d 0 x x x
+ {0,0x9104,0xff0f,' ',3,CMP, REG_DATA8 }, // CMP Rd, #data8 1 0 0 1 0 0 0 1 d d d d 0 1 0 0
+ {0,0x9904,0xff0f,' ',4,CMP, REG_DATA16 }, // CMP Rd, #data16 1 0 0 1 1 0 0 1 d d d d 0 1 0 0
+ {0,0x9204,0xff8f,' ',3,CMP, IREG_DATA8 }, // CMP [Rd], #data8 1 0 0 1 0 0 1 0 0 d d d 0 1 0 0
+ {0,0x9a04,0xff8f,' ',4,CMP, IREG_DATA16 }, // CMP [Rd], #data16 1 0 0 1 1 0 1 0 0 d d d 0 1 0 0
+ {0,0x9304,0xff8f,' ',3,CMP, IREGINC_DATA8 }, // CMP [Rd+], #data8 1 0 0 1 0 0 1 1 0 d d d 0 1 0 0
+ {0,0x9b04,0xff8f,' ',4,CMP, IREGINC_DATA16 }, // CMP [Rd+], #data16 1 0 0 1 1 0 1 1 0 d d d 0 1 0 0
+ {0,0x9404,0xff8f,' ',4,CMP, IREGOFF8_DATA8 }, // CMP [Rd+offset8], #data8 1 0 0 1 0 1 0 0 0 d d d 0 1 0 0
+ {0,0x9c04,0xff8f,' ',5,CMP, IREGOFF8_DATA16 }, // CMP [Rd+offset8], #data16 1 0 0 1 1 1 0 0 0 d d d 0 1 0 0
+ {0,0x9504,0xff8f,' ',5,CMP, IREGOFF16_DATA8 }, // CMP [Rd+offset16], #data8 1 0 0 1 0 1 0 1 0 d d d 0 1 0 0
+ {0,0x9d04,0xff8f,' ',6,CMP, IREGOFF16_DATA16}, // CMP [Rd+offset16], #data16 1 0 0 1 1 1 0 1 0 d d d 0 1 0 0
+ {0,0x9604,0xff8f,' ',4,CMP, DIRECT_DATA8 }, // CMP direct, #data8 1 0 0 1 0 1 1 0 0 b b b 0 1 0 0
+ {0,0x9e04,0xff8f,' ',5,CMP, DIRECT_DATA16 }, // CMP direct, #data16 1 0 0 1 0 1 1 0 0 b b b 0 1 0 0
+ {0,0x900c,0xf70f,' ',2,CPL, REG }, // CPL Rd 1 0 0 1 S 0 0 0 d d d d 1 0 1 0
+ {0,0x9008,0xff0f,' ',2,DA, REG }, // DA Rd 1 0 0 1 0 0 0 0 d d d d 1 0 0 0
+ {0,0xe708,0xff00,' ',2,DIV_w, REG_REG }, // DIV.w Rd, Rs 1 1 1 0 0 1 1 1 d d d d s s s s
+ {0,0xe80b,0xff0f,' ',3,DIV_w, REG_DATA8 }, // DIV.w Rd, #data8 1 1 1 0 1 0 0 0 d d d d 1 0 1 1
+ {0,0xef00,0xff10,' ',2,DIV_d, REG_REG }, // DIV.d Rd, Rs 1 1 1 0 1 1 1 1 d d d 0 s s s s
+ {0,0xe909,0xff1f,' ',4,DIV_d, REG_DATA16 }, // DIV.d Rd, #data16 1 1 1 0 1 0 0 1 d d d 0 1 0 0 1
+ {0,0xe101,0xff00,' ',3,DIVU_b, REG_REG }, // DIVU.b Rd, Rs 1 1 1 0 0 0 0 1 d d d d s s s s
+ {0,0xe801,0xff0f,' ',3,DIVU_b, REG_DATA8 }, // DIVU.b Rd, #data8 1 1 1 0 1 0 0 0 d d d d 0 0 0 1
+ {0,0xe500,0xff00,' ',2,DIVU_w, REG_REG }, // DIVU.w Rd, Rs 1 1 1 0 0 1 0 1 d d d d s s s s
+ {0,0xe803,0xff0f,' ',3,DIVU_w, REG_DATA8 }, // DIVU.w Rd, #data8 1 1 1 0 1 0 0 0 d d d d 0 0 1 1
+ {0,0xed00,0xff10,' ',2,DIVU_d, REG_REG }, // DIVU.d Rd, Rs 1 1 1 0 1 1 0 1 d d d 0 s s s s
+ {0,0xe901,0xff1f,' ',4,DIVU_d, REG_DATA16 }, // DIVU.d Rd, #data16 1 1 1 0 1 0 0 1 d d d 0 0 0 0 1
+
+ {0,0x8708,0xf70f,' ',3,DJNZ, REG_REL8 }, // DJNZ Rd, rel8 1 0 0 0 S 1 1 1 d d d d 1 0 0 0
+ {0,0xe208,0xf7f8,' ',4,DJNZ, DIRECT_REL8 }, // DJNZ direct, rel8 1 1 1 0 S 0 1 0 0 0 0 0 1 x x x
+
+ {1,0xc400,0xff00,' ',4,FCALL, ADDR24 }, // FCALL addr24 1 1 0 0 0 1 0 0
+ {1,0xd400,0xff00,' ',4,FJMP, ADDR24 }, // FJMP addr24 1 1 0 1 0 1 0 0
+
+ {0,0x9780,0xfffc,' ',4, JB, BIT_REL8 }, // JB bit,rel8 1 0 0 1 0 1 1 1 1 0 0 0 0 0 b b
+ {0,0x97c0,0xfffc,' ',4, JBC, BIT_REL8 }, // JBC bit,rel8 1 0 0 1 0 1 1 1 1 1 0 0 0 0 b b
+ {1,0xd500,0xff00,' ',3, JMP, REL16 }, // JMP rel16 1 1 0 1 0 1 0 1 rel16
+ {0,0xd670,0xfff8,' ',2, JMP, IREG }, // JMP [Rs] 1 1 0 1 0 1 1 0 0 1 1 1 0 s s s
+ {0,0xd646,0xffff,' ',2, JMP, A_PLUSDPTR }, // JMP [A+dptr] 1 1 0 1 0 1 1 0 0 1 0 0 0 1 1 0
+ {0,0xd660,0xfff8,' ',2, JMP, IIREG }, // JMP [[Rs+]] 1 1 0 1 0 1 1 0 0 1 1 0 0 s s s
+
+ {0,0x97a0,0xfffc,' ',4, JNB, BIT_REL8 }, // JNB bit,rel8 1 0 0 1 0 1 1 1 1 0 1 0 0 0 b b
+ {1,0xee00,0xff00,' ',2, JNZ, REL8 }, // JNZ rel8 1 1 1 0 1 1 1 0 rel8
+ {1,0xec00,0xff00,' ',2, JZ, REL8 }, // JZ rel8 1 1 1 0 1 1 0 0 rel8
+ {0,0x4000,0xff88,' ',3, LEA, REG_REGOFF8 }, // LEA Rd,Rs+offset8 0 1 0 0 0 0 0 0 0 d d d 0 s s s
+ {0,0x4800,0xff88,' ',3, LEA, REG_REGOFF16 }, // LEA Rd,Rs+offset16 0 1 0 0 0 0 0 0 0 d d d 0 s s s
+ /* LSR(3?) */
+
+ {0,0x8100,0xf700,' ',2,MOV, REG_REG }, // MOV Rd, Rs 1 0 0 0 S 0 0 1 d d d d s s s s
+ {0,0x8200,0xf708,' ',2,MOV, REG_IREG }, // MOV Rd, [Rs] 1 0 0 0 S 0 1 0 d d d d 0 s s s
+ {0,0x8208,0xf708,' ',2,MOV, IREG_REG }, // MOV [Rd], Rs 1 0 0 0 S 0 1 0 s s s s 1 d d d
+ {0,0x8400,0xf708,' ',3,MOV, REG_IREGOFF8 }, // MOV Rd, [Rs+offset8] 1 0 0 0 S 1 0 0 d d d d 0 s s s
+ {0,0x8408,0xf708,' ',3,MOV, IREGOFF8_REG }, // MOV [Rd+offset8], Rs 1 0 0 0 S 1 0 0 s s s s 1 d d d
+ {0,0x8500,0xf708,' ',4,MOV, REG_IREGOFF16 }, // MOV Rd, [Rs+offset16] 1 0 0 0 S 1 0 1 d d d d 0 s s s
+ {0,0x8508,0xf708,' ',4,MOV, IREGOFF16_REG }, // MOV [Rd+offset16], Rs 1 0 0 0 S 1 0 1 s s s s 1 d d d
+ {0,0x8300,0xf708,' ',2,MOV, REG_IREGINC }, // MOV Rd, [Rs+] 1 0 0 0 S 0 1 1 d d d d 0 s s s
+ {0,0x8308,0xf708,' ',2,MOV, IREGINC_REG }, // MOV [Rd+], Rs 1 0 0 0 S 0 1 1 s s s s 1 d d d
+ {0,0x8608,0xf708,' ',3,MOV, DIRECT_REG }, // MOV direct, Rs 1 0 0 0 S 1 1 0 s s s s 1 x x x
+ {0,0x8600,0xf708,' ',3,MOV, REG_DIRECT }, // MOV Rd, direct 1 0 0 0 S 1 1 0 d d d d 0 x x x
+ {0,0x9108,0xff0f,' ',3,MOV, REG_DATA8 }, // MOV Rd, #data8 1 0 0 1 0 0 0 1 d d d d 1 0 0 0
+ {0,0x9908,0xff0f,' ',4,MOV, REG_DATA16 }, // MOV Rd, #data16 1 0 0 1 1 0 0 1 d d d d 1 0 0 0
+ {0,0x9208,0xff8f,' ',3,MOV, IREG_DATA8 }, // MOV [Rd], #data8 1 0 0 1 0 0 1 0 0 d d d 1 0 0 0
+ {0,0x9a08,0xff8f,' ',4,MOV, IREG_DATA16 }, // MOV [Rd], #data16 1 0 0 1 1 0 1 0 0 d d d 1 0 0 0
+ {0,0x9308,0xff8f,' ',3,MOV, IREGINC_DATA8 }, // MOV [Rd+], #data8 1 0 0 1 0 0 1 1 0 d d d 1 0 0 0
+ {0,0x9b08,0xff8f,' ',4,MOV, IREGINC_DATA16 }, // MOV [Rd+], #data16 1 0 0 1 1 0 1 1 0 d d d 1 0 0 0
+ {0,0x9408,0xff8f,' ',4,MOV, IREGOFF8_DATA8 }, // MOV [Rd+offset8], #data8 1 0 0 1 0 1 0 0 0 d d d 1 0 0 0
+ {0,0x9c08,0xff8f,' ',5,MOV, IREGOFF8_DATA16 }, // MOV [Rd+offset8], #data16 1 0 0 1 1 1 0 0 0 d d d 1 0 0 0
+ {0,0x9508,0xff8f,' ',5,MOV, IREGOFF16_DATA8 }, // MOV [Rd+offset16], #data8 1 0 0 1 0 1 0 1 0 d d d 1 0 0 0
+ {0,0x9d08,0xff8f,' ',6,MOV, IREGOFF16_DATA16}, // MOV [Rd+offset16], #data16 1 0 0 1 1 1 0 1 0 d d d 1 0 0 0
+ {0,0x9608,0xff8f,' ',4,MOV, DIRECT_DATA8 }, // MOV direct, #data8 1 0 0 1 0 1 1 0 0 b b b 1 0 0 0
+ {0,0x9e08,0xff8f,' ',5,MOV, DIRECT_DATA16 }, // MOV direct, #data16 1 0 0 1 0 1 1 0 0 b b b 1 0 0 0
+ {0,0x9700,0xf788,' ',4,MOV, DIRECT_DIRECT }, // MOV direct, direct 1 0 0 1 S 1 1 1 0 d d d 0 d d d
+ {0,0x900f,0xff0f,' ',2,MOV, REG_USP }, // MOV Rd, USP 1 0 0 1 0 0 0 0 d d d d 1 1 1 1
+ {0,0x980f,0xff0f,' ',2,MOV, USP_REG }, // MOV USP, RS 1 0 0 1 0 0 0 0 s s s s 1 1 1 1
+ {0,0x0820,0xfffc,' ',3,MOV, CY_BIT }, // MOV C, bit 0 0 0 0 1 0 0 0 0 0 1 0 0 0 b b
+ {0,0x0830,0xfffc,' ',3,MOV, BIT_CY }, // MOV bit, C 0 0 0 0 1 0 0 0 0 0 1 1 0 0 b b
+ {0,0x8000,0xf308,' ',2,MOVC, REG_IREGINC }, // MOVC Rd,[Rs+] 1 0 0 0 S 0 0 0 d d d d 0 s s s
+ {0,0x904e,0xffff,' ',2,MOVC, A_APLUSDPTR }, // MOVC A,[A+DPTR] 1 0 0 1 0 0 0 0 0 1 0 0 1 1 1 0
+ {0,0x904c,0xffff,' ',2,MOVC, A_APLUSPC }, // MOVC A,[A+PC] 1 0 0 1 0 0 0 0 0 1 0 0 1 1 0 0
+ /* MOVS(6), MOVX(2), MUL.x(6) */
+
+ {0,0x900b,0xf70f,' ',2,NEG, REG }, // NEG Rd 1 0 0 1 S 0 0 0 d d d d 1 0 1 1
+ {1,0x0000,0xff00,' ',1,NOP, NO_OPERANDS }, // NOP 0 0 0 0 0 0 0 0
+ {0,0xc300,0xff00,' ',2,NORM, REG_REG }, // NORM Rd,Rs 1 1 0 0 S S 1 1 d d d d s s s s
+ {0,0x6100,0xf700,' ',2, OR, REG_REG }, // OR Rd, Rs 0 1 1 0 S 0 0 1 d d d d s s s s
+ {0,0x6200,0xf708,' ',2, OR, REG_IREG }, // OR Rd, [Rs] 0 1 1 0 S 0 1 0 d d d d 0 s s s
+ {0,0x6208,0xf708,' ',2, OR, IREG_REG }, // OR [Rd], Rs 0 1 1 0 S 0 1 0 s s s s 1 d d d
+ {0,0x6400,0xf708,' ',3, OR, REG_IREGOFF8 }, // OR Rd, [Rs+offset8] 0 1 1 0 S 1 0 0 d d d d 0 s s s
+ {0,0x6408,0xf708,' ',3, OR, IREGOFF8_REG }, // OR [Rd+offset8], Rs 0 1 1 0 S 1 0 0 s s s s 1 d d d
+ {0,0x6500,0xf708,' ',4, OR, REG_IREGOFF16 }, // OR Rd, [Rs+offset16] 0 1 1 0 S 1 0 1 d d d d 0 s s s
+ {0,0x6508,0xf708,' ',4, OR, IREGOFF16_REG }, // OR [Rd+offset16], Rs 0 1 1 0 S 1 0 1 s s s s 1 d d d
+ {0,0x6300,0xf708,' ',2, OR, REG_IREGINC }, // OR Rd, [Rs+] 0 1 1 0 S 0 1 1 d d d d 0 s s s
+ {0,0x6308,0xf708,' ',2, OR, IREGINC_REG }, // OR [Rd+], Rs 0 1 1 0 S 0 1 1 s s s s 1 d d d
+ {0,0x6608,0xf708,' ',3, OR, DIRECT_REG }, // OR direct, Rs 0 1 1 0 S 1 1 0 s s s s 1 x x x
+ {0,0x6600,0xf708,' ',3, OR, REG_DIRECT }, // OR Rd, direct 0 1 1 0 S 1 1 0 d d d d 0 x x x
+ {0,0x9106,0xff0f,' ',3, OR, REG_DATA8 }, // OR Rd, #data8 1 0 0 1 0 0 0 1 d d d d 0 1 1 0
+ {0,0x9906,0xff0f,' ',4, OR, REG_DATA16 }, // OR Rd, #data16 1 0 0 1 1 0 0 1 d d d d 0 1 1 0
+ {0,0x9206,0xff8f,' ',3, OR, IREG_DATA8 }, // OR [Rd], #data8 1 0 0 1 0 0 1 0 0 d d d 0 1 1 0
+ {0,0x9a06,0xff8f,' ',4, OR, IREG_DATA16 }, // OR [Rd], #data16 1 0 0 1 1 0 1 0 0 d d d 0 1 1 0
+ {0,0x9306,0xff8f,' ',3, OR, IREGINC_DATA8 }, // OR [Rd+], #data8 1 0 0 1 0 0 1 1 0 d d d 0 1 1 0
+ {0,0x9b06,0xff8f,' ',4, OR, IREGINC_DATA16 }, // OR [Rd+], #data16 1 0 0 1 1 0 1 1 0 d d d 0 1 1 0
+ {0,0x9406,0xff8f,' ',4, OR, IREGOFF8_DATA8 }, // OR [Rd+offset8], #data8 1 0 0 1 0 1 0 0 0 d d d 0 1 1 0
+ {0,0x9c06,0xff8f,' ',5, OR, IREGOFF8_DATA16 }, // OR [Rd+offset8], #data16 1 0 0 1 1 1 0 0 0 d d d 0 1 1 0
+ {0,0x9506,0xff8f,' ',5, OR, IREGOFF16_DATA8 }, // OR [Rd+offset16], #data8 1 0 0 1 0 1 0 1 0 d d d 0 1 1 0
+ {0,0x9d06,0xff8f,' ',6, OR, IREGOFF16_DATA16}, // OR [Rd+offset16], #data16 1 0 0 1 1 1 0 1 0 d d d 0 1 1 0
+ {0,0x9606,0xff8f,' ',4, OR, DIRECT_DATA8 }, // OR direct, #data8 1 0 0 1 0 1 1 0 0 b b b 0 1 1 0
+ {0,0x9e06,0xff8f,' ',5, OR, DIRECT_DATA16 }, // OR direct, #data16 1 0 0 1 0 1 1 0 0 b b b 0 1 1 0
+ {0,0x0860,0xfffc,' ',3, ORL, CY_BIT }, // ORL C, bit 0 0 0 0 1 0 0 0 0 1 1 0 0 0 b b
+ {0,0x0870,0xfffc,' ',3, ORL, CY_NOTBIT }, // ORL C, /bit 0 0 0 0 1 0 0 0 0 1 1 1 0 0 b b
+ {0,0x8710,0xf7f8,' ',3, POP, DIRECT }, // POP direct 1 0 0 0 S 1 1 1 0 0 0 1 0 d d d
+ {1,0x2700,0xb700,' ',2, POP, RLIST }, // POP Rlist 0 H 1 0 S 1 1 1 rlist
+ {0,0x8700,0xf7f8,' ',3, POPU, DIRECT }, // POPU direct 1 0 0 0 S 1 1 1 0 0 0 0 0 d d d
+ {1,0x3700,0xb700,' ',2, POPU, RLIST }, // POPU Rlist 0 H 1 1 S 1 1 1 rlist
+ {0,0x8730,0xf7f8,' ',3, PUSH, DIRECT }, // PUSH direct 1 0 0 0 S 1 1 1 0 0 1 1 0 d d d
+ {1,0x0700,0xb700,' ',2, PUSH, RLIST }, // PUSH Rlist 0 H 0 0 S 1 1 1 rlist
+ {0,0x8720,0xf7f8,' ',3, PUSHU, DIRECT }, // PUSHU direct 1 0 0 0 S 1 1 1 0 0 1 0 0 d d d
+ {1,0x1700,0xb700,' ',2, PUSHU, RLIST }, // PUSHU Rlist 0 H 0 1 S 1 1 1 rlist
+
+ {0,0xd610,0xffff,' ',2, RESET, NO_OPERANDS }, // RESET 1 1 0 1 0 1 1 0 0 0 0 1 0 0 0 0
+ {0,0xd680,0xffff,' ',2, RET, NO_OPERANDS }, // RET 1 1 0 1 0 1 1 0 1 0 0 0 0 0 0 0
+ {0,0xd690,0xffff,' ',2, RETI, NO_OPERANDS }, // RETI 1 1 0 1 0 1 1 0 1 0 0 1 0 0 0 0
+ /* RL, RLC, RR, RRC */
+ {0,0x0810,0xfffc,' ',3, SETB, BIT_ALONE }, // SETB bit 0 0 0 0 1 0 0 0 0 0 0 1 0 0 b b
+ {0,0x9009,0xf70f,' ',2, SEXT, REG }, // SEXT Rd 1 0 0 1 S 0 0 0 d d d d 1 0 0 1
+ {0,0x2100,0xf700,' ',2,SUB, REG_REG }, // SUB Rd, Rs 0 0 1 0 S 0 0 1 d d d d s s s s
+ {0,0x2200,0xf708,' ',2,SUB, REG_IREG }, // SUB Rd, [Rs] 0 0 1 0 S 0 1 0 d d d d 0 s s s
+ {0,0x2208,0xf708,' ',2,SUB, IREG_REG }, // SUB [Rd], Rs 0 0 1 0 S 0 1 0 s s s s 1 d d d
+ {0,0x2400,0xf708,' ',3,SUB, REG_IREGOFF8 }, // SUB Rd, [Rs+offset8] 0 0 1 0 S 1 0 0 d d d d 0 s s s
+ {0,0x2408,0xf708,' ',3,SUB, IREGOFF8_REG }, // SUB [Rd+offset8], Rs 0 0 1 0 S 1 0 0 s s s s 1 d d d
+ {0,0x2500,0xf708,' ',4,SUB, REG_IREGOFF16 }, // SUB Rd, [Rs+offset16] 0 0 1 0 S 1 0 1 d d d d 0 s s s
+ {0,0x2508,0xf708,' ',4,SUB, IREGOFF16_REG }, // SUB [Rd+offset16], Rs 0 0 1 0 S 1 0 1 s s s s 1 d d d
+ {0,0x2300,0xf708,' ',2,SUB, REG_IREGINC }, // SUB Rd, [Rs+] 0 0 1 0 S 0 1 1 d d d d 0 s s s
+ {0,0x2308,0xf708,' ',2,SUB, IREGINC_REG }, // SUB [Rd+], Rs 0 0 1 0 S 0 1 1 s s s s 1 d d d
+ {0,0x2608,0xf708,' ',3,SUB, DIRECT_REG }, // SUB direct, Rs 0 0 1 0 S 1 1 0 s s s s 1 x x x
+ {0,0x2600,0xf708,' ',3,SUB, REG_DIRECT }, // SUB Rd, direct 0 0 1 0 S 1 1 0 d d d d 0 x x x
+ {0,0x9102,0xff0f,' ',3,SUB, REG_DATA8 }, // SUB Rd, #data8 1 0 0 1 0 0 0 1 d d d d 0 0 1 0
+ {0,0x9902,0xff0f,' ',4,SUB, REG_DATA16 }, // SUB Rd, #data16 1 0 0 1 1 0 0 1 d d d d 0 0 1 0
+ {0,0x9202,0xff8f,' ',3,SUB, IREG_DATA8 }, // SUB [Rd], #data8 1 0 0 1 0 0 1 0 0 d d d 0 0 1 0
+ {0,0x9a02,0xff8f,' ',4,SUB, IREG_DATA16 }, // SUB [Rd], #data16 1 0 0 1 1 0 1 0 0 d d d 0 0 1 0
+ {0,0x9302,0xff8f,' ',3,SUB, IREGINC_DATA8 }, // SUB [Rd+], #data8 1 0 0 1 0 0 1 1 0 d d d 0 0 1 0
+ {0,0x9b02,0xff8f,' ',4,SUB, IREGINC_DATA16 }, // SUB [Rd+], #data16 1 0 0 1 1 0 1 1 0 d d d 0 0 1 0
+ {0,0x9402,0xff8f,' ',4,SUB, IREGOFF8_DATA8 }, // SUB [Rd+offset8], #data8 1 0 0 1 0 1 0 0 0 d d d 0 0 1 0
+ {0,0x9c02,0xff8f,' ',5,SUB, IREGOFF8_DATA16 }, // SUB [Rd+offset8], #data16 1 0 0 1 1 1 0 0 0 d d d 0 0 1 0
+ {0,0x9502,0xff8f,' ',5,SUB, IREGOFF16_DATA8 }, // SUB [Rd+offset16], #data8 1 0 0 1 0 1 0 1 0 d d d 0 0 1 0
+ {0,0x9d02,0xff8f,' ',6,SUB, IREGOFF16_DATA16}, // SUB [Rd+offset16], #data16 1 0 0 1 1 1 0 1 0 d d d 0 0 1 0
+ {0,0x9602,0xff8f,' ',4,SUB, DIRECT_DATA8 }, // SUB direct, #data8 1 0 0 1 0 1 1 0 0 b b b 0 0 1 0
+ {0,0x9e02,0xff8f,' ',5,SUB, DIRECT_DATA16 }, // SUB direct, #data16 1 0 0 1 0 1 1 0 0 b b b 0 0 1 0
+
+ {0,0x3100,0xf700,' ',2,SUBB,REG_REG }, //SUBB Rd, Rs 0 0 1 1 S 0 0 1 d d d d s s s s
+ {0,0x3200,0xf708,' ',2,SUBB,REG_IREG }, //SUBB Rd, [Rs] 0 0 1 1 S 0 1 0 d d d d 0 s s s
+ {0,0x3208,0xf708,' ',2,SUBB,IREG_REG }, //SUBB [Rd], Rs 0 0 1 1 S 0 1 0 s s s s 1 d d d
+ {0,0x3400,0xf708,' ',3,SUBB,REG_IREGOFF8 }, //SUBB Rd, [Rs+offset8] 0 0 1 1 S 1 0 0 d d d d 0 s s s
+ {0,0x3408,0xf708,' ',3,SUBB,IREGOFF8_REG }, //SUBB [Rd+offset8], Rs 0 0 1 1 S 1 0 0 s s s s 1 d d d
+ {0,0x3500,0xf708,' ',4,SUBB,REG_IREGOFF16 }, //SUBB Rd, [Rs+offset16] 0 0 1 1 S 1 0 1 d d d d 0 s s s
+ {0,0x3508,0xf708,' ',4,SUBB,IREGOFF16_REG }, //SUBB [Rd+offset16], Rs 0 0 1 1 S 1 0 1 s s s s 1 d d d
+ {0,0x3300,0xf708,' ',2,SUBB,REG_IREGINC }, //SUBB Rd, [Rs+] 0 0 1 1 S 0 1 1 d d d d 0 s s s
+ {0,0x3308,0xf708,' ',2,SUBB,IREGINC_REG }, //SUBB [Rd+], Rs 0 0 1 1 S 0 1 1 s s s s 1 d d d
+ {0,0x3608,0xf708,' ',3,SUBB,DIRECT_REG }, //SUBB direct, Rs 0 0 1 1 S 1 1 0 s s s s 1 x x x
+ {0,0x3600,0xf708,' ',3,SUBB,REG_DIRECT }, //SUBB Rd, direct 0 0 1 1 S 1 1 0 d d d d 0 x x x
+ {0,0x9103,0xff0f,' ',3,SUBB,REG_DATA8 }, //SUBB Rd, #data8 1 0 0 1 0 0 0 1 d d d d 0 0 1 1
+ {0,0x9903,0xff0f,' ',4,SUBB,REG_DATA16 }, //SUBB Rd, #data16 1 0 0 1 1 0 0 1 d d d d 0 0 1 1
+ {0,0x9203,0xff8f,' ',3,SUBB,IREG_DATA8 }, //SUBB [Rd], #data8 1 0 0 1 0 0 1 0 0 d d d 0 0 1 1
+ {0,0x9a03,0xff8f,' ',4,SUBB,IREG_DATA16 }, //SUBB [Rd], #data16 1 0 0 1 1 0 1 0 0 d d d 0 0 1 1
+ {0,0x9303,0xff8f,' ',3,SUBB,IREGINC_DATA8 }, //SUBB [Rd+], #data8 1 0 0 1 0 0 1 1 0 d d d 0 0 1 1
+ {0,0x9b03,0xff8f,' ',4,SUBB,IREGINC_DATA16 }, //SUBB [Rd+], #data16 1 0 0 1 1 0 1 1 0 d d d 0 0 1 1
+ {0,0x9403,0xff8f,' ',4,SUBB,IREGOFF8_DATA8 }, //SUBB [Rd+offset8], #data8 1 0 0 1 0 1 0 0 0 d d d 0 0 1 1
+ {0,0x9c03,0xff8f,' ',5,SUBB,IREGOFF8_DATA16 }, //SUBB [Rd+offset8], #data16 1 0 0 1 1 1 0 0 0 d d d 0 0 1 1
+ {0,0x9503,0xff8f,' ',5,SUBB,IREGOFF16_DATA8 }, //SUBB [Rd+offset16], #data8 1 0 0 1 0 1 0 1 0 d d d 0 0 1 1
+ {0,0x9d03,0xff8f,' ',6,SUBB,IREGOFF16_DATA16}, //SUBB [Rd+offset16], #data16 1 0 0 1 1 1 0 1 0 d d d 0 0 1 1
+ {0,0x9603,0xff8f,' ',4,SUBB,DIRECT_DATA8 }, //SUBB direct, #data8 1 0 0 1 0 1 1 0 0 b b b 0 0 1 1
+ {0,0x9e03,0xff8f,' ',5,SUBB,DIRECT_DATA16 }, //SUBB direct, #data16 1 0 0 1 0 1 1 0 0 b b b 0 0 1 1
+ {0,0xd630,0xfff0,' ',2,TRAP,DATA4 }, //TRAP #data4 1 1 0 1 0 1 1 0 0 0 1 1 #data4
+ /* XCH(3) */
+
+ {0,0x7100,0xf700,' ',2,XOR, REG_REG }, // XOR Rd, Rs 0 1 1 1 S 0 0 1 d d d d s s s s
+ {0,0x7200,0xf708,' ',2,XOR, REG_IREG }, // XOR Rd, [Rs] 0 1 1 1 S 0 1 0 d d d d 0 s s s
+ {0,0x7208,0xf708,' ',2,XOR, IREG_REG }, // XOR [Rd], Rs 0 1 1 1 S 0 1 0 s s s s 1 d d d
+ {0,0x7400,0xf708,' ',3,XOR, REG_IREGOFF8 }, // XOR Rd, [Rs+offset8] 0 1 1 1 S 1 0 0 d d d d 0 s s s
+ {0,0x7408,0xf708,' ',3,XOR, IREGOFF8_REG }, // XOR [Rd+offset8], Rs 0 1 1 1 S 1 0 0 s s s s 1 d d d
+ {0,0x7500,0xf708,' ',4,XOR, REG_IREGOFF16 }, // XOR Rd, [Rs+offset16] 0 1 1 1 S 1 0 1 d d d d 0 s s s
+ {0,0x7508,0xf708,' ',4,XOR, IREGOFF16_REG }, // XOR [Rd+offset16], Rs 0 1 1 1 S 1 0 1 s s s s 1 d d d
+ {0,0x7300,0xf708,' ',2,XOR, REG_IREGINC }, // XOR Rd, [Rs+] 0 1 1 1 S 0 1 1 d d d d 0 s s s
+ {0,0x7308,0xf708,' ',2,XOR, IREGINC_REG }, // XOR [Rd+], Rs 0 1 1 1 S 0 1 1 s s s s 1 d d d
+ {0,0x7608,0xf708,' ',3,XOR, DIRECT_REG }, // XOR direct, Rs 0 1 1 1 S 1 1 0 s s s s 1 x x x
+ {0,0x7600,0xf708,' ',3,XOR, REG_DIRECT }, // XOR Rd, direct 0 1 1 1 S 1 1 0 d d d d 0 x x x
+ {0,0x9107,0xff0f,' ',3,XOR, REG_DATA8 }, // XOR Rd, #data8 1 0 0 1 0 0 0 1 d d d d 0 1 1 1
+ {0,0x9907,0xff0f,' ',4,XOR, REG_DATA16 }, // XOR Rd, #data16 1 0 0 1 1 0 0 1 d d d d 0 1 1 1
+ {0,0x9207,0xff8f,' ',3,XOR, IREG_DATA8 }, // XOR [Rd], #data8 1 0 0 1 0 0 1 0 0 d d d 0 1 1 1
+ {0,0x9a07,0xff8f,' ',4,XOR, IREG_DATA16 }, // XOR [Rd], #data16 1 0 0 1 1 0 1 0 0 d d d 0 1 1 1
+ {0,0x9307,0xff8f,' ',3,XOR, IREGINC_DATA8 }, // XOR [Rd+], #data8 1 0 0 1 0 0 1 1 0 d d d 0 1 1 1
+ {0,0x9b07,0xff8f,' ',4,XOR, IREGINC_DATA16 }, // XOR [Rd+], #data16 1 0 0 1 1 0 1 1 0 d d d 0 1 1 1
+ {0,0x9407,0xff8f,' ',4,XOR, IREGOFF8_DATA8 }, // XOR [Rd+offset8], #data8 1 0 0 1 0 1 0 0 0 d d d 0 1 1 1
+ {0,0x9c07,0xff8f,' ',5,XOR, IREGOFF8_DATA16 }, // XOR [Rd+offset8], #data16 1 0 0 1 1 1 0 0 0 d d d 0 1 1 1
+ {0,0x9507,0xff8f,' ',5,XOR, IREGOFF16_DATA8 }, // XOR [Rd+offset16], #data8 1 0 0 1 0 1 0 1 0 d d d 0 1 1 1
+ {0,0x9d07,0xff8f,' ',6,XOR, IREGOFF16_DATA16}, // XOR [Rd+offset16], #data16 1 0 0 1 1 1 0 1 0 d d d 0 1 1 1
+ {0,0x9607,0xff8f,' ',4,XOR, DIRECT_DATA8 }, // XOR direct, #data8 1 0 0 1 0 1 1 0 0 b b b 0 1 1 1
+ {0,0x9e07,0xff8f,' ',5,XOR, DIRECT_DATA16 }, // XOR direct, #data16 1 0 0 1 0 1 1 0 0 b b b 0 1 1 1
+
+ {0,0x0000,0x0000, 0,1,BAD_OPCODE, REG_REG}
+};
+
+
+/* End of xa.src/glob.cc */
diff --git a/sim/ucsim/xa.src/glob.h b/sim/ucsim/xa.src/glob.h
new file mode 100644
index 0000000..b85206e
--- /dev/null
+++ b/sim/ucsim/xa.src/glob.h
@@ -0,0 +1,212 @@
+/*
+ * Simulator of microcontrollers (glob.h)
+ *
+ * Copyright (C) 1999,99 Drotos Daniel, Talker Bt.
+ *
+ * To contact author send email to drdani@mazsola.iit.uni-miskolc.hu
+ * Other contributors include:
+ * Karl Bongers karl@turbobit.com,
+ * Johan Knol johan.knol@iduna.nl
+ *
+ */
+
+/* This file is part of microcontroller simulator: ucsim.
+
+UCSIM 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.
+
+UCSIM 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 UCSIM; see the file COPYING. If not, write to the Free
+Software Foundation, 59 Temple Place - Suite 330, Boston, MA
+02111-1307, USA. */
+/*@1@*/
+
+#ifndef GLOB_HEADER
+#define GLOB_HEADER
+
+#include "stypes.h"
+
+/* this needs to match char *op_mnemonic_str[] definition in glob.cc */
+enum {
+BAD_OPCODE=0,
+ADD,
+ADDC,
+ADDS,
+AND,
+ANL,
+ASL,
+ASR,
+BCC,
+BCS,
+BEQ,
+BG,
+BGE,
+BGT,
+BKPT,
+BL,
+BLE,
+BLT,
+BMI,
+BNE,
+BNV,
+BOV,
+BPL,
+BR,
+CALL,
+CJNE,
+CLR,
+CMP,
+CPL,
+DA,
+DIV_w,
+DIV_d,
+DIVU_b,
+DIVU_w,
+DIVU_d,
+DJNZ,
+FCALL,
+FJMP,
+JB,
+JBC,
+JMP,
+JNB,
+JNZ,
+JZ,
+LEA,
+LSR,
+MOV,
+MOVC,
+MOVS,
+MOVX,
+MUL_w,
+MULU_b,
+MULU_w,
+NEG,
+NOP,
+NORM,
+OR,
+ORL,
+POP,
+POPU,
+PUSH,
+PUSHU,
+RESET,
+RET,
+RETI,
+RL,
+RLC,
+RR,
+RRC,
+SETB,
+SEXT,
+SUB,
+SUBB,
+TRAP,
+XCH,
+XOR,
+};
+
+extern const char *op_mnemonic_str[];
+
+/* this classifies the operands and is used in the dissassembly
+ to print the operands. Its also used in the simulation to characterize
+ the op-code function.
+ */
+enum op_operands {
+ // the repeating parameter encoding for ADD, ADDC, SUB, SUBB, AND, XOR, ...
+ REG_REG ,
+ REG_IREG ,
+ IREG_REG ,
+ REG_IREGOFF8 ,
+ IREGOFF8_REG ,
+ REG_IREGOFF16 ,
+ IREGOFF16_REG ,
+ REG_IREGINC ,
+ IREGINC_REG ,
+ DIRECT_REG ,
+ REG_DIRECT ,
+ REG_DATA8 ,
+ REG_DATA16 ,
+ IREG_DATA8 ,
+ IREG_DATA16 ,
+ IREGINC_DATA8 ,
+ IREGINC_DATA16 ,
+ IREGOFF8_DATA8 ,
+ IREGOFF8_DATA16 ,
+ IREGOFF16_DATA8 ,
+ IREGOFF16_DATA16,
+ DIRECT_DATA8 ,
+ DIRECT_DATA16 ,
+
+// odd-ball ones
+ NO_OPERANDS, // for NOP
+ CY_BIT,
+ BIT_CY,
+ CY_NOTBIT,
+ DATA4,
+ REG_DATA4,
+ REG_DATA5,
+ IREG_DATA4,
+ IREGINC_DATA4,
+ IREGOFF8_DATA4,
+ IREGOFF16_DATA4,
+ DIRECT_DATA4,
+
+ REG,
+ IREG,
+ BIT_ALONE,
+ DIRECT,
+ DIRECT_DIRECT,
+ RLIST,
+ ADDR24,
+ BIT_REL8,
+ REG_REL8,
+ DIRECT_REL8,
+ REG_REGOFF8,
+ REG_REGOFF16,
+
+ REG_USP,
+ USP_REG,
+
+ REL8,
+ REL16,
+
+ REG_DIRECT_REL8,
+ REG_DATA8_REL8,
+ REG_DATA16_REL8,
+ IREG_DATA8_REL8,
+ IREG_DATA16_REL8,
+
+ A_APLUSDPTR,
+ A_APLUSPC,
+ A_PLUSDPTR,
+ IIREG
+};
+
+// table of dissassembled instructions
+struct xa_dis_entry
+{
+ uint is1byte; /* only grab 1 byte for table lookup(most are 2 bytes) */
+ uint code; /* bits in opcode used to match table entry(with mask) */
+ uint mask; /* mask used on .code to match up a common opcode */
+ char branch; /* used by main app to implement "next" around calls */
+ uchar length; /* total length of opcode, used by dissasembler and main app */
+ int mnemonic; /* type of opcode(ADD, ADDC...) */
+ int operands; /* unique classification of operands: Rd,Rs = REG_REG,... */
+};
+
+extern struct dis_entry glob_disass_xa[];
+
+extern struct xa_dis_entry disass_xa[];
+
+
+#endif
+
+/* End of xa.src/glob.h */
diff --git a/sim/ucsim/xa.src/inst.cc b/sim/ucsim/xa.src/inst.cc
new file mode 100644
index 0000000..c9f7d08
--- /dev/null
+++ b/sim/ucsim/xa.src/inst.cc
@@ -0,0 +1,1191 @@
+/*
+ * Simulator of microcontrollers (inst.cc)
+ *
+ * Copyright (C) 1999,2002 Drotos Daniel, Talker Bt.
+ *
+ * To contact author send email to drdani@mazsola.iit.uni-miskolc.hu
+ * Other contributors include:
+ * Karl Bongers karl@turbobit.com,
+ * Johan Knol johan.knol@iduna.nl
+ *
+ */
+
+/* This file is part of microcontroller simulator: ucsim.
+
+UCSIM 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.
+
+UCSIM 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 UCSIM; see the file COPYING. If not, write to the Free
+Software Foundation, 59 Temple Place - Suite 330, Boston, MA
+02111-1307, USA. */
+/*@1@*/
+
+#include "ddconfig.h"
+
+#include <stdlib.h>
+
+// local
+#include "glob.h"
+#include "xacl.h"
+#include "regsxa.h"
+
+#define NOTDONE_ASSERT { printf("**********Instr not done at %d!\n", __LINE__); }
+
+void cl_xa::store1(t_addr addr, unsigned char val)
+{
+ if (addr < 0x2000) {
+ set_idata1(addr, val);
+ } else {
+ set_xdata1(addr, val);
+ }
+}
+
+void cl_xa::store2(t_addr addr, unsigned short val)
+{
+ if (addr < 0x2000) {
+ set_idata2(addr, val);
+ } else {
+ set_xdata2(addr, val);
+ }
+}
+
+unsigned char cl_xa::get1(t_addr addr)
+{
+ if (addr < 0x2000) {
+ return get_idata1(addr);
+ } else {
+ return get_xdata1(addr);
+ }
+}
+
+unsigned short cl_xa::get2(t_addr addr)
+{
+ if (addr < 0x2000) {
+ return get_idata2(addr);
+ } else {
+ return get_xdata2(addr);
+ }
+}
+
+int cl_xa::get_reg(int word_flag, unsigned int index)
+{
+ int result;
+
+ if (word_flag) {
+ result = get_word_direct(index);
+ }
+ else {
+ result = get_byte_direct(index);
+ }
+ return result;
+}
+
+bool cl_xa::get_bit(int bit) {
+ short offset=0;
+ unsigned char result;
+
+ if (bit>=0x200) {
+ // in sfr space
+ bit-=0x200;
+ offset=0x400;
+ }
+ result = get_byte_direct(offset + (bit/8)) & (1 << (bit%8));
+ return result;
+}
+
+void cl_xa::set_bit(int bit, int value) {
+ int i;
+ short offset=0;
+ if (bit>=0x200) {
+ // in sfr space
+ bit-=0x200;
+ offset=0x400;
+ }
+
+ i = get_byte_direct(offset + (bit/8));
+ if (value) {
+ set_byte_direct(offset + (bit/8), i | (1 << (bit%8)) );
+ } else {
+ set_byte_direct(offset + (bit/8), i & ~(1 << (bit%8)) );
+ }
+}
+
+#define RI_F0 ((code >> 4) & 0xf)
+#define RI_70 ((code >> 4) & 0x7)
+#define RI_0F (code & 0xf)
+#define RI_07 (code & 0x7)
+
+int cl_xa::inst_ADD(uint code, int operands)
+{
+#undef FUNC1
+#define FUNC1 add1
+#undef FUNC2
+#define FUNC2 add2
+#include "inst_gen.cc"
+
+ return(resGO);
+}
+
+int cl_xa::inst_ADDC(uint code, int operands)
+{
+#undef FUNC1
+#define FUNC1 addc1
+#undef FUNC2
+#define FUNC2 addc2
+#include "inst_gen.cc"
+
+ return(resGO);
+}
+
+int cl_xa::inst_ADDS(uint code, int operands)
+{
+ NOTDONE_ASSERT;
+ return(resGO);
+}
+
+int cl_xa::inst_AND(uint code, int operands)
+{
+#undef FUNC1
+#define FUNC1 and1
+#undef FUNC2
+#define FUNC2 and2
+#include "inst_gen.cc"
+ return(resGO);
+}
+
+/* logical AND bit with Carry flag */
+int cl_xa::inst_ANL(uint code, int operands)
+{
+ unsigned char flags;
+ unsigned short bitAddr = (code&0x03 << 8) + fetch();
+ flags = get_psw();
+
+ if (flags & BIT_C) {
+ /* have work to do */
+ switch(operands) {
+ case CY_BIT :
+ if (!get_bit(bitAddr)) {
+ set_psw(flags & ~BIT_C);
+ }
+ break;
+
+ case CY_NOTBIT :
+ if (get_bit(bitAddr)) {
+ set_psw(flags & ~BIT_C);
+ }
+ break;
+ }
+ }
+
+ return(resGO);
+}
+
+/* arithmetic shift left */
+int cl_xa::inst_ASL(uint code, int operands)
+{
+ unsigned int dst, cnt;
+ unsigned char flags;
+
+ /* ASL, dest, count
+ while (count != 0)
+ C = dest.80H; dest <<= 1; if sign chg then set V=1
+ this is a confusing one...
+ */
+
+ flags = get_psw();
+ flags &= ~BIT_ALL; /* clear these bits */
+
+ switch(operands) {
+ //{0,0xc150,0xf300,' ',2,ASL, REG_REG }, // ASL Rd, Rs 1 1 0 0 S S 0 1 d d d d s s s s
+ case REG_REG :
+ cnt = reg1(RI_0F) & 0x1f;
+ switch (code & 0xc00) {
+ case 0: // byte
+ dst = reg1(RI_F0);
+ dst <<= cnt;
+ set_reg1(RI_F0,dst);
+ if (dst & 0x100)
+ flags |= BIT_C;
+ if ((dst & 0xff) == 0)
+ flags |= BIT_Z;
+ break;
+ case 1: // word
+ dst = reg2(RI_F0);
+ dst <<= cnt;
+ set_reg2(RI_F0,dst);
+ if (dst & 0x10000)
+ flags |= BIT_C;
+ if ((dst & 0xffff) == 0)
+ flags |= BIT_Z;
+ break;
+ case 2: // ?
+ // not really sure about the encoding here..
+ NOTDONE_ASSERT;
+ break;
+ case 3: // dword
+ //dst = reg4(RI_F0);
+ dst = reg2(RI_F0) | (reg2(RI_F0 + 2) << 16);
+ if ((cnt != 0) && (dst & (0x80000000 >> (cnt-1)))) {
+ flags |= BIT_C;
+ }
+ dst <<= cnt;
+ set_reg2(RI_F0,dst & 0xffff);
+ set_reg2(RI_F0+2, (dst>>16) & 0xffff);
+ if (dst == 0)
+ flags |= BIT_Z;
+ break;
+ }
+ break;
+
+ case REG_DATA4 :
+ case REG_DATA5 :
+ switch (code & 0xc00) {
+ case 0: // byte
+ dst = reg1(RI_F0);
+ cnt = operands & 0x0f;
+ dst <<= cnt;
+ set_reg1(RI_F0,dst);
+ if (dst & 0x100)
+ flags |= BIT_C;
+ if ((dst & 0xff) == 0)
+ flags |= BIT_Z;
+ break;
+ case 1: // word
+ dst = reg2(RI_F0);
+ cnt = operands & 0x0f;
+ dst <<= cnt;
+ set_reg2(RI_F0,dst);
+ if (dst & 0x10000)
+ flags |= BIT_C;
+ if ((dst & 0xffff) == 0)
+ flags |= BIT_Z;
+ break;
+ case 2: // ?
+ // not really sure about the encoding here..
+ NOTDONE_ASSERT;
+ break;
+ case 3: // dword
+ dst = reg1(RI_F0 & 0xe);
+ cnt = operands & 0x1f;
+ if ((cnt != 0) && (dst & (0x80000000 >> (cnt-1)))) {
+ flags |= BIT_C;
+ }
+ dst <<= cnt;
+ set_reg2(RI_F0,dst & 0xffff);
+ set_reg2(RI_F0+2, (dst>>16) & 0xffff);
+ if (dst == 0)
+ flags |= BIT_Z;
+ break;
+ }
+ break;
+ }
+ set_psw(flags);
+
+ return(resGO);
+}
+
+/* arithmetic shift right */
+int cl_xa::inst_ASR(uint code, int operands)
+{
+ unsigned int dst, cnt;
+ unsigned char flags;
+
+ /* ASR, dest, count
+ while (count != 0)
+ C = dest.0; dest >>= 1;
+ this is a confusing one...
+ */
+
+ flags = get_psw();
+ flags &= ~BIT_ALL; /* clear these bits */
+
+ switch(operands) {
+ case REG_REG :
+ cnt = reg1(RI_0F) & 0x1f;
+ switch (code & 0xc00) {
+ case 0: // byte
+ dst = reg1(RI_F0);
+ if ((cnt != 0) && (dst & (0x00000001 << (cnt-1))))
+ flags |= BIT_C;
+ if (dst & 0x01)
+ flags |= BIT_C;
+ dst >>= cnt;
+ set_reg1(RI_F0,dst);
+ if ((dst & 0xff) == 0)
+ flags |= BIT_Z;
+ break;
+ case 1: // word
+ dst = reg2(RI_F0);
+ if ((cnt != 0) && (dst & (0x00000001 << (cnt-1))))
+ flags |= BIT_C;
+ dst >>= cnt;
+ set_reg2(RI_F0,dst);
+ if ((dst & 0xffff) == 0)
+ flags |= BIT_Z;
+ break;
+ case 2: // ?
+ // not really sure about the encoding here..
+ NOTDONE_ASSERT;
+ break;
+ case 3: // dword
+ dst = reg2(RI_F0) | (reg2(RI_F0 + 2) << 16);
+ if ((cnt != 0) && (dst & (0x00000001 << (cnt-1))))
+ flags |= BIT_C;
+ dst >>= cnt;
+ set_reg2(RI_F0,dst & 0xffff);
+ set_reg2(RI_F0+2, (dst>>16) & 0xffff);
+ if (dst == 0)
+ flags |= BIT_Z;
+ break;
+ }
+ break;
+
+ case REG_DATA4 :
+ case REG_DATA5 :
+ switch (code & 0xc00) {
+ case 0: // byte
+ dst = reg1(RI_F0);
+ cnt = operands & 0x0f;
+ if ((cnt != 0) && (dst & (0x00000001 << (cnt-1))))
+ flags |= BIT_C;
+ dst >>= cnt;
+ set_reg1(RI_F0,dst);
+ if ((dst & 0xff) == 0)
+ flags |= BIT_Z;
+ break;
+ case 1: // word
+ dst = reg2(RI_F0);
+ cnt = operands & 0x0f;
+ if ((cnt != 0) && (dst & (0x00000001 << (cnt-1))))
+ flags |= BIT_C;
+ dst >>= cnt;
+ set_reg2(RI_F0,dst);
+ if ((dst & 0xffff) == 0)
+ flags |= BIT_Z;
+ break;
+ case 2: // ?
+ // not really sure about the encoding here..
+ NOTDONE_ASSERT;
+ break;
+ case 3: // dword
+ dst = reg1(RI_F0 & 0xe);
+ cnt = operands & 0x1f;
+ if ((cnt != 0) && (dst & (0x00000001 << (cnt-1))))
+ flags |= BIT_C;
+ dst >>= cnt;
+ set_reg2(RI_F0,dst & 0xffff);
+ set_reg2(RI_F0+2, (dst>>16) & 0xffff);
+ if (dst == 0)
+ flags |= BIT_Z;
+ break;
+ }
+ break;
+ }
+ set_psw(flags);
+
+ return(resGO);
+}
+
+int cl_xa::inst_BCC(uint code, int operands)
+{
+ short jmpAddr = fetch1()*2;
+ if (!(get_psw() & BIT_C)) {
+ PC=(PC+jmpAddr)&0xfffffe;
+ }
+ return(resGO);
+}
+
+int cl_xa::inst_BCS(uint code, int operands)
+{
+ short jmpAddr = fetch1()*2;
+ if (get_psw() & BIT_C) {
+ PC=(PC+jmpAddr)&0xfffffe;
+ }
+ return(resGO);
+}
+
+int cl_xa::inst_BEQ(uint code, int operands)
+{
+ short jmpAddr = fetch1()*2;
+ if (get_psw() & BIT_Z) {
+ PC=(PC+jmpAddr)&0xfffffe;
+ }
+ return(resGO);
+}
+
+int cl_xa::inst_BG(uint code, int operands)
+{
+ short jmpAddr = fetch1()*2;
+ short flags=get_psw();
+ bool Z=flags&BIT_Z, C=flags&BIT_C;
+ if (!(Z|C)) {
+ PC=(PC+jmpAddr)&0xfffffe;
+ }
+ return(resGO);
+}
+int cl_xa::inst_BGE(uint code, int operands)
+{
+ short jmpAddr = fetch1()*2;
+ short flags=get_psw();
+ bool N=flags&BIT_N, V=flags&BIT_V;
+ if (!(N^V)) {
+ PC=(PC+jmpAddr)&0xfffffe;
+ }
+ return(resGO);
+}
+int cl_xa::inst_BGT(uint code, int operands)
+{
+ short jmpAddr = fetch1()*2;
+ short flags=get_psw();
+ bool Z=flags&BIT_Z, N=flags&BIT_N, V=flags&BIT_V;
+ if (!((Z|N)^V)) {
+ PC=(PC+jmpAddr)&0xfffffe;
+ }
+ return(resGO);
+}
+int cl_xa::inst_BKPT(uint code, int operands)
+{
+ NOTDONE_ASSERT;
+ return(resGO);
+}
+int cl_xa::inst_BL(uint code, int operands)
+{
+ short jmpAddr = fetch1()*2;
+ short flags=get_psw();
+ bool Z=flags&BIT_Z, C=flags&BIT_C;
+ if (Z|C) {
+ PC=(PC+jmpAddr)&0xfffffe;
+ }
+ return(resGO);
+}
+int cl_xa::inst_BLE(uint code, int operands)
+{
+ short jmpAddr = fetch1()*2;
+ short flags=get_psw();
+ bool Z=flags&BIT_Z, N=flags&BIT_N, V=flags&BIT_V;
+ if ((Z|N)^V) {
+ PC=(PC+jmpAddr)&0xfffffe;
+ }
+ return(resGO);
+}
+int cl_xa::inst_BLT(uint code, int operands)
+{
+ short jmpAddr = fetch1()*2;
+ short flags=get_psw();
+ bool N=flags&BIT_N, V=flags&BIT_V;
+ if (N^V) {
+ PC=(PC+jmpAddr)&0xfffffe;
+ }
+ return(resGO);
+}
+int cl_xa::inst_BMI(uint code, int operands)
+{
+ short jmpAddr = fetch1()*2;
+ if (get_psw()&BIT_N) {
+ PC=(PC+jmpAddr)&0xfffffe;
+ }
+ return(resGO);
+}
+int cl_xa::inst_BNE(uint code, int operands)
+{
+ short jmpAddr = fetch1()*2;
+ if (!(get_psw()&BIT_Z)) {
+ PC=(PC+jmpAddr)&0xfffffe;
+ }
+ return(resGO);
+}
+int cl_xa::inst_BNV(uint code, int operands)
+{
+ short jmpAddr = fetch1()*2;
+ if (!(get_psw()&BIT_V)) {
+ PC=(PC+jmpAddr)&0xfffffe;
+ }
+ return(resGO);
+}
+int cl_xa::inst_BOV(uint code, int operands)
+{
+ short jmpAddr = fetch1()*2;
+ if (get_psw()&BIT_V) {
+ PC=(PC+jmpAddr)&0xfffffe;
+ }
+ return(resGO);
+}
+int cl_xa::inst_BPL(uint code, int operands)
+{
+ short jmpAddr = fetch1()*2;
+ if (!(get_psw()&BIT_N)) {
+ PC=(PC+jmpAddr)&0xfffffe;
+ }
+ return(resGO);
+}
+
+int cl_xa::inst_BR(uint code, int operands)
+{
+ short jmpAddr = fetch1()*2;
+ PC=(PC+jmpAddr)&0xfffffe;
+ return(resGO);
+}
+
+int cl_xa::inst_CALL(uint code, int operands)
+{
+ int jmpaddr;
+ unsigned int sp;
+ bool pageZero=get_scr()&1;
+
+ switch(operands) {
+ case REL16:
+ {
+ jmpaddr = (signed short)fetch2();
+ sp = get_sp() - (pageZero ? 2 : 4);
+ set_sp(sp);
+ store2(sp, PC&0xffff);
+ if (!pageZero) {
+ store2(sp+2, (PC>>16)&0xff);
+ }
+ jmpaddr *= 2;
+ PC = (PC + jmpaddr) & 0xfffffe;
+ }
+ break;
+ case IREG:
+ {
+ sp = get_sp() - (pageZero ? 2 : 4);
+ set_sp(sp);
+ store2(sp, PC&0xffff);
+ if (!pageZero) {
+ store2(sp+2, (PC>>16)&0xff);
+ }
+ jmpaddr = reg2(RI_07);
+ jmpaddr *= 2;
+ PC = (PC + jmpaddr) & 0xfffffe;
+ }
+ break;
+ }
+ return(resGO);
+}
+
+int cl_xa::inst_CJNE(uint code, int operands)
+{
+ switch(operands) {
+ case REG_DIRECT_REL8:
+ {
+ // update C,N,Z
+ if (code & 0x800) { // word op
+ int result;
+ int src = get_word_direct( ((code & 0x7)<<4) | fetch1());
+ int addr = (fetch1() * 2);
+ int dst = reg2(RI_F0);
+ unsigned char flags;
+ flags = get_psw();
+ flags &= ~BIT_ALL; /* clear these bits */
+ result = dst - src;
+ if (result == 0) flags |= BIT_Z;
+ if (result > 0xffff) flags |= BIT_C;
+ if (dst < src) flags |= BIT_N;
+ set_psw(flags);
+ if (flags & BIT_Z)
+ PC += addr;
+ } else {
+ int result;
+ int src = get_byte_direct( ((code & 0x7)<<4) | fetch1());
+ int addr = (fetch1() * 2);
+ int dst = reg1(RI_F0);
+ unsigned char flags;
+ flags = get_psw();
+ flags &= ~BIT_ALL; /* clear these bits */
+ result = dst - src;
+ if (result == 0) flags |= BIT_Z;
+ if (result > 0xff) flags |= BIT_C;
+ if (dst < src) flags |= BIT_N;
+ set_psw(flags);
+ if (flags & BIT_Z)
+ PC += addr;
+ }
+ }
+ break;
+
+ case DIRECT_REL8:
+ {
+ int daddr = ((code & 0x7) << 8) | fetch();
+ int addr = fetch() * 2;
+
+ if (code & 0x800) { // word op
+ unsigned short tmp = get_word_direct(daddr)-1;
+ set_word_direct(daddr, tmp);
+ if (tmp != 0)
+ PC += addr;
+ } else {
+ unsigned char tmp = get_word_direct(daddr)-1;
+ set_byte_direct(daddr, tmp);
+ if (tmp != 0)
+ PC += addr;
+ }
+ }
+ break;
+ }
+ return(resGO);
+}
+
+int cl_xa::inst_CLR(uint code, int operands)
+{
+ unsigned short bitAddr = (code&0x03 << 8) + fetch();
+ set_bit (bitAddr, 0);
+ return(resGO);
+}
+
+int cl_xa::inst_CMP(uint code, int operands)
+{
+#undef FUNC1
+#define FUNC1 cmp1
+#undef FUNC2
+#define FUNC2 cmp2
+#include "inst_gen.cc"
+ return(resGO);
+}
+int cl_xa::inst_CPL(uint code, int operands)
+{
+ NOTDONE_ASSERT;
+ return(resGO);
+}
+int cl_xa::inst_DA(uint code, int operands)
+{
+ NOTDONE_ASSERT;
+ return(resGO);
+}
+int cl_xa::inst_DIV(uint code, int operands)
+{
+ NOTDONE_ASSERT;
+ return(resGO);
+}
+
+int cl_xa::inst_DJNZ(uint code, int operands)
+{
+ // update N Z flags.
+ switch(operands) {
+ case REG_REL8:
+ {
+ int addr = ( ((char)fetch1()) * 2);
+ if (code & 0x800) { // word op
+ unsigned short tmp = mov2(0, reg2(RI_F0)-1);
+ set_reg2(RI_F0, tmp);
+ if (tmp != 0)
+ PC = (PC + addr) & 0xfffffe;
+ } else {
+ unsigned char tmp = mov1(0, reg1(RI_F0)-1);
+ set_reg1(RI_F0, tmp);
+ if (tmp != 0)
+ PC = (PC + addr) & 0xfffffe;
+ }
+ }
+ break;
+
+ case DIRECT_REL8:
+ {
+ int daddr = ((code & 0x7) << 8) | fetch();
+ int addr = fetch() * 2;
+
+ if (code & 0x800) { // word op
+ unsigned short tmp = get_word_direct(daddr)-1;
+ set_word_direct(daddr, tmp);
+ if (tmp != 0)
+ PC += addr;
+ } else {
+ unsigned char tmp = get_word_direct(daddr)-1;
+ set_byte_direct(daddr, tmp);
+ if (tmp != 0)
+ PC += addr;
+ }
+ }
+ break;
+ }
+
+ return(resGO);
+}
+
+int cl_xa::inst_FCALL(uint code, int operands)
+{
+ NOTDONE_ASSERT;
+ return(resGO);
+}
+
+int cl_xa::inst_FJMP(uint code, int operands)
+{
+ NOTDONE_ASSERT;
+ return(resGO);
+}
+
+int cl_xa::inst_JB(uint code, int operands)
+{
+ short bitAddr=((code&0x3)<<8) + fetch1();
+ short jmpAddr = (fetch1() * 2);
+ if (get_bit(bitAddr)) {
+ PC = (PC+jmpAddr)&0xfffffe;
+ }
+ return(resGO);
+}
+int cl_xa::inst_JBC(uint code, int operands)
+{
+ short bitAddr=((code&0x3)<<8) + fetch1();
+ short jmpAddr = (fetch1() * 2);
+ if (get_bit(bitAddr)) {
+ PC = (PC+jmpAddr)&0xfffffe;
+ }
+ set_bit(bitAddr,0);
+ return(resGO);
+}
+int cl_xa::inst_JNB(uint code, int operands)
+{
+ short bitAddr=((code&0x3)<<8) + fetch1();
+ short jmpAddr = (fetch1() * 2);
+ if (!get_bit(bitAddr)) {
+ PC = (PC+jmpAddr)&0xfffffe;
+ }
+ return(resGO);
+}
+int cl_xa::inst_JMP(uint code, int operands)
+{
+ int jmpAddr;
+
+ switch(operands) {
+ case REL16:
+ {
+ jmpAddr = (signed short)fetch2()*2;
+ PC = (PC + jmpAddr) & 0xfffffe;
+ }
+ break;
+ case IREG:
+ PC &= 0xff0000;
+ PC |= (reg2(RI_07) & 0xfffe); /* word aligned */
+ break;
+ /* fixme 2 more... */
+ }
+ return(resGO);
+}
+int cl_xa::inst_JNZ(uint code, int operands)
+{
+ short saddr = (fetch1() * 2);
+ /* reg1(8) = R4L, is ACC for MCS51 compatiblility */
+ if (reg1(8)!=0) {
+ PC = (PC + saddr) & 0xfffffe;
+ }
+ return(resGO);
+}
+int cl_xa::inst_JZ(uint code, int operands)
+{
+ /* reg1(8) = R4L, is ACC for MCS51 compatiblility */
+ short saddr = (fetch1() * 2);
+ if (reg1(8)==0) {
+ PC += saddr;
+ }
+ return(resGO);
+}
+int cl_xa::inst_LEA(uint code, int operands)
+{
+ switch (operands) {
+ case REG_REGOFF8:
+ {
+ char offset=fetch1();
+ set_reg2(RI_70, reg2(RI_07)+offset);
+ break;
+ }
+ case REG_REGOFF16:
+ {
+ short offset=fetch2();
+ set_reg2(RI_70, reg2(RI_07)+offset);
+ break;
+ }
+ }
+ return(resGO);
+}
+int cl_xa::inst_LSR(uint code, int operands)
+{
+ NOTDONE_ASSERT;
+ return(resGO);
+}
+int cl_xa::inst_MOV(uint code, int operands)
+{
+#undef FUNC1
+#define FUNC1 mov1
+#undef FUNC2
+#define FUNC2 mov2
+#include "inst_gen.cc"
+ return(resGO);
+}
+int cl_xa::inst_MOVC(uint code, int operands)
+{
+ switch (operands) {
+ case REG_IREGINC:
+ {
+ short srcreg = reg2(RI_07);
+ if (code & 0x0800) { /* word op */
+ set_reg2( RI_F0,
+ mov2( reg2(RI_F0),
+ getcode2(srcreg)
+ )
+ );
+ } else {
+ set_reg1( RI_F0,
+ mov1( reg1(RI_F0),
+ getcode1(srcreg)
+ )
+ );
+ }
+ if (operands == REG_IREGINC) {
+ set_reg2(RI_07, srcreg+1);
+ }
+ }
+ break;
+ case A_APLUSDPTR:
+ { /* R4l=ACC, R6=DPTR */
+ unsigned int addr = (PC & 0xff0000) | (reg1(4) + reg2(6));
+ unsigned short result;
+ unsigned char flags;
+ flags = get_psw();
+
+ flags &= ~(BIT_Z | BIT_N); /* clear these bits */
+ result = getcode1(addr);
+ set_reg1( 4, result);
+ if (result == 0) flags |= BIT_Z;
+ if (result & 0x80) flags |= BIT_N;
+ set_psw(flags);
+ }
+ break;
+ case A_APLUSPC:
+ { /* R4l=ACC, R6=DPTR */
+ unsigned int addr = (PC + reg1(4));
+ unsigned short result;
+ unsigned char flags;
+ flags = get_psw();
+
+ flags &= ~(BIT_Z | BIT_N); /* clear these bits */
+ result = getcode1(addr);
+ set_reg1( 4, result);
+ if (result == 0) flags |= BIT_Z;
+ if (result & 0x80) flags |= BIT_N;
+ set_psw(flags);
+ }
+ break;
+ }
+ return(resGO);
+}
+int cl_xa::inst_MOVS(uint code, int operands)
+{
+ NOTDONE_ASSERT;
+ return(resGO);
+}
+int cl_xa::inst_MOVX(uint code, int operands)
+{
+ NOTDONE_ASSERT;
+ return(resGO);
+}
+int cl_xa::inst_MUL(uint code, int operands)
+{
+ NOTDONE_ASSERT;
+ return(resGO);
+}
+int cl_xa::inst_NEG(uint code, int operands)
+{
+ NOTDONE_ASSERT;
+ return(resGO);
+}
+int cl_xa::inst_NOP(uint code, int operands)
+{
+ return(resGO);
+}
+int cl_xa::inst_NORM(uint code, int operands)
+{
+ NOTDONE_ASSERT;
+ return(resGO);
+}
+int cl_xa::inst_OR(uint code, int operands)
+{
+#undef FUNC1
+#define FUNC1 or1
+#undef FUNC2
+#define FUNC2 or2
+#include "inst_gen.cc"
+ return(resGO);
+}
+
+int cl_xa::inst_ORL(uint code, int operands)
+{
+ NOTDONE_ASSERT;
+ return(resGO);
+}
+
+int cl_xa::inst_POP(uint code, int operands)
+{
+ unsigned short sp=get_sp();
+ switch(operands) {
+ case DIRECT:
+ {
+ unsigned short direct_addr = ((operands & 0x7) << 8) | fetch();
+
+ if (code & 0x0800) { /* word op */
+ set_word_direct(direct_addr, get2(sp) );
+ } else {
+ set_byte_direct(direct_addr, get2(sp) & 0xff );
+ }
+ set_sp(sp+2);
+ }
+ break;
+
+ case RLIST:
+ {
+ unsigned char rlist = fetch();
+ if (code & 0x0800) { // word op
+ if (code & 0x4000) { // R8-R15
+ if (rlist&0x01) { set_reg2(8, get2(sp)); sp+=2; }
+ if (rlist&0x02) { set_reg2(9, get2(sp)); sp+=2; }
+ if (rlist&0x04) { set_reg2(10, get2(sp)); sp+=2; }
+ if (rlist&0x08) { set_reg2(11, get2(sp)); sp+=2; }
+ if (rlist&0x10) { set_reg2(12, get2(sp)); sp+=2; }
+ if (rlist&0x20) { set_reg2(13, get2(sp)); sp+=2; }
+ if (rlist&0x40) { set_reg2(14, get2(sp)); sp+=2; }
+ if (rlist&0x80) { set_reg2(15, get2(sp)); sp+=2; }
+ } else { // R0-R7
+ if (rlist&0x01) { set_reg2(0, get2(sp)); sp+=2; }
+ if (rlist&0x02) { set_reg2(1, get2(sp)); sp+=2; }
+ if (rlist&0x04) { set_reg2(2, get2(sp)); sp+=2; }
+ if (rlist&0x08) { set_reg2(3, get2(sp)); sp+=2; }
+ if (rlist&0x10) { set_reg2(4, get2(sp)); sp+=2; }
+ if (rlist&0x20) { set_reg2(5, get2(sp)); sp+=2; }
+ if (rlist&0x40) { set_reg2(6, get2(sp)); sp+=2; }
+ if (rlist&0x80) { set_reg2(7, get2(sp)); sp+=2; }
+ }
+ } else { // byte op
+ if (code & 0x4000) { // R4l-R7h
+ if (rlist&0x01) { set_reg1(8, get1(sp)); sp+=2; }
+ if (rlist&0x02) { set_reg1(9, get1(sp)); sp+=2; }
+ if (rlist&0x04) { set_reg1(10, get1(sp)); sp+=2; }
+ if (rlist&0x08) { set_reg1(11, get1(sp)); sp+=2; }
+ if (rlist&0x10) { set_reg1(12, get1(sp)); sp+=2; }
+ if (rlist&0x20) { set_reg1(13, get1(sp)); sp+=2; }
+ if (rlist&0x40) { set_reg1(14, get1(sp)); sp+=2; }
+ if (rlist&0x80) { set_reg1(15, get1(sp)); sp+=2; }
+ } else { // R0l-R3h
+ if (rlist&0x01) { set_reg1(0, get1(sp)); sp+=2; }
+ if (rlist&0x02) { set_reg1(1, get1(sp)); sp+=2; }
+ if (rlist&0x04) { set_reg1(2, get1(sp)); sp+=2; }
+ if (rlist&0x08) { set_reg1(3, get1(sp)); sp+=2; }
+ if (rlist&0x10) { set_reg1(4, get1(sp)); sp+=2; }
+ if (rlist&0x20) { set_reg1(5, get1(sp)); sp+=2; }
+ if (rlist&0x40) { set_reg1(6, get1(sp)); sp+=2; }
+ if (rlist&0x80) { set_reg1(7, get1(sp)); sp+=2; }
+ }
+ }
+ }
+ break;
+ }
+ return(resGO);
+}
+
+int cl_xa::inst_PUSH(uint code, int operands)
+{
+ switch(operands) {
+ case DIRECT:
+ {
+ unsigned short sp;
+ unsigned short direct_addr = ((operands & 0x7) << 8) | fetch();
+
+ sp = get_sp()-2;
+ set_sp(sp);
+ if (code & 0x0800) { /* word op */
+ store2( sp, get_word_direct(direct_addr));
+ } else {
+ store2( sp, get_byte_direct(direct_addr));
+ }
+ }
+ break;
+
+ case RLIST:
+ {
+ unsigned short sp=get_sp();
+ unsigned char rlist = fetch();
+ if (code & 0x0800) { // word op
+ if (code & 0x4000) { // R15-R8
+ if (rlist&0x80) { sp-=2; store2(sp, reg2(15)); }
+ if (rlist&0x40) { sp-=2; store2(sp, reg2(14)); }
+ if (rlist&0x20) { sp-=2; store2(sp, reg2(13)); }
+ if (rlist&0x10) { sp-=2; store2(sp, reg2(12)); }
+ if (rlist&0x08) { sp-=2; store2(sp, reg2(11)); }
+ if (rlist&0x04) { sp-=2; store2(sp, reg2(10)); }
+ if (rlist&0x02) { sp-=2; store2(sp, reg2(9)); }
+ if (rlist&0x01) { sp-=2; store2(sp, reg2(8)); }
+ } else { // R7-R0
+ if (rlist&0x80) { sp-=2; store2(sp, reg2(7)); }
+ if (rlist&0x40) { sp-=2; store2(sp, reg2(6)); }
+ if (rlist&0x20) { sp-=2; store2(sp, reg2(5)); }
+ if (rlist&0x10) { sp-=2; store2(sp, reg2(4)); }
+ if (rlist&0x08) { sp-=2; store2(sp, reg2(3)); }
+ if (rlist&0x04) { sp-=2; store2(sp, reg2(2)); }
+ if (rlist&0x02) { sp-=2; store2(sp, reg2(1)); }
+ if (rlist&0x01) { sp-=2; store2(sp, reg2(0)); }
+ }
+ } else { // byte op
+ if (code & 0x4000) { // R7h-R4l
+ if (rlist&0x80) { sp-=2; store2(sp, reg1(15)); }
+ if (rlist&0x40) { sp-=2; store2(sp, reg1(14)); }
+ if (rlist&0x20) { sp-=2; store2(sp, reg1(13)); }
+ if (rlist&0x10) { sp-=2; store2(sp, reg1(12)); }
+ if (rlist&0x08) { sp-=2; store2(sp, reg1(11)); }
+ if (rlist&0x04) { sp-=2; store2(sp, reg1(10)); }
+ if (rlist&0x02) { sp-=2; store2(sp, reg1(9)); }
+ if (rlist&0x01) { sp-=2; store2(sp, reg1(8)); }
+ } else { // R3h-R0l
+ if (rlist&0x80) { sp-=2; store2(sp, reg1(7)); }
+ if (rlist&0x40) { sp-=2; store2(sp, reg1(6)); }
+ if (rlist&0x20) { sp-=2; store2(sp, reg1(5)); }
+ if (rlist&0x10) { sp-=2; store2(sp, reg1(4)); }
+ if (rlist&0x08) { sp-=2; store2(sp, reg1(3)); }
+ if (rlist&0x04) { sp-=2; store2(sp, reg1(2)); }
+ if (rlist&0x02) { sp-=2; store2(sp, reg1(1)); }
+ if (rlist&0x01) { sp-=2; store2(sp, reg1(0)); }
+ }
+ }
+ set_sp(sp);
+ }
+ break;
+ }
+ return(resGO);
+}
+int cl_xa::inst_RESET(uint code, int operands)
+{
+ NOTDONE_ASSERT;
+ return(resGO);
+}
+int cl_xa::inst_RET(uint code, int operands)
+{
+ unsigned int retaddr;
+ unsigned short sp;
+ bool pageZero=get_scr()&1;
+
+ sp = get_sp();
+ retaddr = get2(sp);
+ if (!pageZero) {
+ retaddr |= get2(sp+2) << 16;
+ set_sp(sp+4);
+ } else {
+ set_sp(sp+2);
+ }
+ PC = retaddr;
+ return(resGO);
+}
+int cl_xa::inst_RETI(uint code, int operands)
+{
+ unsigned int retaddr;
+ unsigned short sp;
+ bool pageZero=get_scr()&1;
+
+ sp = get_sp();
+ set_psw(get2(sp));
+ retaddr = get2(sp+2);
+ if (!pageZero) {
+ retaddr |= get2(sp+4) << 16;
+ set_sp(sp+6);
+ } else {
+ set_sp(sp+4);
+ }
+ PC = retaddr;
+ return(resGO);
+}
+int cl_xa::inst_RL(uint code, int operands)
+{
+ NOTDONE_ASSERT;
+ return(resGO);
+}
+int cl_xa::inst_RLC(uint code, int operands)
+{
+ NOTDONE_ASSERT;
+ return(resGO);
+}
+int cl_xa::inst_RR(uint code, int operands)
+{
+ NOTDONE_ASSERT;
+ return(resGO);
+}
+int cl_xa::inst_RRC(uint code, int operands)
+{
+ NOTDONE_ASSERT;
+ return(resGO);
+}
+int cl_xa::inst_SETB(uint code, int operands)
+{
+ unsigned short bitAddr = (code&0x03 << 8) + fetch();
+ set_bit (bitAddr, 1);
+ return(resGO);
+}
+
+int cl_xa::inst_SEXT(uint code, int operands)
+{
+ bool neg=get_psw()&BIT_N;
+ if (code & 0x0800) { // word op
+ set_reg2(RI_F0, neg ? 0xffff : 0);
+ } else {
+ set_reg1(RI_F0, neg ? 0xff : 0);
+ }
+ return(resGO);
+}
+
+int cl_xa::inst_SUB(uint code, int operands)
+{
+#undef FUNC1
+#define FUNC1 sub1
+#undef FUNC2
+#define FUNC2 sub2
+#include "inst_gen.cc"
+ return(resGO);
+}
+
+int cl_xa::inst_SUBB(uint code, int operands)
+{
+#undef FUNC1
+#define FUNC1 subb1
+#undef FUNC2
+#define FUNC2 subb2
+#include "inst_gen.cc"
+ return(resGO);
+}
+
+int cl_xa::inst_TRAP(uint code, int operands)
+{
+ // steal a few opcodes for simulator only putchar() and exit()
+ // functions. Used in SDCC regression testing.
+ switch (code & 0x0f) {
+ case 0xe:
+ // implement a simulator putchar() routine
+ //printf("PUTCHAR-----> %xH\n", reg1(0));
+ putchar(reg1(0));
+ fflush(stdout);
+ break;
+
+ case 0xf:
+ ::exit(0);
+ break;
+ }
+ return(resGO);
+}
+
+int cl_xa::inst_XCH(uint code, int operands)
+{
+ NOTDONE_ASSERT;
+ return(resGO);
+}
+int cl_xa::inst_XOR(uint code, int operands)
+{
+#undef FUNC1
+#define FUNC1 xor1
+#undef FUNC2
+#define FUNC2 xor2
+#include "inst_gen.cc"
+ return(resGO);
+}
+
+/* End of xa.src/inst.cc */
diff --git a/sim/ucsim/xa.src/inst_gen.cc b/sim/ucsim/xa.src/inst_gen.cc
new file mode 100644
index 0000000..76e3987
--- /dev/null
+++ b/sim/ucsim/xa.src/inst_gen.cc
@@ -0,0 +1,285 @@
+/*
+ * Simulator of microcontrollers (inst_gen.cc)
+ * this code pulled into various parts
+ of inst.cc with FUNC1 and FUNC2 defined as
+ various operations to implement ADD, ADDC, ...
+ *
+ * Copyright (C) 1999,2002 Drotos Daniel, Talker Bt.
+ *
+ * To contact author send email to drdani@mazsola.iit.uni-miskolc.hu
+ * Other contributors include:
+ * Karl Bongers karl@turbobit.com,
+ * Johan Knol
+ *
+ */
+
+/* This file is part of microcontroller simulator: ucsim.
+
+UCSIM 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.
+
+UCSIM 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 UCSIM; see the file COPYING. If not, write to the Free
+Software Foundation, 59 Temple Place - Suite 330, Boston, MA
+02111-1307, USA. */
+/*@1@*/
+
+ switch (operands) {
+ case REG_REG:
+ if (code & 0x0800) { /* word op */
+ set_reg2( RI_F0,
+ FUNC2( reg2(RI_F0), reg2(RI_0F) )
+ );
+ } else {
+ set_reg1( RI_F0,
+ FUNC1( reg1(RI_F0), reg1(RI_0F) )
+ );
+ }
+ break;
+ case REG_IREGINC :
+ case REG_IREG:
+ {
+ short srcreg = reg2(RI_07);
+ if (code & 0x0800) { /* word op */
+ set_reg2( RI_F0,
+ FUNC2( reg2(RI_F0),
+ get2(srcreg)
+ )
+ );
+ } else {
+ set_reg1( RI_F0,
+ FUNC1( reg1(RI_F0),
+ get1(srcreg)
+ )
+ );
+ }
+ if (operands == REG_IREGINC) {
+ set_reg2(RI_07, srcreg+1);
+ }
+ }
+ break;
+ case IREGINC_REG :
+ case IREG_REG :
+ {
+ short addr = reg2(RI_07);
+ if (code & 0x0800) { /* word op */
+ unsigned short wtmp, wtotal;
+ wtmp = get2(addr);
+ wtotal = FUNC2( wtmp, reg2(RI_F0) );
+ store2(addr, wtotal);
+ } else {
+ unsigned char total;
+ total = FUNC1( get1(addr), reg1(RI_F0) );
+ store1(addr, total);
+ }
+ if (operands == IREGINC_REG) {
+ set_reg2(RI_07, addr+1);
+ }
+ }
+ break;
+
+ case IREGOFF8_REG :
+ case IREGOFF16_REG :
+ {
+ int offset;
+ if (operands == IREGOFF8_REG) {
+ offset = (int)((char) fetch());
+ } else {
+ offset = (int)((short)fetch2());
+ }
+ if (code & 0x0800) { /* word op */
+ t_mem addr = reg2(RI_07) + offset;
+ unsigned short wtotal;
+ wtotal = FUNC2( get2(addr), reg2(RI_F0) );
+ store2(addr, wtotal);
+ } else {
+ t_mem addr = reg2(RI_07) + offset;
+ unsigned char total;
+ total = FUNC1( get1(addr), reg1(RI_F0) );
+ store1(addr, total);
+ }
+ }
+ break;
+
+ case REG_IREGOFF8 :
+ case REG_IREGOFF16 :
+ {
+ int offset;
+ if (operands == REG_IREGOFF8) {
+ offset = (int)((char) fetch());
+ } else {
+ offset = (int)((short)fetch2());
+ }
+
+ if (code & 0x0800) { /* word op */
+ set_reg2( RI_F0,
+ FUNC2( reg2(RI_F0),
+ get2(reg2(RI_07)+offset)
+ )
+ );
+ } else {
+ set_reg1( RI_F0,
+ FUNC1( reg1(RI_F0),
+ get1(reg2(RI_07)+offset)
+ )
+ );
+ }
+ }
+ break;
+
+ case DIRECT_REG :
+ {
+ int addr = ((code & 0x7) << 8) | fetch();
+ if (code & 0x0800) { /* word op */
+ unsigned short wtmp = get_word_direct(addr);
+ set_word_direct( addr,
+ FUNC2( wtmp, reg2(RI_F0) )
+ );
+ } else {
+ unsigned char tmp = get_byte_direct(addr);
+ set_byte_direct( addr,
+ FUNC1( tmp, reg1(RI_F0) )
+ );
+ }
+ }
+ break;
+
+ case REG_DIRECT :
+ {
+ int addr = ((code & 0x7) << 8) | fetch();
+ if (code & 0x0800) { /* word op */
+ set_reg2( RI_F0,
+ FUNC2( reg2(RI_F0),
+ get_word_direct(addr)
+ )
+ );
+ } else {
+ set_reg1( RI_F0,
+ FUNC1( reg1(RI_F0),
+ get_byte_direct(addr)
+ )
+ );
+ }
+ }
+ break;
+
+ case REG_DATA8 :
+#if 0
+ {
+ unsigned char dat = fetch();
+ unsigned char res;
+ res = FUNC1( reg1(RI_F0), dat);
+ set_reg1( RI_F0, res );
+ printf("reg_data8 code=%x dat=%x, res=%x r=%x\n", code, dat, res, reg1( RI_F0) );
+ }
+#endif
+ set_reg1( RI_F0, FUNC1( reg1(RI_F0), fetch()) );
+ break;
+
+ case REG_DATA16 :
+ {
+ unsigned short dat = fetch2();
+ set_reg2( RI_F0, FUNC2( reg2(RI_F0), dat) );
+ }
+ break;
+
+ case IREGINC_DATA8 :
+ case IREG_DATA8 :
+ {
+ unsigned char total;
+ unsigned char tmp;
+ t_mem addr = reg2(RI_70);
+ tmp = get1(addr);
+ total = FUNC1(tmp, fetch() );
+ store1(addr, total);
+ if (operands == IREGINC_DATA8) {
+ set_reg2(RI_70, addr+1);
+ }
+ }
+ break;
+
+ case IREGINC_DATA16 :
+ case IREG_DATA16 :
+ {
+ unsigned short total;
+ unsigned short tmp;
+ t_mem addr = reg2(RI_70);
+ tmp = get2(addr);
+ total = FUNC2(tmp, fetch2() );
+ store2(addr, total);
+ if (operands == IREGINC_DATA16) {
+ set_reg2(RI_70, addr+1);
+ }
+ }
+ break;
+
+ case IREGOFF8_DATA8 :
+ case IREGOFF16_DATA8 :
+ {
+ unsigned short addr;
+ int offset;
+ unsigned char tmp;
+ if (operands == IREGOFF8_DATA8) {
+ offset = (int)((char) fetch());
+ } else {
+ offset = (int)((short)fetch2());
+ }
+ tmp = fetch();
+ addr = reg2(RI_70);
+
+ store1( addr+offset,
+ FUNC1( tmp,
+ get1(addr+offset)
+ )
+ );
+ }
+ break;
+
+ case IREGOFF8_DATA16 :
+ case IREGOFF16_DATA16 :
+ {
+ unsigned short addr;
+ int offset;
+ unsigned short tmp;
+ if (operands == IREGOFF8_DATA16) {
+ offset = (int)((char) fetch());
+ } else {
+ offset = (int)((short)fetch2());
+ }
+ tmp = fetch2();
+ addr = reg2(RI_70);
+
+ store2( addr+offset,
+ FUNC2( tmp,
+ get2(addr+offset)
+ )
+ );
+ }
+ break;
+
+ case DIRECT_DATA8 :
+ {
+ int addr = ((code & 0x70) << 4) | fetch();
+ unsigned char bdir = get_byte_direct(addr);
+ unsigned char bdat = fetch();
+ set_byte_direct( addr, FUNC1( bdir, bdat) );
+ }
+ break;
+
+ case DIRECT_DATA16 :
+ {
+ int addr = ((code & 0x70) << 4) | fetch();
+ unsigned short wdir = get_word_direct(addr);
+ unsigned short wdat = fetch2();
+ set_word_direct( addr, FUNC2( wdir, wdat) );
+ }
+ break;
+ }
+
diff --git a/sim/ucsim/xa.src/instcl.h b/sim/ucsim/xa.src/instcl.h
new file mode 100644
index 0000000..a6a8267
--- /dev/null
+++ b/sim/ucsim/xa.src/instcl.h
@@ -0,0 +1,71 @@
+/* xa.src/instcl.h */
+
+ virtual int inst_ADD(uint code, int operands);
+ virtual int inst_ADDC(uint code, int operands);
+ virtual int inst_ADDS(uint code, int operands);
+ virtual int inst_AND(uint code, int operands);
+ virtual int inst_ANL(uint code, int operands);
+ virtual int inst_ASL(uint code, int operands);
+ virtual int inst_ASR(uint code, int operands);
+ virtual int inst_BCC(uint code, int operands);
+ virtual int inst_BCS(uint code, int operands);
+ virtual int inst_BEQ(uint code, int operands);
+ virtual int inst_BG(uint code, int operands);
+ virtual int inst_BGE(uint code, int operands);
+ virtual int inst_BGT(uint code, int operands);
+ virtual int inst_BKPT(uint code, int operands);
+ virtual int inst_BL(uint code, int operands);
+ virtual int inst_BLE(uint code, int operands);
+ virtual int inst_BLT(uint code, int operands);
+ virtual int inst_BMI(uint code, int operands);
+ virtual int inst_BNE(uint code, int operands);
+ virtual int inst_BNV(uint code, int operands);
+ virtual int inst_BOV(uint code, int operands);
+ virtual int inst_BPL(uint code, int operands);
+ virtual int inst_BR(uint code, int operands);
+ virtual int inst_CALL(uint code, int operands);
+ virtual int inst_CJNE(uint code, int operands);
+ virtual int inst_CLR(uint code, int operands);
+ virtual int inst_CMP(uint code, int operands);
+ virtual int inst_CPL(uint code, int operands);
+ virtual int inst_DA(uint code, int operands);
+ virtual int inst_DIV(uint code, int operands);
+ virtual int inst_DJNZ(uint code, int operands);
+ virtual int inst_FCALL(uint code, int operands);
+ virtual int inst_FJMP(uint code, int operands);
+ virtual int inst_JB(uint code, int operands);
+ virtual int inst_JBC(uint code, int operands);
+ virtual int inst_JNB(uint code, int operands);
+ virtual int inst_JMP(uint code, int operands);
+ virtual int inst_JNZ(uint code, int operands);
+ virtual int inst_JZ(uint code, int operands);
+ virtual int inst_LEA(uint code, int operands);
+ virtual int inst_LSR(uint code, int operands);
+ virtual int inst_MOV(uint code, int operands);
+ virtual int inst_MOVC(uint code, int operands);
+ virtual int inst_MOVS(uint code, int operands);
+ virtual int inst_MOVX(uint code, int operands);
+ virtual int inst_MUL(uint code, int operands);
+ virtual int inst_NEG(uint code, int operands);
+ virtual int inst_NOP(uint code, int operands);
+ virtual int inst_NORM(uint code, int operands);
+ virtual int inst_OR(uint code, int operands);
+ virtual int inst_ORL(uint code, int operands);
+ virtual int inst_POP(uint code, int operands);
+ virtual int inst_PUSH(uint code, int operands);
+ virtual int inst_RET(uint code, int operands);
+ virtual int inst_RETI(uint code, int operands);
+ virtual int inst_RESET(uint code, int operands);
+ virtual int inst_RL(uint code, int operands);
+ virtual int inst_RLC(uint code, int operands);
+ virtual int inst_RR(uint code, int operands);
+ virtual int inst_RRC(uint code, int operands);
+ virtual int inst_SETB(uint code, int operands);
+ virtual int inst_SEXT(uint code, int operands);
+ virtual int inst_SUB(uint code, int operands);
+ virtual int inst_SUBB(uint code, int operands);
+ virtual int inst_TRAP(uint code, int operands);
+ virtual int inst_XCH(uint code, int operands);
+ virtual int inst_XOR(uint code, int operands);
+
+/* End of xa.src/instcl.h */
diff --git a/sim/ucsim/xa.src/regsxa.h b/sim/ucsim/xa.src/regsxa.h
new file mode 100644
index 0000000..2df2d3e
--- /dev/null
+++ b/sim/ucsim/xa.src/regsxa.h
@@ -0,0 +1,285 @@
+/*
+ * Simulator of microcontrollers (regsxa.h)
+ *
+ * Copyright (C) 1999,2002 Drotos Daniel, Talker Bt.
+ *
+ * To contact author send email to drdani@mazsola.iit.uni-miskolc.hu
+ * Other contributors include:
+ * Karl Bongers karl@turbobit.com,
+ * Johan Knol
+ *
+ */
+
+/* This file is part of microcontroller simulator: ucsim.
+
+UCSIM 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.
+
+UCSIM 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 UCSIM; see the file COPYING. If not, write to the Free
+Software Foundation, 59 Temple Place - Suite 330, Boston, MA
+02111-1307, USA. */
+/*@1@*/
+
+#ifndef REGSAVR_HEADER
+#define REGSAVR_HEADER
+
+#define REGS_OFFSET 0x800
+
+#include "ddconfig.h"
+
+struct t_regs
+{
+ int dummy;
+};
+
+/* these macros suck, what was I thinking? Try to make it go fast
+ at the our expense? Daniels going to hate me if I continue to
+ clutter up his nice C++ with old crusty C macros :) Karl.
+*/
+
+/* store to sfr */
+#define set_word_direct(addr, val) { sfr->write((t_addr) (addr), (val) & 0xff); \
+ sfr->write((t_addr) ((addr)+1), ((val) >> 8) & 0xff); \
+ vc.wr+= 2; }
+#define set_byte_direct(addr, val) { sfr->write((t_addr) (addr), (val) ); vc.wr++; }
+
+/* get from sfr */
+#define get_byte_direct(addr) (vc.rd++, (sfr->read((t_addr) (addr))))
+#define get_word_direct(addr) (vc.rd+= 2, ((sfr->read((t_addr) (addr)) | (sfr->read((t_addr) ((addr)+1)) << 8) )))
+
+/* store to idata(onchip) ram */
+#define set_idata2(addr, val) { iram->write((t_addr) (addr), (val) & 0xff); \
+ iram->write((t_addr) (addr+1), ((val) >> 8) & 0xff); \
+ vc.wr+= 2; }
+#define set_idata1(addr, val) { iram->write((t_addr) (addr), (val) ); vc.wr++; }
+
+/* get from idata(onchip) ram */
+#define get_idata1(addr) (vc.rd++, (iram->read((t_addr) (addr))))
+#define get_idata2(addr) (vc.rd+= 2, (iram->read((t_addr) (addr)) | (iram->read((t_addr) (addr+1)) << 8) ))
+
+/* store to xdata(external) ram */
+#define set_xdata2(addr, val) { ram->write((t_addr) (addr), (val) & 0xff); \
+ ram->write((t_addr) (addr+1), ((val) >> 8) & 0xff); \
+ vc.wr+= 2; }
+#define set_xdata1(addr, val) { ram->write((t_addr) (addr), val); vc.wr++; }
+
+/* get from xdata(external) ram */
+#define get_xdata1(addr) (vc.rd++, (ram->read((t_addr) (addr))))
+#define get_xdata2(addr) (vc.rd+= 2, (ram->read((t_addr) (addr)) | (ram->read((t_addr) (addr+1)) << 8) ))
+
+/* get from code */
+#define getcode1(addr) (vc.rd++, rom->read((t_addr) (addr)))
+#define getcode2(addr) (vc.rd+= 2, (rom->read((t_addr) (addr)) | (rom->read((t_addr) (addr+1)) << 8) ))
+
+/* fetch from opcode code space */
+#define fetch2() ((fetch() << 8) | fetch())
+#define fetch1() fetch()
+
+/* get a 1 or 2 byte register */
+#define reg2(_index) get_reg(1, REGS_OFFSET + ((_index)<<1)) /* function in inst.cc */
+#define reg1(_index) (unsigned char)get_reg(0, REGS_OFFSET + (_index))
+
+#define set_reg1(_index, _value) { \
+ set_byte_direct((REGS_OFFSET+(_index)), _value); \
+}
+
+#define set_reg2(_index, _value) { \
+ set_word_direct( (REGS_OFFSET+((_index)<<1)), _value); \
+}
+
+#define set_reg(_word_flag, _index, _value) { \
+ if (_word_flag) \
+ { set_reg2((_index), _value) } \
+ else \
+ { set_reg1((_index), _value) } \
+}
+
+/* R7 mirrors 1 of 2 real SP's
+ note: we will probably need a real function here...
+ */
+#define set_sp(_value) { \
+ { set_word_direct(REGS_OFFSET+(7*2), _value); } \
+}
+
+#define get_sp() ((u16_t)(get_word_direct(REGS_OFFSET+(7*2))))
+
+/* the program status word */
+#define PSW 0x400
+#define get_psw() ((u16_t)(get_word_direct(PSW)))
+#define set_psw(_flags) set_word_direct(PSW, _flags)
+
+/* the system configuration register */
+#define SCR 0x440
+#define get_scr() get_byte_direct(SCR)
+#define set_scr(scr) set_byte_direct(SCR, scr)
+
+// PSW bits...(note: consider replacing with Bit defines used in s51.src code)
+#define BIT_C 0x80
+#define BIT_AC 0x40
+#define BIT_V 0x04
+#define BIT_N 0x02
+#define BIT_Z 0x01
+#define BIT_ALL (BIT_C | BIT_AC | BIT_V | BIT_N | BIT_Z)
+
+
+#if 0
+/*--------------------------------------------------------------------
+Developer Notes.
+
+This user guide has got the detailed information on the XA chip.
+
+http://www.semiconductors.philips.com/acrobat/various/XA_USER_GUIDE_1.pdf
+
+f: {unused slot(word accessable only) for R8-R15}
+e: R7h,R7l Stack pointer, ptr to USP(PSW.SM=0), or SSP(PSW.SM=1)
+c: R6h,R6l
+a: R5h,R5l
+8: R4h,R4l
+below are the banked registers which mirror(B0..B3) depending on
+PSW.(RS0,RS1)
+6: R3h,R3l
+4: R2h,R2l
+2: R1h,R1l
+0: R0h,R0l
+
+Registers are all bit addressable as:
+2: bx1f,bx1e...b8(R0h) bx17,bx16..bx10(R0l)
+0: bxf,bxe...b8(R0h) b7,b6..b0(R0l)
+
+Memory is little endian:
+addr0: LSB
+addr1: MSB
+
+Data word access limited to word boundaries. If non-word address used,
+then will act as lesser word alignment used(addr b0=0).
+
+Internal memory takes precedence over external memory, unless
+explicit movx used.
+
+64K segment memory layout, bank registers used include:
+DS(data segment) and ES(extra segment) and forms high byte of
+24 bit address. Stack is in DS, so ES typically used to access
+user data.
+
+SFR(1K direct space) is above normal 1K direct address space(0-3FFH)
+between 400H to 7FFH.
+
+Branch targets must reside on even boundaries
+
+MOVC instructions use either PC(SSEL.4=0) or CS(SSEL.4=1) register.
+
+Core SFRs:
+PCON, SCR, SSEL, PSWH, PSWL, CS, ES, DS
+(1K SFR space)
+400H-43FH are bit or byte accesable.
+400H-5FFH is for built in SFR hardware.
+600H-7FFH is for external SFR hardware access.
+SFR access is independent of segment regs.
+SFR inacessable from indirect addressing(must use direct-addr in opcodes).
+
+Bit space:
+0 to ffH - R0 to R15
+100H to 1ffH - 20h to 3fH(direct ram, relative to DS)
+200H to 3FFH - 400H to 43FH(on board SFRs)
+
+PSW Flags: Carry(C), Aux Carry(AC), Overflow(V), Negative(N), Zero(Z).
+
+Stack ptr is pre-decremented, followed by load(word operation),
+default SPs are set to 100H. So first PUSH would go to FEH-FFH.
+
+DIRECT MEMORY SPACE
+
+When we speak of direct memory space we refer to opcodes like
+MOV Rd, direct
+The "direct" part is always composed of 11 bits in the opcode.
+So the total size of "direct" space is 2K bytes.
+
+1.) This direct memory space contains the SFRs starting at 0x400 offset.
+
+Internal onchip memory(SFRs and onchip RAM) always override
+external memory. Read the specific Chip documentation for the
+location of SFRs and RAM.
+
+The codes space is independent.
+
+The registers: 4 banks of 8 bytes(R0-R3), R4-R7 8 bytes, and stack
+pointers are self contained and not part of any address space.
+(The CS,ES,DS appear to reside in SFR space).
+
+This is still confusing, let take some examples.
+
+---------------------------
+XA-G49 chip has 2k bytes built in RAM.
+
+According to the XA-G49 datasheet:
+
+With the DS set to 0, then all indirect address references
+between 0-7FFH reference the onchip 2K RAM. Direct address
+references below 0x400 access onchip 2K RAM.
+
+With the DS not set to 0, then all indirect address references
+between 0-7FFH reference external memory. Direct address
+references below 0x400 access external memory.
+
+Any direct address references between 400H and 7FFH access the SFRs
+regardless of the segment register contents.
+
+To access any external memory which overlaps the 2K onchip memory
+ues the MOVX instruction.
+
+---------------------------
+Proposed segment layout use for SDCC/XA compiler:
+
+XDATA -> external memory(use indirect addressing, ignore direct
+ addressing, ignore any overlap with onchip memory).
+
+IDATA -> onchip memory(use indirect addressing, ignore direct
+ addressing, assume small model where DS,ES always 0).
+
+DATA -> SFR memory access using direct addressing.
+
+CODE -> Far calls/returns are available.
+
+(Johan, Im just trying to spell this out explicitly for
+my own understanding.)
+
+---------------------------
+Proposed segment layout use for ucSim XA simulator.
+
+ram -> external memory.
+
+rom -> external/internal code.
+
+sfr -> SFR register space. Include registers/register banks here
+in some unused location to provide a means to dump all the register
+file contents using the "ds" command. Could make sfr memory larger
+than 0x800, and use the space above 0x800 to hold registers/sp-s.
+
+idata -> onchip memory.
+
+I think we can determine the size of idata memory at run time, so
+this could allow for various sized onchip memorys. So indirect
+memory accesses like this:
+set_indirect1(addr, value) {
+ if (addr < mem_size(idata)) {
+ set_idata(addr,value);
+ } else {
+ set_xdata(addr,value);
+ }
+}
+
+----------------------------------------------
+*/
+#endif
+
+
+#endif
+/* End of xa.src/regsxa.h */
diff --git a/sim/ucsim/xa.src/simxa.cc b/sim/ucsim/xa.src/simxa.cc
new file mode 100644
index 0000000..6120f2b
--- /dev/null
+++ b/sim/ucsim/xa.src/simxa.cc
@@ -0,0 +1,45 @@
+/*
+ * Simulator of microcontrollers (simxa.cc)
+ *
+ * Copyright (C) 1999,99 Drotos Daniel, Talker Bt.
+ *
+ * To contact author send email to drdani@mazsola.iit.uni-miskolc.hu
+ *
+ */
+
+/* This file is part of microcontroller simulator: ucsim.
+
+UCSIM 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.
+
+UCSIM 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 UCSIM; see the file COPYING. If not, write to the Free
+Software Foundation, 59 Temple Place - Suite 330, Boston, MA
+02111-1307, USA. */
+/*@1@*/
+
+
+// local
+#include "simxacl.h"
+#include "xacl.h"
+
+
+cl_simxa::cl_simxa(class cl_app *the_app):
+ cl_sim(the_app)
+{}
+
+class cl_uc *
+cl_simxa::mk_controller(void)
+{
+ return(new cl_xa(this));
+}
+
+
+/* End of xa.src/simxa.cc */
diff --git a/sim/ucsim/xa.src/simxacl.h b/sim/ucsim/xa.src/simxacl.h
new file mode 100644
index 0000000..1a22c5b
--- /dev/null
+++ b/sim/ucsim/xa.src/simxacl.h
@@ -0,0 +1,45 @@
+/*
+ * Simulator of microcontrollers (simxacl.h)
+ *
+ * Copyright (C) 1999,99 Drotos Daniel, Talker Bt.
+ *
+ * To contact author send email to drdani@mazsola.iit.uni-miskolc.hu
+ *
+ */
+
+/* This file is part of microcontroller simulator: ucsim.
+
+UCSIM 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.
+
+UCSIM 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 UCSIM; see the file COPYING. If not, write to the Free
+Software Foundation, 59 Temple Place - Suite 330, Boston, MA
+02111-1307, USA. */
+/*@1@*/
+
+#ifndef SIMXACL_HEADER
+#define SIMXACL_HEADER
+
+#include "simcl.h"
+
+
+class cl_simxa: public cl_sim
+{
+public:
+ cl_simxa(class cl_app *the_app);
+
+ virtual class cl_uc *mk_controller(void);
+};
+
+
+#endif
+
+/* End of xa.src/simxacl.h */
diff --git a/sim/ucsim/xa.src/sxa.cc b/sim/ucsim/xa.src/sxa.cc
new file mode 100644
index 0000000..0cf0759
--- /dev/null
+++ b/sim/ucsim/xa.src/sxa.cc
@@ -0,0 +1,56 @@
+/*
+ * Simulator of microcontrollers (sxa.cc)
+ *
+ * Copyright (C) 1999,99 Drotos Daniel, Talker Bt.
+ *
+ * To contact author send email to drdani@mazsola.iit.uni-miskolc.hu
+ *
+ */
+
+/* This file is part of microcontroller simulator: ucsim.
+
+UCSIM 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.
+
+UCSIM 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 UCSIM; see the file COPYING. If not, write to the Free
+Software Foundation, 59 Temple Place - Suite 330, Boston, MA
+02111-1307, USA. */
+/*@1@*/
+
+// prj
+#include "globals.h"
+
+// sim.src
+#include "appcl.h"
+
+// local
+#include "simxacl.h"
+
+
+int
+main(int argc, char *argv[])
+{
+ class cl_sim *sim;
+
+ application= new cl_app();
+ application->init(argc, argv);
+ sim= new cl_simxa(application);
+ if (sim->init())
+ sim->state|= SIM_QUIT;
+ application->set_simulator(sim);
+ application->run();
+ application->done();
+ delete application;
+ return(0);
+}
+
+
+/* End of xa.src/sxa.cc */
diff --git a/sim/ucsim/xa.src/xa.cc b/sim/ucsim/xa.src/xa.cc
new file mode 100644
index 0000000..92452ba
--- /dev/null
+++ b/sim/ucsim/xa.src/xa.cc
@@ -0,0 +1,1190 @@
+/*
+ * Simulator of microcontrollers (xa.cc)
+ *
+ * Copyright (C) 1999,2002 Drotos Daniel, Talker Bt.
+ *
+ * To contact author send email to drdani@mazsola.iit.uni-miskolc.hu
+ * Other contributors include:
+ * Karl Bongers karl@turbobit.com,
+ * Johan Knol johan.knol@iduna.nl
+ */
+
+/* This file is part of microcontroller simulator: ucsim.
+
+UCSIM 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.
+
+UCSIM 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 UCSIM; see the file COPYING. If not, write to the Free
+Software Foundation, 59 Temple Place - Suite 330, Boston, MA
+02111-1307, USA. */
+/*@1@*/
+
+#include "ddconfig.h"
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <ctype.h>
+#include "i_string.h"
+
+// prj
+#include "pobjcl.h"
+
+// sim
+#include "simcl.h"
+
+// local
+#include "xacl.h"
+#include "glob.h"
+#include "regsxa.h"
+
+
+/*
+ * Names of SFRs
+ */
+
+static struct name_entry sfr_tabXA51[]=
+{
+ //#include "xa_sfr.cc"
+ {CPU_XA, 0x400, "PSW"}, /* Program status word */
+ {CPU_XA, 0x400, "PSWL"}, /* Program status word (low byte) */
+ {CPU_XA, 0x401, "PSWH"}, /* Program status word (high byte) */
+ {CPU_XA, 0x402, "PSW51"}, /* 80C51 compatible PSW */
+ {CPU_XA, 0x403, "SSEL"}, /* Segment selection register */
+ {CPU_XA, 0x404, "PCON"}, /* Power control register */
+ {CPU_XA, 0x410, "TCON"}, /* Timer 0 and 1 control register */
+ {CPU_XA, 0x411, "TSTAT"}, /* Timer 0 and 1 extended status */
+ {CPU_XA, 0x418, "T2CON"}, /* Timer 2 control register */
+ {CPU_XA, 0x419, "T2MOD"}, /* Timer 2 mode control */
+ {CPU_XA, 0x41F, "WDCON"}, /* Watchdog control register */
+ {CPU_XA, 0x420, "S0CON"}, /* Serial port 0 control register */
+ {CPU_XA, 0x421, "S0STAT"}, /* Serial port 0 extended status */
+ {CPU_XA, 0x424, "S1CON"}, /* Serial port 1 control register */
+ {CPU_XA, 0x425, "S1STAT"}, /* Serial port 1 extended status */
+ {CPU_XA, 0x426, "IEL"}, /* Interrupt enable low byte */
+ {CPU_XA, 0x427, "IEH"}, /* Interrupt enable high byte */
+ {CPU_XA, 0x42A, "SWR"}, /* Software Interrupt Request */
+ {CPU_XA, 0x430, "P0"}, /* Port 0 */
+ {CPU_XA, 0x431, "P1"}, /* Port 1 */
+ {CPU_XA, 0x432, "P2"}, /* Port 2 */
+ {CPU_XA, 0x433, "P3"}, /* Port3 */
+ {CPU_XA, 0x440, "SCR"}, /* System configuration register */
+ {CPU_XA, 0x441, "DS"}, /* Data segment */
+ {CPU_XA, 0x442, "ES"}, /* Extra segment */
+ {CPU_XA, 0x443, "CS"}, /* Code segment */
+ {CPU_XA, 0x450, "TL0"}, /* Timer 0 low byte */
+ {CPU_XA, 0x451, "TH0"}, /* Timer 0 high byte */
+ {CPU_XA, 0x452, "TL1"}, /* Timer 1 low byte */
+ {CPU_XA, 0x453, "TH1"}, /* Timer 1 high byte */
+ {CPU_XA, 0x454, "RTL0"}, /* Timer 0 extended reload, low byte */
+ {CPU_XA, 0x455, "RTH0"}, /* Timer 0 extended reload, high byte */
+ {CPU_XA, 0x456, "RTL1"}, /* Timer 1 extended reload, low byte */
+ {CPU_XA, 0x457, "RTH1"}, /* Timer 1 extended reload, high byte */
+ {CPU_XA, 0x458, "TL2"}, /* Timer 2 low byte */
+ {CPU_XA, 0x459, "TH2"}, /* Timer 2 high byte */
+ {CPU_XA, 0x45A, "T2CAPL"}, /* Timer 2 capture register, low byte */
+ {CPU_XA, 0x45B, "T2CAPH"}, /* Timer 2 capture register, high byte */
+ {CPU_XA, 0x45C, "TMOD"}, /* Timer 0 and 1 mode register */
+ {CPU_XA, 0x45D, "WFEED1"}, /* Watchdog feed 1 */
+ {CPU_XA, 0x45E, "WFEED2"}, /* Watchdog feed 2 */
+ {CPU_XA, 0x45F, "WDL"}, /* Watchdog timer reload */
+ {CPU_XA, 0x460, "S0BUF"}, /* Serial port 0 buffer register */
+ {CPU_XA, 0x461, "S0ADDR"}, /* Serial port 0 address register */
+ {CPU_XA, 0x462, "S0ADEN"}, /* Serial port 0 address enable register */
+ {CPU_XA, 0x464, "S1BUF"}, /* Serial port 1 buffer register */
+ {CPU_XA, 0x465, "S1ADDR"}, /* Serial port 1 address register */
+ {CPU_XA, 0x466, "S1ADEN"}, /* Serial port 1 address enable register */
+ {CPU_XA, 0x468, "BTRL"}, /* Bus timing register high byte */
+ {CPU_XA, 0x469, "BTRH"}, /* Bus timing register low byte */
+ {CPU_XA, 0x46A, "BCR"}, /* Bus configuration register */
+ {CPU_XA, 0x470, "P0CFGA"}, /* Port 0 configuration A */
+ {CPU_XA, 0x471, "P1CFGA"}, /* Port 1 configuration A */
+ {CPU_XA, 0x472, "P2CFGA"}, /* Port 2 configuration A */
+ {CPU_XA, 0x473, "P3CFGA"}, /* Port 3 configuration A */
+ {CPU_XA, 0x47A, "SWE"}, /* Software Interrupt Enable */
+ {CPU_XA, 0x4A0, "IPA0"}, /* Interrupt priority 0 */
+ {CPU_XA, 0x4A1, "IPA1"}, /* Interrupt priority 1 */
+ {CPU_XA, 0x4A2, "IPA2"}, /* Interrupt priority 2 */
+ {CPU_XA, 0x4A4, "IPA4"}, /* Interrupt priority 4 */
+ {CPU_XA, 0x4A5, "IPA5"}, /* Interrupt priority 5 */
+ {CPU_XA, 0x4F0, "P0CFGB"}, /* Port 0 configuration B */
+ {CPU_XA, 0x4F1, "P1CFGB"}, /* Port 1 configuration B */
+ {CPU_XA, 0x4F2, "P2CFGB"}, /* Port 2 configuration B */
+ {CPU_XA, 0x4F3, "P3CFGB"}, /* Port 3 configuration B */
+ { 0, 0, NULL }
+};
+
+/*
+ * Names of SBITs
+ */
+
+static struct name_entry bit_tabXA51[]=
+{
+ //#include "xa_bit.cc"
+ {CPU_XA, 0x33B, "ETI1"}, /* TX interrupt enable 1 */
+ {CPU_XA, 0x33A, "ERI1"}, /* RX interrupt enable 1 */
+ {CPU_XA, 0x339, "ETI0"}, /* TX interrupt enable 0 */
+ {CPU_XA, 0x338, "ERI0"}, /* RX interrupt enable 0 */
+ {CPU_XA, 0x337, "EA"}, /* global int. enable */
+ {CPU_XA, 0x334, "ET2"}, /* timer 2 interrupt */
+ {CPU_XA, 0x333, "ET1"}, /* timer 1 interrupt */
+ {CPU_XA, 0x332, "EX1"}, /* external interrupt 1 */
+ {CPU_XA, 0x331, "ET0"}, /* timer 0 interrupt */
+ {CPU_XA, 0x330, "EX0"}, /* external interrupt 0 */
+ {CPU_XA, 0x221, "PD"}, /* power down */
+ {CPU_XA, 0x220, "IDL"},
+ {CPU_XA, 0x20F, "SM"},
+ {CPU_XA, 0x20E, "TM"},
+ {CPU_XA, 0x20D, "RS1"},
+ {CPU_XA, 0x20C, "RS0"},
+ {CPU_XA, 0x20B, "IM3"},
+ {CPU_XA, 0x20A, "IM2"},
+ {CPU_XA, 0x209, "IM1"},
+ {CPU_XA, 0x208, "IM0"},
+ {CPU_XA, 0x307, "S0M0"},
+ {CPU_XA, 0x306, "S0M1"},
+ {CPU_XA, 0x305, "S0M2"},
+ {CPU_XA, 0x304, "R0EN"},
+ {CPU_XA, 0x303, "T0B8"},
+ {CPU_XA, 0x302, "R0B8"},
+ {CPU_XA, 0x301, "TI0"}, /* serial port 0 tx ready */
+ {CPU_XA, 0x300, "RI0"}, /* serial port 0 rx ready */
+ {CPU_XA, 0x30B, "FE0"},
+ {CPU_XA, 0x30A, "BR0"},
+ {CPU_XA, 0x309, "OE0"},
+ {CPU_XA, 0x308, "STINT0"},
+ {CPU_XA, 0x327, "S1M0"},
+ {CPU_XA, 0x326, "S1M1"},
+ {CPU_XA, 0x325, "S1M2"},
+ {CPU_XA, 0x324, "R1EN"},
+ {CPU_XA, 0x323, "T1B8"},
+ {CPU_XA, 0x322, "R1B8"},
+ {CPU_XA, 0x321, "TI1"}, /* serial port 0 tx ready */
+ {CPU_XA, 0x320, "RI1"}, /* serial port 0 rx ready */
+ {CPU_XA, 0x32B, "FE1"},
+ {CPU_XA, 0x32A, "BR1"},
+ {CPU_XA, 0x329, "OE1"},
+ {CPU_XA, 0x328, "STINT1"},
+ {CPU_XA, 0x356, "SWR7"},
+ {CPU_XA, 0x355, "SWR6"},
+ {CPU_XA, 0x354, "SWR5"},
+ {CPU_XA, 0x353, "SWR4"},
+ {CPU_XA, 0x352, "SWR3"},
+ {CPU_XA, 0x351, "SWR2"},
+ {CPU_XA, 0x350, "SWR1"},
+ {CPU_XA, 0x2C7, "TF2"},
+ {CPU_XA, 0x2C6, "EXF2"},
+ {CPU_XA, 0x2C5, "RCLK0"},
+ {CPU_XA, 0x2C4, "TCLK0"},
+ {CPU_XA, 0x2CD, "RCLK1"},
+ {CPU_XA, 0x2CC, "TCLK1"},
+ {CPU_XA, 0x2C3, "EXEN2"},
+ {CPU_XA, 0x2C2, "TR2"},
+ {CPU_XA, 0x2C1, "CT2"},
+ {CPU_XA, 0x2C0, "CPRL2"},
+ {CPU_XA, 0x2C9, "T2OE"},
+ {CPU_XA, 0x2C8, "DCEN"},
+ {CPU_XA, 0x287, "TF1"},
+ {CPU_XA, 0x286, "TR1"},
+ {CPU_XA, 0x285, "TF0"},
+ {CPU_XA, 0x284, "TR0"},
+ {CPU_XA, 0x283, "IE1"},
+ {CPU_XA, 0x282, "IT1"},
+ {CPU_XA, 0x281, "IE0"},
+ {CPU_XA, 0x280, "IT0"},
+ {CPU_XA, 0x28A, "T1OE"},
+ {CPU_XA, 0x288, "T0OE"},
+ {CPU_XA, 0x2FF, "PRE2"},
+ {CPU_XA, 0x2FE, "PRE1"},
+ {CPU_XA, 0x2FD, "PRE0"},
+ {CPU_XA, 0x2FA, "WDRUN"},
+ {CPU_XA, 0x2F9, "WDTOF"},
+ {CPU_XA, 0x2F8, "WDMOD"},
+ {CPU_XA, 0x388, "WR1"},
+ {CPU_XA, 0x38F, "T2EX"},
+ {CPU_XA, 0x38C, "RXD1"},
+ {CPU_XA, 0x38D, "TXD1"},
+ {CPU_XA, 0x398, "RXD0"},
+ {CPU_XA, 0x399, "TXD0"},
+ {CPU_XA, 0x39A, "INT0"},
+ {CPU_XA, 0x39B, "INT1"},
+ {CPU_XA, 0x39C, "T0"},
+ {CPU_XA, 0x39D, "T1"},
+ {CPU_XA, 0x39E, "WR"},
+ {CPU_XA, 0x39F, "RD"},
+ { 0, 0, NULL }
+};
+
+
+/*
+ * Base type of xa controllers
+ */
+
+cl_xa::cl_xa(class cl_sim *asim):
+ cl_uc(asim)
+{
+ type= (struct cpu_entry *)malloc(sizeof(struct cpu_entry));
+ type->type= CPU_XA;
+}
+
+int
+cl_xa::init(void)
+{
+ cl_uc::init(); /* Memories now exist */
+
+ /* set SCR to osc/4, native XA mode, flat 24 */
+ set_scr(0);
+ /* initialize SP to 100H */
+ set_reg2(7, 0x100);
+ /* set PSW from reset vector */
+ set_psw(getcode2(0));
+ /* set PC from reset vector */
+ PC = getcode2(2);
+
+ printf("The XA Simulator is in development, UNSTABLE, DEVELOPERS ONLY!\n");
+
+ int i;
+ for (i= 0; sfr_tabXA51[i].name != NULL; i++)
+ {
+ if (type->type & sfr_tabXA51[i].cpu_type)
+ {
+ class cl_var *v;
+ vars->add(v= new cl_var(chars(sfr_tabXA51[i].name),
+ sfr,
+ sfr_tabXA51[i].addr, ""));
+ v->init();
+ }
+ }
+ for (i= 0; bit_tabXA51[i].name != NULL; i++)
+ {
+ if (type->type & bit_tabXA51[i].cpu_type)
+ {
+ class cl_var *v;
+ t_addr a= bit_tabXA51[i].addr;
+ int bitnr, offset= 0;
+ if (a >= 0x200)
+ {
+ a-= 0x200;
+ offset= 0x400;
+ }
+ bitnr= a%8;
+ a= offset + a/8;
+ vars->add(v= new cl_var(chars(bit_tabXA51[i].name),
+ sfr,
+ a, "", bitnr));
+ v->init();
+ }
+ }
+ return(0);
+}
+
+
+char *
+cl_xa::id_string(void)
+{
+ return((char*)"unspecified XA");
+}
+
+
+/*
+ * Making elements of the controller
+ */
+
+void
+cl_xa::mk_hw_elements(void)
+{
+ //class cl_base *o;
+ cl_uc::mk_hw_elements();
+}
+
+void
+cl_xa::make_memories(void)
+{
+ class cl_address_space *as;
+
+ as= rom= new cl_address_space("rom", 0, 0x10000, 8);
+ as->init();
+ address_spaces->add(as);
+ as= iram= new cl_address_space("iram", 0, 0x2000, 8);
+ as->init();
+ address_spaces->add(as);
+ as= sfr= new cl_address_space("sfr", 0x0, 0x2000, 8);
+ as->init();
+ address_spaces->add(as);
+ as= ram= new cl_address_space("xram", 0, 0x10000, 8);
+ as->init();
+ address_spaces->add(as);
+
+ class cl_address_decoder *ad;
+ class cl_memory_chip *chip;
+
+ chip= new cl_memory_chip("rom_chip", 0x10000, 8);
+ chip->init();
+ memchips->add(chip);
+ ad= new cl_address_decoder(as= address_space("rom"), chip, 0, 0xffff, 0);
+ ad->init();
+ as->decoders->add(ad);
+ ad->activate(0);
+
+ chip= new cl_memory_chip("iram_chip", 0x2000, 8);
+ chip->init();
+ memchips->add(chip);
+ ad= new cl_address_decoder(as= address_space("iram"), chip, 0, 0x1fff, 0);
+ ad->init();
+ as->decoders->add(ad);
+ ad->activate(0);
+
+ chip= new cl_memory_chip("xram_chip", 0x10000, 8);
+ chip->init();
+ memchips->add(chip);
+ ad= new cl_address_decoder(as= address_space("xram"), chip, 0, 0xffff, 0);
+ ad->init();
+ as->decoders->add(ad);
+ ad->activate(0);
+
+ chip= new cl_memory_chip("sfr_chip", 0x2000, 8);
+ chip->init();
+ memchips->add(chip);
+ ad= new cl_address_decoder(as= address_space("sfr"), chip, 0x0, 0x1fff, 0);
+ ad->init();
+ as->decoders->add(ad);
+ ad->activate(0);
+}
+
+
+/*
+ * Help command interpreter
+ */
+
+struct dis_entry *
+cl_xa::dis_tbl(void)
+{
+ // this should be unused, we need to make main prog code
+ // independent of any array thing.
+ printf("ERROR - Using disass[] table in XA sim code!\n");
+ return(glob_disass_xa);
+}
+
+struct name_entry *cl_xa::sfr_tbl(void)
+{
+ return(sfr_tabXA51);
+}
+
+struct name_entry *cl_xa::bit_tbl(void)
+{
+ return(bit_tabXA51);
+}
+
+int
+cl_xa::inst_length(t_addr addr)
+{
+ int len = 0;
+
+ get_disasm_info(addr, &len, NULL, NULL, NULL, NULL);
+
+ return len;
+}
+
+int
+cl_xa::inst_branch(t_addr addr)
+{
+ int b;
+
+ get_disasm_info(addr, NULL, &b, NULL, NULL, NULL);
+
+ return b;
+}
+
+int
+cl_xa::longest_inst(void)
+{
+ return 6;
+}
+
+static char dir_name[64];
+char *cl_xa::get_dir_name(short addr) {
+ if (!/*get*/addr_name(addr, sfr/*_tbl()*/, dir_name)) {
+ sprintf (dir_name, "0x%03x", addr);
+ }
+ return dir_name;
+}
+
+static char bit_name[64];
+char *cl_xa::get_bit_name(short addr) {
+ t_addr a= addr; int offset= 0, bitnr= addr%8;
+ if (a >= 0x200) { a-= 0x200; offset= 0x400; }
+ a= offset+a/8;
+ if (!/*get*/addr_name(a/*ddr*/, sfr/*bit_tbl()*/, bitnr, bit_name)) {
+ sprintf (bit_name, "0x%03x", addr);
+ }
+ return bit_name;
+}
+
+/*--------------------------------------------------------------------
+get_disasm_info - Given an address, return information about the opcode
+ which resides there.
+ addr - address of opcode we want information on.
+ ret_len - return length of opcode.
+ ret_branch - return a character which indicates if we are
+ a branching opcode. Used by main app to implement "Next"
+ function which steps over functions.
+ immed_offset - return a number which represents the number of bytes
+ offset to where any immediate data is(tail end of opcode). Used
+ for printing disassembly.
+ operands - return a key indicating the form of the operands,
+ used for printing the disassembly.
+ mnemonic - return a key indicating the mnemonic of the instruction.
+
+ Return value: Return the operand code formed by either the single
+ byte opcode or 2 bytes of the opcode for multi-byte opcodes.
+
+ Note: Any of the return pointer parameters can be set to NULL to
+ indicate the caller does not want the information.
+|--------------------------------------------------------------------*/
+int
+cl_xa::get_disasm_info(t_addr addr,
+ int *ret_len,
+ int *ret_branch,
+ int *immed_offset,
+ int *parms,
+ int *mnemonic)
+{
+ uint code;
+ //int len = 0;
+ int immed_n = 0;
+ int i;
+ int start_addr = addr;
+
+ code= rom->get(addr++);
+ if (code == 0x00) {
+ i= 0;
+ while (disass_xa[i].mnemonic != NOP)
+ i++;
+ } else {
+ //len = 2;
+ code = (code << 8) | rom->get(addr++);
+ i= 0;
+ while ((code & disass_xa[i].mask) != disass_xa[i].code &&
+ disass_xa[i].mnemonic != BAD_OPCODE)
+ i++;
+ }
+
+ if (ret_len)
+ *ret_len = disass_xa[i].length;
+ if (ret_branch)
+ *ret_branch = disass_xa[i].branch;
+ if (immed_offset) {
+ if (immed_n > 0)
+ *immed_offset = immed_n;
+ else *immed_offset = (addr - start_addr);
+ }
+ if (parms) {
+ *parms = disass_xa[i].operands;
+ }
+ if (mnemonic) {
+ *mnemonic = disass_xa[i].mnemonic;
+ }
+
+ return code;
+}
+
+static const char *w_reg_strs[] = {
+ "R0", "R1",
+ "R2", "R3",
+ "R4", "R5",
+ "R6", "R7",
+ "R8", "R9",
+ "R10", "R11",
+ "R12", "R13",
+ "R14", "R15"};
+
+static const char *b_reg_strs[] = {
+ "R0l", "R0h",
+ "R1l", "R1h",
+ "R2l", "R2h",
+ "R3l", "R3h",
+ "R4l", "R4h",
+ "R5l", "R5h",
+ "R6l", "R6h",
+ "R7l", "R7h"};
+
+/*--------------------------------------------------------------------
+disass - Disassemble an opcode.
+ addr - address of opcode to disassemble/print.
+ sep - optionally points to string(tab) to use as separator.
+|--------------------------------------------------------------------*/
+char *
+cl_xa::disass(t_addr addr, const char *sep)
+{
+ char work[256], parm_str[40];
+ char *buf, *p, *b;
+ int code;
+ int len = 0;
+ int immed_offset = 0;
+ int operands;
+ int mnemonic;
+ const char **reg_strs;
+
+ p= work;
+
+ code = get_disasm_info(addr, &len, NULL, &immed_offset, &operands, &mnemonic);
+
+ if (mnemonic == BAD_OPCODE) {
+ buf= (char*)malloc(30);
+ strcpy(buf, "UNKNOWN/INVALID");
+ return(buf);
+ }
+
+ if (code & 0x0800)
+ reg_strs = w_reg_strs;
+ else
+ reg_strs = b_reg_strs;
+
+ switch(operands) {
+ // the repeating common parameter encoding for ADD, ADDC, SUB, AND...
+ case REG_REG :
+ sprintf(parm_str, "%s,%s",
+ reg_strs[((code >> 4) & 0xf)],
+ reg_strs[(code & 0xf)]);
+ break;
+ case REG_IREG :
+ sprintf(parm_str, "%s,[%s]",
+ reg_strs[((code >> 4) & 0xf)],
+ w_reg_strs[(code & 0xf)]);
+ break;
+ case IREG_REG :
+ sprintf(parm_str, "[%s],%s",
+ w_reg_strs[(code & 0x7)],
+ reg_strs[((code >> 4) & 0xf)] );
+ break;
+ case REG_IREGOFF8 :
+ sprintf(parm_str, "%s,[%s+%02x]",
+ reg_strs[((code >> 4) & 0xf)],
+ w_reg_strs[(code & 0x7)],
+ rom->get(addr+immed_offset));
+ ++immed_offset;
+ break;
+ case IREGOFF8_REG :
+ sprintf(parm_str, "[%s+%02x],%s",
+ w_reg_strs[(code & 0x7)],
+ rom->get(addr+immed_offset),
+ reg_strs[((code >> 4) & 0xf)] );
+ ++immed_offset;
+ break;
+ case REG_IREGOFF16 :
+ sprintf(parm_str, "%s,[%s+%04x]",
+ reg_strs[((code >> 4) & 0xf)],
+ w_reg_strs[(code & 0x7)],
+ (short)((rom->get(addr+immed_offset+1)) |
+ (rom->get(addr+immed_offset)<<8)) );
+ ++immed_offset;
+ ++immed_offset;
+ break;
+ case IREGOFF16_REG :
+ sprintf(parm_str, "[%s+%04x],%s",
+ w_reg_strs[(code & 0x7)],
+ (short)((rom->get(addr+immed_offset+1)) |
+ (rom->get(addr+immed_offset)<<8)),
+ reg_strs[((code >> 4) & 0xf)] );
+ ++immed_offset;
+ ++immed_offset;
+ break;
+ case REG_IREGINC :
+ sprintf(parm_str, "%s,[%s+]",
+ reg_strs[((code >> 4) & 0xf)],
+ w_reg_strs[(code & 0xf)]);
+ break;
+ case IREGINC_REG :
+ sprintf(parm_str, "[%s+],%s",
+ w_reg_strs[(code & 0x7)],
+ reg_strs[((code >> 4) & 0xf)] );
+ break;
+ case DIRECT_REG :
+ sprintf(parm_str, "%s,%s",
+ get_dir_name(((code & 0x7) << 8) |
+ rom->get(addr+immed_offset)),
+ reg_strs[((code >> 4) & 0xf)] );
+ ++immed_offset;
+ break;
+ case REG_DIRECT :
+ sprintf(parm_str, "%s,%s",
+ reg_strs[((code >> 4) & 0xf)],
+ get_dir_name(((code & 0x7) << 8) |
+ rom->get(addr+immed_offset)));
+ ++immed_offset;
+ break;
+ case REG_DATA8 :
+ sprintf(parm_str, "%s,#0x%02x",
+ b_reg_strs[((code >> 4) & 0xf)],
+ rom->get(addr+immed_offset) );
+ ++immed_offset;
+ break;
+ case REG_DATA16 :
+ sprintf(parm_str, "%s,#0x%04x",
+ reg_strs[((code >> 4) & 0xf)],
+ (short)((rom->get(addr+immed_offset+1)) |
+ (rom->get(addr+immed_offset)<<8)) );
+ ++immed_offset;
+ ++immed_offset;
+ break;
+ case IREG_DATA8 :
+ sprintf(parm_str, "[%s], 0x%02x",
+ w_reg_strs[((code >> 4) & 0x7)],
+ rom->get(addr+immed_offset) );
+ ++immed_offset;
+ break;
+ case IREG_DATA16 :
+ sprintf(parm_str, "[%s], 0x%04x",
+ w_reg_strs[((code >> 4) & 0x7)],
+ (short)((rom->get(addr+immed_offset+1)) |
+ (rom->get(addr+immed_offset)<<8)) );
+ ++immed_offset;
+ ++immed_offset;
+ break;
+ case IREGINC_DATA8 :
+ sprintf(parm_str, "[%s+], 0x%02x",
+ w_reg_strs[((code >> 4) & 0x7)],
+ rom->get(addr+immed_offset) );
+ ++immed_offset;
+ break;
+ case IREGINC_DATA16 :
+ sprintf(parm_str, "[%s+], 0x%04x",
+ w_reg_strs[((code >> 4) & 0x7)],
+ (short)((rom->get(addr+immed_offset+1)) |
+ (rom->get(addr+immed_offset)<<8)) );
+ ++immed_offset;
+ ++immed_offset;
+ break;
+ case IREGOFF8_DATA8 :
+ sprintf(parm_str, "[%s+%02x], 0x%02x",
+ w_reg_strs[((code >> 4) & 0x7)],
+ rom->get(addr+immed_offset),
+ rom->get(addr+immed_offset+1) );
+ immed_offset += 2;
+ break;
+ case IREGOFF8_DATA16 :
+ sprintf(parm_str, "[%s+%02x], 0x%04x",
+ w_reg_strs[((code >> 4) & 0x7)],
+ rom->get(addr+immed_offset),
+ (short)((rom->get(addr+immed_offset+2)) |
+ (rom->get(addr+immed_offset+1)<<8)) );
+ immed_offset += 3;
+ break;
+ case IREGOFF16_DATA8 :
+ sprintf(parm_str, "[%s+%04x], 0x%02x",
+ w_reg_strs[((code >> 4) & 0x7)],
+ (short)((rom->get(addr+immed_offset+1)) |
+ (rom->get(addr+immed_offset+0)<<8)),
+ rom->get(addr+immed_offset+2) );
+ immed_offset += 3;
+ break;
+ case IREGOFF16_DATA16 :
+ sprintf(parm_str, "[%s+%04x], 0x%04x",
+ w_reg_strs[((code >> 4) & 0x7)],
+ (short)((rom->get(addr+immed_offset+1)) |
+ (rom->get(addr+immed_offset+0)<<8)),
+ (short)((rom->get(addr+immed_offset+3)) |
+ (rom->get(addr+immed_offset+2)<<8)) );
+ immed_offset += 4;
+ break;
+ case DIRECT_DATA8 :
+ sprintf(parm_str, "%s,#0x%02x",
+ get_dir_name(((code & 0x0070) << 4) |
+ rom->get(addr+immed_offset)),
+ rom->get(addr+immed_offset+1));
+ immed_offset += 3;
+ break;
+ case DIRECT_DATA16 :
+ sprintf(parm_str, "%s,#0x%04x",
+ get_dir_name(((code & 0x0070) << 4) |
+ rom->get(addr+immed_offset)),
+ rom->get(addr+immed_offset+2) +
+ (rom->get(addr+immed_offset+1)<<8));
+ immed_offset += 3;
+ break;
+
+// odd-ball ones
+ case NO_OPERANDS : // for NOP
+ strcpy(parm_str, "");
+ break;
+ case CY_BIT :
+ sprintf(parm_str, "C,%s",
+ get_bit_name(((code&0x0003)<<8) + rom->get(addr+2)));
+ break;
+ case BIT_CY :
+ sprintf(parm_str, "%s,C",
+ get_bit_name(((code&0x0003)<<8) + rom->get(addr+2)));
+ break;
+ case REG_DATA4 :
+ strcpy(parm_str, "REG_DATA4");
+ break;
+ case REG_DATA5 :
+ strcpy(parm_str, "REG_DATA5");
+ break;
+ case IREG_DATA4 :
+ strcpy(parm_str, "IREG_DATA4");
+ break;
+ case IREGINC_DATA4 :
+ strcpy(parm_str, "IREGINC_DATA4");
+ break;
+ case IREGOFF8_DATA4 :
+ strcpy(parm_str, "IREGOFF8_DATA4");
+ break;
+ case IREGOFF16_DATA4 :
+ strcpy(parm_str, "IREGOFF16_DATA4");
+ break;
+ case DIRECT_DATA4 :
+ sprintf(parm_str, "%s,#0x%x",
+ get_dir_name(((code & 0x70)<<4) |
+ rom->get(addr+2)),
+ code&0x0f);
+ break;
+ case DIRECT :
+ sprintf(parm_str, "%s",
+ get_dir_name(((code & 0x007) << 4) +
+ rom->get(addr+2)));
+ break;
+ case REG :
+ sprintf(parm_str, "%s",
+ reg_strs[((code >> 4) & 0xf)] );
+ break;
+ case IREG :
+ sprintf(parm_str, "[%s]",
+ reg_strs[((code >> 4) & 0xf)] );
+ break;
+ case BIT_ALONE :
+ sprintf(parm_str, "%s",
+ get_bit_name(((code&0x0003)<<8) + rom->get(addr+2)));
+ break;
+ case BIT_REL8 :
+ sprintf(parm_str, "%s,0x%04lx",
+ get_bit_name((code&0x0003)<<8) + rom->get(addr+2),
+ (long)(((signed char)rom->get(addr+3)*2+addr+len)&0xfffe));
+ break;
+ case DATA4:
+ sprintf(parm_str, "#0x%02x", code&0x0f);
+ break;
+ case ADDR24 :
+ sprintf(parm_str, "0x%06x",
+ (rom->get(addr+3)<<16) +
+ (rom->get(addr+1)<<8) +
+ rom->get(addr+2));
+ break;
+ break;
+ case REG_REL8 :
+ sprintf(parm_str, "%s,0x%04lx",
+ reg_strs[(code>>4) & 0xf],
+ (long)(((signed char)rom->get(addr+2)*2+addr+len)&0xfffe));
+ break;
+ case DIRECT_REL8 :
+ sprintf(parm_str, "%s,0x%04lx",
+ get_dir_name(((code&0x07)<<8) +
+ rom->get(addr+2)),
+ (long)(((signed char)rom->get(addr+2)*2+addr+len)&0xfffe));
+ break;
+ case REG_USP:
+ sprintf(parm_str, "REG_USP");
+ break;
+ case USP_REG:
+ sprintf(parm_str, "USP_REG");
+ break;
+ case REL8 :
+ sprintf(parm_str, "0x%04lx",
+ (long)(((signed char)rom->get(addr+1)*2+addr+len)&0xfffe));
+ break;
+ case REL16 :
+ sprintf(parm_str, "0x%04lx",
+ (long)(((signed short)((rom->get(addr+1)<<8) + rom->get(addr+2))*2+addr+len)&0xfffe));
+ break;
+
+ case RLIST : {
+ /* TODO: the list should be comma reperated
+ and maybe for POP the list should be reversed */
+ unsigned char rlist=code&0xff;
+ parm_str[0]='\0';
+ if (code&0x0800) { // word list
+ if (code&0x4000) { // R8-R15
+ if (rlist&0x80) strcat (parm_str, "R15 ");
+ if (rlist&0x40) strcat (parm_str, "R14");
+ if (rlist&0x20) strcat (parm_str, "R13 ");
+ if (rlist&0x10) strcat (parm_str, "R12 ");
+ if (rlist&0x08) strcat (parm_str, "R11 ");
+ if (rlist&0x04) strcat (parm_str, "R10 ");
+ if (rlist&0x02) strcat (parm_str, "R9 ");
+ if (rlist&0x01) strcat (parm_str, "R8 ");
+ } else { // R7-R0
+ if (rlist&0x80) strcat (parm_str, "R7 ");
+ if (rlist&0x40) strcat (parm_str, "R6 ");
+ if (rlist&0x20) strcat (parm_str, "R5 ");
+ if (rlist&0x10) strcat (parm_str, "R4 ");
+ if (rlist&0x08) strcat (parm_str, "R3 ");
+ if (rlist&0x04) strcat (parm_str, "R2 ");
+ if (rlist&0x02) strcat (parm_str, "R1 ");
+ if (rlist&0x01) strcat (parm_str, "R0 ");
+ }
+ } else { // byte list
+ if (code&0x4000) { //R7h-R4l
+ if (rlist&0x80) strcat (parm_str, "R7h ");
+ if (rlist&0x40) strcat (parm_str, "R7l ");
+ if (rlist&0x20) strcat (parm_str, "R6h ");
+ if (rlist&0x10) strcat (parm_str, "R6l ");
+ if (rlist&0x08) strcat (parm_str, "R5h ");
+ if (rlist&0x04) strcat (parm_str, "R5l ");
+ if (rlist&0x02) strcat (parm_str, "R4h ");
+ if (rlist&0x01) strcat (parm_str, "R4l ");
+ } else { // R3h-R0l
+ if (rlist&0x80) strcat (parm_str, "R3h ");
+ if (rlist&0x40) strcat (parm_str, "R3l ");
+ if (rlist&0x20) strcat (parm_str, "R2h ");
+ if (rlist&0x10) strcat (parm_str, "R2l ");
+ if (rlist&0x08) strcat (parm_str, "R1h ");
+ if (rlist&0x04) strcat (parm_str, "R1l ");
+ if (rlist&0x02) strcat (parm_str, "R0h ");
+ if (rlist&0x01) strcat (parm_str, "R0l ");
+ }
+ }
+ }
+ break;
+
+ case REG_DIRECT_REL8 :
+ sprintf(parm_str, "%s,%s,0x%02x",
+ reg_strs[((code >> 4) & 0xf)],
+ get_dir_name(((code & 0x7) << 8) +
+ rom->get(addr+immed_offset)),
+ ((signed char) rom->get(addr+immed_offset+1) * 2) & 0xfffe );
+ break;
+ case REG_DATA8_REL8 :
+ sprintf(parm_str, "%s,#0x%02x,0x%02x",
+ reg_strs[((code >> 4) & 0xf)],
+ rom->get(addr+immed_offset+1),
+ ((signed char)rom->get(addr+immed_offset) * 2) & 0xfffe );
+ break;
+ case REG_DATA16_REL8 :
+ sprintf(parm_str, "%s,#0x%04x,0x%02x",
+ w_reg_strs[(code >> 4) & 0xf],
+ rom->get(addr+immed_offset+2) +
+ (rom->get(addr+immed_offset+1)<<8),
+ ((signed char)rom->get(addr+immed_offset) * 2) & 0xfffe );
+ break;
+ case IREG_DATA8_REL8 :
+ sprintf(parm_str, "[%s],#0x%02x,0x%02x",
+ reg_strs[((code >> 4) & 0x7)],
+ rom->get(addr+immed_offset+1),
+ ((signed char)rom->get(addr+immed_offset) * 2) & 0xfffe );
+ break;
+ case IREG_DATA16_REL8 :
+ sprintf(parm_str, "[%s],#0x%04x,0x%02x",
+ w_reg_strs[(code >> 4) & 0x7],
+ rom->get(addr+immed_offset+2) +
+ (rom->get(addr+immed_offset+1)<<8),
+ ((signed char)rom->get(addr+immed_offset) * 2) & 0xfffe );
+ break;
+
+ case A_APLUSDPTR :
+ strcpy(parm_str, "A, [A+DPTR]");
+ break;
+
+ case A_APLUSPC :
+ strcpy(parm_str, "A, [A+PC]");
+ break;
+
+ case REG_REGOFF8 :
+ sprintf(parm_str, "%s,%s+0x%02x",
+ w_reg_strs[(code >> 4) & 0x7],
+ w_reg_strs[code & 0x7],
+ rom->get(addr+immed_offset));
+ break;
+
+ case REG_REGOFF16 :
+ sprintf(parm_str, "%s,%s+0x%02x",
+ w_reg_strs[(code >> 4) & 0x7],
+ w_reg_strs[code & 0x7],
+ rom->get(addr+immed_offset+1) +
+ (rom->get(addr+immed_offset+0)<<8));
+ break;
+
+ case A_PLUSDPTR :
+ strcpy(parm_str, "[A+DPTR]");
+ break;
+
+ case IIREG :
+ sprintf(parm_str, "[[%s]]",
+ w_reg_strs[(code & 0x7)]);
+ break;
+
+ default:
+ strcpy(parm_str, "???");
+ break;
+ }
+
+ sprintf(work, "%s %s",
+ op_mnemonic_str[ mnemonic ],
+ parm_str);
+
+ p= strchr(work, ' ');
+ if (!p)
+ {
+ buf= strdup(work);
+ return(buf);
+ }
+ if (sep == NULL)
+ buf= (char *)malloc(6+strlen(p)+1);
+ else
+ buf= (char *)malloc((p-work)+strlen(sep)+strlen(p)+1);
+
+ for (p= work, b= buf; *p != ' '; p++, b++)
+ *b= *p;
+ p++;
+ *b= '\0';
+ if (sep == NULL)
+ {
+ while (strlen(buf) < 6)
+ strcat(buf, " ");
+ }
+ else
+ strcat(buf, sep);
+ strcat(buf, p);
+ return(buf);
+}
+
+/*--------------------------------------------------------------------
+ print_regs - Print the registers, flags and other useful information.
+ Used to print a status line while stepping through the code.
+|--------------------------------------------------------------------*/
+void
+cl_xa::print_regs(class cl_console_base *con)
+{
+ unsigned char flags;
+
+ flags = get_psw();
+ con->dd_printf("CA---VNZ | ", flags);
+ con->dd_printf("R0:%04x R1:%04x R2:%04x R3:%04x\n",
+ reg2(0), reg2(1), reg2(2), reg2(3));
+
+ con->dd_printf("%c%c---%c%c%c | ",
+ (flags & BIT_C)?'1':'0',
+ (flags & BIT_AC)?'1':'0',
+ (flags & BIT_V)?'1':'0',
+ (flags & BIT_N)?'1':'0',
+ (flags & BIT_Z)?'1':'0');
+
+ con->dd_printf("R4:%04x R5:%04x R6:%04x SP:%04x ES:%04x DS:%04x\n",
+ reg2(4), reg2(5), reg2(6), reg2(7), 0, 0);
+
+ print_disass(PC, con);
+}
+
+
+/*--------------------------------------------------------------------
+ exec_inst - Called to implement simulator execution of 1 instruction
+ at the current PC(program counter) address.
+|--------------------------------------------------------------------*/
+int cl_xa::exec_inst(void)
+{
+ t_mem code1;
+ uint code;
+ int i;
+ int operands;
+
+ instPC= PC;
+
+ if (fetch(&code1))
+ return(resBREAKPOINT);
+ tick(1);
+
+/* the following lookups make for a slow simulation, we will
+ figure out how to make it fast later... */
+
+ /* scan to see if its a 1 byte-opcode */
+ code = (code1 << 8);
+ i= 0;
+ while ( ((code & disass_xa[i].mask) != disass_xa[i].code ||
+ (!disass_xa[i].is1byte)) /* not a one byte op code */
+ &&
+ disass_xa[i].mnemonic != BAD_OPCODE)
+ i++;
+
+ if (disass_xa[i].mnemonic == BAD_OPCODE) {
+ /* hit the end of the list, must be a 2 or more byte opcode */
+ /* fetch another code byte and search the list again */
+ //if (fetch(&code2)) ?not sure if break allowed in middle of opcode?
+ // return(resBREAKPOINT);
+ code |= fetch(); /* add 2nd opcode */
+
+ i= 0;
+ while ((code & disass_xa[i].mask) != disass_xa[i].code &&
+ disass_xa[i].mnemonic != BAD_OPCODE)
+ i++;
+ /* we should have found the opcode by now, if not invalid entry at eol */
+ }
+
+ operands = (int)(disass_xa[i].operands);
+ switch (disass_xa[i].mnemonic)
+ {
+ case ADD:
+ return inst_ADD(code, operands);
+ case ADDC:
+ return inst_ADDC(code, operands);
+ case ADDS:
+ return inst_ADDS(code, operands);
+ case AND:
+ return inst_AND(code, operands);
+ case ANL:
+ return inst_ANL(code, operands);
+ case ASL:
+ return inst_ASL(code, operands);
+ case ASR:
+ return inst_ASR(code, operands);
+ case BCC:
+ return inst_BCC(code, operands);
+ case BCS:
+ return inst_BCS(code, operands);
+ case BEQ:
+ return inst_BEQ(code, operands);
+ case BG:
+ return inst_BG(code, operands);
+ case BGE:
+ return inst_BGE(code, operands);
+ case BGT:
+ return inst_BGT(code, operands);
+ case BKPT:
+ return inst_BKPT(code, operands);
+ case BL:
+ return inst_BL(code, operands);
+ case BLE:
+ return inst_BLE(code, operands);
+ case BLT:
+ return inst_BLT(code, operands);
+ case BMI:
+ return inst_BMI(code, operands);
+ case BNE:
+ return inst_BNE(code, operands);
+ case BNV:
+ return inst_BNV(code, operands);
+ case BOV:
+ return inst_BOV(code, operands);
+ case BPL:
+ return inst_BPL(code, operands);
+ case BR:
+ return inst_BR(code, operands);
+ case CALL:
+ return inst_CALL(code, operands);
+ case CJNE:
+ return inst_CJNE(code, operands);
+ case CLR:
+ return inst_CLR(code, operands);
+ case CMP:
+ return inst_CMP(code, operands);
+ case CPL:
+ return inst_CPL(code, operands);
+ case DA:
+ return inst_DA(code, operands);
+ case DIV_w :
+ case DIV_d :
+ case DIVU_b:
+ case DIVU_w:
+ case DIVU_d:
+ return inst_DIV(code, operands);
+ case DJNZ:
+ return inst_DJNZ(code, operands);
+ case FCALL:
+ return inst_FCALL(code, operands);
+ case FJMP:
+ return inst_FJMP(code, operands);
+ case JB:
+ return inst_JB(code, operands);
+ case JBC:
+ return inst_JBC(code, operands);
+ case JMP:
+ return inst_JMP(code, operands);
+ case JNB:
+ return inst_JNB(code, operands);
+ case JNZ:
+ return inst_JNZ(code, operands);
+ case JZ:
+ return inst_JZ(code, operands);
+ case LEA:
+ return inst_LEA(code, operands);
+ case LSR:
+ return inst_LSR(code, operands);
+ case MOV:
+ return inst_MOV(code, operands);
+ case MOVC:
+ return inst_MOVC(code, operands);
+ case MOVS:
+ return inst_MOVS(code, operands);
+ case MOVX:
+ return inst_MOVX(code, operands);
+ case MUL_w:
+ case MULU_b:
+ case MULU_w:
+ return inst_MUL(code, operands);
+ case NEG:
+ return inst_NEG(code, operands);
+ case NOP:
+ return inst_NOP(code, operands);
+ case NORM:
+ return inst_NORM(code, operands);
+ case OR:
+ return inst_OR(code, operands);
+ case ORL:
+ return inst_ORL(code, operands);
+ case POP:
+ case POPU:
+ return inst_POP(code, operands);
+ case PUSH:
+ case PUSHU:
+ return inst_PUSH(code, operands);
+ case RESET:
+ return inst_RESET(code, operands);
+ case RET:
+ return inst_RET(code, operands);
+ case RETI:
+ return inst_RETI(code, operands);
+ case RL:
+ return inst_RL(code, operands);
+ case RLC:
+ return inst_RLC(code, operands);
+ case RR:
+ return inst_RR(code, operands);
+ case RRC:
+ return inst_RRC(code, operands);
+ case SETB:
+ return inst_SETB(code, operands);
+ case SEXT:
+ return inst_SEXT(code, operands);
+ case SUB:
+ return inst_SUB(code, operands);
+ case SUBB:
+ return inst_SUBB(code, operands);
+ case TRAP:
+ return inst_TRAP(code, operands);
+ case XCH:
+ return inst_XCH(code, operands);
+ case XOR:
+ return inst_XOR(code, operands);
+
+ case BAD_OPCODE:
+ default:
+ break;
+ }
+
+ /*if (PC)
+ PC--;
+ else
+ PC= get_mem_size(MEM_ROM_ID)-1;*/
+ PC= rom->inc_address(PC, -1);
+ //tick(-clock_per_cycle());
+ sim->stop(resINV_INST);
+ return(resINV_INST);
+}
+
+
+/* End of xa.src/xa.cc */
diff --git a/sim/ucsim/xa.src/xacl.h b/sim/ucsim/xa.src/xacl.h
new file mode 100644
index 0000000..c1ee5ce
--- /dev/null
+++ b/sim/ucsim/xa.src/xacl.h
@@ -0,0 +1,400 @@
+/*
+ * Simulator of microcontrollers (xacl.h)
+ *
+ * Copyright (C) 1999,99 Drotos Daniel, Talker Bt.
+ *
+ * To contact author send email to drdani@mazsola.iit.uni-miskolc.hu
+ * Other contributors include:
+ * Karl Bongers karl@turbobit.com,
+ * Johan Knol johan.knol@iduna.nl
+ *
+ */
+
+/* This file is part of microcontroller simulator: ucsim.
+
+UCSIM 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.
+
+UCSIM 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 UCSIM; see the file COPYING. If not, write to the Free
+Software Foundation, 59 Temple Place - Suite 330, Boston, MA
+02111-1307, USA. */
+/*@1@*/
+
+#ifndef XACL_HEADER
+#define XACL_HEADER
+
+#include "uccl.h"
+
+#include "regsxa.h"
+
+/*
+ * Base type of XA microcontrollers
+ */
+
+class cl_xa: public cl_uc
+{
+public:
+ class cl_address_space *ram;
+ class cl_address_space *rom;
+ struct t_regs regs;
+
+ class cl_address_space *sfr, *iram;
+
+ // for now make it as simple as possible
+// TYPE_UBYTE mem_direct[1024*2];
+//#ifndef WORDS_BIGENDIAN
+// TYPE_UWORD *wmem_direct; /* word pointer at mem_direct */
+//#endif
+
+public:
+ cl_xa(class cl_sim *asim);
+ virtual int init(void);
+ virtual char *id_string(void);
+
+ //virtual class cl_m *mk_mem(enum mem_class type, char *class_name);
+ //virtual t_addr get_mem_size(enum mem_class type);
+ virtual void mk_hw_elements(void);
+ virtual void make_memories(void);
+
+ virtual struct dis_entry *dis_tbl(void);
+
+ virtual struct name_entry *sfr_tbl(void);
+ virtual struct name_entry *bit_tbl(void);
+ virtual char *get_dir_name(short);
+ virtual char *get_bit_name(short);
+
+ virtual int inst_length(t_addr addr);
+ virtual int inst_branch(t_addr addr);
+ virtual int longest_inst(void);
+
+ virtual int get_disasm_info(t_addr addr,
+ int *ret_len,
+ int *ret_branch,
+ int *immed_offset,
+ int *parms,
+ int *mnemonic);
+
+ virtual char *disass(t_addr addr, const char *sep);
+ virtual void print_regs(class cl_console_base *con);
+
+ virtual int exec_inst(void);
+ virtual int get_reg(int word_flag, unsigned int index);
+
+ virtual void store1(t_addr addr, unsigned char val);
+ virtual void store2(t_addr addr, unsigned short val);
+ virtual unsigned char get1(t_addr addr);
+ virtual unsigned short get2(t_addr addr);
+
+ virtual bool get_bit(int bit);
+ virtual void set_bit(int bit, int value);
+
+#include "instcl.h"
+
+ private :
+
+ /* following are macros which get substituted for FUNC1() and FUNC2()
+ in the inst.cc to form the body of ADD,ADDC,SUB,XOR,... */
+ /* can I put these in the .cc file and still have them do the inline thing? */
+ /*-------------------------------------
+ add - flags changed:C,AC,V,N,Z.
+ |---------------------------------------*/
+ inline unsigned char add1(unsigned char dst, unsigned char src)
+ {
+ unsigned int result;
+ unsigned char flags;
+ flags = get_psw();
+ flags &= ~BIT_ALL; /* clear these bits */
+ result = dst + src;
+ if (result == 0) flags |= BIT_Z;
+ if (result > 0xff) flags |= BIT_C;
+ if (result & 0x80) flags |= BIT_N;
+ /* fixme: do AC, V */
+ set_psw(flags);
+ return (unsigned char) result;
+ }
+
+ inline unsigned short add2(unsigned short dst, unsigned short src)
+ {
+ unsigned int result;
+ unsigned char flags;
+ flags = get_psw();
+ flags &= ~BIT_ALL; /* clear these bits */
+ result = dst + src;
+ if (result == 0) flags |= BIT_Z;
+ if (result > 0xff) flags |= BIT_C;
+ if (result & 0x80) flags |= BIT_N;
+ /* fixme: do AC, V */
+ set_psw(flags);
+ return (unsigned short) result;
+ }
+
+ /*-------------------------------------
+ addc - flags changed:C,AC,V,N,Z.
+ |---------------------------------------*/
+ inline unsigned char addc1(unsigned char dst, unsigned char src)
+ {
+ unsigned int result;
+ unsigned char flags;
+ flags = get_psw();
+ if (flags & BIT_C) {
+ flags &= ~BIT_ALL; /* clear these bits */
+ result = dst + src + 1;
+ } else {
+ flags &= ~BIT_ALL; /* clear these bits */
+ result = dst + src;
+ }
+ if (result == 0) flags |= BIT_Z;
+ if (result > 0xff) flags |= BIT_C;
+ if (result & 0x80) flags |= BIT_N;
+ /* fixme: do AC, V */
+ set_psw(flags);
+ return (unsigned char) result;
+ }
+
+ inline unsigned short addc2(unsigned short dst, unsigned short src)
+ {
+ unsigned int result;
+ unsigned char flags;
+ flags = get_psw();
+ flags &= ~BIT_ALL; /* clear these bits */
+ if (flags & BIT_C) {
+ flags &= ~BIT_ALL; /* clear these bits */
+ result = dst + src + 1;
+ } else {
+ flags &= ~BIT_ALL; /* clear these bits */
+ result = dst + src;
+ }
+ if (result == 0) flags |= BIT_Z;
+ if (result > 0xff) flags |= BIT_C;
+ if (result & 0x80) flags |= BIT_N;
+ /* fixme: do AC, V */
+ set_psw(flags);
+ return (unsigned short) result;
+ }
+
+ /*-------------------------------------
+ sub - flags changed:C,AC,V,N,Z.
+ |---------------------------------------*/
+ inline unsigned char sub1(unsigned char dst, unsigned char src)
+ {
+ unsigned int result;
+ unsigned char flags;
+ flags = get_psw();
+ flags &= ~BIT_ALL; /* clear these bits */
+ result = dst - src;
+ if (result == 0) flags |= BIT_Z;
+ if (result > 0xff) flags |= BIT_C;
+ if (dst < src) flags |= BIT_N;
+ /* fixme: do AC, V */
+ set_psw(flags);
+ return (unsigned char) result;
+ }
+
+ inline unsigned short sub2(unsigned short dst, unsigned short src)
+ {
+ unsigned int result;
+ unsigned char flags;
+ flags = get_psw();
+ flags &= ~BIT_ALL; /* clear these bits */
+ result = dst - src;
+ if (result == 0) flags |= BIT_Z;
+ if (result > 0xff) flags |= BIT_C;
+ if (dst < src) flags |= BIT_N;
+ /* fixme: do AC, V */
+ set_psw(flags);
+ return (unsigned short) result;
+ }
+
+ /*-------------------------------------
+ subb - flags changed:C,AC,V,N,Z.
+ |---------------------------------------*/
+ inline unsigned char subb1(unsigned char dst, unsigned char src)
+ {
+ unsigned int result;
+ unsigned char flags;
+ flags = get_psw();
+ if (flags & BIT_C) {
+ flags &= ~BIT_ALL; /* clear these bits */
+ result = dst - src - 1;
+ } else {
+ flags &= ~BIT_ALL; /* clear these bits */
+ result = dst - src;
+ }
+ if (result == 0) flags |= BIT_Z;
+ if (result > 0xff) flags |= BIT_C;
+ if (dst < src) flags |= BIT_N;
+ /* fixme: do AC, V */
+ set_psw(flags);
+ return (unsigned char) result;
+ }
+
+ inline unsigned short subb2(unsigned short dst, unsigned short src)
+ {
+ unsigned int result;
+ unsigned char flags;
+ flags = get_psw();
+ flags &= ~BIT_ALL; /* clear these bits */
+ if (flags & BIT_C) {
+ flags &= ~BIT_ALL; /* clear these bits */
+ result = dst - src - 1;
+ } else {
+ flags &= ~BIT_ALL; /* clear these bits */
+ result = dst - src;
+ }
+ if (result == 0) flags |= BIT_Z;
+ if (result > 0xff) flags |= BIT_C;
+ if (dst < src) flags |= BIT_N;
+ /* fixme: do AC, V */
+ set_psw(flags);
+ return (unsigned short) result;
+ }
+
+ /*-------------------------------------
+ cmp - flags changed:C,AC,V,N,Z.
+ |---------------------------------------*/
+ inline unsigned char cmp1(unsigned char dst, unsigned char src)
+ {
+ unsigned int result;
+ unsigned char flags;
+ flags = get_psw();
+ flags &= ~BIT_ALL; /* clear these bits */
+ result = dst - src;
+ if (result == 0) flags |= BIT_Z;
+ if (result > 0xff) flags |= BIT_C;
+ if (dst < src) flags |= BIT_N;
+ /* fixme: do AC, V */
+ set_psw(flags);
+ return (unsigned char) dst;
+ }
+
+ inline unsigned short cmp2(unsigned short dst, unsigned short src)
+ {
+ unsigned int result;
+ unsigned char flags;
+ flags = get_psw();
+ flags &= ~BIT_ALL; /* clear these bits */
+ result = dst - src;
+ if (result == 0) flags |= BIT_Z;
+ if (result > 0xff) flags |= BIT_C;
+ if (dst < src) flags |= BIT_N;
+ /* fixme: do AC, V */
+ set_psw(flags);
+ return (unsigned short) dst;
+ }
+
+ /*-------------------------------------
+ and - flags changed:N,Z.
+ |---------------------------------------*/
+ inline unsigned char and1(unsigned char dst, unsigned char src)
+ {
+ unsigned int result;
+ unsigned char flags;
+ flags = get_psw() & ~(BIT_N | BIT_Z); /* clear these bits */
+ result = dst & src;
+ if (result == 0) flags |= BIT_Z;
+ if (result & 0x80) flags |= BIT_N;
+ set_psw(flags);
+ return (unsigned char) result;
+ }
+
+ inline unsigned short and2(unsigned short dst, unsigned short src)
+ {
+ unsigned int result;
+ unsigned char flags;
+ flags = get_psw() & ~(BIT_N | BIT_Z); /* clear these bits */
+ result = dst & src;
+ if (result == 0) flags |= BIT_Z;
+ if (result & 0x80) flags |= BIT_N;
+ set_psw(flags);
+ return (unsigned short) result;
+ }
+
+ /*-------------------------------------
+ or - flags changed:N,Z.
+ |---------------------------------------*/
+ inline unsigned char or1(unsigned char dst, unsigned char src)
+ {
+ unsigned int result;
+ unsigned char flags;
+ flags = get_psw() & ~(BIT_N | BIT_Z); /* clear these bits */
+ result = dst | src;
+ if (result == 0) flags |= BIT_Z;
+ if (result & 0x80) flags |= BIT_N;
+ set_psw(flags);
+ return (unsigned char) result;
+ }
+
+ inline unsigned short or2(unsigned short dst, unsigned short src)
+ {
+ unsigned int result;
+ unsigned char flags;
+ flags = get_psw() & ~(BIT_N | BIT_Z); /* clear these bits */
+ result = dst | src;
+ if (result == 0) flags |= BIT_Z;
+ if (result & 0x80) flags |= BIT_N;
+ set_psw(flags);
+ return (unsigned short) result;
+ }
+
+ /*-------------------------------------
+ xor - flags changed:N,Z.
+ |---------------------------------------*/
+ inline unsigned char xor1(unsigned char dst, unsigned char src)
+ {
+ unsigned char flags;
+ flags = get_psw() & ~(BIT_N | BIT_Z); /* clear these bits */
+ dst ^= src;
+ if (dst == 0) flags |= BIT_Z;
+ if (dst & 0x80) flags |= BIT_N;
+ set_psw(flags);
+ return (unsigned char) dst;
+ }
+
+ inline unsigned short xor2(unsigned short dst, unsigned short src)
+ {
+ unsigned char flags;
+ flags = get_psw() & ~(BIT_N | BIT_Z); /* clear these bits */
+ dst ^= src;
+ if (dst == 0) flags |= BIT_Z;
+ if (dst & 0x8000) flags |= BIT_N;
+ set_psw(flags);
+ return (unsigned short) dst;
+ }
+
+ /*-------------------------------------
+ mov - flags changed:N,Z.
+ |---------------------------------------*/
+ inline unsigned char mov1(unsigned char dst, unsigned char src)
+ {
+ unsigned char flags;
+ flags = get_psw() & ~(BIT_N | BIT_Z); /* clear these bits */
+ dst = src;
+ if (dst == 0) flags |= BIT_Z;
+ if (dst & 0x80) flags |= BIT_N;
+ set_psw(flags);
+ return (unsigned char) dst;
+ }
+
+ inline unsigned short mov2(unsigned short dst, unsigned short src)
+ {
+ unsigned char flags;
+ flags = get_psw() & ~(BIT_N | BIT_Z); /* clear these bits */
+ dst = src;
+ if (dst == 0) flags |= BIT_Z;
+ if (dst & 0x8000) flags |= BIT_N;
+ set_psw(flags);
+ return (unsigned short) dst;
+ }
+};
+
+#endif
+
+/* End of xa.src/xacl.h */