summaryrefslogtreecommitdiff
path: root/sim/ucsim/sim.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/sim.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/sim.src')
-rw-r--r--sim/ucsim/sim.src/(c).127
-rw-r--r--sim/ucsim/sim.src/Makefile127
-rw-r--r--sim/ucsim/sim.src/Makefile.dep122
-rw-r--r--sim/ucsim/sim.src/Makefile.in127
-rw-r--r--sim/ucsim/sim.src/arg.cc635
-rw-r--r--sim/ucsim/sim.src/arg.obin0 -> 112584 bytes
-rw-r--r--sim/ucsim/sim.src/argcl.h229
-rw-r--r--sim/ucsim/sim.src/brk.cc312
-rw-r--r--sim/ucsim/sim.src/brk.obin0 -> 75552 bytes
-rw-r--r--sim/ucsim/sim.src/brkcl.h139
-rw-r--r--sim/ucsim/sim.src/clean.mk22
-rw-r--r--sim/ucsim/sim.src/conf.mk10
-rw-r--r--sim/ucsim/sim.src/guiobj.cc37
-rw-r--r--sim/ucsim/sim.src/guiobj.obin0 -> 13160 bytes
-rw-r--r--sim/ucsim/sim.src/guiobjcl.h45
-rw-r--r--sim/ucsim/sim.src/hw.cc687
-rw-r--r--sim/ucsim/sim.src/hw.obin0 -> 164496 bytes
-rw-r--r--sim/ucsim/sim.src/hwcl.h159
-rw-r--r--sim/ucsim/sim.src/itsrc.cc228
-rw-r--r--sim/ucsim/sim.src/itsrc.obin0 -> 56728 bytes
-rw-r--r--sim/ucsim/sim.src/itsrccl.h115
-rw-r--r--sim/ucsim/sim.src/iwrap.cc522
-rw-r--r--sim/ucsim/sim.src/iwrap.h525
-rw-r--r--sim/ucsim/sim.src/iwrap.obin0 -> 416432 bytes
-rw-r--r--sim/ucsim/sim.src/mem.cc2634
-rw-r--r--sim/ucsim/sim.src/mem.obin0 -> 519016 bytes
-rw-r--r--sim/ucsim/sim.src/memcl.h644
-rw-r--r--sim/ucsim/sim.src/obsolete.cc1360
-rw-r--r--sim/ucsim/sim.src/obsolete.h286
-rw-r--r--sim/ucsim/sim.src/port_hw.cc324
-rw-r--r--sim/ucsim/sim.src/port_hw.obin0 -> 89080 bytes
-rw-r--r--sim/ucsim/sim.src/port_hwcl.h79
-rw-r--r--sim/ucsim/sim.src/serial_hw.cc511
-rw-r--r--sim/ucsim/sim.src/serial_hw.obin0 -> 130800 bytes
-rw-r--r--sim/ucsim/sim.src/serial_hwcl.h113
-rw-r--r--sim/ucsim/sim.src/sim.cc372
-rw-r--r--sim/ucsim/sim.src/sim.obin0 -> 68440 bytes
-rw-r--r--sim/ucsim/sim.src/simcl.h84
-rw-r--r--sim/ucsim/sim.src/simif.cc972
-rw-r--r--sim/ucsim/sim.src/simif.obin0 -> 251992 bytes
-rw-r--r--sim/ucsim/sim.src/simifcl.h380
-rw-r--r--sim/ucsim/sim.src/stack.cc564
-rw-r--r--sim/ucsim/sim.src/stack.obin0 -> 207632 bytes
-rw-r--r--sim/ucsim/sim.src/stackcl.h249
-rw-r--r--sim/ucsim/sim.src/test_mem_speed.cc99
-rw-r--r--sim/ucsim/sim.src/uc.cc2616
-rw-r--r--sim/ucsim/sim.src/uc.obin0 -> 760848 bytes
-rw-r--r--sim/ucsim/sim.src/uccl.h413
-rw-r--r--sim/ucsim/sim.src/uccl_instructions.h256
-rw-r--r--sim/ucsim/sim.src/var.cc108
-rw-r--r--sim/ucsim/sim.src/var.obin0 -> 37224 bytes
-rw-r--r--sim/ucsim/sim.src/varcl.h71
-rw-r--r--sim/ucsim/sim.src/vcd.cc464
-rw-r--r--sim/ucsim/sim.src/vcd.obin0 -> 97128 bytes
-rw-r--r--sim/ucsim/sim.src/vcdcl.h66
55 files changed, 16733 insertions, 0 deletions
diff --git a/sim/ucsim/sim.src/(c).1 b/sim/ucsim/sim.src/(c).1
new file mode 100644
index 0000000..ce02b92
--- /dev/null
+++ b/sim/ucsim/sim.src/(c).1
@@ -0,0 +1,27 @@
+/*
+ * Simulator of microcontrollers (sim.src/@@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/sim.src/Makefile b/sim/ucsim/sim.src/Makefile
new file mode 100644
index 0000000..0320f19
--- /dev/null
+++ b/sim/ucsim/sim.src/Makefile
@@ -0,0 +1,127 @@
+#
+# S51 sim.src/Makefile
+#
+# (c) Drotos Daniel, Talker Bt. 1997,99
+#
+
+STARTYEAR = 1997
+
+SHELL = /bin/sh
+CXX = g++
+CPP = gcc -E
+CXXCPP = g++ -E
+RANLIB = ranlib
+INSTALL = /usr/bin/install -c
+MAKEDEP = g++ -MM
+AR = ar
+
+top_builddir = ..
+top_srcdir = ..
+
+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)/gui.src
+CFLAGS = -g -O2 -Wall
+CXXFLAGS = -g -O2 -g -Wall
+
+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 = stack.o mem.o sim.o itsrc.o brk.o arg.o \
+ guiobj.o uc.o hw.o simif.o serial_hw.o port_hw.o \
+ iwrap.o var.o vcd.o
+
+
+# Compiling entire program or any subproject
+# ------------------------------------------
+all: checkconf sim_lib
+
+test_mem_speed: $(top_builddir)/lib*.a test_mem_speed.o
+ $(CXX) -o $@ test_mem_speed.o -L$(top_builddir) -Wl,--start-group -lsim -lucsimutil -lcmd -Wl,--end-group
+
+sim.src: all
+
+
+# Compiling and installing everything and runing test
+# ---------------------------------------------------
+install: all installdirs
+
+
+# Deleting all the installed files
+# --------------------------------
+uninstall:
+
+
+# Performing self-test
+# --------------------
+check: test
+ ./test_mem_speed
+
+test: test_mem_speed
+
+# Performing installation test
+# ----------------------------
+installcheck:
+
+
+# Creating installation directories
+# ---------------------------------
+installdirs:
+
+
+# Creating dependencies
+# ---------------------
+dep: main.dep
+
+Makefile.dep: $(srcdir)/*.cc $(srcdir)/*.h
+ $(MAKEDEP) $(CPPFLAGS) $(filter %.cc,$^) >Makefile.dep
+
+-include Makefile.dep
+include $(srcdir)/clean.mk
+
+#parser.cc: parser.y
+
+#plex.cc: plex.l
+
+# My rules
+# --------
+
+sim_lib: $(top_builddir)/libsim.a
+
+$(top_builddir)/libsim.a: $(OBJECTS)
+ $(AR) -rc $@ $(OBJECTS)
+ $(RANLIB) $@
+
+.cc.o:
+ $(CXX) $(CXXFLAGS) $(CPPFLAGS) $(TARGET_ARCH) -c $< -o $@
+
+.y.cc:
+ rm -f $*.cc $*.h
+ $(YACC) -d $<
+ mv y.tab.c $*.cc
+ mv y.tab.h $*.h
+
+.l.cc:
+ rm -f $*.cc
+ $(LEX) -t $< >$*.cc
+
+
+# Remaking configuration
+# ----------------------
+checkconf:
+ @if [ -f $(top_builddir)/devel ]; then\
+ $(MAKE) -f conf.mk srcdir="$(srcdir)" top_builddir="$(top_builddir)" freshconf;\
+ fi
+
+# End of sim.src/Makefile
diff --git a/sim/ucsim/sim.src/Makefile.dep b/sim/ucsim/sim.src/Makefile.dep
new file mode 100644
index 0000000..313a42c
--- /dev/null
+++ b/sim/ucsim/sim.src/Makefile.dep
@@ -0,0 +1,122 @@
+test_mem_speed.o: test_mem_speed.cc memcl.h ../ddconfig.h ../stypes.h \
+ ../ddconfig.h ../pobjcl.h ../pobjt.h ../eventcl.h ../charscl.h \
+ guiobjcl.h ../eventcl.h ../errorcl.h ../pobjcl.h ../stypes.h hwcl.h \
+ ../cmd.src/newcmdcl.h ../optioncl.h ../cmd.src/commandcl.h \
+ ../cmd.src/newcmdcl.h ../cmd.src/newcmdposixcl.h ../fiocl.h \
+ ../cmd.src/cmdutil.h uccl.h ../pobjt.h brkcl.h stackcl.h varcl.h \
+ uccl_instructions.h
+itsrc.o: itsrc.cc ../ddconfig.h ../i_string.h ../ddconfig.h itsrccl.h \
+ ../pobjcl.h ../pobjt.h ../eventcl.h ../charscl.h ../stypes.h uccl.h \
+ ../pobjt.h hwcl.h guiobjcl.h ../cmd.src/newcmdcl.h ../optioncl.h \
+ ../pobjcl.h ../stypes.h ../cmd.src/commandcl.h ../cmd.src/newcmdcl.h \
+ ../cmd.src/newcmdposixcl.h ../fiocl.h ../cmd.src/cmdutil.h memcl.h \
+ ../eventcl.h ../errorcl.h brkcl.h stackcl.h varcl.h uccl_instructions.h
+mem.o: mem.cc ../i_string.h ../ddconfig.h ../utils.h ../stypes.h \
+ ../charscl.h ../fiocl.h ../pobjcl.h ../pobjt.h ../eventcl.h ../globals.h \
+ ../appcl.h ../optioncl.h argcl.h ../pobjcl.h ../stypes.h simcl.h \
+ ../cmd.src/newcmdcl.h ../ddconfig.h ../optioncl.h ../cmd.src/commandcl.h \
+ ../cmd.src/newcmdcl.h ../gui.src/guicl.h ../gui.src/ifcl.h guiobjcl.h \
+ uccl.h ../pobjt.h hwcl.h guiobjcl.h ../cmd.src/newcmdposixcl.h \
+ ../fiocl.h ../cmd.src/cmdutil.h memcl.h ../eventcl.h ../errorcl.h \
+ brkcl.h stackcl.h varcl.h uccl_instructions.h argcl.h simcl.h \
+ ../cmd.src/cmdutil.h memcl.h hwcl.h
+brk.o: brk.cc ../ddconfig.h ../pobjcl.h ../ddconfig.h ../pobjt.h \
+ ../eventcl.h ../charscl.h ../globals.h ../stypes.h ../appcl.h \
+ ../pobjcl.h ../optioncl.h argcl.h ../stypes.h simcl.h \
+ ../cmd.src/newcmdcl.h ../optioncl.h ../cmd.src/commandcl.h \
+ ../cmd.src/newcmdcl.h ../gui.src/guicl.h ../gui.src/ifcl.h guiobjcl.h \
+ uccl.h ../pobjt.h hwcl.h guiobjcl.h ../cmd.src/newcmdposixcl.h \
+ ../fiocl.h ../cmd.src/cmdutil.h memcl.h ../eventcl.h ../errorcl.h \
+ brkcl.h stackcl.h varcl.h uccl_instructions.h argcl.h brkcl.h
+arg.o: arg.cc ../ddconfig.h ../i_string.h ../ddconfig.h ../globals.h \
+ ../stypes.h ../appcl.h ../pobjcl.h ../pobjt.h ../eventcl.h ../charscl.h \
+ ../optioncl.h argcl.h ../pobjcl.h ../stypes.h simcl.h \
+ ../cmd.src/newcmdcl.h ../optioncl.h ../cmd.src/commandcl.h \
+ ../cmd.src/newcmdcl.h ../gui.src/guicl.h ../gui.src/ifcl.h guiobjcl.h \
+ uccl.h ../pobjt.h hwcl.h guiobjcl.h ../cmd.src/newcmdposixcl.h \
+ ../fiocl.h ../cmd.src/cmdutil.h memcl.h ../eventcl.h ../errorcl.h \
+ brkcl.h stackcl.h varcl.h uccl_instructions.h argcl.h simcl.h \
+ ../cmd.src/cmdutil.h argcl.h
+var.o: var.cc varcl.h ../pobjcl.h ../ddconfig.h ../pobjt.h ../eventcl.h \
+ ../charscl.h ../cmd.src/newcmdcl.h ../ddconfig.h ../optioncl.h \
+ ../pobjcl.h ../stypes.h ../cmd.src/commandcl.h ../cmd.src/newcmdcl.h \
+ memcl.h ../stypes.h guiobjcl.h ../eventcl.h ../errorcl.h
+vcd.o: vcd.cc ../utils.h ../stypes.h ../ddconfig.h ../charscl.h \
+ ../fiocl.h ../pobjcl.h ../pobjt.h ../eventcl.h argcl.h ../pobjcl.h \
+ ../stypes.h vcdcl.h hwcl.h guiobjcl.h ../ddconfig.h \
+ ../cmd.src/newcmdcl.h ../optioncl.h ../cmd.src/commandcl.h \
+ ../cmd.src/newcmdcl.h ../cmd.src/newcmdposixcl.h ../fiocl.h \
+ ../cmd.src/cmdutil.h memcl.h ../eventcl.h ../errorcl.h uccl.h ../pobjt.h \
+ brkcl.h stackcl.h varcl.h uccl_instructions.h
+port_hw.o: port_hw.cc ../globals.h ../ddconfig.h ../stypes.h ../appcl.h \
+ ../pobjcl.h ../pobjt.h ../eventcl.h ../charscl.h ../optioncl.h argcl.h \
+ ../pobjcl.h ../stypes.h simcl.h ../cmd.src/newcmdcl.h ../ddconfig.h \
+ ../optioncl.h ../cmd.src/commandcl.h ../cmd.src/newcmdcl.h \
+ ../gui.src/guicl.h ../gui.src/ifcl.h guiobjcl.h uccl.h ../pobjt.h hwcl.h \
+ guiobjcl.h ../cmd.src/newcmdposixcl.h ../fiocl.h ../cmd.src/cmdutil.h \
+ memcl.h ../eventcl.h ../errorcl.h brkcl.h stackcl.h varcl.h \
+ uccl_instructions.h argcl.h port_hwcl.h hwcl.h
+obsolete.o: obsolete.cc
+serial_hw.o: serial_hw.cc ../utils.h ../stypes.h ../ddconfig.h \
+ ../charscl.h ../fiocl.h ../pobjcl.h ../pobjt.h ../eventcl.h ../globals.h \
+ ../appcl.h ../optioncl.h argcl.h ../pobjcl.h ../stypes.h simcl.h \
+ ../cmd.src/newcmdcl.h ../ddconfig.h ../optioncl.h ../cmd.src/commandcl.h \
+ ../cmd.src/newcmdcl.h ../gui.src/guicl.h ../gui.src/ifcl.h guiobjcl.h \
+ uccl.h ../pobjt.h hwcl.h guiobjcl.h ../cmd.src/newcmdposixcl.h \
+ ../fiocl.h ../cmd.src/cmdutil.h memcl.h ../eventcl.h ../errorcl.h \
+ brkcl.h stackcl.h varcl.h uccl_instructions.h argcl.h serial_hwcl.h \
+ hwcl.h
+simif.o: simif.cc ../i_string.h ../ddconfig.h ../globals.h ../stypes.h \
+ ../appcl.h ../pobjcl.h ../pobjt.h ../eventcl.h ../charscl.h \
+ ../optioncl.h argcl.h ../pobjcl.h ../stypes.h simcl.h \
+ ../cmd.src/newcmdcl.h ../ddconfig.h ../optioncl.h ../cmd.src/commandcl.h \
+ ../cmd.src/newcmdcl.h ../gui.src/guicl.h ../gui.src/ifcl.h guiobjcl.h \
+ uccl.h ../pobjt.h hwcl.h guiobjcl.h ../cmd.src/newcmdposixcl.h \
+ ../fiocl.h ../cmd.src/cmdutil.h memcl.h ../eventcl.h ../errorcl.h \
+ brkcl.h stackcl.h varcl.h uccl_instructions.h argcl.h simcl.h simifcl.h \
+ uccl.h hwcl.h
+sim.o: sim.cc ../ddconfig.h ../i_string.h ../ddconfig.h ../globals.h \
+ ../stypes.h ../appcl.h ../pobjcl.h ../pobjt.h ../eventcl.h ../charscl.h \
+ ../optioncl.h argcl.h ../pobjcl.h ../stypes.h simcl.h \
+ ../cmd.src/newcmdcl.h ../optioncl.h ../cmd.src/commandcl.h \
+ ../cmd.src/newcmdcl.h ../gui.src/guicl.h ../gui.src/ifcl.h guiobjcl.h \
+ uccl.h ../pobjt.h hwcl.h guiobjcl.h ../cmd.src/newcmdposixcl.h \
+ ../fiocl.h ../cmd.src/cmdutil.h memcl.h ../eventcl.h ../errorcl.h \
+ brkcl.h stackcl.h varcl.h uccl_instructions.h argcl.h ../utils.h \
+ ../fiocl.h ../cmd.src/cmd_execcl.h ../cmd.src/cmd_guicl.h simcl.h \
+ ../appcl.h simifcl.h uccl.h hwcl.h
+hw.o: hw.cc ../ddconfig.h ../i_string.h ../ddconfig.h ../stypes.h \
+ ../globals.h ../stypes.h ../appcl.h ../pobjcl.h ../pobjt.h ../eventcl.h \
+ ../charscl.h ../optioncl.h argcl.h ../pobjcl.h simcl.h \
+ ../cmd.src/newcmdcl.h ../optioncl.h ../cmd.src/commandcl.h \
+ ../cmd.src/newcmdcl.h ../gui.src/guicl.h ../gui.src/ifcl.h guiobjcl.h \
+ uccl.h ../pobjt.h hwcl.h guiobjcl.h ../cmd.src/newcmdposixcl.h \
+ ../fiocl.h ../cmd.src/cmdutil.h memcl.h ../eventcl.h ../errorcl.h \
+ brkcl.h stackcl.h varcl.h uccl_instructions.h argcl.h hwcl.h
+uc.o: uc.cc ../ddconfig.h ../i_string.h ../ddconfig.h ../globals.h \
+ ../stypes.h ../appcl.h ../pobjcl.h ../pobjt.h ../eventcl.h ../charscl.h \
+ ../optioncl.h argcl.h ../pobjcl.h ../stypes.h simcl.h \
+ ../cmd.src/newcmdcl.h ../optioncl.h ../cmd.src/commandcl.h \
+ ../cmd.src/newcmdcl.h ../gui.src/guicl.h ../gui.src/ifcl.h guiobjcl.h \
+ uccl.h ../pobjt.h hwcl.h guiobjcl.h ../cmd.src/newcmdposixcl.h \
+ ../fiocl.h ../cmd.src/cmdutil.h memcl.h ../eventcl.h ../errorcl.h \
+ brkcl.h stackcl.h varcl.h uccl_instructions.h argcl.h ../utils.h \
+ ../fiocl.h ../cmd.src/cmdutil.h ../cmd.src/cmd_uccl.h \
+ ../cmd.src/cmd_bpcl.h ../cmd.src/cmd_getcl.h ../cmd.src/cmd_setcl.h \
+ ../cmd.src/cmd_infocl.h ../cmd.src/cmd_timercl.h ../cmd.src/cmd_statcl.h \
+ ../cmd.src/cmd_memcl.h uccl.h hwcl.h memcl.h simcl.h itsrccl.h simifcl.h \
+ vcdcl.h
+iwrap.o: iwrap.cc iwrap.h uccl.h ../stypes.h ../ddconfig.h ../pobjcl.h \
+ ../pobjt.h ../eventcl.h ../charscl.h ../pobjt.h hwcl.h guiobjcl.h \
+ ../ddconfig.h ../cmd.src/newcmdcl.h ../optioncl.h ../pobjcl.h \
+ ../stypes.h ../cmd.src/commandcl.h ../cmd.src/newcmdcl.h \
+ ../cmd.src/newcmdposixcl.h ../fiocl.h ../cmd.src/cmdutil.h memcl.h \
+ ../eventcl.h ../errorcl.h brkcl.h stackcl.h varcl.h uccl_instructions.h
+stack.o: stack.cc ../cmd.src/newcmdcl.h ../ddconfig.h ../pobjcl.h \
+ ../ddconfig.h ../pobjt.h ../eventcl.h ../charscl.h ../optioncl.h \
+ ../pobjcl.h ../stypes.h ../cmd.src/commandcl.h ../cmd.src/newcmdcl.h \
+ uccl.h ../stypes.h ../pobjt.h hwcl.h guiobjcl.h \
+ ../cmd.src/newcmdposixcl.h ../fiocl.h ../cmd.src/cmdutil.h memcl.h \
+ ../eventcl.h ../errorcl.h brkcl.h stackcl.h varcl.h uccl_instructions.h
+guiobj.o: guiobj.cc guiobjcl.h ../ddconfig.h ../pobjcl.h ../ddconfig.h \
+ ../pobjt.h ../eventcl.h ../charscl.h
diff --git a/sim/ucsim/sim.src/Makefile.in b/sim/ucsim/sim.src/Makefile.in
new file mode 100644
index 0000000..65e952e
--- /dev/null
+++ b/sim/ucsim/sim.src/Makefile.in
@@ -0,0 +1,127 @@
+#
+# S51 sim.src/Makefile
+#
+# (c) Drotos Daniel, Talker Bt. 1997,99
+#
+
+STARTYEAR = 1997
+
+SHELL = /bin/sh
+CXX = @CXX@
+CPP = @CPP@
+CXXCPP = @CXXCPP@
+RANLIB = @RANLIB@
+INSTALL = @INSTALL@
+MAKEDEP = @MAKEDEP@
+AR = @AR@
+
+top_builddir = @top_builddir@
+top_srcdir = @top_srcdir@
+
+DEFS = $(subs -DHAVE_CONFIG_H,,@DEFS@)
+CPPFLAGS = @CPPFLAGS@ -I$(srcdir) -I$(top_srcdir) -I$(top_builddir) \
+ -I$(top_srcdir)/cmd.src -I$(top_srcdir)/gui.src
+CFLAGS = @CFLAGS@ @WALL_FLAG@
+CXXFLAGS = @CXXFLAGS@ @WALL_FLAG@
+
+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 = stack.o mem.o sim.o itsrc.o brk.o arg.o \
+ guiobj.o uc.o hw.o simif.o serial_hw.o port_hw.o \
+ iwrap.o var.o vcd.o
+
+
+# Compiling entire program or any subproject
+# ------------------------------------------
+all: checkconf sim_lib
+
+test_mem_speed: $(top_builddir)/lib*.a test_mem_speed.o
+ $(CXX) -o $@ test_mem_speed.o -L$(top_builddir) -Wl,--start-group -lsim -lucsimutil -lcmd -Wl,--end-group
+
+sim.src: all
+
+
+# Compiling and installing everything and runing test
+# ---------------------------------------------------
+install: all installdirs
+
+
+# Deleting all the installed files
+# --------------------------------
+uninstall:
+
+
+# Performing self-test
+# --------------------
+check: test
+ ./test_mem_speed
+
+test: test_mem_speed
+
+# Performing installation test
+# ----------------------------
+installcheck:
+
+
+# Creating installation directories
+# ---------------------------------
+installdirs:
+
+
+# Creating dependencies
+# ---------------------
+dep: main.dep
+
+Makefile.dep: $(srcdir)/*.cc $(srcdir)/*.h
+ $(MAKEDEP) $(CPPFLAGS) $(filter %.cc,$^) >Makefile.dep
+
+-include Makefile.dep
+include $(srcdir)/clean.mk
+
+#parser.cc: parser.y
+
+#plex.cc: plex.l
+
+# My rules
+# --------
+
+sim_lib: $(top_builddir)/libsim.a
+
+$(top_builddir)/libsim.a: $(OBJECTS)
+ $(AR) -rc $@ $(OBJECTS)
+ $(RANLIB) $@
+
+.cc.o:
+ $(CXX) $(CXXFLAGS) $(CPPFLAGS) $(TARGET_ARCH) -c $< -o $@
+
+.y.cc:
+ rm -f $*.cc $*.h
+ $(YACC) -d $<
+ mv y.tab.c $*.cc
+ mv y.tab.h $*.h
+
+.l.cc:
+ rm -f $*.cc
+ $(LEX) -t $< >$*.cc
+
+
+# Remaking configuration
+# ----------------------
+checkconf:
+ @if [ -f $(top_builddir)/devel ]; then\
+ $(MAKE) -f conf.mk srcdir="$(srcdir)" top_builddir="$(top_builddir)" freshconf;\
+ fi
+
+# End of sim.src/Makefile
diff --git a/sim/ucsim/sim.src/arg.cc b/sim/ucsim/sim.src/arg.cc
new file mode 100644
index 0000000..c20dac4
--- /dev/null
+++ b/sim/ucsim/sim.src/arg.cc
@@ -0,0 +1,635 @@
+/*
+ * Simulator of microcontrollers (arg.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@*/
+
+#include "ddconfig.h"
+
+#include <stdio.h>
+#include <stdlib.h>
+#include "i_string.h"
+
+// prj
+#include "globals.h"
+
+// sim
+#include "simcl.h"
+
+// cmd
+#include "cmdutil.h"
+
+// local
+#include "argcl.h"
+
+
+/*
+ * Making the argument
+ */
+
+cl_arg::cl_arg(long lv):
+ cl_base()
+{
+ i_value= lv;
+ s_value= 0;
+}
+
+cl_arg::cl_arg(const char *sv):
+ cl_base()
+{
+ s_value= sv?strdup(sv):0;
+}
+
+cl_arg::cl_arg(double fv):
+ cl_base()
+{
+ f_value= fv;
+ s_value= 0;
+}
+
+cl_arg::cl_arg(void *pv):
+ cl_base()
+{
+ p_value= pv;
+ s_value= 0;
+}
+
+cl_arg::~cl_arg(void)
+{
+ if (s_value)
+ free((void*)s_value);
+}
+
+
+/*
+ * Getting value of the argument
+ */
+
+bool
+cl_arg::get_ivalue(long *value)
+{
+ if (value)
+ *value= i_value;
+ return(true);
+}
+
+char *
+cl_arg::get_svalue(void)
+{
+ return(s_value);
+}
+
+double
+cl_arg::get_fvalue(void)
+{
+ return(f_value);
+}
+
+void *
+cl_arg::get_pvalue(void)
+{
+ return(p_value);
+}
+
+
+/*
+ * Command parameters
+ *----------------------------------------------------------------------------
+ */
+
+cl_cmd_arg::~cl_cmd_arg(void)
+{
+ if (interpreted_as_string)
+ {
+ if (value.string.string)
+ free(value.string.string);
+ }
+}
+
+bool
+cl_cmd_arg::as_address(class cl_uc *uc)
+{
+ return(get_address(uc, &(value.address)));
+}
+
+bool
+cl_cmd_arg::as_number(void)
+{
+ return(get_ivalue(&(value.number)));
+}
+
+bool
+cl_cmd_arg::as_data(void)
+{
+ long l;
+ bool ret= get_ivalue(&l);
+ value.data= l;
+ return(ret);
+}
+
+bool
+cl_cmd_arg::as_memory(class cl_uc *uc)
+{
+ value.memory.memory= uc->memory(get_svalue());
+ value.memory.address_space= 0;
+ value.memory.memchip= 0;
+ if (value.memory.memory)
+ {
+ if (value.memory.memory->is_chip())
+ value.memory.memchip=
+ dynamic_cast<class cl_memory_chip *>(value.memory.memory);
+ if (value.memory.memory->is_address_space())
+ value.memory.address_space=
+ dynamic_cast<class cl_address_space *>(value.memory.memory);
+ }
+ return(value.memory.memory != 0);
+}
+
+bool
+cl_cmd_arg::as_hw(class cl_uc *uc)
+{
+ return(false);
+}
+
+bool
+cl_cmd_arg::as_cell(class cl_uc *uc)
+{
+ return(false);
+}
+
+bool
+cl_cmd_arg::as_string(void)
+{
+ char *s= get_svalue();
+ if (!s)
+ return(false);
+ if (is_string())
+ value.string.string= proc_escape(s, &value.string.len);
+ else
+ {
+ value.string.string= strdup(s);
+ value.string.len= strlen(s);
+ }
+ return(interpreted_as_string= value.string.string != NULL);
+}
+
+bool
+cl_cmd_arg::as_bit(class cl_uc *uc)
+{
+ return(get_bit_address(uc,
+ &(value.bit.mem),
+ &(value.bit.mem_address),
+ &(value.bit.mask)));
+}
+
+
+/* Interger number */
+
+cl_cmd_int_arg::cl_cmd_int_arg(/*class cl_uc *iuc,*/ long addr):
+ cl_cmd_arg(/*iuc,*/ addr)
+{}
+
+bool
+cl_cmd_int_arg::get_address(class cl_uc *uc, t_addr *addr)
+{
+ long iv;
+
+ bool b= get_ivalue(&iv);
+ if (addr)
+ *addr= iv;
+ return(b);
+}
+
+bool
+cl_cmd_int_arg::get_bit_address(class cl_uc *uc, // input
+ class cl_address_space **mem, // outputs
+ t_addr *mem_addr,
+ t_mem *bit_mask)
+{
+ t_addr bit_addr;
+
+ if (!get_address(uc, &bit_addr))
+ return(false);
+
+ if (mem)
+ *mem= uc->bit2mem(bit_addr, mem_addr, bit_mask);
+ return(mem && *mem);
+}
+
+bool
+cl_cmd_int_arg::as_string(void)
+{
+ value.string.string= (char*)malloc(100);
+ sprintf(value.string.string, "%ld", i_value);
+ value.string.len= strlen(value.string.string);
+ return(interpreted_as_string= value.string.string != NULL);
+}
+
+
+/* Symbol */
+
+cl_cmd_sym_arg::cl_cmd_sym_arg(const char *sym):
+ cl_cmd_arg(sym)
+{}
+
+bool
+cl_cmd_sym_arg::as_string(void)
+{
+ char *s= get_svalue();
+ if (!s)
+ return(false);
+ value.string.string= strdup(s);
+ value.string.len= strlen(s);
+ return(interpreted_as_string= value.string.string != NULL);
+}
+
+bool
+cl_cmd_sym_arg::get_address(class cl_uc *uc, t_addr *addr)
+{
+ t_addr a;
+
+ if (uc->symbol2address(get_svalue(), NULL, &a))
+ {
+ if (addr)
+ *addr= a;
+ return 1;
+ }
+ return(0);
+}
+
+bool
+cl_cmd_sym_arg::get_bit_address(class cl_uc *uc, // input
+ class cl_address_space **mem, // outputs
+ t_addr *mem_addr,
+ t_mem *bit_mask)
+{
+ /*
+ struct name_entry *ne;
+
+ ne= uc->get_name_entry(uc->bit_tbl(), get_svalue());
+ if (ne == NULL)
+ return(false);
+ if (mem)
+ *mem= uc->bit2mem(ne->addr, mem_addr, bit_mask);
+ return(mem && *mem);
+ */
+ class cl_var *v= uc->var(get_svalue());
+ if (v)
+ {
+ if (mem)
+ *mem= v->as;
+ if (mem_addr)
+ *mem_addr= v->addr;
+ if (bit_mask)
+ {
+ if (v->bitnr < 0)
+ {
+ *bit_mask= 1;
+ }
+ else
+ {
+ *bit_mask= 1 << v->bitnr;
+ }
+ }
+ return true;
+ }
+ return false;
+}
+
+bool
+cl_cmd_sym_arg::as_address(class cl_uc *uc)
+{
+ t_addr a;
+ if (uc->symbol2address(get_svalue(), NULL, &a))
+ {
+ value.address= a;
+ return true;
+ }
+ return(false);
+}
+
+bool
+cl_cmd_sym_arg::as_hw(class cl_uc *uc)
+{
+ cl_hw *hw, *found;
+ int i= 0;
+
+ hw= found= uc->get_hw(get_svalue(), &i);
+ if (!hw)
+ return(false);
+ i++;
+ found= uc->get_hw(get_svalue(), &i);
+ if (found)
+ return(false);
+ value.hw= hw;
+ return(true);
+}
+
+bool
+cl_cmd_sym_arg::as_cell(class cl_uc *uc)
+{
+ class cl_address_space *as;
+ t_addr addr;
+
+ if (uc->symbol2address(get_svalue(), &as, &addr))
+ {
+ value.cell= as->get_cell(addr);
+ return value.cell != NULL;
+ }
+ return false;
+}
+
+
+/* String */
+
+cl_cmd_str_arg::cl_cmd_str_arg(const char *str):
+ cl_cmd_arg(str)
+{
+}
+
+
+/* Bit */
+
+cl_cmd_bit_arg::cl_cmd_bit_arg(/*class cl_uc *iuc,*/
+ class cl_cmd_arg *asfr, class cl_cmd_arg *abit):
+ cl_cmd_arg(/*iuc,*/ (long)0)
+{
+ sfr= asfr;
+ bit= abit;
+}
+
+cl_cmd_bit_arg::~cl_cmd_bit_arg(void)
+{
+ if (sfr)
+ delete sfr;
+ if (bit)
+ delete bit;
+}
+
+bool
+cl_cmd_bit_arg::get_address(class cl_uc *uc, t_addr *addr)
+{
+ if (sfr)
+ return(sfr->get_address(uc, addr));
+ return(0);
+}
+
+bool
+cl_cmd_bit_arg::get_bit_address(class cl_uc *uc, // input
+ class cl_address_space **mem, // outputs
+ t_addr *mem_addr,
+ t_mem *bit_mask)
+{
+ if (mem)
+ {
+ *mem= uc->address_space(MEM_SFR_ID);
+ if (!*mem)
+ return(false);
+ }
+ if (mem_addr)
+ {
+ if (!sfr ||
+ !sfr->get_address(uc, mem_addr))
+ return(false);
+ }
+ if (bit_mask)
+ {
+ if (!bit)
+ return(false);
+ long l;
+ if (!bit->get_ivalue(&l) ||
+ l > 7)
+ return(false);
+ *bit_mask= 1 << l;
+ }
+ return(true);
+}
+
+
+/* Array */
+
+cl_cmd_array_arg::cl_cmd_array_arg(/*class cl_uc *iuc,*/
+ class cl_cmd_arg *aname,
+ class cl_cmd_arg *aindex):
+ cl_cmd_arg(/*iuc,*/ (long)0)
+{
+ name_arg= aname;
+ index= aindex;
+}
+
+cl_cmd_array_arg::~cl_cmd_array_arg(void)
+{
+ if (name_arg)
+ delete name_arg;
+ if (index)
+ delete index;
+}
+
+bool
+cl_cmd_array_arg::as_hw(class cl_uc *uc)
+{
+ char *n;
+ t_addr a;
+
+ if (name_arg == 0 ||
+ index == 0 ||
+ (n= name_arg->get_svalue()) == NULL ||
+ !index->get_address(uc, &a))
+ return(false);
+
+ value.hw= uc->get_hw(n, a, NULL);
+ return(value.hw != NULL);
+}
+
+bool
+cl_cmd_array_arg::as_cell(class cl_uc *uc)
+{
+ // address_space[address]
+ char *n;
+ t_addr a;
+ if (name_arg == 0 ||
+ index == 0 ||
+ (n= name_arg->get_svalue()) == NULL ||
+ !index->get_address(uc, &a))
+ return false;
+ class cl_memory *m= uc->memory(n);
+ if (!m)
+ return false;
+ if (!m->is_address_space())
+ return false;
+ value.cell= ((cl_address_space*)m)->get_cell(a);
+ return value.cell != NULL;
+}
+
+
+/*
+ * Program arguments
+ *----------------------------------------------------------------------------
+ */
+/*
+cl_prg_arg::cl_prg_arg(char sn, char *ln, long lv):
+ cl_arg(lv)
+{
+ short_name= sn;
+ long_name = ln?strdup(ln):0;
+}
+
+cl_prg_arg::cl_prg_arg(char sn, char *ln, char *sv):
+ cl_arg(sv)
+{
+ short_name= sn;
+ long_name = ln?strdup(ln):0;
+}
+
+cl_prg_arg::cl_prg_arg(char sn, char *ln, double fv):
+ cl_arg(fv)
+{
+ short_name= sn;
+ long_name = ln?strdup(ln):0;
+}
+
+cl_prg_arg::cl_prg_arg(char sn, char *ln, void *pv):
+ cl_arg(pv)
+{
+ short_name= sn;
+ long_name = ln?strdup(ln):0;
+}
+
+cl_prg_arg::~cl_prg_arg(void)
+{
+ if (long_name)
+ free(long_name);
+}
+*/
+
+/*
+ * List of arguments
+ *----------------------------------------------------------------------------
+ */
+/*
+int
+cl_arguments::arg_avail(char nam)
+{
+ class cl_prg_arg *a;
+ int i;
+
+ for (i= 0; i < count; i++)
+ {
+ a= (class cl_prg_arg *)(at(i));
+ if (a->short_name == nam)
+ return(1);
+ }
+ return(0);
+}
+
+int
+cl_arguments::arg_avail(char *nam)
+{
+ class cl_prg_arg *a;
+ int i;
+
+ for (i= 0; i < count; i++)
+ {
+ a= (class cl_prg_arg *)(at(i));
+ if (a->long_name &&
+ strcmp(a->long_name, nam) == 0)
+ return(1);
+ }
+ return(0);
+}
+
+long
+cl_arguments::get_iarg(char sname, char *lname)
+{
+ class cl_prg_arg *a;
+ int i;
+
+ for (i= 0; i < count; i++)
+ {
+ a= (class cl_prg_arg *)(at(i));
+ if ((sname && a->short_name == sname) ||
+ (lname && a->long_name && strcmp(a->long_name, lname) == 0))
+ {
+ long iv;
+ if (a->get_ivalue(&iv))
+ return(iv);
+ else
+ //FIXME
+ return(0);
+ }
+ }
+ return(0);
+}
+
+char *
+cl_arguments::get_sarg(char sname, char *lname)
+{
+ class cl_prg_arg *a;
+ int i;
+
+ for (i= 0; i < count; i++)
+ {
+ a= (class cl_prg_arg *)(at(i));
+ if ((sname && a->short_name == sname) ||
+ (lname && a->long_name && strcmp(a->long_name, lname) == 0))
+ return(a->get_svalue());
+ }
+ return(0);
+}
+
+
+double
+cl_arguments::get_farg(char sname, char *lname)
+{
+ class cl_prg_arg *a;
+ int i;
+
+ for (i= 0; i < count; i++)
+ {
+ a= (class cl_prg_arg *)(at(i));
+ if ((sname && a->short_name == sname) ||
+ (lname && a->long_name && strcmp(a->long_name, lname) == 0))
+ return(a->get_fvalue());
+ }
+ return(0);
+}
+
+void *
+cl_arguments::get_parg(char sname, char *lname)
+{
+ class cl_prg_arg *a;
+ int i;
+
+ for (i= 0; i < count; i++)
+ {
+ a= (class cl_prg_arg *)(at(i));
+ if ((sname && a->short_name == sname) ||
+ (lname && a->long_name && strcmp(a->long_name, lname) == 0))
+ return(a->get_pvalue());
+ }
+ return(0);
+}
+*/
+
+/* End of arg.cc */
diff --git a/sim/ucsim/sim.src/arg.o b/sim/ucsim/sim.src/arg.o
new file mode 100644
index 0000000..4773caa
--- /dev/null
+++ b/sim/ucsim/sim.src/arg.o
Binary files differ
diff --git a/sim/ucsim/sim.src/argcl.h b/sim/ucsim/sim.src/argcl.h
new file mode 100644
index 0000000..004aa30
--- /dev/null
+++ b/sim/ucsim/sim.src/argcl.h
@@ -0,0 +1,229 @@
+/*
+ * Simulator of microcontrollers (sim.src/argcl.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 SIM_ARGCL_HEADER
+#define SIM_ARGCL_HEADER
+
+// prj
+#include "pobjcl.h"
+#include "stypes.h"
+
+
+/*
+ * Base type of arguments/parameters
+ */
+
+class cl_arg: public cl_base
+{
+public:
+ union {
+ long i_value;
+ double f_value;
+ void *p_value;
+ };
+ char *s_value;
+
+public:
+ cl_arg(long lv);
+ cl_arg(const char *lv);
+ cl_arg(double fv);
+ cl_arg(void *pv);
+ virtual ~cl_arg(void);
+
+ virtual bool get_ivalue(long *value);
+ virtual char *get_svalue(void);
+ virtual double get_fvalue(void);
+ virtual void *get_pvalue(void);
+ virtual bool get_bit_address(class cl_uc *uc, // input
+ class cl_address_space **mem, // outputs
+ t_addr *mem_addr,
+ t_mem *bit_mask) { return(false); }
+};
+
+
+/*
+ * Command parameters
+ */
+
+class cl_cmd_arg: public cl_arg
+{
+public:
+ //class cl_uc *uc;
+ bool interpreted_as_string;
+ union {
+ long number;
+ t_addr address;
+ t_mem data;
+ struct {
+ class cl_memory *memory;
+ class cl_address_space *address_space;
+ class cl_memory_chip *memchip;
+ } memory;
+ class cl_hw *hw;
+ struct {
+ int len;
+ char *string;
+ } string;
+ struct {
+ t_mem *array;
+ int len;
+ } data_list;
+ struct {
+ class cl_address_space *mem;
+ t_addr mem_address;
+ t_mem mask;
+ } bit;
+ class cl_memory_cell *cell;
+ } value;
+
+public:
+ cl_cmd_arg(long i): cl_arg(i)
+ { interpreted_as_string= false; }
+ cl_cmd_arg(const char *s): cl_arg(s)
+ { interpreted_as_string= false; }
+ virtual ~cl_cmd_arg(void);
+
+ virtual int is_string(void) { return(false); }
+ virtual bool get_address(class cl_uc *uc, t_addr *addr) { return(false); }
+ virtual bool as_address(class cl_uc *uc);
+ virtual bool as_number(void);
+ virtual bool as_data(void);
+ virtual bool as_string(void);
+ virtual bool as_memory(class cl_uc *uc);
+ virtual bool as_hw(class cl_uc *uc);
+ virtual bool as_cell(class cl_uc *uc);
+ virtual bool as_bit(class cl_uc *uc);
+};
+
+class cl_cmd_int_arg: public cl_cmd_arg
+{
+public:
+ cl_cmd_int_arg(long addr);
+
+ virtual bool get_address(class cl_uc *uc, t_addr *addr);
+ virtual bool get_bit_address(class cl_uc *uc, // input
+ class cl_address_space **mem, // outputs
+ t_addr *mem_addr,
+ t_mem *bit_mask);
+ virtual bool as_string(void);
+};
+
+class cl_cmd_sym_arg: public cl_cmd_arg
+{
+public:
+ cl_cmd_sym_arg(const char *sym);
+
+ virtual bool get_address(class cl_uc *uc, t_addr *addr);
+ virtual bool get_bit_address(class cl_uc *uc, // input
+ class cl_address_space **mem, // outputs
+ t_addr *mem_addr,
+ t_mem *bit_mask);
+ virtual bool as_address(class cl_uc *uc);
+ virtual bool as_number(void) { return(false); }
+ virtual bool as_string(void);
+ virtual bool as_hw(class cl_uc *uc);
+ virtual bool as_cell(class cl_uc *uc);
+};
+
+class cl_cmd_str_arg: public cl_cmd_arg
+{
+public:
+ cl_cmd_str_arg(const char *str);
+
+ virtual int is_string(void) { return(1); }
+ virtual bool as_number(void) { return(false); }
+};
+
+class cl_cmd_bit_arg: public cl_cmd_arg
+{
+public:
+ class cl_cmd_arg *sfr, *bit;
+
+public:
+ cl_cmd_bit_arg(class cl_cmd_arg *asfr, class cl_cmd_arg *abit);
+ virtual ~cl_cmd_bit_arg(void);
+
+ virtual bool get_address(class cl_uc *uc, t_addr *addr);
+ virtual bool get_bit_address(class cl_uc *uc, // input
+ class cl_address_space **mem, // outputs
+ t_addr *mem_addr,
+ t_mem *bit_mask);
+};
+
+class cl_cmd_array_arg: public cl_cmd_arg
+{
+public:
+ class cl_cmd_arg *name_arg, *index;
+
+public:
+ cl_cmd_array_arg(class cl_cmd_arg *aname, class cl_cmd_arg *aindex);
+ virtual ~cl_cmd_array_arg(void);
+ virtual bool as_hw(class cl_uc *uc);
+ virtual bool as_cell(class cl_uc *uc);
+};
+
+
+/*
+ * Program arguments
+ */
+
+/*class cl_prg_arg: public cl_arg
+{
+public:
+ char short_name;
+ char *long_name;
+
+public:
+ cl_prg_arg(char sn, char *ln, long lv);
+ cl_prg_arg(char sn, char *ln, char *lv);
+ cl_prg_arg(char sn, char *ln, double fv);
+ cl_prg_arg(char sn, char *ln, void *pv);
+ virtual ~cl_prg_arg(void);
+};*/
+
+
+/*
+ * List of arguments
+ */
+
+/*class cl_arguments: public cl_list
+{
+public:
+ cl_arguments(void): cl_list(5, 5) {}
+
+ int arg_avail(char nam);
+ int arg_avail(char *nam);
+ virtual long get_iarg(char sname, char *lname);
+ virtual char *get_sarg(char sname, char *lname);
+ virtual double get_farg(char sname, char *lname);
+ virtual void *get_parg(char sname, char *lname);
+};*/
+
+
+#endif
+
+/* End of argcl.h */
diff --git a/sim/ucsim/sim.src/brk.cc b/sim/ucsim/sim.src/brk.cc
new file mode 100644
index 0000000..aaa396a
--- /dev/null
+++ b/sim/ucsim/sim.src/brk.cc
@@ -0,0 +1,312 @@
+/*
+ * Simulator of microcontrollers (brk.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@*/
+
+#include "ddconfig.h"
+
+#include <stdio.h>
+#include <ctype.h>
+
+#include "pobjcl.h"
+#include "globals.h"
+
+#include "brkcl.h"
+
+
+/*
+ * Base object of breakpoints
+ */
+
+cl_brk::cl_brk(class cl_address_space *imem, int inr, t_addr iaddr,
+ enum brk_perm iperm, int ihit):
+ cl_base()
+{
+ mem = imem;
+ nr = inr;
+ addr = iaddr;
+ perm = iperm;
+ hit = ihit;
+ cnt = ihit;
+ cond = chars("");
+ commands= chars("");
+}
+
+cl_brk::~cl_brk(void)
+{}
+
+bool
+cl_brk::condition(void)
+{
+ if (cond.empty())
+ return true;
+ long l;
+ l= application->eval(cond);
+ //fprintf(stderr,"BP[%d]EVAL: %s =%ld\n", nr, (char*)cond, l);
+ return l!=0;
+}
+
+void
+cl_brk::activate(void)
+{
+ if (mem)
+ mem->set_brk(addr, this);
+}
+
+void
+cl_brk::inactivate(void)
+{
+ if (mem)
+ mem->del_brk(addr, this);
+}
+
+bool
+cl_brk::do_hit(void)
+{
+ cnt--;
+ if (cnt <= 0)
+ {
+ cnt= hit;
+ if (condition())
+ return(1);
+ }
+ return(0);
+}
+
+
+/*
+ * FETCH type of breakpoint
+ */
+
+cl_fetch_brk::cl_fetch_brk(class cl_address_space *imem, int inr, t_addr iaddr,
+ enum brk_perm iperm, int ihit):
+ cl_brk(imem, inr, iaddr, iperm, ihit)
+{
+ code = 0;
+}
+
+enum brk_type
+cl_fetch_brk::type(void)
+{
+ return(brkFETCH);
+}
+
+
+/*
+ * Base of EVENT type of breakpoints
+ */
+
+cl_ev_brk::cl_ev_brk(class cl_address_space *imem, int inr, t_addr iaddr,
+ enum brk_perm iperm, int ihit,
+ enum brk_event ievent, const char *iid):
+ cl_brk(imem, inr, iaddr, iperm, ihit)
+{
+ event= ievent;
+ id = iid;
+ mem = imem;
+}
+
+cl_ev_brk::cl_ev_brk(class cl_address_space *imem, int inr, t_addr iaddr,
+ enum brk_perm iperm, int ihit, char op):
+ cl_brk(imem, inr, iaddr, iperm, ihit)
+{
+ mem = imem;
+ if ((op= toupper(op)) == 'R')
+ {
+ event= brkREAD;
+ id= "read";
+ }
+ else if (op == 'W')
+ {
+ event= brkWRITE;
+ id= "write";
+ }
+ else
+ {
+ event= brkACCESS;
+ id= "access";
+ }
+}
+
+enum brk_type
+cl_ev_brk::type(void)
+{
+ return(brkEVENT);
+}
+
+bool
+cl_ev_brk::match(struct event_rec *ev)
+{
+ return(false);
+}
+
+
+/*
+ * Collection of break-points
+ *
+ * This is a sorted collection, sorted by nr field of brk items.
+ */
+
+brk_coll::brk_coll(t_index alimit, t_index adelta,
+ class cl_address_space *arom):
+ cl_sorted_list(alimit, adelta, "breakpoints")
+{
+ rom= arom;
+}
+
+void *
+brk_coll::key_of(void *item)
+{
+ return((void *)&(((class cl_brk *)(item))->nr));
+}
+
+
+int
+brk_coll::compare(void *key1, void *key2)
+{
+ int k1, k2;
+
+ k1= *(int *)key1;
+ k2= *(int *)key2;
+
+ if (k1 == k2)
+ return(0);
+ else
+ if (k1 < k2)
+ return(-1);
+ else
+ return(+1);
+}
+
+
+/*
+ * Checking if there is an event breakpoint for the specified event
+ */
+
+bool
+brk_coll::there_is_event(enum brk_event ev)
+{
+ class cl_brk *b;
+ int i;
+
+ for (i= 0; i < count; i++)
+ {
+ b= (class cl_brk *)at(i);
+ if (b->type() == brkEVENT &&
+ ((class cl_ev_brk *)b)->event == ev)
+ return(true);
+ }
+ return(false);
+}
+
+/*int
+brk_coll::make_new_nr(void)
+{
+ if (count == 0)
+ return(1);
+ class cl_brk *b= (class cl_brk *)(at(count-1));
+ return(b->nr+1);
+}*/
+
+void
+brk_coll::add_bp(class cl_brk *bp)
+{
+ add(bp);
+ bp->activate();
+ return;
+ /*if (rom &&
+ bp->addr < rom->size)
+ / *rom->bp_map->set(bp->addr)* /rom->set_brk(bp->addr, bp);*/
+}
+
+void
+brk_coll::del_bp(t_addr addr)
+{
+ int idx;
+ class cl_brk *bp;
+
+ if ((bp= get_bp(addr, &idx)))
+ {
+ bp->inactivate();
+ free_at(idx);
+ }
+ return;
+}
+
+void
+brk_coll::del_bp(t_index idx, int /*dummy*/)
+{
+ class cl_brk *bp;
+
+ if (idx >= count)
+ return;
+ bp= (class cl_brk *)(at(idx));
+ if (!bp)
+ return;
+ bp->inactivate();
+ free_at(idx);
+}
+
+class cl_brk *
+brk_coll::get_bp(t_addr addr, int *idx)
+{
+ if (rom &&
+ rom->valid_address(addr) &&
+ rom->get_cell_flag(addr, CELL_FETCH_BRK))
+ {
+ for (*idx= 0; *idx < count; (*idx)++)
+ {
+ class cl_brk *b= (class cl_brk *)(at(*idx));
+ if (b->addr == addr)
+ return(b);
+ }
+ }
+ return(0);
+}
+
+class cl_brk *
+brk_coll::get_bp(int nr)
+{
+ int i;
+
+ for (i= 0; i < count; i++)
+ {
+ class cl_brk *bp= (class cl_brk *)(at(i));
+ if (bp->nr == nr)
+ return(bp);
+ }
+ return(0);
+}
+
+bool
+brk_coll::bp_at(t_addr addr)
+{
+ return(rom &&
+ rom->valid_address(addr) &&
+ rom->get_cell_flag(addr, CELL_FETCH_BRK));
+}
+
+
+/* End of brk.cc */
diff --git a/sim/ucsim/sim.src/brk.o b/sim/ucsim/sim.src/brk.o
new file mode 100644
index 0000000..baa285c
--- /dev/null
+++ b/sim/ucsim/sim.src/brk.o
Binary files differ
diff --git a/sim/ucsim/sim.src/brkcl.h b/sim/ucsim/sim.src/brkcl.h
new file mode 100644
index 0000000..6de5ed8
--- /dev/null
+++ b/sim/ucsim/sim.src/brkcl.h
@@ -0,0 +1,139 @@
+/*
+ * Simulator of microcontrollers (sim.src/brkcl.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 SIM_BRKCL_HEADER
+#define SIM_BRKCL_HEADER
+
+#include "ddconfig.h"
+
+// prj
+#include "pobjcl.h"
+#include "stypes.h"
+
+// sim
+#include "memcl.h"
+
+
+/*
+ * Base object of breakpoints
+ */
+
+class cl_brk: public cl_base
+{
+protected:
+ class cl_address_space *mem;
+public:
+ int nr;
+ t_addr addr;
+ enum brk_perm perm; // permanency (FIX,DYNAMIC)
+ int hit;
+ int cnt;
+ chars cond;
+ chars commands;
+
+ cl_brk(class cl_address_space *imem, int inr, t_addr iaddr,
+ enum brk_perm iperm, int ihit);
+ virtual ~cl_brk(void);
+
+ class cl_address_space *get_mem(void) { return(mem); }
+
+ virtual bool condition(void);
+ virtual void activate(void);
+ virtual void inactivate(void);
+ virtual enum brk_type type(void)= 0;
+ virtual enum brk_event get_event(void)= 0;
+ virtual bool do_hit(void);
+};
+
+
+/*
+ * FETCH type of breakpoints
+ */
+
+class cl_fetch_brk: public cl_brk
+{
+public:
+ uchar code;
+
+ cl_fetch_brk(class cl_address_space *imem, int inr, t_addr iaddr,
+ enum brk_perm iperm, int ihit);
+
+ virtual enum brk_type type(void);
+ virtual enum brk_event get_event(void) { return(brkNONE); }
+};
+
+
+/*
+ * Base of EVENT type of breakpoints
+ */
+
+class cl_ev_brk: public cl_brk
+{
+public:
+ cl_ev_brk(class cl_address_space *imem, int inr, t_addr iaddr,
+ enum brk_perm iperm,
+ int ihit, enum brk_event ievent, const char *iid);
+ cl_ev_brk(class cl_address_space *imem, int inr, t_addr iaddr,
+ enum brk_perm iperm,
+ int ihit, char op);
+ enum brk_event event;
+ const char *id;
+
+ virtual enum brk_type type(void);
+ virtual enum brk_event get_event(void) { return(event); }
+ virtual bool match(struct event_rec *ev);
+};
+
+
+/*
+ * Collection of breakpoint sorted by address
+ */
+
+class brk_coll: public cl_sorted_list
+{
+public:
+ class cl_address_space/*rom*/ *rom;
+public:
+ brk_coll(t_index alimit, t_index adelta, class cl_address_space/*rom*/*arom);
+ virtual void *key_of(void *item);
+ virtual int compare(void *key1, void *key2);
+
+ virtual bool there_is_event(enum brk_event ev);
+ //virtual int make_new_nr(void);
+
+ virtual void add_bp(class cl_brk *bp);
+ virtual void del_bp(t_addr addr);
+ virtual void del_bp(t_index idx, int /*dummy*/);
+ virtual class cl_brk *get_bp(t_addr addr, int *idx);
+ virtual class cl_brk *get_bp(int nr);
+ virtual bool bp_at(t_addr addr);
+};
+
+
+#endif
+
+/* End of brkcl.h */
diff --git a/sim/ucsim/sim.src/clean.mk b/sim/ucsim/sim.src/clean.mk
new file mode 100644
index 0000000..89e5433
--- /dev/null
+++ b/sim/ucsim/sim.src/clean.mk
@@ -0,0 +1,22 @@
+# Deleting all files created by building the program
+# --------------------------------------------------
+clean:
+ rm -f *core *[%~] *.[oa] test_mem_speed
+ rm -f .[a-z]*~
+
+
+# Deleting all files created by configuring or building the program
+# -----------------------------------------------------------------
+distclean: clean
+ 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
diff --git a/sim/ucsim/sim.src/conf.mk b/sim/ucsim/sim.src/conf.mk
new file mode 100644
index 0000000..1a777f2
--- /dev/null
+++ b/sim/ucsim/sim.src/conf.mk
@@ -0,0 +1,10 @@
+#
+# Makefile targets to remake configuration
+#
+
+freshconf: Makefile
+
+Makefile: $(srcdir)/Makefile.in $(top_builddir)/configure.ac
+ cd $(top_builddir) && $(SHELL) ./config.status
+
+# End of conf.mk
diff --git a/sim/ucsim/sim.src/guiobj.cc b/sim/ucsim/sim.src/guiobj.cc
new file mode 100644
index 0000000..6019bc2
--- /dev/null
+++ b/sim/ucsim/sim.src/guiobj.cc
@@ -0,0 +1,37 @@
+/*
+ * Simulator of microcontrollers (guiobj.cc)
+ *
+ * Copyright (C) 2001,01 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@*/
+
+#include "guiobjcl.h"
+
+
+cl_guiobj::cl_guiobj(void):
+ cl_base()
+{
+}
+
+
+/* End of gui.src/guiobj.cc */
diff --git a/sim/ucsim/sim.src/guiobj.o b/sim/ucsim/sim.src/guiobj.o
new file mode 100644
index 0000000..bf50ecf
--- /dev/null
+++ b/sim/ucsim/sim.src/guiobj.o
Binary files differ
diff --git a/sim/ucsim/sim.src/guiobjcl.h b/sim/ucsim/sim.src/guiobjcl.h
new file mode 100644
index 0000000..e01dbce
--- /dev/null
+++ b/sim/ucsim/sim.src/guiobjcl.h
@@ -0,0 +1,45 @@
+/*
+ * Simulator of microcontrollers (sim.src/guiobjcl.h)
+ *
+ * Copyright (C) 2001,01 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 SIM_GUIOBJCL_HEADER
+#define SIM_GUIOBJCL_HEADER
+
+#include "ddconfig.h"
+
+#include "pobjcl.h"
+
+
+class cl_guiobj: public cl_base
+{
+public:
+ cl_guiobj(void);
+};
+
+
+#endif
+
+/* End of sim.src/guiobjcl.h */
diff --git a/sim/ucsim/sim.src/hw.cc b/sim/ucsim/sim.src/hw.cc
new file mode 100644
index 0000000..7e7bc08
--- /dev/null
+++ b/sim/ucsim/sim.src/hw.cc
@@ -0,0 +1,687 @@
+/*
+ * Simulator of microcontrollers (hw.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@*/
+
+#include "ddconfig.h"
+
+#include <ctype.h>
+#include <stdlib.h>
+#include "i_string.h"
+
+#include "stypes.h"
+#include "globals.h"
+
+#include "hwcl.h"
+
+
+/*
+ *____________________________________________________________________________
+ */
+
+cl_hw::cl_hw(class cl_uc *auc, enum hw_cath cath, int aid, const char *aid_string):
+ cl_guiobj()
+{
+ flags= HWF_INSIDE;
+ uc= auc;
+ cathegory= cath;
+ id= aid;
+ if (aid_string &&
+ *aid_string)
+ id_string= strdup(aid_string);
+ else
+ id_string= strdup("unknown hw element");
+ set_name(id_string);
+ char *s= (char*)malloc(strlen(get_name("hw"))+100);
+ sprintf(s, "partners of %s", get_name("hw"));
+ partners= new cl_list(2, 2, s);
+ sprintf(s, "watched cells of %s", get_name("hw"));
+ free(s);
+ cfg= 0;
+ io= 0;
+}
+
+cl_hw::~cl_hw(void)
+{
+ free((void*)id_string);
+ delete partners;
+}
+
+int
+cl_hw::init(void)
+{
+ chars n(id_string);
+ char s[100];
+ int i;
+
+ on= true;
+
+ snprintf(s, 99, "%d", id);
+ n+= '_';
+ n+= s;
+ n+= cchars("_cfg");
+
+ cfg= new cl_address_space(n, 0, cfg_size(), sizeof(t_mem)*8);
+ cfg->init();
+ cfg->hidden= true;
+ uc->address_spaces->add(cfg);
+
+ for (i= 0; i < cfg_size(); i++)
+ {
+ cfg->register_hw(i, this, false);
+ }
+
+ cache_run= -1;
+ cache_time= 0;
+ return 0;
+}
+
+void
+cl_hw::new_hw_adding(class cl_hw *new_hw)
+{
+}
+
+void
+cl_hw::new_hw_added(class cl_hw *new_hw)
+{
+ int i;
+
+ for (i= 0; i < partners->count; i++)
+ {
+ class cl_partner_hw *ph= (class cl_partner_hw *)(partners->at(i));
+ ph->refresh(new_hw);
+ }
+}
+
+class cl_hw *
+cl_hw::make_partner(enum hw_cath cath, int id)
+{
+ class cl_partner_hw *ph;
+ class cl_hw *hw;
+
+ ph= new cl_partner_hw(uc, cath, id);
+ partners->add(ph);
+ hw= ph->get_partner();
+ return(hw);
+}
+
+t_mem
+cl_hw::read(class cl_memory_cell *cell)
+{
+ conf(cell, NULL);
+ return cell->get();
+}
+
+void
+cl_hw::write(class cl_memory_cell *cell, t_mem *val)
+{
+ conf(cell, val);
+}
+
+bool
+cl_hw::conf(class cl_memory_cell *cell, t_mem *val)
+{
+ t_addr a;
+ if (cfg->is_owned(cell, &a))
+ {
+ conf_op(cell, a, val);
+ if (val)
+ cell->set(*val);
+ return true;
+ }
+ return false;
+}
+
+t_mem
+cl_hw::conf_op(cl_memory_cell *cell, t_addr addr, t_mem *val)
+{
+ return cell->get();
+}
+
+void
+cl_hw::cfg_set(t_addr addr, t_mem val)
+{
+ cfg->set(addr, val);
+}
+
+void
+cl_hw::cfg_write(t_addr addr, t_mem val)
+{
+ cfg->write(addr, val);
+}
+
+t_mem
+cl_hw::cfg_get(t_addr addr)
+{
+ return cfg->get(addr);
+}
+
+t_mem
+cl_hw::cfg_read(t_addr addr)
+{
+ return cfg->read(addr);
+}
+
+char *
+cl_hw::cfg_help(t_addr addr)
+{
+ return (char*)"N/A";
+}
+
+void
+cl_hw::set_cmd(class cl_cmdline *cmdline, class cl_console_base *con)
+{
+ con->dd_printf("Nothing to do\n");
+}
+
+class cl_memory_cell *
+cl_hw::register_cell(class cl_address_space *mem, t_addr addr)
+{
+ if (mem)
+ mem->register_hw(addr, this, false);
+ else
+ printf("regcell JAJ no mem\n");
+ return mem->get_cell(addr);
+}
+
+class cl_memory_cell *
+cl_hw::register_cell(class cl_memory_cell *cell)
+{
+ if (cell)
+ {
+ cell->add_hw(this);
+ }
+ return cell;
+}
+
+void
+cl_hw::unregister_cell(class cl_memory_cell *the_cell)
+{
+ if (the_cell)
+ the_cell->remove_hw(this);
+}
+
+
+/*
+ * Simulating `cycles' number of machine cycle
+ */
+
+int
+cl_hw::tick(int cycles)
+{
+ return(0);
+}
+
+void
+cl_hw::inform_partners(enum hw_event he, void *params)
+{
+ int i;
+
+ for (i= 0; i < partners->count; i++)
+ {
+ class cl_partner_hw *ph= (class cl_partner_hw *)(partners->at(i));
+ ph->happen(this, he, params);
+ }
+}
+
+void
+cl_hw::touch(void)
+{
+ refresh_display(false);
+}
+
+void
+cl_hw::make_io()
+{
+ if (!io)
+ {
+ io= new cl_hw_io(this);
+ io->init();
+ application->get_commander()->add_console(io);
+ }
+}
+
+void
+cl_hw::new_io(class cl_f *f_in, class cl_f *f_out)
+{
+ make_io();
+ if (!io)
+ return ;
+ io->tu_reset();
+ io->replace_files(true, f_in, f_out);
+ if (f_in)
+ {
+ f_in->interactive(NULL);
+ f_in->raw();
+ f_in->echo(NULL);
+ }
+ draw_display();
+ //application->get_commander()->update_active();
+}
+
+void
+cl_hw::new_i(class cl_f *f_in)
+{
+ make_io();
+ if (!io)
+ return ;
+ io->tu_reset();
+ io->replace_files(true, f_in, io->get_fout());
+ if (f_in)
+ {
+ f_in->interactive(NULL);
+ f_in->raw();
+ f_in->echo(NULL);
+ }
+ draw_display();
+}
+
+void
+cl_hw::new_o(class cl_f *f_out)
+{
+ make_io();
+ if (!io)
+ return ;
+ io->tu_reset();
+ io->replace_files(true, io->get_fin(), f_out);
+ draw_display();
+}
+
+class cl_hw_io *
+cl_hw::get_io(void)
+{
+ return io;
+}
+
+bool
+cl_hw::proc_input(void)
+{
+ int c;
+
+ if (!io)
+ return false;
+
+ class cl_f *fin= io->get_fin();
+ class cl_f *fout= io->get_fout();
+
+ if (fin)
+ {
+ if (fin->eof())
+ {
+ if (fout &&
+ (fout->file_id == fin->file_id))
+ {
+ io->tu_reset();
+ delete fout;
+ io->replace_files(false, fin, 0);
+ }
+ delete fin;
+ io->replace_files(false, 0, 0);
+ return true;
+ }
+ fin->read(&c, 1);
+ return handle_input(c);
+ }
+ return false;
+}
+
+bool
+cl_hw::handle_input(int c)
+{
+ if (!io)
+ return false;
+
+ io->tu_go(1,3);
+ io->tu_cll();
+ switch (c)
+ {
+ case 's'-'a'+1: case 'r'-'a'+1: case 'g'-'a'+1:
+ uc->sim->change_run();
+ if (uc->sim->state & SIM_GO)
+ io->dd_printf("Simulation started.");
+ else
+ io->dd_printf("Simulation stopped.");
+ break;
+ case 't'-'a'+1:
+ uc->reset();
+ io->dd_printf("CPU reset.");
+ break;
+ case 'q'-'a'+1:
+ uc->sim->state|= SIM_QUIT;
+ io->dd_printf("Exit simulator.");
+ io->tu_reset();
+ break;
+ case 'o'-'a'+1:
+ io->dd_printf("Closing display.");
+ io->tu_reset();
+ io->tu_cls();
+ io->convert2console();
+ break;
+ case 'l'-'a'+1:
+ draw_display();
+ break;
+ case 'n'-'a'+1:
+ {
+ class cl_hw *h= next_displayer();
+ if (!h)
+ io->dd_printf("No other displayer.");
+ else
+ {
+ io->tu_reset();
+ io->tu_cls();
+ io->pass2hw(h);
+ }
+ break;
+ }
+ default:
+ return false;
+ break;
+ }
+ return true;
+}
+
+void
+cl_hw::refresh_display(bool force)
+{
+ if (!io)
+ return ;
+ int n= uc->sim->state & SIM_GO;
+ if ((n != cache_run) ||
+ force)
+ {
+ io->tu_go(66,1);
+ if (n)
+ io->dd_cprintf("ui_run" , "%s", "Run ");
+ else
+ io->dd_cprintf("ui_stop", "%s", "Stop");
+ cache_run= n;
+ }
+ unsigned int t= (unsigned int)(uc->get_rtime()) * 500;
+ if ((t != cache_time) ||
+ force)
+ {
+ io->tu_go(28,2);
+ io->dd_cprintf("ui_time", "%u ms", t);
+ if (t < cache_time)
+ io->dd_printf(" ");
+ cache_time= t;
+ }
+}
+
+void
+cl_hw::draw_display(void)
+{
+ if (!io)
+ return ;
+ io->tu_go(1, 1);
+ io->dd_cprintf("ui_mkey", "[^s] ");
+ io->dd_cprintf("ui_mitem", "Start/stop ");
+ io->dd_cprintf("ui_mkey", "[^t] ");
+ io->dd_cprintf("ui_mitem", "reseT ");
+ io->dd_cprintf("ui_mkey", "[^q] ");
+ io->dd_cprintf("ui_mitem", "Quit ");
+ io->dd_cprintf("ui_mkey", "[^o] ");
+ io->dd_cprintf("ui_mitem", "clOse ");
+ io->dd_cprintf("ui_mkey", "[^l] ");
+ io->dd_cprintf("ui_mitem", "redraw\n");
+ io->dd_cprintf("ui_mkey", "[^n] ");
+ io->dd_cprintf("ui_mitem", "chaNge display ");
+ io->dd_cprintf("ui_label", "Time: ");
+ io->tu_go(66,2);
+ chars s("", "%s[%d]", id_string, id);
+ io->dd_cprintf("ui_title", "%-13s", (char*)s);
+}
+
+class cl_hw *
+cl_hw::next_displayer(void)
+{
+ if (!uc)
+ return NULL;
+ return uc->hws->next_displayer(this);
+}
+
+
+void
+cl_hw::print_info(class cl_console_base *con)
+{
+ con->dd_printf("%s[%d]\n", id_string, id);
+ print_cfg_info(con);
+}
+
+void
+cl_hw::print_cfg_info(class cl_console_base *con)
+{
+ t_mem v;
+ t_addr a, s, e;
+ con->dd_printf("Configuration memory of %s\n", get_name());
+ if (cfg)
+ {
+ s= cfg->get_start_address();
+ e= s + cfg->get_size();
+ for (a= s; a <= e; a++)
+ {
+ v= cfg->read(a);
+ con->dd_cprintf("dump_address", "0x%02x ", AU(a));
+ con->dd_cprintf("dump_number", "%08x ",v);
+ if ((v < 128) &&
+ isprint((int)v))
+ con->dd_cprintf("dump_char", "%c", v);
+ else
+ con->dd_cprintf("dump_char", ".");
+ con->dd_printf(" %s\n", cfg_help(a));
+ }
+ }
+}
+
+/*
+ * List of hw
+ */
+
+t_index
+cl_hws::add(void *item)
+{
+ int i;
+ t_index res;
+
+ // pre-add
+ for (i= 0; i < count; i++)
+ {
+ class cl_hw *hw= (class cl_hw *)(at(i));
+ hw->new_hw_adding((class cl_hw *)item);
+ }
+ // add
+ res= cl_list::add(item);
+ // post-add
+ for (i= 0; i < count; i++)
+ {
+ class cl_hw *hw= (class cl_hw *)(at(i));
+ hw->new_hw_added((class cl_hw *)item);
+ }
+ ((class cl_hw *)item)->added_to_uc();
+ return(res);
+}
+
+class cl_hw *
+cl_hws::next_displayer(class cl_hw *hw)
+{
+ int i, j;
+ cl_hw_io *io;
+ cl_f *fi, *fo;
+
+ if (!index_of(hw, &i))
+ return NULL;
+
+ for (j= i+1; j < count; j++)
+ {
+ class cl_hw *h= (class cl_hw *)(at(j));
+ h->make_io();
+ if ((io= h->get_io()))
+ {
+ fi= io->get_fin();
+ fo= io->get_fout();
+ if (!fi &&
+ !fo)
+ return h;
+ }
+ }
+ for (j= 0; j < i; j++)
+ {
+ class cl_hw *h= (class cl_hw *)(at(j));
+ h->make_io();
+ if ((io= h->get_io()))
+ {
+ fi= io->get_fin();
+ fo= io->get_fout();
+ if (!fi &&
+ !fo)
+ return h;
+ }
+ }
+ return NULL;
+}
+
+
+/*
+ *____________________________________________________________________________
+ */
+
+cl_partner_hw::cl_partner_hw(class cl_uc *auc, enum hw_cath cath, int aid):
+ cl_base()
+{
+ uc= auc;
+ cathegory= cath;
+ id= aid;
+ partner= uc->get_hw(cathegory, id, 0);
+}
+
+class cl_hw *
+cl_partner_hw::get_partner(void)
+{
+ return(partner);
+}
+
+void
+cl_partner_hw::refresh(void)
+{
+ class cl_hw *hw= uc->get_hw(cathegory, id, 0);
+
+ if (!hw)
+ return;
+ if (partner)
+ {
+ // partner is already set
+ if (partner != hw)
+ {
+ // partner changed?
+ partner= hw;
+ }
+ else
+ partner= hw;
+ }
+ partner= hw;
+}
+
+void
+cl_partner_hw::refresh(class cl_hw *new_hw)
+{
+ if (!new_hw)
+ return;
+ if (cathegory == new_hw->cathegory &&
+ id == new_hw->id)
+ {
+ if (partner)
+ {
+ // partner changed?
+ partner= new_hw;
+ }
+ else
+ partner= new_hw;
+ }
+}
+
+void
+cl_partner_hw::happen(class cl_hw *where, enum hw_event he, void *params)
+{
+ if (partner)
+ partner->happen(where, he, params);
+}
+
+
+/*
+ *____________________________________________________________________________
+ */
+
+cl_hw_io::cl_hw_io(class cl_hw *ihw):
+ cl_console()
+{
+ hw= ihw;
+ set_name(chars("", "%s[%d]", ihw->id_string, ihw->id));
+}
+
+int
+cl_hw_io::init(void)
+{
+ set_flag(CONS_NOWELCOME, true);
+ return 0;
+}
+
+int
+cl_hw_io::proc_input(class cl_cmdset *cmdset)
+{
+ if (hw)
+ hw->proc_input();
+ else
+ {
+ int c;
+ fin->read(&c, 1);
+ dd_printf("Unhandled hwio command: %c %d 0x%02x\n", isprint(c)?c:'?', c, c);
+ }
+ return 0;
+}
+
+
+void
+cl_hw_io::convert2console(void)
+{
+ if (fin &&
+ fout)
+ {
+ class cl_console *con= new cl_console(fin, fout, application);
+ con->init();
+ application->get_commander()->add_console(con);
+ }
+ drop_files();
+}
+
+void
+cl_hw_io::pass2hw(class cl_hw *new_hw)
+{
+ if (new_hw)
+ new_hw->new_io(fin, fout);
+ drop_files();
+}
+
+
+/* End of hw.cc */
diff --git a/sim/ucsim/sim.src/hw.o b/sim/ucsim/sim.src/hw.o
new file mode 100644
index 0000000..dad0dd4
--- /dev/null
+++ b/sim/ucsim/sim.src/hw.o
Binary files differ
diff --git a/sim/ucsim/sim.src/hwcl.h b/sim/ucsim/sim.src/hwcl.h
new file mode 100644
index 0000000..ff5c050
--- /dev/null
+++ b/sim/ucsim/sim.src/hwcl.h
@@ -0,0 +1,159 @@
+/*
+ * Simulator of microcontrollers (sim.src/hwcl.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@*/
+
+/* Abstract hw element. It can be a timer, serial line or whatever */
+
+#ifndef SIM_HWCL_HEADER
+#define SIM_HWCL_HEADER
+
+#include "stypes.h"
+#include "pobjcl.h"
+#include "guiobjcl.h"
+
+// cmd.src
+#include "newcmdcl.h"
+#include "newcmdposixcl.h"
+
+// local
+#include "memcl.h"
+#include "uccl.h"
+
+
+class cl_hw;
+
+class cl_hw_io: public cl_console
+{
+ protected:
+ class cl_hw *hw;
+ public:
+ cl_hw_io(class cl_hw *ihw);
+ virtual int init(void);
+
+ virtual int proc_input(class cl_cmdset *cmdset);
+ virtual bool prevent_quit(void) { return get_fin() && get_fin()->tty; }
+ virtual void print_prompt(void) {}
+
+ virtual void convert2console(void);
+ virtual void pass2hw(class cl_hw *new_hw);
+};
+
+
+class cl_hw: public cl_guiobj
+{
+ public:
+ int flags;
+ class cl_uc *uc;
+ enum hw_cath cathegory;
+ int id;
+ const char *id_string;
+ bool on;
+ protected:
+ class cl_list *partners;
+ class cl_address_space *cfg;
+ class cl_hw_io *io;
+ int cache_run;
+ unsigned int cache_time;
+ public:
+ cl_hw(class cl_uc *auc, enum hw_cath cath, int aid, const char *aid_string);
+ virtual ~cl_hw(void);
+
+ virtual int init(void);
+ virtual int cfg_size(void) { return 1; }
+
+ virtual void new_hw_adding(class cl_hw *new_hw);
+ virtual void new_hw_added(class cl_hw *new_hw);
+ virtual void added_to_uc(void) {}
+ virtual class cl_hw *make_partner(enum hw_cath cath, int id);
+
+ virtual t_mem read(class cl_memory_cell *cell);
+ virtual void write(class cl_memory_cell *cell, t_mem *val);
+ virtual bool conf(class cl_memory_cell *cell, t_mem *val);
+ virtual t_mem conf_op(cl_memory_cell *cell, t_addr addr, t_mem *val);
+ virtual void cfg_set(t_addr addr, t_mem val);
+ virtual void cfg_write(t_addr addr, t_mem val);
+ virtual t_mem cfg_get(t_addr addr);
+ virtual t_mem cfg_read(t_addr addr);
+ virtual char *cfg_help(t_addr addr);
+
+ virtual void set_cmd(class cl_cmdline *cmdline, class cl_console_base *con);
+ virtual class cl_memory_cell *register_cell(class cl_address_space *mem,
+ t_addr addr);
+ virtual class cl_memory_cell *register_cell(class cl_memory_cell *cell);
+ virtual void unregister_cell(class cl_memory_cell *cell);
+
+ virtual int tick(int cycles);
+ virtual void reset(void) {}
+ virtual void happen(class cl_hw * /*where*/, enum hw_event /*he*/,
+ void * /*params*/) {}
+ virtual void inform_partners(enum hw_event he, void *params);
+ virtual void touch(void);
+
+ virtual void make_io(void);
+ virtual void new_io(class cl_f *f_in, class cl_f *f_out);
+ virtual void new_i(class cl_f *f_in);
+ virtual void new_o(class cl_f *f_out);
+ virtual cl_hw_io *get_io(void);
+ virtual bool proc_input(void);
+ virtual bool handle_input(int c);
+ virtual void refresh_display(bool force);
+ virtual void draw_display(void);
+ virtual cl_hw *next_displayer(void);
+
+ virtual void print_info(class cl_console_base *con);
+ virtual void print_cfg_info(class cl_console_base *con);
+};
+
+class cl_hws: public cl_list
+{
+ public:
+ cl_hws(void): cl_list(2, 2, cchars("hws")) {}
+ virtual t_index add(void *item);
+ virtual cl_hw *next_displayer(class cl_hw *hw);
+};
+
+
+class cl_partner_hw: public cl_base
+{
+ protected:
+ class cl_uc *uc;
+ enum hw_cath cathegory;
+ int id;
+ class cl_hw *partner;
+ public:
+ cl_partner_hw(class cl_uc *auc, enum hw_cath cath, int aid);
+
+ virtual class cl_hw *get_partner(void);
+ virtual void refresh(void);
+ virtual void refresh(class cl_hw *new_hw);
+
+ virtual void happen(class cl_hw *where, enum hw_event he, void *params);
+};
+
+
+#endif
+
+/* End of hwcl.h */
diff --git a/sim/ucsim/sim.src/itsrc.cc b/sim/ucsim/sim.src/itsrc.cc
new file mode 100644
index 0000000..5ee9fbe
--- /dev/null
+++ b/sim/ucsim/sim.src/itsrc.cc
@@ -0,0 +1,228 @@
+/*
+ * Simulator of microcontrollers (itsrc.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@*/
+
+#include "ddconfig.h"
+
+#include <stdio.h>
+#include <stdlib.h>
+#include "i_string.h"
+
+#include "itsrccl.h"
+#include "pobjcl.h"
+#include "stypes.h"
+#include "memcl.h"
+
+
+/*
+ * Interrupt source
+ ******************************************************************************
+ */
+
+cl_it_src::cl_it_src(cl_uc *Iuc,
+ int Inuof,
+ class cl_memory_cell *Iie_cell,
+ t_mem Iie_mask,
+ class cl_memory_cell *Isrc_cell,
+ t_mem Isrc_mask,
+ t_addr Iaddr,
+ bool Iclr_bit,
+ bool Iindirect,
+ const char *Iname,
+ int apoll_priority):
+ /*cl_base()*/
+ cl_hw(Iuc, HW_INTERRUPT, 100+Inuof, chars("", "itsrc_%d", Inuof))
+{
+ uc= Iuc;
+ poll_priority= apoll_priority;
+ nuof = Inuof;
+ ie_cell = Iie_cell;
+ ie_mask = Iie_mask;
+ src_cell= Isrc_cell;
+ src_mask= Isrc_mask;
+ addr = Iaddr;
+ clr_bit = Iclr_bit;
+ indirect= Iindirect;
+ if (Iname != NULL)
+ set_name(Iname);
+ else
+ set_name("unknown");
+ active= true;
+}
+
+cl_it_src::~cl_it_src(void) {}
+
+int
+cl_it_src::init(void)
+{
+ register_cell(ie_cell);
+ register_cell(src_cell);
+ return 0;
+}
+
+bool
+cl_it_src::is_active(void)
+{
+ return(active);
+}
+
+void
+cl_it_src::set_active_status(bool Aactive)
+{
+ active= Aactive;
+}
+
+void
+cl_it_src::activate(void)
+{
+ set_active_status(true);
+}
+
+void
+cl_it_src::deactivate(void)
+{
+ set_active_status(false);
+}
+
+
+bool
+cl_it_src::enabled(void)
+{
+ if (!ie_cell)
+ return false;
+ t_mem e= ie_cell->get();
+ e&= ie_mask;
+ return e != 0;
+}
+
+bool
+cl_it_src::pending(void)
+{
+ if (!src_cell)
+ return false;
+ t_mem s= src_cell->get();
+ s&= src_mask;
+ return s != 0;
+}
+
+void
+cl_it_src::clear(void)
+{
+ if (clr_bit)
+ src_cell->set_bit0(src_mask);
+}
+
+void
+cl_it_src::write(class cl_memory_cell *cell, t_mem *val)
+{
+ t_mem iev= ie_cell->get();
+ t_mem srcv= src_cell->get();
+ t_mem ier, srcr;
+
+ if (cell == ie_cell)
+ {
+ //printf("ITSRC ie=%x\n", *val);
+ iev= *val;
+ }
+ if (cell == src_cell)
+ {
+ //printf("ITSRC src=%x\n", *val);
+ srcv= *val;
+ }
+ ier= iev&ie_mask;
+ srcr= srcv&src_mask;
+ /*
+ printf("%2d iev =%x & %x = %x\n", nuof, iev, ie_mask, ier);
+ printf("%2d srcv=%x & %x = %x\n", nuof, srcv, src_mask, srcr);
+ printf("%2d ie=%s src=%s req=%s\n", nuof,
+ ier?"true":"false",
+ srcr?"true":"false",
+ (ier&&srcr)?"TRUE":"FALSE");
+ */
+ if (ier)
+ {
+ if (srcr)
+ {
+ //printf("%2d IRQ\n", nuof);
+ uc->irq= true;
+ }
+ }
+}
+
+t_mem
+cl_it_src::read(class cl_memory_cell *cell)
+{
+ return cell->get();
+}
+
+
+/*
+ * Sorted list of IRQ sources
+ */
+
+cl_irqs::cl_irqs(t_index alimit, t_index adelta):
+ cl_sorted_list(alimit, adelta, "irqs")
+{
+ Duplicates= true;
+}
+
+void *
+cl_irqs::key_of(void *item)
+{
+ class cl_it_src *itsrc= (class cl_it_src *)item;
+ return(&itsrc->poll_priority);
+}
+
+int
+cl_irqs::compare(void *key1, void *key2)
+{
+ int *k1= (int*)key1, *k2= (int*)key2;
+
+ if (*k1 == *k2)
+ return(0);
+ else if (*k1 < *k2)
+ return(-1);
+ return(1);
+}
+
+
+/*
+ * Interrupt level
+ ******************************************************************************
+ */
+
+it_level::it_level(int alevel, uint aaddr, uint aPC, class cl_it_src *is):
+ cl_base()
+{
+ level = alevel;
+ addr = aaddr;
+ PC = aPC;
+ source= is;
+}
+
+
+
+/* End of itsrc.cc */
diff --git a/sim/ucsim/sim.src/itsrc.o b/sim/ucsim/sim.src/itsrc.o
new file mode 100644
index 0000000..df35fde
--- /dev/null
+++ b/sim/ucsim/sim.src/itsrc.o
Binary files differ
diff --git a/sim/ucsim/sim.src/itsrccl.h b/sim/ucsim/sim.src/itsrccl.h
new file mode 100644
index 0000000..519c86a
--- /dev/null
+++ b/sim/ucsim/sim.src/itsrccl.h
@@ -0,0 +1,115 @@
+/*
+ * Simulator of microcontrollers (sim.src/itsrccl.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 SIM_ITSRCCL_HEADER
+#define SIM_ITSRCCL_HEADER
+
+#include "pobjcl.h"
+#include "stypes.h"
+
+#include "uccl.h"
+#include "memcl.h"
+
+
+/*
+ * Represents source of interrupt
+ */
+
+class cl_it_src: public /*cl_base*/cl_hw
+{
+ private:
+ class cl_uc *uc;
+ protected:
+ class cl_memory_cell *ie_cell;
+ class cl_memory_cell *src_cell;
+public:
+ int poll_priority;
+ int nuof; // Number of IT to check priority
+ t_mem ie_mask; // Mask in IE register
+ t_mem src_mask; // Mask of source bit in src_reg
+ t_addr addr; // Address of service routine
+ bool clr_bit; // Request bit must be cleared when IT accepted
+ bool active; // Acceptance can be disabled
+ bool indirect; // address comes from a vector table from `addr'
+
+ cl_it_src(cl_uc *Iuc,
+ int Inuof,
+ class cl_memory_cell *Iie_cell,
+ t_mem Iie_mask,
+ class cl_memory_cell *Isrc_cell,
+ t_mem Isrc_mask,
+ t_addr Iaddr,
+ bool Iclr_bit,
+ bool Iindirect,
+ const char *Iname,
+ int apoll_priority);
+ virtual ~cl_it_src(void);
+ virtual int init(void);
+
+ bool is_active(void);
+ virtual void set_active_status(bool Aactive);
+ virtual void activate(void);
+ virtual void deactivate(void);
+
+ virtual bool enabled(void);
+ virtual bool pending(void);
+ virtual void clear(void);
+
+ virtual void write(class cl_memory_cell *cell, t_mem *val);
+ virtual t_mem read(class cl_memory_cell *cell);
+};
+
+
+class cl_irqs: public cl_sorted_list
+{
+public:
+ cl_irqs(t_index alimit, t_index adelta);
+ virtual void *key_of(void *item);
+ virtual int compare(void *key1, void *key2);
+};
+
+
+/*
+ * This class is used to follow levels of accepted interrupts
+ * It used on a stack of active interrupt services (it_levels of cl_uc)
+ */
+
+class it_level: public cl_base
+{
+public:
+ int level;
+ uint addr;
+ uint PC;
+ class cl_it_src *source;
+public:
+ it_level(int alevel, uint aaddr, uint aPC, class cl_it_src *is);
+};
+
+
+#endif
+
+/* End of itsrccl.h */
diff --git a/sim/ucsim/sim.src/iwrap.cc b/sim/ucsim/sim.src/iwrap.cc
new file mode 100644
index 0000000..179fb79
--- /dev/null
+++ b/sim/ucsim/sim.src/iwrap.cc
@@ -0,0 +1,522 @@
+#include "iwrap.h"
+
+int instruction_wrapper_00(class cl_uc *uc, t_mem code) { return uc->instruction_00(code); }
+int instruction_wrapper_01(class cl_uc *uc, t_mem code) { return uc->instruction_01(code); }
+int instruction_wrapper_02(class cl_uc *uc, t_mem code) { return uc->instruction_02(code); }
+int instruction_wrapper_03(class cl_uc *uc, t_mem code) { return uc->instruction_03(code); }
+int instruction_wrapper_04(class cl_uc *uc, t_mem code) { return uc->instruction_04(code); }
+int instruction_wrapper_05(class cl_uc *uc, t_mem code) { return uc->instruction_05(code); }
+int instruction_wrapper_06(class cl_uc *uc, t_mem code) { return uc->instruction_06(code); }
+int instruction_wrapper_07(class cl_uc *uc, t_mem code) { return uc->instruction_07(code); }
+int instruction_wrapper_08(class cl_uc *uc, t_mem code) { return uc->instruction_08(code); }
+int instruction_wrapper_09(class cl_uc *uc, t_mem code) { return uc->instruction_09(code); }
+int instruction_wrapper_0a(class cl_uc *uc, t_mem code) { return uc->instruction_0a(code); }
+int instruction_wrapper_0b(class cl_uc *uc, t_mem code) { return uc->instruction_0b(code); }
+int instruction_wrapper_0c(class cl_uc *uc, t_mem code) { return uc->instruction_0c(code); }
+int instruction_wrapper_0d(class cl_uc *uc, t_mem code) { return uc->instruction_0d(code); }
+int instruction_wrapper_0e(class cl_uc *uc, t_mem code) { return uc->instruction_0e(code); }
+int instruction_wrapper_0f(class cl_uc *uc, t_mem code) { return uc->instruction_0f(code); }
+int instruction_wrapper_10(class cl_uc *uc, t_mem code) { return uc->instruction_10(code); }
+int instruction_wrapper_11(class cl_uc *uc, t_mem code) { return uc->instruction_11(code); }
+int instruction_wrapper_12(class cl_uc *uc, t_mem code) { return uc->instruction_12(code); }
+int instruction_wrapper_13(class cl_uc *uc, t_mem code) { return uc->instruction_13(code); }
+int instruction_wrapper_14(class cl_uc *uc, t_mem code) { return uc->instruction_14(code); }
+int instruction_wrapper_15(class cl_uc *uc, t_mem code) { return uc->instruction_15(code); }
+int instruction_wrapper_16(class cl_uc *uc, t_mem code) { return uc->instruction_16(code); }
+int instruction_wrapper_17(class cl_uc *uc, t_mem code) { return uc->instruction_17(code); }
+int instruction_wrapper_18(class cl_uc *uc, t_mem code) { return uc->instruction_18(code); }
+int instruction_wrapper_19(class cl_uc *uc, t_mem code) { return uc->instruction_19(code); }
+int instruction_wrapper_1a(class cl_uc *uc, t_mem code) { return uc->instruction_1a(code); }
+int instruction_wrapper_1b(class cl_uc *uc, t_mem code) { return uc->instruction_1b(code); }
+int instruction_wrapper_1c(class cl_uc *uc, t_mem code) { return uc->instruction_1c(code); }
+int instruction_wrapper_1d(class cl_uc *uc, t_mem code) { return uc->instruction_1d(code); }
+int instruction_wrapper_1e(class cl_uc *uc, t_mem code) { return uc->instruction_1e(code); }
+int instruction_wrapper_1f(class cl_uc *uc, t_mem code) { return uc->instruction_1f(code); }
+int instruction_wrapper_20(class cl_uc *uc, t_mem code) { return uc->instruction_20(code); }
+int instruction_wrapper_21(class cl_uc *uc, t_mem code) { return uc->instruction_21(code); }
+int instruction_wrapper_22(class cl_uc *uc, t_mem code) { return uc->instruction_22(code); }
+int instruction_wrapper_23(class cl_uc *uc, t_mem code) { return uc->instruction_23(code); }
+int instruction_wrapper_24(class cl_uc *uc, t_mem code) { return uc->instruction_24(code); }
+int instruction_wrapper_25(class cl_uc *uc, t_mem code) { return uc->instruction_25(code); }
+int instruction_wrapper_26(class cl_uc *uc, t_mem code) { return uc->instruction_26(code); }
+int instruction_wrapper_27(class cl_uc *uc, t_mem code) { return uc->instruction_27(code); }
+int instruction_wrapper_28(class cl_uc *uc, t_mem code) { return uc->instruction_28(code); }
+int instruction_wrapper_29(class cl_uc *uc, t_mem code) { return uc->instruction_29(code); }
+int instruction_wrapper_2a(class cl_uc *uc, t_mem code) { return uc->instruction_2a(code); }
+int instruction_wrapper_2b(class cl_uc *uc, t_mem code) { return uc->instruction_2b(code); }
+int instruction_wrapper_2c(class cl_uc *uc, t_mem code) { return uc->instruction_2c(code); }
+int instruction_wrapper_2d(class cl_uc *uc, t_mem code) { return uc->instruction_2d(code); }
+int instruction_wrapper_2e(class cl_uc *uc, t_mem code) { return uc->instruction_2e(code); }
+int instruction_wrapper_2f(class cl_uc *uc, t_mem code) { return uc->instruction_2f(code); }
+int instruction_wrapper_30(class cl_uc *uc, t_mem code) { return uc->instruction_30(code); }
+int instruction_wrapper_31(class cl_uc *uc, t_mem code) { return uc->instruction_31(code); }
+int instruction_wrapper_32(class cl_uc *uc, t_mem code) { return uc->instruction_32(code); }
+int instruction_wrapper_33(class cl_uc *uc, t_mem code) { return uc->instruction_33(code); }
+int instruction_wrapper_34(class cl_uc *uc, t_mem code) { return uc->instruction_34(code); }
+int instruction_wrapper_35(class cl_uc *uc, t_mem code) { return uc->instruction_35(code); }
+int instruction_wrapper_36(class cl_uc *uc, t_mem code) { return uc->instruction_36(code); }
+int instruction_wrapper_37(class cl_uc *uc, t_mem code) { return uc->instruction_37(code); }
+int instruction_wrapper_38(class cl_uc *uc, t_mem code) { return uc->instruction_38(code); }
+int instruction_wrapper_39(class cl_uc *uc, t_mem code) { return uc->instruction_39(code); }
+int instruction_wrapper_3a(class cl_uc *uc, t_mem code) { return uc->instruction_3a(code); }
+int instruction_wrapper_3b(class cl_uc *uc, t_mem code) { return uc->instruction_3b(code); }
+int instruction_wrapper_3c(class cl_uc *uc, t_mem code) { return uc->instruction_3c(code); }
+int instruction_wrapper_3d(class cl_uc *uc, t_mem code) { return uc->instruction_3d(code); }
+int instruction_wrapper_3e(class cl_uc *uc, t_mem code) { return uc->instruction_3e(code); }
+int instruction_wrapper_3f(class cl_uc *uc, t_mem code) { return uc->instruction_3f(code); }
+int instruction_wrapper_40(class cl_uc *uc, t_mem code) { return uc->instruction_40(code); }
+int instruction_wrapper_41(class cl_uc *uc, t_mem code) { return uc->instruction_41(code); }
+int instruction_wrapper_42(class cl_uc *uc, t_mem code) { return uc->instruction_42(code); }
+int instruction_wrapper_43(class cl_uc *uc, t_mem code) { return uc->instruction_43(code); }
+int instruction_wrapper_44(class cl_uc *uc, t_mem code) { return uc->instruction_44(code); }
+int instruction_wrapper_45(class cl_uc *uc, t_mem code) { return uc->instruction_45(code); }
+int instruction_wrapper_46(class cl_uc *uc, t_mem code) { return uc->instruction_46(code); }
+int instruction_wrapper_47(class cl_uc *uc, t_mem code) { return uc->instruction_47(code); }
+int instruction_wrapper_48(class cl_uc *uc, t_mem code) { return uc->instruction_48(code); }
+int instruction_wrapper_49(class cl_uc *uc, t_mem code) { return uc->instruction_49(code); }
+int instruction_wrapper_4a(class cl_uc *uc, t_mem code) { return uc->instruction_4a(code); }
+int instruction_wrapper_4b(class cl_uc *uc, t_mem code) { return uc->instruction_4b(code); }
+int instruction_wrapper_4c(class cl_uc *uc, t_mem code) { return uc->instruction_4c(code); }
+int instruction_wrapper_4d(class cl_uc *uc, t_mem code) { return uc->instruction_4d(code); }
+int instruction_wrapper_4e(class cl_uc *uc, t_mem code) { return uc->instruction_4e(code); }
+int instruction_wrapper_4f(class cl_uc *uc, t_mem code) { return uc->instruction_4f(code); }
+int instruction_wrapper_50(class cl_uc *uc, t_mem code) { return uc->instruction_50(code); }
+int instruction_wrapper_51(class cl_uc *uc, t_mem code) { return uc->instruction_51(code); }
+int instruction_wrapper_52(class cl_uc *uc, t_mem code) { return uc->instruction_52(code); }
+int instruction_wrapper_53(class cl_uc *uc, t_mem code) { return uc->instruction_53(code); }
+int instruction_wrapper_54(class cl_uc *uc, t_mem code) { return uc->instruction_54(code); }
+int instruction_wrapper_55(class cl_uc *uc, t_mem code) { return uc->instruction_55(code); }
+int instruction_wrapper_56(class cl_uc *uc, t_mem code) { return uc->instruction_56(code); }
+int instruction_wrapper_57(class cl_uc *uc, t_mem code) { return uc->instruction_57(code); }
+int instruction_wrapper_58(class cl_uc *uc, t_mem code) { return uc->instruction_58(code); }
+int instruction_wrapper_59(class cl_uc *uc, t_mem code) { return uc->instruction_59(code); }
+int instruction_wrapper_5a(class cl_uc *uc, t_mem code) { return uc->instruction_5a(code); }
+int instruction_wrapper_5b(class cl_uc *uc, t_mem code) { return uc->instruction_5b(code); }
+int instruction_wrapper_5c(class cl_uc *uc, t_mem code) { return uc->instruction_5c(code); }
+int instruction_wrapper_5d(class cl_uc *uc, t_mem code) { return uc->instruction_5d(code); }
+int instruction_wrapper_5e(class cl_uc *uc, t_mem code) { return uc->instruction_5e(code); }
+int instruction_wrapper_5f(class cl_uc *uc, t_mem code) { return uc->instruction_5f(code); }
+int instruction_wrapper_60(class cl_uc *uc, t_mem code) { return uc->instruction_60(code); }
+int instruction_wrapper_61(class cl_uc *uc, t_mem code) { return uc->instruction_61(code); }
+int instruction_wrapper_62(class cl_uc *uc, t_mem code) { return uc->instruction_62(code); }
+int instruction_wrapper_63(class cl_uc *uc, t_mem code) { return uc->instruction_63(code); }
+int instruction_wrapper_64(class cl_uc *uc, t_mem code) { return uc->instruction_64(code); }
+int instruction_wrapper_65(class cl_uc *uc, t_mem code) { return uc->instruction_65(code); }
+int instruction_wrapper_66(class cl_uc *uc, t_mem code) { return uc->instruction_66(code); }
+int instruction_wrapper_67(class cl_uc *uc, t_mem code) { return uc->instruction_67(code); }
+int instruction_wrapper_68(class cl_uc *uc, t_mem code) { return uc->instruction_68(code); }
+int instruction_wrapper_69(class cl_uc *uc, t_mem code) { return uc->instruction_69(code); }
+int instruction_wrapper_6a(class cl_uc *uc, t_mem code) { return uc->instruction_6a(code); }
+int instruction_wrapper_6b(class cl_uc *uc, t_mem code) { return uc->instruction_6b(code); }
+int instruction_wrapper_6c(class cl_uc *uc, t_mem code) { return uc->instruction_6c(code); }
+int instruction_wrapper_6d(class cl_uc *uc, t_mem code) { return uc->instruction_6d(code); }
+int instruction_wrapper_6e(class cl_uc *uc, t_mem code) { return uc->instruction_6e(code); }
+int instruction_wrapper_6f(class cl_uc *uc, t_mem code) { return uc->instruction_6f(code); }
+int instruction_wrapper_70(class cl_uc *uc, t_mem code) { return uc->instruction_70(code); }
+int instruction_wrapper_71(class cl_uc *uc, t_mem code) { return uc->instruction_71(code); }
+int instruction_wrapper_72(class cl_uc *uc, t_mem code) { return uc->instruction_72(code); }
+int instruction_wrapper_73(class cl_uc *uc, t_mem code) { return uc->instruction_73(code); }
+int instruction_wrapper_74(class cl_uc *uc, t_mem code) { return uc->instruction_74(code); }
+int instruction_wrapper_75(class cl_uc *uc, t_mem code) { return uc->instruction_75(code); }
+int instruction_wrapper_76(class cl_uc *uc, t_mem code) { return uc->instruction_76(code); }
+int instruction_wrapper_77(class cl_uc *uc, t_mem code) { return uc->instruction_77(code); }
+int instruction_wrapper_78(class cl_uc *uc, t_mem code) { return uc->instruction_78(code); }
+int instruction_wrapper_79(class cl_uc *uc, t_mem code) { return uc->instruction_79(code); }
+int instruction_wrapper_7a(class cl_uc *uc, t_mem code) { return uc->instruction_7a(code); }
+int instruction_wrapper_7b(class cl_uc *uc, t_mem code) { return uc->instruction_7b(code); }
+int instruction_wrapper_7c(class cl_uc *uc, t_mem code) { return uc->instruction_7c(code); }
+int instruction_wrapper_7d(class cl_uc *uc, t_mem code) { return uc->instruction_7d(code); }
+int instruction_wrapper_7e(class cl_uc *uc, t_mem code) { return uc->instruction_7e(code); }
+int instruction_wrapper_7f(class cl_uc *uc, t_mem code) { return uc->instruction_7f(code); }
+int instruction_wrapper_80(class cl_uc *uc, t_mem code) { return uc->instruction_80(code); }
+int instruction_wrapper_81(class cl_uc *uc, t_mem code) { return uc->instruction_81(code); }
+int instruction_wrapper_82(class cl_uc *uc, t_mem code) { return uc->instruction_82(code); }
+int instruction_wrapper_83(class cl_uc *uc, t_mem code) { return uc->instruction_83(code); }
+int instruction_wrapper_84(class cl_uc *uc, t_mem code) { return uc->instruction_84(code); }
+int instruction_wrapper_85(class cl_uc *uc, t_mem code) { return uc->instruction_85(code); }
+int instruction_wrapper_86(class cl_uc *uc, t_mem code) { return uc->instruction_86(code); }
+int instruction_wrapper_87(class cl_uc *uc, t_mem code) { return uc->instruction_87(code); }
+int instruction_wrapper_88(class cl_uc *uc, t_mem code) { return uc->instruction_88(code); }
+int instruction_wrapper_89(class cl_uc *uc, t_mem code) { return uc->instruction_89(code); }
+int instruction_wrapper_8a(class cl_uc *uc, t_mem code) { return uc->instruction_8a(code); }
+int instruction_wrapper_8b(class cl_uc *uc, t_mem code) { return uc->instruction_8b(code); }
+int instruction_wrapper_8c(class cl_uc *uc, t_mem code) { return uc->instruction_8c(code); }
+int instruction_wrapper_8d(class cl_uc *uc, t_mem code) { return uc->instruction_8d(code); }
+int instruction_wrapper_8e(class cl_uc *uc, t_mem code) { return uc->instruction_8e(code); }
+int instruction_wrapper_8f(class cl_uc *uc, t_mem code) { return uc->instruction_8f(code); }
+int instruction_wrapper_90(class cl_uc *uc, t_mem code) { return uc->instruction_90(code); }
+int instruction_wrapper_91(class cl_uc *uc, t_mem code) { return uc->instruction_91(code); }
+int instruction_wrapper_92(class cl_uc *uc, t_mem code) { return uc->instruction_92(code); }
+int instruction_wrapper_93(class cl_uc *uc, t_mem code) { return uc->instruction_93(code); }
+int instruction_wrapper_94(class cl_uc *uc, t_mem code) { return uc->instruction_94(code); }
+int instruction_wrapper_95(class cl_uc *uc, t_mem code) { return uc->instruction_95(code); }
+int instruction_wrapper_96(class cl_uc *uc, t_mem code) { return uc->instruction_96(code); }
+int instruction_wrapper_97(class cl_uc *uc, t_mem code) { return uc->instruction_97(code); }
+int instruction_wrapper_98(class cl_uc *uc, t_mem code) { return uc->instruction_98(code); }
+int instruction_wrapper_99(class cl_uc *uc, t_mem code) { return uc->instruction_99(code); }
+int instruction_wrapper_9a(class cl_uc *uc, t_mem code) { return uc->instruction_9a(code); }
+int instruction_wrapper_9b(class cl_uc *uc, t_mem code) { return uc->instruction_9b(code); }
+int instruction_wrapper_9c(class cl_uc *uc, t_mem code) { return uc->instruction_9c(code); }
+int instruction_wrapper_9d(class cl_uc *uc, t_mem code) { return uc->instruction_9d(code); }
+int instruction_wrapper_9e(class cl_uc *uc, t_mem code) { return uc->instruction_9e(code); }
+int instruction_wrapper_9f(class cl_uc *uc, t_mem code) { return uc->instruction_9f(code); }
+int instruction_wrapper_a0(class cl_uc *uc, t_mem code) { return uc->instruction_a0(code); }
+int instruction_wrapper_a1(class cl_uc *uc, t_mem code) { return uc->instruction_a1(code); }
+int instruction_wrapper_a2(class cl_uc *uc, t_mem code) { return uc->instruction_a2(code); }
+int instruction_wrapper_a3(class cl_uc *uc, t_mem code) { return uc->instruction_a3(code); }
+int instruction_wrapper_a4(class cl_uc *uc, t_mem code) { return uc->instruction_a4(code); }
+int instruction_wrapper_a5(class cl_uc *uc, t_mem code) { return uc->instruction_a5(code); }
+int instruction_wrapper_a6(class cl_uc *uc, t_mem code) { return uc->instruction_a6(code); }
+int instruction_wrapper_a7(class cl_uc *uc, t_mem code) { return uc->instruction_a7(code); }
+int instruction_wrapper_a8(class cl_uc *uc, t_mem code) { return uc->instruction_a8(code); }
+int instruction_wrapper_a9(class cl_uc *uc, t_mem code) { return uc->instruction_a9(code); }
+int instruction_wrapper_aa(class cl_uc *uc, t_mem code) { return uc->instruction_aa(code); }
+int instruction_wrapper_ab(class cl_uc *uc, t_mem code) { return uc->instruction_ab(code); }
+int instruction_wrapper_ac(class cl_uc *uc, t_mem code) { return uc->instruction_ac(code); }
+int instruction_wrapper_ad(class cl_uc *uc, t_mem code) { return uc->instruction_ad(code); }
+int instruction_wrapper_ae(class cl_uc *uc, t_mem code) { return uc->instruction_ae(code); }
+int instruction_wrapper_af(class cl_uc *uc, t_mem code) { return uc->instruction_af(code); }
+int instruction_wrapper_b0(class cl_uc *uc, t_mem code) { return uc->instruction_b0(code); }
+int instruction_wrapper_b1(class cl_uc *uc, t_mem code) { return uc->instruction_b1(code); }
+int instruction_wrapper_b2(class cl_uc *uc, t_mem code) { return uc->instruction_b2(code); }
+int instruction_wrapper_b3(class cl_uc *uc, t_mem code) { return uc->instruction_b3(code); }
+int instruction_wrapper_b4(class cl_uc *uc, t_mem code) { return uc->instruction_b4(code); }
+int instruction_wrapper_b5(class cl_uc *uc, t_mem code) { return uc->instruction_b5(code); }
+int instruction_wrapper_b6(class cl_uc *uc, t_mem code) { return uc->instruction_b6(code); }
+int instruction_wrapper_b7(class cl_uc *uc, t_mem code) { return uc->instruction_b7(code); }
+int instruction_wrapper_b8(class cl_uc *uc, t_mem code) { return uc->instruction_b8(code); }
+int instruction_wrapper_b9(class cl_uc *uc, t_mem code) { return uc->instruction_b9(code); }
+int instruction_wrapper_ba(class cl_uc *uc, t_mem code) { return uc->instruction_ba(code); }
+int instruction_wrapper_bb(class cl_uc *uc, t_mem code) { return uc->instruction_bb(code); }
+int instruction_wrapper_bc(class cl_uc *uc, t_mem code) { return uc->instruction_bc(code); }
+int instruction_wrapper_bd(class cl_uc *uc, t_mem code) { return uc->instruction_bd(code); }
+int instruction_wrapper_be(class cl_uc *uc, t_mem code) { return uc->instruction_be(code); }
+int instruction_wrapper_bf(class cl_uc *uc, t_mem code) { return uc->instruction_bf(code); }
+int instruction_wrapper_c0(class cl_uc *uc, t_mem code) { return uc->instruction_c0(code); }
+int instruction_wrapper_c1(class cl_uc *uc, t_mem code) { return uc->instruction_c1(code); }
+int instruction_wrapper_c2(class cl_uc *uc, t_mem code) { return uc->instruction_c2(code); }
+int instruction_wrapper_c3(class cl_uc *uc, t_mem code) { return uc->instruction_c3(code); }
+int instruction_wrapper_c4(class cl_uc *uc, t_mem code) { return uc->instruction_c4(code); }
+int instruction_wrapper_c5(class cl_uc *uc, t_mem code) { return uc->instruction_c5(code); }
+int instruction_wrapper_c6(class cl_uc *uc, t_mem code) { return uc->instruction_c6(code); }
+int instruction_wrapper_c7(class cl_uc *uc, t_mem code) { return uc->instruction_c7(code); }
+int instruction_wrapper_c8(class cl_uc *uc, t_mem code) { return uc->instruction_c8(code); }
+int instruction_wrapper_c9(class cl_uc *uc, t_mem code) { return uc->instruction_c9(code); }
+int instruction_wrapper_ca(class cl_uc *uc, t_mem code) { return uc->instruction_ca(code); }
+int instruction_wrapper_cb(class cl_uc *uc, t_mem code) { return uc->instruction_cb(code); }
+int instruction_wrapper_cc(class cl_uc *uc, t_mem code) { return uc->instruction_cc(code); }
+int instruction_wrapper_cd(class cl_uc *uc, t_mem code) { return uc->instruction_cd(code); }
+int instruction_wrapper_ce(class cl_uc *uc, t_mem code) { return uc->instruction_ce(code); }
+int instruction_wrapper_cf(class cl_uc *uc, t_mem code) { return uc->instruction_cf(code); }
+int instruction_wrapper_d0(class cl_uc *uc, t_mem code) { return uc->instruction_d0(code); }
+int instruction_wrapper_d1(class cl_uc *uc, t_mem code) { return uc->instruction_d1(code); }
+int instruction_wrapper_d2(class cl_uc *uc, t_mem code) { return uc->instruction_d2(code); }
+int instruction_wrapper_d3(class cl_uc *uc, t_mem code) { return uc->instruction_d3(code); }
+int instruction_wrapper_d4(class cl_uc *uc, t_mem code) { return uc->instruction_d4(code); }
+int instruction_wrapper_d5(class cl_uc *uc, t_mem code) { return uc->instruction_d5(code); }
+int instruction_wrapper_d6(class cl_uc *uc, t_mem code) { return uc->instruction_d6(code); }
+int instruction_wrapper_d7(class cl_uc *uc, t_mem code) { return uc->instruction_d7(code); }
+int instruction_wrapper_d8(class cl_uc *uc, t_mem code) { return uc->instruction_d8(code); }
+int instruction_wrapper_d9(class cl_uc *uc, t_mem code) { return uc->instruction_d9(code); }
+int instruction_wrapper_da(class cl_uc *uc, t_mem code) { return uc->instruction_da(code); }
+int instruction_wrapper_db(class cl_uc *uc, t_mem code) { return uc->instruction_db(code); }
+int instruction_wrapper_dc(class cl_uc *uc, t_mem code) { return uc->instruction_dc(code); }
+int instruction_wrapper_dd(class cl_uc *uc, t_mem code) { return uc->instruction_dd(code); }
+int instruction_wrapper_de(class cl_uc *uc, t_mem code) { return uc->instruction_de(code); }
+int instruction_wrapper_df(class cl_uc *uc, t_mem code) { return uc->instruction_df(code); }
+int instruction_wrapper_e0(class cl_uc *uc, t_mem code) { return uc->instruction_e0(code); }
+int instruction_wrapper_e1(class cl_uc *uc, t_mem code) { return uc->instruction_e1(code); }
+int instruction_wrapper_e2(class cl_uc *uc, t_mem code) { return uc->instruction_e2(code); }
+int instruction_wrapper_e3(class cl_uc *uc, t_mem code) { return uc->instruction_e3(code); }
+int instruction_wrapper_e4(class cl_uc *uc, t_mem code) { return uc->instruction_e4(code); }
+int instruction_wrapper_e5(class cl_uc *uc, t_mem code) { return uc->instruction_e5(code); }
+int instruction_wrapper_e6(class cl_uc *uc, t_mem code) { return uc->instruction_e6(code); }
+int instruction_wrapper_e7(class cl_uc *uc, t_mem code) { return uc->instruction_e7(code); }
+int instruction_wrapper_e8(class cl_uc *uc, t_mem code) { return uc->instruction_e8(code); }
+int instruction_wrapper_e9(class cl_uc *uc, t_mem code) { return uc->instruction_e9(code); }
+int instruction_wrapper_ea(class cl_uc *uc, t_mem code) { return uc->instruction_ea(code); }
+int instruction_wrapper_eb(class cl_uc *uc, t_mem code) { return uc->instruction_eb(code); }
+int instruction_wrapper_ec(class cl_uc *uc, t_mem code) { return uc->instruction_ec(code); }
+int instruction_wrapper_ed(class cl_uc *uc, t_mem code) { return uc->instruction_ed(code); }
+int instruction_wrapper_ee(class cl_uc *uc, t_mem code) { return uc->instruction_ee(code); }
+int instruction_wrapper_ef(class cl_uc *uc, t_mem code) { return uc->instruction_ef(code); }
+int instruction_wrapper_f0(class cl_uc *uc, t_mem code) { return uc->instruction_f0(code); }
+int instruction_wrapper_f1(class cl_uc *uc, t_mem code) { return uc->instruction_f1(code); }
+int instruction_wrapper_f2(class cl_uc *uc, t_mem code) { return uc->instruction_f2(code); }
+int instruction_wrapper_f3(class cl_uc *uc, t_mem code) { return uc->instruction_f3(code); }
+int instruction_wrapper_f4(class cl_uc *uc, t_mem code) { return uc->instruction_f4(code); }
+int instruction_wrapper_f5(class cl_uc *uc, t_mem code) { return uc->instruction_f5(code); }
+int instruction_wrapper_f6(class cl_uc *uc, t_mem code) { return uc->instruction_f6(code); }
+int instruction_wrapper_f7(class cl_uc *uc, t_mem code) { return uc->instruction_f7(code); }
+int instruction_wrapper_f8(class cl_uc *uc, t_mem code) { return uc->instruction_f8(code); }
+int instruction_wrapper_f9(class cl_uc *uc, t_mem code) { return uc->instruction_f9(code); }
+int instruction_wrapper_fa(class cl_uc *uc, t_mem code) { return uc->instruction_fa(code); }
+int instruction_wrapper_fb(class cl_uc *uc, t_mem code) { return uc->instruction_fb(code); }
+int instruction_wrapper_fc(class cl_uc *uc, t_mem code) { return uc->instruction_fc(code); }
+int instruction_wrapper_fd(class cl_uc *uc, t_mem code) { return uc->instruction_fd(code); }
+int instruction_wrapper_fe(class cl_uc *uc, t_mem code) { return uc->instruction_fe(code); }
+int instruction_wrapper_ff(class cl_uc *uc, t_mem code) { return uc->instruction_ff(code); }
+
+void
+fill_def_wrappers(instruction_wrapper_fn itab[])
+{
+ itab[0x00]= instruction_wrapper_00;
+ itab[0x01]= instruction_wrapper_01;
+ itab[0x02]= instruction_wrapper_02;
+ itab[0x03]= instruction_wrapper_03;
+ itab[0x04]= instruction_wrapper_04;
+ itab[0x05]= instruction_wrapper_05;
+ itab[0x06]= instruction_wrapper_06;
+ itab[0x07]= instruction_wrapper_07;
+ itab[0x08]= instruction_wrapper_08;
+ itab[0x09]= instruction_wrapper_09;
+ itab[0x0a]= instruction_wrapper_0a;
+ itab[0x0b]= instruction_wrapper_0b;
+ itab[0x0c]= instruction_wrapper_0c;
+ itab[0x0d]= instruction_wrapper_0d;
+ itab[0x0e]= instruction_wrapper_0e;
+ itab[0x0f]= instruction_wrapper_0f;
+ itab[0x10]= instruction_wrapper_10;
+ itab[0x11]= instruction_wrapper_11;
+ itab[0x12]= instruction_wrapper_12;
+ itab[0x13]= instruction_wrapper_13;
+ itab[0x14]= instruction_wrapper_14;
+ itab[0x15]= instruction_wrapper_15;
+ itab[0x16]= instruction_wrapper_16;
+ itab[0x17]= instruction_wrapper_17;
+ itab[0x18]= instruction_wrapper_18;
+ itab[0x19]= instruction_wrapper_19;
+ itab[0x1a]= instruction_wrapper_1a;
+ itab[0x1b]= instruction_wrapper_1b;
+ itab[0x1c]= instruction_wrapper_1c;
+ itab[0x1d]= instruction_wrapper_1d;
+ itab[0x1e]= instruction_wrapper_1e;
+ itab[0x1f]= instruction_wrapper_1f;
+ itab[0x20]= instruction_wrapper_20;
+ itab[0x21]= instruction_wrapper_21;
+ itab[0x22]= instruction_wrapper_22;
+ itab[0x23]= instruction_wrapper_23;
+ itab[0x24]= instruction_wrapper_24;
+ itab[0x25]= instruction_wrapper_25;
+ itab[0x26]= instruction_wrapper_26;
+ itab[0x27]= instruction_wrapper_27;
+ itab[0x28]= instruction_wrapper_28;
+ itab[0x29]= instruction_wrapper_29;
+ itab[0x2a]= instruction_wrapper_2a;
+ itab[0x2b]= instruction_wrapper_2b;
+ itab[0x2c]= instruction_wrapper_2c;
+ itab[0x2d]= instruction_wrapper_2d;
+ itab[0x2e]= instruction_wrapper_2e;
+ itab[0x2f]= instruction_wrapper_2f;
+ itab[0x30]= instruction_wrapper_30;
+ itab[0x31]= instruction_wrapper_31;
+ itab[0x32]= instruction_wrapper_32;
+ itab[0x33]= instruction_wrapper_33;
+ itab[0x34]= instruction_wrapper_34;
+ itab[0x35]= instruction_wrapper_35;
+ itab[0x36]= instruction_wrapper_36;
+ itab[0x37]= instruction_wrapper_37;
+ itab[0x38]= instruction_wrapper_38;
+ itab[0x39]= instruction_wrapper_39;
+ itab[0x3a]= instruction_wrapper_3a;
+ itab[0x3b]= instruction_wrapper_3b;
+ itab[0x3c]= instruction_wrapper_3c;
+ itab[0x3d]= instruction_wrapper_3d;
+ itab[0x3e]= instruction_wrapper_3e;
+ itab[0x3f]= instruction_wrapper_3f;
+ itab[0x40]= instruction_wrapper_40;
+ itab[0x41]= instruction_wrapper_41;
+ itab[0x42]= instruction_wrapper_42;
+ itab[0x43]= instruction_wrapper_43;
+ itab[0x44]= instruction_wrapper_44;
+ itab[0x45]= instruction_wrapper_45;
+ itab[0x46]= instruction_wrapper_46;
+ itab[0x47]= instruction_wrapper_47;
+ itab[0x48]= instruction_wrapper_48;
+ itab[0x49]= instruction_wrapper_49;
+ itab[0x4a]= instruction_wrapper_4a;
+ itab[0x4b]= instruction_wrapper_4b;
+ itab[0x4c]= instruction_wrapper_4c;
+ itab[0x4d]= instruction_wrapper_4d;
+ itab[0x4e]= instruction_wrapper_4e;
+ itab[0x4f]= instruction_wrapper_4f;
+ itab[0x50]= instruction_wrapper_50;
+ itab[0x51]= instruction_wrapper_51;
+ itab[0x52]= instruction_wrapper_52;
+ itab[0x53]= instruction_wrapper_53;
+ itab[0x54]= instruction_wrapper_54;
+ itab[0x55]= instruction_wrapper_55;
+ itab[0x56]= instruction_wrapper_56;
+ itab[0x57]= instruction_wrapper_57;
+ itab[0x58]= instruction_wrapper_58;
+ itab[0x59]= instruction_wrapper_59;
+ itab[0x5a]= instruction_wrapper_5a;
+ itab[0x5b]= instruction_wrapper_5b;
+ itab[0x5c]= instruction_wrapper_5c;
+ itab[0x5d]= instruction_wrapper_5d;
+ itab[0x5e]= instruction_wrapper_5e;
+ itab[0x5f]= instruction_wrapper_5f;
+ itab[0x60]= instruction_wrapper_60;
+ itab[0x61]= instruction_wrapper_61;
+ itab[0x62]= instruction_wrapper_62;
+ itab[0x63]= instruction_wrapper_63;
+ itab[0x64]= instruction_wrapper_64;
+ itab[0x65]= instruction_wrapper_65;
+ itab[0x66]= instruction_wrapper_66;
+ itab[0x67]= instruction_wrapper_67;
+ itab[0x68]= instruction_wrapper_68;
+ itab[0x69]= instruction_wrapper_69;
+ itab[0x6a]= instruction_wrapper_6a;
+ itab[0x6b]= instruction_wrapper_6b;
+ itab[0x6c]= instruction_wrapper_6c;
+ itab[0x6d]= instruction_wrapper_6d;
+ itab[0x6e]= instruction_wrapper_6e;
+ itab[0x6f]= instruction_wrapper_6f;
+ itab[0x70]= instruction_wrapper_70;
+ itab[0x71]= instruction_wrapper_71;
+ itab[0x72]= instruction_wrapper_72;
+ itab[0x73]= instruction_wrapper_73;
+ itab[0x74]= instruction_wrapper_74;
+ itab[0x75]= instruction_wrapper_75;
+ itab[0x76]= instruction_wrapper_76;
+ itab[0x77]= instruction_wrapper_77;
+ itab[0x78]= instruction_wrapper_78;
+ itab[0x79]= instruction_wrapper_79;
+ itab[0x7a]= instruction_wrapper_7a;
+ itab[0x7b]= instruction_wrapper_7b;
+ itab[0x7c]= instruction_wrapper_7c;
+ itab[0x7d]= instruction_wrapper_7d;
+ itab[0x7e]= instruction_wrapper_7e;
+ itab[0x7f]= instruction_wrapper_7f;
+ itab[0x80]= instruction_wrapper_80;
+ itab[0x81]= instruction_wrapper_81;
+ itab[0x82]= instruction_wrapper_82;
+ itab[0x83]= instruction_wrapper_83;
+ itab[0x84]= instruction_wrapper_84;
+ itab[0x85]= instruction_wrapper_85;
+ itab[0x86]= instruction_wrapper_86;
+ itab[0x87]= instruction_wrapper_87;
+ itab[0x88]= instruction_wrapper_88;
+ itab[0x89]= instruction_wrapper_89;
+ itab[0x8a]= instruction_wrapper_8a;
+ itab[0x8b]= instruction_wrapper_8b;
+ itab[0x8c]= instruction_wrapper_8c;
+ itab[0x8d]= instruction_wrapper_8d;
+ itab[0x8e]= instruction_wrapper_8e;
+ itab[0x8f]= instruction_wrapper_8f;
+ itab[0x90]= instruction_wrapper_90;
+ itab[0x91]= instruction_wrapper_91;
+ itab[0x92]= instruction_wrapper_92;
+ itab[0x93]= instruction_wrapper_93;
+ itab[0x94]= instruction_wrapper_94;
+ itab[0x95]= instruction_wrapper_95;
+ itab[0x96]= instruction_wrapper_96;
+ itab[0x97]= instruction_wrapper_97;
+ itab[0x98]= instruction_wrapper_98;
+ itab[0x99]= instruction_wrapper_99;
+ itab[0x9a]= instruction_wrapper_9a;
+ itab[0x9b]= instruction_wrapper_9b;
+ itab[0x9c]= instruction_wrapper_9c;
+ itab[0x9d]= instruction_wrapper_9d;
+ itab[0x9e]= instruction_wrapper_9e;
+ itab[0x9f]= instruction_wrapper_9f;
+ itab[0xa0]= instruction_wrapper_a0;
+ itab[0xa1]= instruction_wrapper_a1;
+ itab[0xa2]= instruction_wrapper_a2;
+ itab[0xa3]= instruction_wrapper_a3;
+ itab[0xa4]= instruction_wrapper_a4;
+ itab[0xa5]= instruction_wrapper_a5;
+ itab[0xa6]= instruction_wrapper_a6;
+ itab[0xa7]= instruction_wrapper_a7;
+ itab[0xa8]= instruction_wrapper_a8;
+ itab[0xa9]= instruction_wrapper_a9;
+ itab[0xaa]= instruction_wrapper_aa;
+ itab[0xab]= instruction_wrapper_ab;
+ itab[0xac]= instruction_wrapper_ac;
+ itab[0xad]= instruction_wrapper_ad;
+ itab[0xae]= instruction_wrapper_ae;
+ itab[0xaf]= instruction_wrapper_af;
+ itab[0xb0]= instruction_wrapper_b0;
+ itab[0xb1]= instruction_wrapper_b1;
+ itab[0xb2]= instruction_wrapper_b2;
+ itab[0xb3]= instruction_wrapper_b3;
+ itab[0xb4]= instruction_wrapper_b4;
+ itab[0xb5]= instruction_wrapper_b5;
+ itab[0xb6]= instruction_wrapper_b6;
+ itab[0xb7]= instruction_wrapper_b7;
+ itab[0xb8]= instruction_wrapper_b8;
+ itab[0xb9]= instruction_wrapper_b9;
+ itab[0xba]= instruction_wrapper_ba;
+ itab[0xbb]= instruction_wrapper_bb;
+ itab[0xbc]= instruction_wrapper_bc;
+ itab[0xbd]= instruction_wrapper_bd;
+ itab[0xbe]= instruction_wrapper_be;
+ itab[0xbf]= instruction_wrapper_bf;
+ itab[0xc0]= instruction_wrapper_c0;
+ itab[0xc1]= instruction_wrapper_c1;
+ itab[0xc2]= instruction_wrapper_c2;
+ itab[0xc3]= instruction_wrapper_c3;
+ itab[0xc4]= instruction_wrapper_c4;
+ itab[0xc5]= instruction_wrapper_c5;
+ itab[0xc6]= instruction_wrapper_c6;
+ itab[0xc7]= instruction_wrapper_c7;
+ itab[0xc8]= instruction_wrapper_c8;
+ itab[0xc9]= instruction_wrapper_c9;
+ itab[0xca]= instruction_wrapper_ca;
+ itab[0xcb]= instruction_wrapper_cb;
+ itab[0xcc]= instruction_wrapper_cc;
+ itab[0xcd]= instruction_wrapper_cd;
+ itab[0xce]= instruction_wrapper_ce;
+ itab[0xcf]= instruction_wrapper_cf;
+ itab[0xd0]= instruction_wrapper_d0;
+ itab[0xd1]= instruction_wrapper_d1;
+ itab[0xd2]= instruction_wrapper_d2;
+ itab[0xd3]= instruction_wrapper_d3;
+ itab[0xd4]= instruction_wrapper_d4;
+ itab[0xd5]= instruction_wrapper_d5;
+ itab[0xd6]= instruction_wrapper_d6;
+ itab[0xd7]= instruction_wrapper_d7;
+ itab[0xd8]= instruction_wrapper_d8;
+ itab[0xd9]= instruction_wrapper_d9;
+ itab[0xda]= instruction_wrapper_da;
+ itab[0xdb]= instruction_wrapper_db;
+ itab[0xdc]= instruction_wrapper_dc;
+ itab[0xdd]= instruction_wrapper_dd;
+ itab[0xde]= instruction_wrapper_de;
+ itab[0xdf]= instruction_wrapper_df;
+ itab[0xe0]= instruction_wrapper_e0;
+ itab[0xe1]= instruction_wrapper_e1;
+ itab[0xe2]= instruction_wrapper_e2;
+ itab[0xe3]= instruction_wrapper_e3;
+ itab[0xe4]= instruction_wrapper_e4;
+ itab[0xe5]= instruction_wrapper_e5;
+ itab[0xe6]= instruction_wrapper_e6;
+ itab[0xe7]= instruction_wrapper_e7;
+ itab[0xe8]= instruction_wrapper_e8;
+ itab[0xe9]= instruction_wrapper_e9;
+ itab[0xea]= instruction_wrapper_ea;
+ itab[0xeb]= instruction_wrapper_eb;
+ itab[0xec]= instruction_wrapper_ec;
+ itab[0xed]= instruction_wrapper_ed;
+ itab[0xee]= instruction_wrapper_ee;
+ itab[0xef]= instruction_wrapper_ef;
+ itab[0xf0]= instruction_wrapper_f0;
+ itab[0xf1]= instruction_wrapper_f1;
+ itab[0xf2]= instruction_wrapper_f2;
+ itab[0xf3]= instruction_wrapper_f3;
+ itab[0xf4]= instruction_wrapper_f4;
+ itab[0xf5]= instruction_wrapper_f5;
+ itab[0xf6]= instruction_wrapper_f6;
+ itab[0xf7]= instruction_wrapper_f7;
+ itab[0xf8]= instruction_wrapper_f8;
+ itab[0xf9]= instruction_wrapper_f9;
+ itab[0xfa]= instruction_wrapper_fa;
+ itab[0xfb]= instruction_wrapper_fb;
+ itab[0xfc]= instruction_wrapper_fc;
+ itab[0xfd]= instruction_wrapper_fd;
+ itab[0xfe]= instruction_wrapper_fe;
+ itab[0xff]= instruction_wrapper_ff;
+
+}
+
+/* End of sim.src/iwrap.cc */
diff --git a/sim/ucsim/sim.src/iwrap.h b/sim/ucsim/sim.src/iwrap.h
new file mode 100644
index 0000000..1f7ebc2
--- /dev/null
+++ b/sim/ucsim/sim.src/iwrap.h
@@ -0,0 +1,525 @@
+#ifndef IWRAP_HEADER
+#define IWRAP_HEADER
+
+#include "uccl.h"
+
+
+extern int instruction_wrapper_00(class cl_uc *uc, t_mem code);
+extern int instruction_wrapper_00(class cl_uc *uc, t_mem code);
+extern int instruction_wrapper_01(class cl_uc *uc, t_mem code);
+extern int instruction_wrapper_01(class cl_uc *uc, t_mem code);
+extern int instruction_wrapper_02(class cl_uc *uc, t_mem code);
+extern int instruction_wrapper_02(class cl_uc *uc, t_mem code);
+extern int instruction_wrapper_03(class cl_uc *uc, t_mem code);
+extern int instruction_wrapper_03(class cl_uc *uc, t_mem code);
+extern int instruction_wrapper_04(class cl_uc *uc, t_mem code);
+extern int instruction_wrapper_04(class cl_uc *uc, t_mem code);
+extern int instruction_wrapper_05(class cl_uc *uc, t_mem code);
+extern int instruction_wrapper_05(class cl_uc *uc, t_mem code);
+extern int instruction_wrapper_06(class cl_uc *uc, t_mem code);
+extern int instruction_wrapper_06(class cl_uc *uc, t_mem code);
+extern int instruction_wrapper_07(class cl_uc *uc, t_mem code);
+extern int instruction_wrapper_07(class cl_uc *uc, t_mem code);
+extern int instruction_wrapper_08(class cl_uc *uc, t_mem code);
+extern int instruction_wrapper_08(class cl_uc *uc, t_mem code);
+extern int instruction_wrapper_09(class cl_uc *uc, t_mem code);
+extern int instruction_wrapper_09(class cl_uc *uc, t_mem code);
+extern int instruction_wrapper_0a(class cl_uc *uc, t_mem code);
+extern int instruction_wrapper_0a(class cl_uc *uc, t_mem code);
+extern int instruction_wrapper_0b(class cl_uc *uc, t_mem code);
+extern int instruction_wrapper_0b(class cl_uc *uc, t_mem code);
+extern int instruction_wrapper_0c(class cl_uc *uc, t_mem code);
+extern int instruction_wrapper_0c(class cl_uc *uc, t_mem code);
+extern int instruction_wrapper_0d(class cl_uc *uc, t_mem code);
+extern int instruction_wrapper_0d(class cl_uc *uc, t_mem code);
+extern int instruction_wrapper_0e(class cl_uc *uc, t_mem code);
+extern int instruction_wrapper_0e(class cl_uc *uc, t_mem code);
+extern int instruction_wrapper_0f(class cl_uc *uc, t_mem code);
+extern int instruction_wrapper_0f(class cl_uc *uc, t_mem code);
+extern int instruction_wrapper_10(class cl_uc *uc, t_mem code);
+extern int instruction_wrapper_10(class cl_uc *uc, t_mem code);
+extern int instruction_wrapper_11(class cl_uc *uc, t_mem code);
+extern int instruction_wrapper_11(class cl_uc *uc, t_mem code);
+extern int instruction_wrapper_12(class cl_uc *uc, t_mem code);
+extern int instruction_wrapper_12(class cl_uc *uc, t_mem code);
+extern int instruction_wrapper_13(class cl_uc *uc, t_mem code);
+extern int instruction_wrapper_13(class cl_uc *uc, t_mem code);
+extern int instruction_wrapper_14(class cl_uc *uc, t_mem code);
+extern int instruction_wrapper_14(class cl_uc *uc, t_mem code);
+extern int instruction_wrapper_15(class cl_uc *uc, t_mem code);
+extern int instruction_wrapper_15(class cl_uc *uc, t_mem code);
+extern int instruction_wrapper_16(class cl_uc *uc, t_mem code);
+extern int instruction_wrapper_16(class cl_uc *uc, t_mem code);
+extern int instruction_wrapper_17(class cl_uc *uc, t_mem code);
+extern int instruction_wrapper_17(class cl_uc *uc, t_mem code);
+extern int instruction_wrapper_18(class cl_uc *uc, t_mem code);
+extern int instruction_wrapper_18(class cl_uc *uc, t_mem code);
+extern int instruction_wrapper_19(class cl_uc *uc, t_mem code);
+extern int instruction_wrapper_19(class cl_uc *uc, t_mem code);
+extern int instruction_wrapper_1a(class cl_uc *uc, t_mem code);
+extern int instruction_wrapper_1a(class cl_uc *uc, t_mem code);
+extern int instruction_wrapper_1b(class cl_uc *uc, t_mem code);
+extern int instruction_wrapper_1b(class cl_uc *uc, t_mem code);
+extern int instruction_wrapper_1c(class cl_uc *uc, t_mem code);
+extern int instruction_wrapper_1c(class cl_uc *uc, t_mem code);
+extern int instruction_wrapper_1d(class cl_uc *uc, t_mem code);
+extern int instruction_wrapper_1d(class cl_uc *uc, t_mem code);
+extern int instruction_wrapper_1e(class cl_uc *uc, t_mem code);
+extern int instruction_wrapper_1e(class cl_uc *uc, t_mem code);
+extern int instruction_wrapper_1f(class cl_uc *uc, t_mem code);
+extern int instruction_wrapper_1f(class cl_uc *uc, t_mem code);
+extern int instruction_wrapper_20(class cl_uc *uc, t_mem code);
+extern int instruction_wrapper_20(class cl_uc *uc, t_mem code);
+extern int instruction_wrapper_21(class cl_uc *uc, t_mem code);
+extern int instruction_wrapper_21(class cl_uc *uc, t_mem code);
+extern int instruction_wrapper_22(class cl_uc *uc, t_mem code);
+extern int instruction_wrapper_22(class cl_uc *uc, t_mem code);
+extern int instruction_wrapper_23(class cl_uc *uc, t_mem code);
+extern int instruction_wrapper_23(class cl_uc *uc, t_mem code);
+extern int instruction_wrapper_24(class cl_uc *uc, t_mem code);
+extern int instruction_wrapper_24(class cl_uc *uc, t_mem code);
+extern int instruction_wrapper_25(class cl_uc *uc, t_mem code);
+extern int instruction_wrapper_25(class cl_uc *uc, t_mem code);
+extern int instruction_wrapper_26(class cl_uc *uc, t_mem code);
+extern int instruction_wrapper_26(class cl_uc *uc, t_mem code);
+extern int instruction_wrapper_27(class cl_uc *uc, t_mem code);
+extern int instruction_wrapper_27(class cl_uc *uc, t_mem code);
+extern int instruction_wrapper_28(class cl_uc *uc, t_mem code);
+extern int instruction_wrapper_28(class cl_uc *uc, t_mem code);
+extern int instruction_wrapper_29(class cl_uc *uc, t_mem code);
+extern int instruction_wrapper_29(class cl_uc *uc, t_mem code);
+extern int instruction_wrapper_2a(class cl_uc *uc, t_mem code);
+extern int instruction_wrapper_2a(class cl_uc *uc, t_mem code);
+extern int instruction_wrapper_2b(class cl_uc *uc, t_mem code);
+extern int instruction_wrapper_2b(class cl_uc *uc, t_mem code);
+extern int instruction_wrapper_2c(class cl_uc *uc, t_mem code);
+extern int instruction_wrapper_2c(class cl_uc *uc, t_mem code);
+extern int instruction_wrapper_2d(class cl_uc *uc, t_mem code);
+extern int instruction_wrapper_2d(class cl_uc *uc, t_mem code);
+extern int instruction_wrapper_2e(class cl_uc *uc, t_mem code);
+extern int instruction_wrapper_2e(class cl_uc *uc, t_mem code);
+extern int instruction_wrapper_2f(class cl_uc *uc, t_mem code);
+extern int instruction_wrapper_2f(class cl_uc *uc, t_mem code);
+extern int instruction_wrapper_30(class cl_uc *uc, t_mem code);
+extern int instruction_wrapper_30(class cl_uc *uc, t_mem code);
+extern int instruction_wrapper_31(class cl_uc *uc, t_mem code);
+extern int instruction_wrapper_31(class cl_uc *uc, t_mem code);
+extern int instruction_wrapper_32(class cl_uc *uc, t_mem code);
+extern int instruction_wrapper_32(class cl_uc *uc, t_mem code);
+extern int instruction_wrapper_33(class cl_uc *uc, t_mem code);
+extern int instruction_wrapper_33(class cl_uc *uc, t_mem code);
+extern int instruction_wrapper_34(class cl_uc *uc, t_mem code);
+extern int instruction_wrapper_34(class cl_uc *uc, t_mem code);
+extern int instruction_wrapper_35(class cl_uc *uc, t_mem code);
+extern int instruction_wrapper_35(class cl_uc *uc, t_mem code);
+extern int instruction_wrapper_36(class cl_uc *uc, t_mem code);
+extern int instruction_wrapper_36(class cl_uc *uc, t_mem code);
+extern int instruction_wrapper_37(class cl_uc *uc, t_mem code);
+extern int instruction_wrapper_37(class cl_uc *uc, t_mem code);
+extern int instruction_wrapper_38(class cl_uc *uc, t_mem code);
+extern int instruction_wrapper_38(class cl_uc *uc, t_mem code);
+extern int instruction_wrapper_39(class cl_uc *uc, t_mem code);
+extern int instruction_wrapper_39(class cl_uc *uc, t_mem code);
+extern int instruction_wrapper_3a(class cl_uc *uc, t_mem code);
+extern int instruction_wrapper_3a(class cl_uc *uc, t_mem code);
+extern int instruction_wrapper_3b(class cl_uc *uc, t_mem code);
+extern int instruction_wrapper_3b(class cl_uc *uc, t_mem code);
+extern int instruction_wrapper_3c(class cl_uc *uc, t_mem code);
+extern int instruction_wrapper_3c(class cl_uc *uc, t_mem code);
+extern int instruction_wrapper_3d(class cl_uc *uc, t_mem code);
+extern int instruction_wrapper_3d(class cl_uc *uc, t_mem code);
+extern int instruction_wrapper_3e(class cl_uc *uc, t_mem code);
+extern int instruction_wrapper_3e(class cl_uc *uc, t_mem code);
+extern int instruction_wrapper_3f(class cl_uc *uc, t_mem code);
+extern int instruction_wrapper_3f(class cl_uc *uc, t_mem code);
+extern int instruction_wrapper_40(class cl_uc *uc, t_mem code);
+extern int instruction_wrapper_40(class cl_uc *uc, t_mem code);
+extern int instruction_wrapper_41(class cl_uc *uc, t_mem code);
+extern int instruction_wrapper_41(class cl_uc *uc, t_mem code);
+extern int instruction_wrapper_42(class cl_uc *uc, t_mem code);
+extern int instruction_wrapper_42(class cl_uc *uc, t_mem code);
+extern int instruction_wrapper_43(class cl_uc *uc, t_mem code);
+extern int instruction_wrapper_43(class cl_uc *uc, t_mem code);
+extern int instruction_wrapper_44(class cl_uc *uc, t_mem code);
+extern int instruction_wrapper_44(class cl_uc *uc, t_mem code);
+extern int instruction_wrapper_45(class cl_uc *uc, t_mem code);
+extern int instruction_wrapper_45(class cl_uc *uc, t_mem code);
+extern int instruction_wrapper_46(class cl_uc *uc, t_mem code);
+extern int instruction_wrapper_46(class cl_uc *uc, t_mem code);
+extern int instruction_wrapper_47(class cl_uc *uc, t_mem code);
+extern int instruction_wrapper_47(class cl_uc *uc, t_mem code);
+extern int instruction_wrapper_48(class cl_uc *uc, t_mem code);
+extern int instruction_wrapper_48(class cl_uc *uc, t_mem code);
+extern int instruction_wrapper_49(class cl_uc *uc, t_mem code);
+extern int instruction_wrapper_49(class cl_uc *uc, t_mem code);
+extern int instruction_wrapper_4a(class cl_uc *uc, t_mem code);
+extern int instruction_wrapper_4a(class cl_uc *uc, t_mem code);
+extern int instruction_wrapper_4b(class cl_uc *uc, t_mem code);
+extern int instruction_wrapper_4b(class cl_uc *uc, t_mem code);
+extern int instruction_wrapper_4c(class cl_uc *uc, t_mem code);
+extern int instruction_wrapper_4c(class cl_uc *uc, t_mem code);
+extern int instruction_wrapper_4d(class cl_uc *uc, t_mem code);
+extern int instruction_wrapper_4d(class cl_uc *uc, t_mem code);
+extern int instruction_wrapper_4e(class cl_uc *uc, t_mem code);
+extern int instruction_wrapper_4e(class cl_uc *uc, t_mem code);
+extern int instruction_wrapper_4f(class cl_uc *uc, t_mem code);
+extern int instruction_wrapper_4f(class cl_uc *uc, t_mem code);
+extern int instruction_wrapper_50(class cl_uc *uc, t_mem code);
+extern int instruction_wrapper_50(class cl_uc *uc, t_mem code);
+extern int instruction_wrapper_51(class cl_uc *uc, t_mem code);
+extern int instruction_wrapper_51(class cl_uc *uc, t_mem code);
+extern int instruction_wrapper_52(class cl_uc *uc, t_mem code);
+extern int instruction_wrapper_52(class cl_uc *uc, t_mem code);
+extern int instruction_wrapper_53(class cl_uc *uc, t_mem code);
+extern int instruction_wrapper_53(class cl_uc *uc, t_mem code);
+extern int instruction_wrapper_54(class cl_uc *uc, t_mem code);
+extern int instruction_wrapper_54(class cl_uc *uc, t_mem code);
+extern int instruction_wrapper_55(class cl_uc *uc, t_mem code);
+extern int instruction_wrapper_55(class cl_uc *uc, t_mem code);
+extern int instruction_wrapper_56(class cl_uc *uc, t_mem code);
+extern int instruction_wrapper_56(class cl_uc *uc, t_mem code);
+extern int instruction_wrapper_57(class cl_uc *uc, t_mem code);
+extern int instruction_wrapper_57(class cl_uc *uc, t_mem code);
+extern int instruction_wrapper_58(class cl_uc *uc, t_mem code);
+extern int instruction_wrapper_58(class cl_uc *uc, t_mem code);
+extern int instruction_wrapper_59(class cl_uc *uc, t_mem code);
+extern int instruction_wrapper_59(class cl_uc *uc, t_mem code);
+extern int instruction_wrapper_5a(class cl_uc *uc, t_mem code);
+extern int instruction_wrapper_5a(class cl_uc *uc, t_mem code);
+extern int instruction_wrapper_5b(class cl_uc *uc, t_mem code);
+extern int instruction_wrapper_5b(class cl_uc *uc, t_mem code);
+extern int instruction_wrapper_5c(class cl_uc *uc, t_mem code);
+extern int instruction_wrapper_5c(class cl_uc *uc, t_mem code);
+extern int instruction_wrapper_5d(class cl_uc *uc, t_mem code);
+extern int instruction_wrapper_5d(class cl_uc *uc, t_mem code);
+extern int instruction_wrapper_5e(class cl_uc *uc, t_mem code);
+extern int instruction_wrapper_5e(class cl_uc *uc, t_mem code);
+extern int instruction_wrapper_5f(class cl_uc *uc, t_mem code);
+extern int instruction_wrapper_5f(class cl_uc *uc, t_mem code);
+extern int instruction_wrapper_60(class cl_uc *uc, t_mem code);
+extern int instruction_wrapper_60(class cl_uc *uc, t_mem code);
+extern int instruction_wrapper_61(class cl_uc *uc, t_mem code);
+extern int instruction_wrapper_61(class cl_uc *uc, t_mem code);
+extern int instruction_wrapper_62(class cl_uc *uc, t_mem code);
+extern int instruction_wrapper_62(class cl_uc *uc, t_mem code);
+extern int instruction_wrapper_63(class cl_uc *uc, t_mem code);
+extern int instruction_wrapper_63(class cl_uc *uc, t_mem code);
+extern int instruction_wrapper_64(class cl_uc *uc, t_mem code);
+extern int instruction_wrapper_64(class cl_uc *uc, t_mem code);
+extern int instruction_wrapper_65(class cl_uc *uc, t_mem code);
+extern int instruction_wrapper_65(class cl_uc *uc, t_mem code);
+extern int instruction_wrapper_66(class cl_uc *uc, t_mem code);
+extern int instruction_wrapper_66(class cl_uc *uc, t_mem code);
+extern int instruction_wrapper_67(class cl_uc *uc, t_mem code);
+extern int instruction_wrapper_67(class cl_uc *uc, t_mem code);
+extern int instruction_wrapper_68(class cl_uc *uc, t_mem code);
+extern int instruction_wrapper_68(class cl_uc *uc, t_mem code);
+extern int instruction_wrapper_69(class cl_uc *uc, t_mem code);
+extern int instruction_wrapper_69(class cl_uc *uc, t_mem code);
+extern int instruction_wrapper_6a(class cl_uc *uc, t_mem code);
+extern int instruction_wrapper_6a(class cl_uc *uc, t_mem code);
+extern int instruction_wrapper_6b(class cl_uc *uc, t_mem code);
+extern int instruction_wrapper_6b(class cl_uc *uc, t_mem code);
+extern int instruction_wrapper_6c(class cl_uc *uc, t_mem code);
+extern int instruction_wrapper_6c(class cl_uc *uc, t_mem code);
+extern int instruction_wrapper_6d(class cl_uc *uc, t_mem code);
+extern int instruction_wrapper_6d(class cl_uc *uc, t_mem code);
+extern int instruction_wrapper_6e(class cl_uc *uc, t_mem code);
+extern int instruction_wrapper_6e(class cl_uc *uc, t_mem code);
+extern int instruction_wrapper_6f(class cl_uc *uc, t_mem code);
+extern int instruction_wrapper_6f(class cl_uc *uc, t_mem code);
+extern int instruction_wrapper_70(class cl_uc *uc, t_mem code);
+extern int instruction_wrapper_70(class cl_uc *uc, t_mem code);
+extern int instruction_wrapper_71(class cl_uc *uc, t_mem code);
+extern int instruction_wrapper_71(class cl_uc *uc, t_mem code);
+extern int instruction_wrapper_72(class cl_uc *uc, t_mem code);
+extern int instruction_wrapper_72(class cl_uc *uc, t_mem code);
+extern int instruction_wrapper_73(class cl_uc *uc, t_mem code);
+extern int instruction_wrapper_73(class cl_uc *uc, t_mem code);
+extern int instruction_wrapper_74(class cl_uc *uc, t_mem code);
+extern int instruction_wrapper_74(class cl_uc *uc, t_mem code);
+extern int instruction_wrapper_75(class cl_uc *uc, t_mem code);
+extern int instruction_wrapper_75(class cl_uc *uc, t_mem code);
+extern int instruction_wrapper_76(class cl_uc *uc, t_mem code);
+extern int instruction_wrapper_76(class cl_uc *uc, t_mem code);
+extern int instruction_wrapper_77(class cl_uc *uc, t_mem code);
+extern int instruction_wrapper_77(class cl_uc *uc, t_mem code);
+extern int instruction_wrapper_78(class cl_uc *uc, t_mem code);
+extern int instruction_wrapper_78(class cl_uc *uc, t_mem code);
+extern int instruction_wrapper_79(class cl_uc *uc, t_mem code);
+extern int instruction_wrapper_79(class cl_uc *uc, t_mem code);
+extern int instruction_wrapper_7a(class cl_uc *uc, t_mem code);
+extern int instruction_wrapper_7a(class cl_uc *uc, t_mem code);
+extern int instruction_wrapper_7b(class cl_uc *uc, t_mem code);
+extern int instruction_wrapper_7b(class cl_uc *uc, t_mem code);
+extern int instruction_wrapper_7c(class cl_uc *uc, t_mem code);
+extern int instruction_wrapper_7c(class cl_uc *uc, t_mem code);
+extern int instruction_wrapper_7d(class cl_uc *uc, t_mem code);
+extern int instruction_wrapper_7d(class cl_uc *uc, t_mem code);
+extern int instruction_wrapper_7e(class cl_uc *uc, t_mem code);
+extern int instruction_wrapper_7e(class cl_uc *uc, t_mem code);
+extern int instruction_wrapper_7f(class cl_uc *uc, t_mem code);
+extern int instruction_wrapper_7f(class cl_uc *uc, t_mem code);
+extern int instruction_wrapper_80(class cl_uc *uc, t_mem code);
+extern int instruction_wrapper_80(class cl_uc *uc, t_mem code);
+extern int instruction_wrapper_81(class cl_uc *uc, t_mem code);
+extern int instruction_wrapper_81(class cl_uc *uc, t_mem code);
+extern int instruction_wrapper_82(class cl_uc *uc, t_mem code);
+extern int instruction_wrapper_82(class cl_uc *uc, t_mem code);
+extern int instruction_wrapper_83(class cl_uc *uc, t_mem code);
+extern int instruction_wrapper_83(class cl_uc *uc, t_mem code);
+extern int instruction_wrapper_84(class cl_uc *uc, t_mem code);
+extern int instruction_wrapper_84(class cl_uc *uc, t_mem code);
+extern int instruction_wrapper_85(class cl_uc *uc, t_mem code);
+extern int instruction_wrapper_85(class cl_uc *uc, t_mem code);
+extern int instruction_wrapper_86(class cl_uc *uc, t_mem code);
+extern int instruction_wrapper_86(class cl_uc *uc, t_mem code);
+extern int instruction_wrapper_87(class cl_uc *uc, t_mem code);
+extern int instruction_wrapper_87(class cl_uc *uc, t_mem code);
+extern int instruction_wrapper_88(class cl_uc *uc, t_mem code);
+extern int instruction_wrapper_88(class cl_uc *uc, t_mem code);
+extern int instruction_wrapper_89(class cl_uc *uc, t_mem code);
+extern int instruction_wrapper_89(class cl_uc *uc, t_mem code);
+extern int instruction_wrapper_8a(class cl_uc *uc, t_mem code);
+extern int instruction_wrapper_8a(class cl_uc *uc, t_mem code);
+extern int instruction_wrapper_8b(class cl_uc *uc, t_mem code);
+extern int instruction_wrapper_8b(class cl_uc *uc, t_mem code);
+extern int instruction_wrapper_8c(class cl_uc *uc, t_mem code);
+extern int instruction_wrapper_8c(class cl_uc *uc, t_mem code);
+extern int instruction_wrapper_8d(class cl_uc *uc, t_mem code);
+extern int instruction_wrapper_8d(class cl_uc *uc, t_mem code);
+extern int instruction_wrapper_8e(class cl_uc *uc, t_mem code);
+extern int instruction_wrapper_8e(class cl_uc *uc, t_mem code);
+extern int instruction_wrapper_8f(class cl_uc *uc, t_mem code);
+extern int instruction_wrapper_8f(class cl_uc *uc, t_mem code);
+extern int instruction_wrapper_90(class cl_uc *uc, t_mem code);
+extern int instruction_wrapper_90(class cl_uc *uc, t_mem code);
+extern int instruction_wrapper_91(class cl_uc *uc, t_mem code);
+extern int instruction_wrapper_91(class cl_uc *uc, t_mem code);
+extern int instruction_wrapper_92(class cl_uc *uc, t_mem code);
+extern int instruction_wrapper_92(class cl_uc *uc, t_mem code);
+extern int instruction_wrapper_93(class cl_uc *uc, t_mem code);
+extern int instruction_wrapper_93(class cl_uc *uc, t_mem code);
+extern int instruction_wrapper_94(class cl_uc *uc, t_mem code);
+extern int instruction_wrapper_94(class cl_uc *uc, t_mem code);
+extern int instruction_wrapper_95(class cl_uc *uc, t_mem code);
+extern int instruction_wrapper_95(class cl_uc *uc, t_mem code);
+extern int instruction_wrapper_96(class cl_uc *uc, t_mem code);
+extern int instruction_wrapper_96(class cl_uc *uc, t_mem code);
+extern int instruction_wrapper_97(class cl_uc *uc, t_mem code);
+extern int instruction_wrapper_97(class cl_uc *uc, t_mem code);
+extern int instruction_wrapper_98(class cl_uc *uc, t_mem code);
+extern int instruction_wrapper_98(class cl_uc *uc, t_mem code);
+extern int instruction_wrapper_99(class cl_uc *uc, t_mem code);
+extern int instruction_wrapper_99(class cl_uc *uc, t_mem code);
+extern int instruction_wrapper_9a(class cl_uc *uc, t_mem code);
+extern int instruction_wrapper_9a(class cl_uc *uc, t_mem code);
+extern int instruction_wrapper_9b(class cl_uc *uc, t_mem code);
+extern int instruction_wrapper_9b(class cl_uc *uc, t_mem code);
+extern int instruction_wrapper_9c(class cl_uc *uc, t_mem code);
+extern int instruction_wrapper_9c(class cl_uc *uc, t_mem code);
+extern int instruction_wrapper_9d(class cl_uc *uc, t_mem code);
+extern int instruction_wrapper_9d(class cl_uc *uc, t_mem code);
+extern int instruction_wrapper_9e(class cl_uc *uc, t_mem code);
+extern int instruction_wrapper_9e(class cl_uc *uc, t_mem code);
+extern int instruction_wrapper_9f(class cl_uc *uc, t_mem code);
+extern int instruction_wrapper_9f(class cl_uc *uc, t_mem code);
+extern int instruction_wrapper_a0(class cl_uc *uc, t_mem code);
+extern int instruction_wrapper_a0(class cl_uc *uc, t_mem code);
+extern int instruction_wrapper_a1(class cl_uc *uc, t_mem code);
+extern int instruction_wrapper_a1(class cl_uc *uc, t_mem code);
+extern int instruction_wrapper_a2(class cl_uc *uc, t_mem code);
+extern int instruction_wrapper_a2(class cl_uc *uc, t_mem code);
+extern int instruction_wrapper_a3(class cl_uc *uc, t_mem code);
+extern int instruction_wrapper_a3(class cl_uc *uc, t_mem code);
+extern int instruction_wrapper_a4(class cl_uc *uc, t_mem code);
+extern int instruction_wrapper_a4(class cl_uc *uc, t_mem code);
+extern int instruction_wrapper_a5(class cl_uc *uc, t_mem code);
+extern int instruction_wrapper_a5(class cl_uc *uc, t_mem code);
+extern int instruction_wrapper_a6(class cl_uc *uc, t_mem code);
+extern int instruction_wrapper_a6(class cl_uc *uc, t_mem code);
+extern int instruction_wrapper_a7(class cl_uc *uc, t_mem code);
+extern int instruction_wrapper_a7(class cl_uc *uc, t_mem code);
+extern int instruction_wrapper_a8(class cl_uc *uc, t_mem code);
+extern int instruction_wrapper_a8(class cl_uc *uc, t_mem code);
+extern int instruction_wrapper_a9(class cl_uc *uc, t_mem code);
+extern int instruction_wrapper_a9(class cl_uc *uc, t_mem code);
+extern int instruction_wrapper_aa(class cl_uc *uc, t_mem code);
+extern int instruction_wrapper_aa(class cl_uc *uc, t_mem code);
+extern int instruction_wrapper_ab(class cl_uc *uc, t_mem code);
+extern int instruction_wrapper_ab(class cl_uc *uc, t_mem code);
+extern int instruction_wrapper_ac(class cl_uc *uc, t_mem code);
+extern int instruction_wrapper_ac(class cl_uc *uc, t_mem code);
+extern int instruction_wrapper_ad(class cl_uc *uc, t_mem code);
+extern int instruction_wrapper_ad(class cl_uc *uc, t_mem code);
+extern int instruction_wrapper_ae(class cl_uc *uc, t_mem code);
+extern int instruction_wrapper_ae(class cl_uc *uc, t_mem code);
+extern int instruction_wrapper_af(class cl_uc *uc, t_mem code);
+extern int instruction_wrapper_af(class cl_uc *uc, t_mem code);
+extern int instruction_wrapper_b0(class cl_uc *uc, t_mem code);
+extern int instruction_wrapper_b0(class cl_uc *uc, t_mem code);
+extern int instruction_wrapper_b1(class cl_uc *uc, t_mem code);
+extern int instruction_wrapper_b1(class cl_uc *uc, t_mem code);
+extern int instruction_wrapper_b2(class cl_uc *uc, t_mem code);
+extern int instruction_wrapper_b2(class cl_uc *uc, t_mem code);
+extern int instruction_wrapper_b3(class cl_uc *uc, t_mem code);
+extern int instruction_wrapper_b3(class cl_uc *uc, t_mem code);
+extern int instruction_wrapper_b4(class cl_uc *uc, t_mem code);
+extern int instruction_wrapper_b4(class cl_uc *uc, t_mem code);
+extern int instruction_wrapper_b5(class cl_uc *uc, t_mem code);
+extern int instruction_wrapper_b5(class cl_uc *uc, t_mem code);
+extern int instruction_wrapper_b6(class cl_uc *uc, t_mem code);
+extern int instruction_wrapper_b6(class cl_uc *uc, t_mem code);
+extern int instruction_wrapper_b7(class cl_uc *uc, t_mem code);
+extern int instruction_wrapper_b7(class cl_uc *uc, t_mem code);
+extern int instruction_wrapper_b8(class cl_uc *uc, t_mem code);
+extern int instruction_wrapper_b8(class cl_uc *uc, t_mem code);
+extern int instruction_wrapper_b9(class cl_uc *uc, t_mem code);
+extern int instruction_wrapper_b9(class cl_uc *uc, t_mem code);
+extern int instruction_wrapper_ba(class cl_uc *uc, t_mem code);
+extern int instruction_wrapper_ba(class cl_uc *uc, t_mem code);
+extern int instruction_wrapper_bb(class cl_uc *uc, t_mem code);
+extern int instruction_wrapper_bb(class cl_uc *uc, t_mem code);
+extern int instruction_wrapper_bc(class cl_uc *uc, t_mem code);
+extern int instruction_wrapper_bc(class cl_uc *uc, t_mem code);
+extern int instruction_wrapper_bd(class cl_uc *uc, t_mem code);
+extern int instruction_wrapper_bd(class cl_uc *uc, t_mem code);
+extern int instruction_wrapper_be(class cl_uc *uc, t_mem code);
+extern int instruction_wrapper_be(class cl_uc *uc, t_mem code);
+extern int instruction_wrapper_bf(class cl_uc *uc, t_mem code);
+extern int instruction_wrapper_bf(class cl_uc *uc, t_mem code);
+extern int instruction_wrapper_c0(class cl_uc *uc, t_mem code);
+extern int instruction_wrapper_c0(class cl_uc *uc, t_mem code);
+extern int instruction_wrapper_c1(class cl_uc *uc, t_mem code);
+extern int instruction_wrapper_c1(class cl_uc *uc, t_mem code);
+extern int instruction_wrapper_c2(class cl_uc *uc, t_mem code);
+extern int instruction_wrapper_c2(class cl_uc *uc, t_mem code);
+extern int instruction_wrapper_c3(class cl_uc *uc, t_mem code);
+extern int instruction_wrapper_c3(class cl_uc *uc, t_mem code);
+extern int instruction_wrapper_c4(class cl_uc *uc, t_mem code);
+extern int instruction_wrapper_c4(class cl_uc *uc, t_mem code);
+extern int instruction_wrapper_c5(class cl_uc *uc, t_mem code);
+extern int instruction_wrapper_c5(class cl_uc *uc, t_mem code);
+extern int instruction_wrapper_c6(class cl_uc *uc, t_mem code);
+extern int instruction_wrapper_c6(class cl_uc *uc, t_mem code);
+extern int instruction_wrapper_c7(class cl_uc *uc, t_mem code);
+extern int instruction_wrapper_c7(class cl_uc *uc, t_mem code);
+extern int instruction_wrapper_c8(class cl_uc *uc, t_mem code);
+extern int instruction_wrapper_c8(class cl_uc *uc, t_mem code);
+extern int instruction_wrapper_c9(class cl_uc *uc, t_mem code);
+extern int instruction_wrapper_c9(class cl_uc *uc, t_mem code);
+extern int instruction_wrapper_ca(class cl_uc *uc, t_mem code);
+extern int instruction_wrapper_ca(class cl_uc *uc, t_mem code);
+extern int instruction_wrapper_cb(class cl_uc *uc, t_mem code);
+extern int instruction_wrapper_cb(class cl_uc *uc, t_mem code);
+extern int instruction_wrapper_cc(class cl_uc *uc, t_mem code);
+extern int instruction_wrapper_cc(class cl_uc *uc, t_mem code);
+extern int instruction_wrapper_cd(class cl_uc *uc, t_mem code);
+extern int instruction_wrapper_cd(class cl_uc *uc, t_mem code);
+extern int instruction_wrapper_ce(class cl_uc *uc, t_mem code);
+extern int instruction_wrapper_ce(class cl_uc *uc, t_mem code);
+extern int instruction_wrapper_cf(class cl_uc *uc, t_mem code);
+extern int instruction_wrapper_cf(class cl_uc *uc, t_mem code);
+extern int instruction_wrapper_d0(class cl_uc *uc, t_mem code);
+extern int instruction_wrapper_d0(class cl_uc *uc, t_mem code);
+extern int instruction_wrapper_d1(class cl_uc *uc, t_mem code);
+extern int instruction_wrapper_d1(class cl_uc *uc, t_mem code);
+extern int instruction_wrapper_d2(class cl_uc *uc, t_mem code);
+extern int instruction_wrapper_d2(class cl_uc *uc, t_mem code);
+extern int instruction_wrapper_d3(class cl_uc *uc, t_mem code);
+extern int instruction_wrapper_d3(class cl_uc *uc, t_mem code);
+extern int instruction_wrapper_d4(class cl_uc *uc, t_mem code);
+extern int instruction_wrapper_d4(class cl_uc *uc, t_mem code);
+extern int instruction_wrapper_d5(class cl_uc *uc, t_mem code);
+extern int instruction_wrapper_d5(class cl_uc *uc, t_mem code);
+extern int instruction_wrapper_d6(class cl_uc *uc, t_mem code);
+extern int instruction_wrapper_d6(class cl_uc *uc, t_mem code);
+extern int instruction_wrapper_d7(class cl_uc *uc, t_mem code);
+extern int instruction_wrapper_d7(class cl_uc *uc, t_mem code);
+extern int instruction_wrapper_d8(class cl_uc *uc, t_mem code);
+extern int instruction_wrapper_d8(class cl_uc *uc, t_mem code);
+extern int instruction_wrapper_d9(class cl_uc *uc, t_mem code);
+extern int instruction_wrapper_d9(class cl_uc *uc, t_mem code);
+extern int instruction_wrapper_da(class cl_uc *uc, t_mem code);
+extern int instruction_wrapper_da(class cl_uc *uc, t_mem code);
+extern int instruction_wrapper_db(class cl_uc *uc, t_mem code);
+extern int instruction_wrapper_db(class cl_uc *uc, t_mem code);
+extern int instruction_wrapper_dc(class cl_uc *uc, t_mem code);
+extern int instruction_wrapper_dc(class cl_uc *uc, t_mem code);
+extern int instruction_wrapper_dd(class cl_uc *uc, t_mem code);
+extern int instruction_wrapper_dd(class cl_uc *uc, t_mem code);
+extern int instruction_wrapper_de(class cl_uc *uc, t_mem code);
+extern int instruction_wrapper_de(class cl_uc *uc, t_mem code);
+extern int instruction_wrapper_df(class cl_uc *uc, t_mem code);
+extern int instruction_wrapper_df(class cl_uc *uc, t_mem code);
+extern int instruction_wrapper_e0(class cl_uc *uc, t_mem code);
+extern int instruction_wrapper_e0(class cl_uc *uc, t_mem code);
+extern int instruction_wrapper_e1(class cl_uc *uc, t_mem code);
+extern int instruction_wrapper_e1(class cl_uc *uc, t_mem code);
+extern int instruction_wrapper_e2(class cl_uc *uc, t_mem code);
+extern int instruction_wrapper_e2(class cl_uc *uc, t_mem code);
+extern int instruction_wrapper_e3(class cl_uc *uc, t_mem code);
+extern int instruction_wrapper_e3(class cl_uc *uc, t_mem code);
+extern int instruction_wrapper_e4(class cl_uc *uc, t_mem code);
+extern int instruction_wrapper_e4(class cl_uc *uc, t_mem code);
+extern int instruction_wrapper_e5(class cl_uc *uc, t_mem code);
+extern int instruction_wrapper_e5(class cl_uc *uc, t_mem code);
+extern int instruction_wrapper_e6(class cl_uc *uc, t_mem code);
+extern int instruction_wrapper_e6(class cl_uc *uc, t_mem code);
+extern int instruction_wrapper_e7(class cl_uc *uc, t_mem code);
+extern int instruction_wrapper_e7(class cl_uc *uc, t_mem code);
+extern int instruction_wrapper_e8(class cl_uc *uc, t_mem code);
+extern int instruction_wrapper_e8(class cl_uc *uc, t_mem code);
+extern int instruction_wrapper_e9(class cl_uc *uc, t_mem code);
+extern int instruction_wrapper_e9(class cl_uc *uc, t_mem code);
+extern int instruction_wrapper_ea(class cl_uc *uc, t_mem code);
+extern int instruction_wrapper_ea(class cl_uc *uc, t_mem code);
+extern int instruction_wrapper_eb(class cl_uc *uc, t_mem code);
+extern int instruction_wrapper_eb(class cl_uc *uc, t_mem code);
+extern int instruction_wrapper_ec(class cl_uc *uc, t_mem code);
+extern int instruction_wrapper_ec(class cl_uc *uc, t_mem code);
+extern int instruction_wrapper_ed(class cl_uc *uc, t_mem code);
+extern int instruction_wrapper_ed(class cl_uc *uc, t_mem code);
+extern int instruction_wrapper_ee(class cl_uc *uc, t_mem code);
+extern int instruction_wrapper_ee(class cl_uc *uc, t_mem code);
+extern int instruction_wrapper_ef(class cl_uc *uc, t_mem code);
+extern int instruction_wrapper_ef(class cl_uc *uc, t_mem code);
+extern int instruction_wrapper_f0(class cl_uc *uc, t_mem code);
+extern int instruction_wrapper_f0(class cl_uc *uc, t_mem code);
+extern int instruction_wrapper_f1(class cl_uc *uc, t_mem code);
+extern int instruction_wrapper_f1(class cl_uc *uc, t_mem code);
+extern int instruction_wrapper_f2(class cl_uc *uc, t_mem code);
+extern int instruction_wrapper_f2(class cl_uc *uc, t_mem code);
+extern int instruction_wrapper_f3(class cl_uc *uc, t_mem code);
+extern int instruction_wrapper_f3(class cl_uc *uc, t_mem code);
+extern int instruction_wrapper_f4(class cl_uc *uc, t_mem code);
+extern int instruction_wrapper_f4(class cl_uc *uc, t_mem code);
+extern int instruction_wrapper_f5(class cl_uc *uc, t_mem code);
+extern int instruction_wrapper_f5(class cl_uc *uc, t_mem code);
+extern int instruction_wrapper_f6(class cl_uc *uc, t_mem code);
+extern int instruction_wrapper_f6(class cl_uc *uc, t_mem code);
+extern int instruction_wrapper_f7(class cl_uc *uc, t_mem code);
+extern int instruction_wrapper_f7(class cl_uc *uc, t_mem code);
+extern int instruction_wrapper_f8(class cl_uc *uc, t_mem code);
+extern int instruction_wrapper_f8(class cl_uc *uc, t_mem code);
+extern int instruction_wrapper_f9(class cl_uc *uc, t_mem code);
+extern int instruction_wrapper_f9(class cl_uc *uc, t_mem code);
+extern int instruction_wrapper_fa(class cl_uc *uc, t_mem code);
+extern int instruction_wrapper_fa(class cl_uc *uc, t_mem code);
+extern int instruction_wrapper_fb(class cl_uc *uc, t_mem code);
+extern int instruction_wrapper_fb(class cl_uc *uc, t_mem code);
+extern int instruction_wrapper_fc(class cl_uc *uc, t_mem code);
+extern int instruction_wrapper_fc(class cl_uc *uc, t_mem code);
+extern int instruction_wrapper_fd(class cl_uc *uc, t_mem code);
+extern int instruction_wrapper_fd(class cl_uc *uc, t_mem code);
+extern int instruction_wrapper_fe(class cl_uc *uc, t_mem code);
+extern int instruction_wrapper_fe(class cl_uc *uc, t_mem code);
+extern int instruction_wrapper_ff(class cl_uc *uc, t_mem code);
+extern int instruction_wrapper_ff(class cl_uc *uc, t_mem code);
+
+extern void fill_def_wrappers(instruction_wrapper_fn itab[]);
+
+
+#endif
+
+/* End of sim.src/iwrap.h */
diff --git a/sim/ucsim/sim.src/iwrap.o b/sim/ucsim/sim.src/iwrap.o
new file mode 100644
index 0000000..4895f2e
--- /dev/null
+++ b/sim/ucsim/sim.src/iwrap.o
Binary files differ
diff --git a/sim/ucsim/sim.src/mem.cc b/sim/ucsim/sim.src/mem.cc
new file mode 100644
index 0000000..7b5947a
--- /dev/null
+++ b/sim/ucsim/sim.src/mem.cc
@@ -0,0 +1,2634 @@
+/*
+ * Simulator of microcontrollers (mem.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@*/
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <ctype.h>
+#include <stdarg.h>
+#include "i_string.h"
+
+// prj
+#include "utils.h"
+#include "globals.h"
+
+// sim
+#include "simcl.h"
+
+// cmd
+#include "newcmdcl.h"
+#include "cmdutil.h"
+
+// local
+#include "memcl.h"
+#include "hwcl.h"
+
+
+static class cl_mem_error_registry mem_error_registry;
+
+/*
+ * 3rd version of memory system
+ */
+
+cl_memory::cl_memory(const char *id, t_addr asize, int awidth):
+ cl_base()
+{
+ if ((size= asize) > max_mem_size)
+ size= max_mem_size;
+ set_name(id);
+ addr_format= data_format= 0;
+ width= awidth;
+ start_address= 0;
+ uc= 0;
+ hidden= false;
+}
+
+cl_memory::~cl_memory(void)
+{
+ if (addr_format)
+ free(addr_format);
+ if (data_format)
+ free(data_format);
+}
+
+int
+cl_memory::init(void)
+{
+ chars c= chars("",
+ //addr_format= (char *)malloc(10);
+ /*sprintf(addr_format,*/ "0x%%0%d",
+ size-1<=0xf?1:
+ (size-1<=0xff?2:
+ (size-1<=0xfff?3:
+ (size-1<=0xffff?4:
+ (size-1<=0xfffff?5:
+ (size-1<=0xffffff?6:12))))));
+ if (sizeof(t_addr) > sizeof(long))
+ c+= cchars("L");//strcat(addr_format, "L");
+ else if (sizeof(t_addr) > sizeof(int))
+ c+= cchars("l");//strcat(addr_format, "l");
+ c+= cchars("x");//strcat(addr_format, "x");
+ addr_format= strdup((char*)c);
+ //data_format= (char *)malloc(10);
+ c= cchars("");
+ /*sprintf(data_*/c.format(/*"0x"*/"%%0%d", width/4+((width%4)?1:0));
+ if (sizeof(t_mem) > sizeof(long))
+ c+= cchars("L");//strcat(data_format, "L");
+ else if (sizeof(t_mem) > sizeof(int))
+ c+= cchars("l");//strcat(data_format, "l");
+ c+= cchars("x");//strcat(data_format, "x");
+ data_format= strdup((char*)c);
+ data_mask= 1;
+ int w= width;
+ for (--w; w; w--)
+ {
+ data_mask<<= 1;
+ data_mask|= 1;
+ }
+ dump_finished= start_address;
+ return(0);
+}
+
+
+bool
+cl_memory::valid_address(t_addr addr)
+{
+ return(addr >= start_address &&
+ addr < start_address+size);
+}
+
+t_addr
+cl_memory::inc_address(t_addr addr, int val)
+{
+ if (!start_address)
+ return(((signed)addr+val)%size);
+ addr-= start_address;
+ addr+= val;
+ addr%= size;
+ addr+= start_address;
+ return(addr);
+}
+
+t_addr
+cl_memory::inc_address(t_addr addr)
+{
+ if (!start_address)
+ return(((signed)addr+1)%size);
+ addr-= start_address;
+ addr++;
+ addr%= size;
+ addr+= start_address;
+ return(addr);
+}
+
+t_addr
+cl_memory::validate_address(t_addr addr)
+{
+ while (addr < start_address)
+ addr+= size;
+ if (addr > start_address+size)
+ {
+ addr-= start_address;
+ addr%= size;
+ addr+= start_address;
+ }
+ return(addr);
+}
+
+
+void
+cl_memory::err_inv_addr(t_addr addr)
+{
+ if (!uc)
+ return;
+ class cl_error *e= new cl_error_mem_invalid_address(this, addr);
+ uc->error(e);
+}
+
+void
+cl_memory::err_non_decoded(t_addr addr)
+{
+ if (!uc)
+ return;
+ class cl_error *e= new cl_error_mem_non_decoded(this, addr);
+ uc->error(e);
+}
+
+
+t_addr
+cl_memory::dump(t_addr start, t_addr stop, int bpl, /*class cl_f *f*/class cl_console_base *con)
+{
+ int i, step;
+ t_addr lva= lowest_valid_address();
+ t_addr hva= highest_valid_address();
+ class cl_f *f= con->get_fout();
+
+ if (!f)
+ return dump_finished;
+
+ if (start < lva)
+ start= lva;
+ if (start > hva)
+ return dump_finished;
+ if (stop > hva)
+ stop= hva;
+ if (stop < lva)
+ return dump_finished;
+ if (stop >= start)
+ {
+ step= +1;
+ stop++;
+ if (start + bpl > stop)
+ bpl= stop - start;
+ }
+ else
+ {
+ step= -1;
+ stop--;
+ if (start - bpl < stop)
+ bpl= start - stop;
+ }
+ while ((step>0)?(start < stop):(start > stop))
+ {
+ // 1. field: address
+ /*f->prntf*/con->dd_cprintf("dump_address", addr_format, start);
+ /*f->write_str*/con->dd_printf(" ");
+ // 2. field: hex list
+ for (i= 0;
+ (i < bpl) &&
+ (start+i*step >= lva) &&
+ (start+i*step <= hva) &&
+ (start+i*step != stop);
+ i++)
+ {
+ /*f->prntf*/con->dd_cprintf("dump_number", data_format, read/*get*/(start+i*step));
+ /*f->write_str*/con->dd_printf(" ");
+ }
+ // 3. field: char list
+ while (i < bpl)
+ {
+ int j;
+ j= width/4 + ((width%4)?1:0) + 1;
+ while (j)
+ {
+ /*f->write_str*/con->dd_printf(" ");
+ j--;
+ }
+ i++;
+ }
+ for (i= 0; (i < bpl) &&
+ (start+i*step >= lva) &&
+ (start+i*step <= hva) &&
+ (start+i*step != stop);
+ i++)
+ {
+ long c= read(start+i*step);
+ /*f->prntf*/con->dd_cprintf("dump_char", "%c", isprint(255&c)?(255&c):'.');
+ if (width > 8)
+ /*f->prntf*/con->dd_cprintf("dump_char", "%c", isprint(255&(c>>8))?(255&(c>>8)):'.');
+ if (width > 16)
+ /*f->prntf*/con->dd_cprintf("dump_char", "%c", isprint(255&(c>>16))?(255&(c>>16)):'.');
+ if (width > 24)
+ /*f->prntf*/con->dd_cprintf("dump_char", "%c", isprint(255&(c>>24))?(255&(c>>24)):'.');
+ }
+ /*f->prntf*/con->dd_printf("\n");
+ dump_finished= start+i*step;
+ start+= i*step;
+ }
+ return(dump_finished);
+}
+
+t_addr
+cl_memory::dump_s(t_addr start, t_addr stop, int bpl, /*class cl_f *f*/class cl_console_base *con)
+{
+ t_addr lva= lowest_valid_address();
+ t_addr hva= highest_valid_address();
+ class cl_f *f= con->get_fout();
+
+ if (!f)
+ return dump_finished;
+ if (start < 0)
+ start= dump_finished;
+ if (stop < 0)
+ stop= start + 10*8 - 1;
+
+ if (start < lva)
+ start= lva;
+ if (start > hva)
+ return dump_finished;
+ if (stop > hva)
+ stop= hva;
+ if (stop < lva)
+ return dump_finished;
+
+ if (bpl < 0)
+ bpl= 8;
+ t_addr a= start;
+ t_mem d= read(a);
+ char last= '\n';
+ con->dd_printf("%s", (char*)(con->get_color_ansiseq("dump_char")));
+ while ((a <= stop) &&
+ (d != 0) &&
+ (a <= hva))
+ {
+ char c= d;
+ int i= d;
+ chars s;
+ if (a >= lva)
+ {
+ switch (c)
+ { // ' " ? \ a b f n r t v
+ case '\'': s= (char*)"\\\'"; f->write((char*)s, s.len()); break;
+ case '\"': s= (char*)"\\\""; f->write((char*)s, s.len()); break;
+ case '\?': s= (char*)"\\\?"; f->write((char*)s, s.len()); break;
+ case '\\': s= (char*)"\\\\"; f->write((char*)s, s.len()); break;
+ case '\a': s= (char*)"\\a"; f->write((char*)s, s.len()); break;
+ case '\b': s= (char*)"\\b"; f->write((char*)s, s.len()); break;
+ case '\f': s= (char*)"\\f"; f->write((char*)s, s.len()); break;
+ case '\n': s= (char*)"\\n"; f->write((char*)s, s.len()); break;
+ case '\r': s= (char*)"\\r"; f->write((char*)s, s.len()); break;
+ case '\t': s= (char*)"\\t"; f->write((char*)s, s.len()); break;
+ case '\v': s= (char*)"\\v"; f->write((char*)s, s.len()); break;
+ default:
+ if (isprint(i))
+ f->write(&c, 1);
+ else
+ {
+ s.format("\\%03o", i);
+ f->write((char*)s, s.len());
+ }
+ }
+ last= c;
+ }
+ d= read(++a);
+ }
+ if (last != '\n')
+ f->write_str("\n");
+ return dump_finished= a;
+}
+
+t_addr
+cl_memory::dump_b(t_addr start, t_addr stop, int bpl, /*class cl_f *f*/class cl_console_base *con)
+{
+ t_addr lva= lowest_valid_address();
+ t_addr hva= highest_valid_address();
+ class cl_f *f= con->get_fout();
+
+ if (!f)
+ return dump_finished;
+ if (start < 0)
+ start= dump_finished;
+ if (stop < 0)
+ stop= start + 10*8 - 1;
+
+ if (start < lva)
+ start= lva;
+ if (start > hva)
+ return dump_finished;
+ if (stop > hva)
+ stop= hva;
+ if (stop < lva)
+ return dump_finished;
+
+ if (bpl < 0)
+ bpl= 8;
+ t_addr a= start;
+ t_mem d= read(a);
+ while ((a <= stop) &&
+ (a <= hva))
+ {
+ char c= d;
+ if (a >= lva)
+ {
+ f->write(&c, 1);
+ }
+ d= read(++a);
+ }
+ return dump_finished= a;
+}
+
+t_addr
+cl_memory::dump_i(t_addr start, t_addr stop, int bpl, /*class cl_f *f*/class cl_console_base *con)
+{
+ t_addr lva= lowest_valid_address();
+ t_addr hva= highest_valid_address();
+ unsigned int sum;
+ t_addr start_line;
+ class cl_f *f= con->get_fout();
+
+ if (!f)
+ return dump_finished;
+ if (start < 0)
+ start= dump_finished;
+ if (start < lva)
+ start= lva;
+ if (stop < 0)
+ stop= start + 10*8 - 1;
+ if (stop > hva)
+ stop= hva;
+
+ if (start < lva)
+ start= lva;
+ if (start > hva)
+ return dump_finished;
+ if (stop > hva)
+ stop= hva;
+ if (stop < lva)
+ return dump_finished;
+
+ if (start > stop)
+ return dump_finished= stop;
+
+ if (bpl < 0)
+ bpl= 16;
+ if (bpl > 32)
+ bpl= 32;
+ t_addr a= start;
+ sum= 0;
+ start_line= a;
+ while (a <= stop)
+ {
+ a++;
+ if (((a % bpl) == 0) ||
+ (a > stop))
+ {
+ // dump line
+ if ((a - start_line) > 0)
+ {
+ unsigned char c;
+ sum= 0;
+ c= a-start_line;
+ f->prntf(":%02X%04X00", c, start_line);
+ sum+= c;
+ c= int(start_line >> 8) & 0xff;
+ sum+= c;
+ c= start_line & 0xff;
+ sum+= c;
+ int i;
+ for (i= 0; i < a-start_line; i++)
+ {
+ c= read(start_line + i);
+ f->prntf("%02X", c);
+ sum+= c;
+ }
+ sum&= 0xff;
+ unsigned char chk= 0x100 - sum;
+ f->prntf("%02X\r\n", chk);
+ }
+ start_line= a;
+ }
+ }
+ f->write_str(":00000001FF\r\n");
+ return dump_finished= a;
+}
+
+t_addr
+cl_memory::dump(/*class cl_f *f*/class cl_console_base *con)
+{
+ if (con->get_fout() == NULL)
+ return dump_finished;
+ return(dump(dump_finished, dump_finished+10*8-1, 8, /*f*/con));
+}
+
+t_addr
+cl_memory::dump(enum dump_format fmt,
+ t_addr start, t_addr stop, int bpl,
+ /*class cl_f *f*/class cl_console_base *con)
+{
+ t_addr lva= lowest_valid_address();
+ t_addr hva= highest_valid_address();
+
+ //if (!f)
+ //return dump_finished;
+ if (start < 0)
+ start= dump_finished;
+ if (stop < 0)
+ stop= start + 10*8 - 1;
+
+ if (start < lva)
+ start= lva;
+ if (start > hva)
+ return dump_finished;
+ if (stop > hva)
+ stop= hva;
+ if (stop < lva)
+ return dump_finished;
+
+ if (bpl < 0)
+ bpl= 8;
+ switch (fmt & df_format)
+ {
+ case df_hex:
+ return dump(start, stop, bpl, /*f*/con);
+ case df_string:
+ return dump_s(start, stop, bpl, /*f*/con);
+ case df_ihex:
+ return dump_i(start, stop, bpl, /*f*/con);
+ case df_binary:
+ return dump_b(start, stop, bpl, /*f*/con);
+ default:
+ return dump(start, stop, bpl, /*f*/con);
+ }
+ return dump_finished;
+}
+
+bool
+cl_memory::search_next(bool case_sensitive,
+ t_mem *array, int len, t_addr *addr)
+{
+ t_addr a;
+ int i;
+ bool found;
+
+ if (addr == NULL)
+ a= 0;
+ else
+ a= *addr;
+
+ if (a+len > size)
+ return(false);
+
+ found= false;
+ while (!found &&
+ a+len <= size)
+ {
+ bool match= true;
+ for (i= 0; i < len && match; i++)
+ {
+ t_mem d1, d2;
+ d1= get(a+i);
+ d2= array[i];
+ if (!case_sensitive)
+ {
+ if (/*d1 < 128*/isalpha(d1))
+ d1= toupper(d1);
+ if (/*d2 < 128*/isalpha(d2))
+ d2= toupper(d2);
+ }
+ match= d1 == d2;
+ }
+ found= match;
+ if (!found)
+ a++;
+ }
+
+ if (addr)
+ *addr= a;
+ return(found);
+}
+
+void
+cl_memory::print_info(chars pre, class cl_console_base *con)
+{
+ char *n= (char*)(get_name());
+ if (!hidden)
+ {
+ con->dd_printf("%s0x%06x-0x%06x %8d %s (%d,%s,%s)\n", (char*)pre,
+ AU(get_start_address()),
+ AU(highest_valid_address()),
+ AU(get_size()),
+ n,
+ width, data_format, addr_format);
+ }
+}
+
+
+/*
+ * Memory operators
+ */
+
+cl_memory_operator::cl_memory_operator(class cl_memory_cell *acell/*,
+ t_addr addr*/):
+ cl_base()
+{
+ cell= acell;
+ if (cell)
+ {
+ //data= cell->data;
+ mask= cell->mask;
+ }
+ else
+ {
+ //data= 0;
+ mask= ~0;
+ }
+ next_operator= 0;
+ //address= addr;
+}
+/*
+cl_memory_operator::cl_memory_operator(class cl_memory_cell *acell,
+ t_addr addr,
+ t_mem *data_place, t_mem the_mask):
+ cl_base()
+{
+ cell= acell;
+ //data= data_place;
+ mask= the_mask;
+ next_operator= 0;
+ address= addr;
+}
+*/
+/*
+void
+cl_memory_operator::set_data(t_mem *data_place, t_mem the_mask)
+{
+ data= data_place;
+ mask= the_mask;
+}
+*/
+
+t_mem
+cl_memory_operator::read(void)
+{
+ if (next_operator)
+ return(next_operator->read());
+ else if (cell)
+ return(/* *data*/cell->get());
+ return 0;
+}
+
+t_mem
+cl_memory_operator::write(t_mem val)
+{
+ if (next_operator)
+ return(next_operator->write(val));
+ else if (cell)
+ return(/* *data=*/cell->set(val & mask));
+ return val;
+}
+
+
+/* Memory operator for bank switcher */
+
+cl_bank_switcher_operator::cl_bank_switcher_operator(class cl_memory_cell *acell,
+ /*t_addr addr,*/
+ class cl_banker *the_banker):
+ cl_memory_operator(acell/*, addr*/)
+{
+ banker= the_banker;
+ set_name("bank_switcher");
+}
+
+t_mem
+cl_bank_switcher_operator::write(t_mem val)
+{
+ if (next_operator)
+ next_operator->write(val);
+ if (cell) /* *data=*/ cell->set(val & mask);
+ banker->activate(NULL);
+ if (cell)
+ return cell->get();
+ return /* *data*/ 0;
+}
+
+
+/* Memory operator for hw callbacks */
+
+cl_hw_operator::cl_hw_operator(class cl_memory_cell *acell/*, t_addr addr*/,
+ //t_mem *data_place, t_mem the_mask,
+ class cl_hw *ahw):
+ cl_memory_operator(acell/*, addr*//*, data_place, the_mask*/)
+{
+ hw= ahw;
+ set_name(chars("hw:")+hw->get_name());
+}
+
+
+t_mem
+cl_hw_operator::read(void)
+{
+ t_mem d1= 0, d2= 0;
+
+ if (hw)
+ d1= hw->read(cell);
+
+ if (next_operator)
+ d2= next_operator->read();
+
+ return(hw?d1:d2);
+}
+
+t_mem
+cl_hw_operator::read(enum hw_cath skip)
+{
+ t_mem d1= 0/* *data*/, d2= d1;
+ bool use= false;
+
+ if (hw &&
+ hw->cathegory != skip)
+ use= true, d1= hw->read(cell);
+
+ if (next_operator)
+ d2= next_operator->read();
+ else if (cell)
+ d2= cell->get();
+ else
+ return use= true;
+
+ return(use?d1:d2);
+}
+
+t_mem
+cl_hw_operator::write(t_mem val)
+{
+ if (hw)
+ hw->write(cell, &val);
+ if (next_operator)
+ val= next_operator->write(val);
+ //if (cell) return(/* *data=*//*cell->set(val & mask)*/val);
+ return val;
+}
+
+
+/* Write event break on cell */
+
+cl_write_operator::cl_write_operator(class cl_memory_cell *acell/*, t_addr addr*/,
+ //t_mem *data_place, t_mem the_mask,
+ class cl_uc *auc, class cl_brk *the_bp):
+ cl_event_break_operator(acell/*, addr*//*, data_place, the_mask*/, auc, the_bp)
+{
+ uc= auc;
+ bp= the_bp;
+ set_name("write_event");
+}
+
+t_mem
+cl_write_operator::write(t_mem val)
+{
+ //printf("write event at 0x%x bp=%p\n",address,bp);
+ if (bp->do_hit())
+ uc->events->add(bp);
+ if (next_operator)
+ return(next_operator->write(val));
+ else if (cell)
+ return(/* *data=*/cell->set(val & mask));
+ return val;
+}
+
+
+/* Read event break on cell */
+
+cl_read_operator::cl_read_operator(class cl_memory_cell *acell/*, t_addr addr*/,
+ //t_mem *data_place, t_mem the_mask,
+ class cl_uc *auc, class cl_brk *the_bp):
+ cl_event_break_operator(acell/*, addr*//*, data_place, the_mask*/, auc, the_bp)
+{
+ uc= auc;
+ bp= the_bp;
+ set_name("read_event");
+}
+
+t_mem
+cl_read_operator::read(void)
+{
+ //printf("read event at 0x%x bp=%p\n",address,bp);
+ if (bp->do_hit())
+ uc->events->add(bp);
+ if (next_operator)
+ return(next_operator->read());
+ else if (cell)
+ return(/* *data*/cell->get());
+ return 0;
+}
+
+
+/*
+ * Cell data
+ */
+
+t_mem
+cl_cell_data::d()
+{
+ return data?(*data):0;
+}
+
+void
+cl_cell_data::d(t_mem v)
+{
+ data?(*data=v):0;
+}
+
+void
+cl_cell_data::dl(t_mem v)
+{
+ data?(*data=v):0;
+}
+
+// bit cell for bit spaces
+
+t_mem
+cl_bit_cell::d()
+{
+ if (!data)
+ return 0;
+ return (*data&mask)?1:0;
+}
+
+void
+cl_bit_cell::d(t_mem v)
+{
+ if (!data)
+ return;
+ if (v)
+ *data|= mask;
+ else
+ *data&= ~mask;
+}
+
+
+// 8 bit cell;
+
+t_mem
+cl_cell8::d()
+{
+ return data?((/*u8_t*/uchar)*data):0;
+}
+
+void
+cl_cell8::d(t_mem v)
+{
+ data?(*data=(/*u8_t*/uchar)v):0;
+}
+
+// 8 bit cell for bit spaces
+
+t_mem
+cl_bit_cell8::d()
+{
+ if (!data)
+ return 0;
+ /*u8_t*/uchar x= (/*u8_t*/uchar) *data;
+ x&= mask;
+ return x?1:0;
+}
+
+void
+cl_bit_cell8::d(t_mem v)
+{
+ if (!data)
+ return;
+ if (v)
+ *data |= (/*u8_t*/uchar)mask;
+ else
+ *data &= ~(/*u8_t*/uchar)mask;
+}
+
+// 16 bit cell;
+
+t_mem
+cl_cell16::d()
+{
+ return data?((u16_t)*data):0;
+}
+
+void
+cl_cell16::d(t_mem v)
+{
+ data?(*data=(u16_t)v):0;
+}
+
+// 16 bit cell for bit spaces
+
+t_mem
+cl_bit_cell16::d()
+{
+ if (!data)
+ return 0;
+ return (((u16_t)*data)&((u16_t)mask))?1:0;
+}
+
+void
+cl_bit_cell16::d(t_mem v)
+{
+ if (!data)
+ return;
+ if (v)
+ *data |= (u16_t)mask;
+ else
+ *data &= ~(u16_t)mask;
+}
+
+
+/*
+ * Memory cell
+ */
+
+cl_memory_cell::cl_memory_cell(uchar awidth)//: cl_base()
+{
+ data= 0;
+ flags= CELL_NON_DECODED;
+ width= awidth;
+ //*data= 0;
+ def_data= 0;
+ operators= NULL;
+ //bank= 0;
+ //banked_data_ptrs= 0;
+#ifdef STATISTIC
+ nuof_writes= nuof_reads= 0;
+#endif
+ mask= 1;
+ int w= width;
+ for (--w; w; w--)
+ {
+ mask<<= 1;
+ mask|= 1;
+ }
+}
+
+cl_memory_cell::~cl_memory_cell(void)
+{
+ if ((flags & CELL_NON_DECODED) &&
+ data)
+ ;//free(data);
+}
+
+int
+cl_memory_cell::init(void)
+{
+ //cl_base::init();
+ data= &def_data;
+ //flags= CELL_NON_DECODED;
+ /*mask= 1;
+ int w= width;
+ for (--w; w; w--)
+ {
+ mask<<= 1;
+ mask|= 1;
+ }*/
+ //set(0/*rand()*/);
+ return(0);
+}
+
+
+uchar
+cl_memory_cell::get_flags(void)
+{
+ return(flags);
+}
+
+bool
+cl_memory_cell::get_flag(enum cell_flag flag)
+{
+ return(flags & flag);
+}
+
+void
+cl_memory_cell::set_flags(uchar what)
+{
+ flags= what;
+}
+
+void
+cl_memory_cell::set_flag(enum cell_flag flag, bool val)
+{
+ if (val)
+ flags|= flag;
+ else
+ flags&= ~(flag);
+}
+
+
+void
+cl_memory_cell::un_decode(void)
+{
+ if ((flags & CELL_NON_DECODED) == 0)
+ {
+ data= &def_data;//(t_mem *)malloc(sizeof(t_mem));
+ flags|= CELL_NON_DECODED;
+ }
+}
+
+void
+cl_memory_cell::decode(class cl_memory_chip *chip, t_addr addr)
+{
+ if (flags & CELL_NON_DECODED)
+ ;//free(data);
+ data= chip->get_slot(addr);
+ if (!data)
+ {
+ data= &def_data;//(t_mem *)malloc(sizeof(t_mem));
+ flags|= CELL_NON_DECODED;
+ }
+ else
+ flags&= ~(CELL_NON_DECODED);
+}
+
+void
+cl_memory_cell::decode(t_mem *data_ptr)
+{
+ if (data_ptr == NULL)
+ {
+ data= &def_data;
+ flags|= CELL_NON_DECODED;
+ }
+ else
+ {
+ data= data_ptr;
+ flags&= ~CELL_NON_DECODED;
+ }
+}
+
+void
+cl_memory_cell::decode(t_mem *data_ptr, t_mem bit_mask)
+{
+ if (data_ptr == NULL)
+ {
+ data= &def_data;
+ flags|= CELL_NON_DECODED;
+ }
+ else
+ {
+ data= data_ptr;
+ flags&= ~CELL_NON_DECODED;
+ }
+ mask= bit_mask;
+}
+
+t_mem
+cl_memory_cell::read(void)
+{
+#ifdef STATISTIC
+ nuof_reads++;
+#endif
+ if (operators)
+ return(operators->read());
+ return /* *data*/d();
+}
+
+t_mem
+cl_memory_cell::read(enum hw_cath skip)
+{
+#ifdef STATISTIC
+ nuof_reads++;
+#endif
+ if (operators)
+ return(operators->read(skip));
+ return /* *data*/d();
+}
+
+t_mem
+cl_memory_cell::get(void)
+{
+ return /* *data*/d();
+}
+
+t_mem
+cl_memory_cell::write(t_mem val)
+{
+#ifdef STATISTIC
+ nuof_writes++;
+#endif
+ if (operators)
+ val= operators->write(val);
+ if (flags & CELL_READ_ONLY)
+ return d();
+ if (width == 1)
+ d(val);
+ else
+ d(val & mask);
+ return d();
+}
+
+t_mem
+cl_memory_cell::set(t_mem val)
+{
+ if (flags & CELL_READ_ONLY)
+ return d();
+ if (width == 1)
+ d(val);
+ else
+ /* *data=*/d(val & mask);
+ return /* *data*/d();
+}
+
+t_mem
+cl_memory_cell::download(t_mem val)
+{
+ if (width == 1)
+ dl(val);
+ else
+ /* *data=*/dl(val & mask);
+ return /* *data*/d();
+}
+
+t_mem
+cl_memory_cell::add(long what)
+{
+ /* *data=*/ d( (*data + what) & mask);
+ return(/* *data*/d());
+}
+
+t_mem
+cl_memory_cell::wadd(long what)
+{
+ t_mem d= (*data + what) & mask;
+ return(write(d));
+}
+
+void
+cl_memory_cell::set_bit1(t_mem bits)
+{
+ bits&= mask;
+ /*(*data)|=*//*d*/set(d()| bits);
+}
+
+void
+cl_memory_cell::write_bit1(t_mem bits)
+{
+ bits&= mask;
+ /*(*data)|=*//*d*/write(d()| bits);
+}
+
+void
+cl_memory_cell::set_bit0(t_mem bits)
+{
+ bits&= mask;
+ /*(*data)&=*//*d*/set(d()& ~bits);
+}
+
+void
+cl_memory_cell::write_bit0(t_mem bits)
+{
+ bits&= mask;
+ /*(*data)&=*//*d*/write(d()& ~bits);
+}
+
+void
+cl_memory_cell::toggle_bits(t_mem bits)
+{
+ bits&= mask;
+ /*d*/set(d() ^ bits);
+}
+
+void
+cl_memory_cell::wtoggle_bits(t_mem bits)
+{
+ bits&= mask;
+ /*d*/write(d() ^ bits);
+}
+
+
+void
+cl_memory_cell::append_operator(class cl_memory_operator *op)
+{
+ if (!operators)
+ operators= op;
+ else
+ {
+ class cl_memory_operator *o= operators, *n;
+ n= o->get_next();
+ while (n)
+ {
+ o= n;
+ n= o->get_next();
+ }
+ o->set_next(op);
+ }
+}
+
+void
+cl_memory_cell::prepend_operator(class cl_memory_operator *op)
+{
+ if (op)
+ {
+ op->set_next(operators);
+ operators= op;
+ }
+}
+
+void
+cl_memory_cell::del_operator(class cl_brk *brk)
+{
+ if (!operators)
+ return;
+ class cl_memory_operator *op= operators;
+ if (operators->match(brk))
+ {
+ operators= op->get_next();
+ delete op;
+ }
+ else
+ {
+ while (op->get_next() &&
+ !op->get_next()->match(brk))
+ op= op->get_next();
+ if (op->get_next())
+ {
+ class cl_memory_operator *m= op->get_next();
+ op->set_next(m->get_next());;
+ delete m;
+ }
+ }
+}
+
+void
+cl_memory_cell::del_operator(class cl_hw *hw)
+{
+ if (!operators)
+ return;
+ class cl_memory_operator *op= operators;
+ if (operators->match(hw))
+ {
+ operators= op->get_next();
+ delete op;
+ }
+ else
+ {
+ while (op->get_next() &&
+ !op->get_next()->match(hw))
+ op= op->get_next();
+ if (op->get_next())
+ {
+ class cl_memory_operator *m= op->get_next();
+ op->set_next(m->get_next());
+ delete m;
+ }
+ }
+}
+
+class cl_banker *
+cl_memory_cell::get_banker(void)
+{
+ class cl_memory_operator *op= operators;
+ class cl_banker *b= NULL;
+
+ while (op)
+ {
+ b= op->get_banker();
+ if (b)
+ return b;
+ op= op->get_next();
+ }
+ return NULL;
+}
+
+class cl_memory_cell *
+cl_memory_cell::add_hw(class cl_hw *hw/*, t_addr addr*/)
+{
+ class cl_hw_operator *o= new cl_hw_operator(this/*, addr*//*, data, mask*/, hw);
+ append_operator(o);
+ return(this);
+}
+
+void
+cl_memory_cell::remove_hw(class cl_hw *hw)
+{
+ del_operator(hw);
+}
+
+/*class cl_hw *
+cl_memory_cell::get_hw(int ith)
+{
+ return(0);
+}*/
+
+class cl_event_handler *
+cl_memory_cell::get_event_handler(void)
+{
+ return(0);
+}
+
+void
+cl_memory_cell::print_info(chars pre, class cl_console_base *con)
+{
+ con->dd_printf("%sFlags:", (char*)pre);
+ if (flags & CELL_VAR)
+ con->dd_printf(" VAR");
+ if (flags & CELL_INST)
+ con->dd_printf(" INST");
+ if (flags & CELL_FETCH_BRK)
+ con->dd_printf(" FBRK");
+ if (flags & CELL_READ_ONLY)
+ con->dd_printf(" RO");
+ if (flags & CELL_NON_DECODED)
+ con->dd_printf(" NDC");
+ con->dd_printf("\n");
+ print_operators(pre, con);
+}
+
+void
+cl_memory_cell::print_operators(chars pre, class cl_console_base *con)
+{
+ class cl_memory_operator *o= operators;
+ if (!operators)
+ return;
+ int i= 0;
+ while (o)
+ {
+ printf("%s %02d. %s\n", (char*)pre, i, o->get_name("?"));
+ i++;
+ o= o->get_next();
+ }
+}
+
+
+/*
+ * Dummy cell for non-existent addresses
+ */
+
+t_mem
+cl_dummy_cell::write(t_mem val)
+{
+#ifdef STATISTIC
+ nuof_writes++;
+#endif
+ *data= rand() & mask;
+ return(*data);
+}
+
+t_mem
+cl_dummy_cell::set(t_mem val)
+{
+ *data= rand() & mask;
+ return(*data);
+}
+
+
+/*
+ * Address space
+ */
+
+cl_address_space::cl_address_space(const char *id,
+ t_addr astart, t_addr asize, int awidth):
+ cl_memory(id, asize, awidth)
+{
+ class cl_memory_cell c(awidth);
+ class cl_bit_cell8 bc8(awidth);
+ class cl_cell8 c8(awidth);
+ class cl_cell16 c16(awidth);
+ class cl_memory_cell *cell= &c;
+ start_address= astart;
+ decoders= new cl_decoder_list(2, 2, false);
+ cella= (class cl_memory_cell *)malloc(size * sizeof(class cl_memory_cell));
+ if (awidth == 1)
+ cell= &bc8;
+ else if (awidth <= 8)
+ cell= &c8;
+ else if (awidth <= 16)
+ cell= &c16;
+ //cell->init();
+ int i;
+ for (i= 0; i < size; i++)
+ {
+ void *p1= &(cella[i]);
+ void *p2= cell;
+ memcpy(p1, p2, sizeof(c));
+ cella[i].init();
+ }
+ dummy= new cl_dummy_cell(awidth);
+ dummy->init();
+}
+
+cl_address_space::~cl_address_space(void)
+{
+ delete decoders;
+ int i;
+ for (i= 0; i < size; i++)
+ {
+ cella[i].~cl_memory_cell();
+ }
+ free(cella);
+ delete dummy;
+}
+
+
+t_mem
+cl_address_space::read(t_addr addr)
+{
+ t_addr idx= addr-start_address;
+ if (idx >= size ||
+ addr < start_address)
+ {
+ err_inv_addr(addr);
+ return(dummy->read());
+ }
+ return(cella[idx].read());
+}
+
+t_mem
+cl_address_space::read(t_addr addr, enum hw_cath skip)
+{
+ t_addr idx= addr-start_address;
+ if (idx >= size ||
+ addr < start_address)
+ {
+ err_inv_addr(addr);
+ return(dummy->read());
+ }
+ return(cella[idx].read(skip));
+}
+
+t_mem
+cl_address_space::get(t_addr addr)
+{
+ t_addr idx= addr-start_address;
+ if (idx >= size ||
+ addr < start_address)
+ {
+ err_inv_addr(addr);
+ return(dummy->get());
+ }
+ return cella[idx].get();//*(cella[idx].data);
+}
+
+t_mem
+cl_address_space::write(t_addr addr, t_mem val)
+{
+ t_addr idx= addr-start_address;
+ if (idx >= size ||
+ addr < start_address)
+ {
+ err_inv_addr(addr);
+ return(dummy->write(val));
+ }
+ //if (cella[idx].get_flag(CELL_NON_DECODED)) printf("%s[%d] nondec write=%x\n",get_name(),addr,val);
+ return(cella[idx].write(val));
+}
+
+void
+cl_address_space::set(t_addr addr, t_mem val)
+{
+ t_addr idx= addr-start_address;
+ if (idx >= size ||
+ addr < start_address)
+ {
+ err_inv_addr(addr);
+ dummy->set(val);
+ return;
+ }
+ /* *(cella[idx].data)=*/cella[idx].set( val/*&(data_mask)*/);
+}
+
+void
+cl_address_space::download(t_addr addr, t_mem val)
+{
+ t_addr idx= addr-start_address;
+ if (idx >= size ||
+ addr < start_address)
+ {
+ err_inv_addr(addr);
+ dummy->download(val);
+ return;
+ }
+ /* *(cella[idx].data)=*/cella[idx].download( val/*&(data_mask)*/);
+}
+
+t_mem
+cl_address_space::wadd(t_addr addr, long what)
+{
+ t_addr idx= addr-start_address;
+ if (idx >= size ||
+ addr < start_address)
+ {
+ err_inv_addr(addr);
+ }
+ return(cella[idx].wadd(what));
+}
+
+/* Set or clear bits, without callbacks */
+
+void
+cl_address_space::set_bit1(t_addr addr, t_mem bits)
+{
+ t_addr idx= addr-start_address;
+ if (idx >= size ||
+ addr < start_address)
+ return;
+ class cl_memory_cell *cell= &(cella[idx]);
+ cell->set_bit1(bits);
+}
+
+void
+cl_address_space::set_bit0(t_addr addr, t_mem bits)
+{
+ t_addr idx= addr-start_address;
+ if (idx >= size ||
+ addr < start_address)
+ return;
+ class cl_memory_cell *cell= &(cella[idx]);
+ cell->set_bit0(bits);
+}
+
+
+class cl_memory_cell *
+cl_address_space::get_cell(t_addr addr)
+{
+ t_addr idx= addr-start_address;
+ if (idx >= size ||
+ addr < start_address)
+ {
+ err_inv_addr(addr);
+ return(dummy);
+ }
+ return(&cella[idx]);
+}
+
+
+int
+cl_address_space::get_cell_flag(t_addr addr)
+{
+ t_addr idx= addr-start_address;
+ if (idx >= size ||
+ addr < start_address)
+ {
+ return(dummy->get_flags());
+ }
+ return(cella[idx].get_flags());
+}
+
+bool
+cl_address_space::get_cell_flag(t_addr addr, enum cell_flag flag)
+{
+ t_addr idx= addr-start_address;
+ if (idx >= size ||
+ addr < start_address)
+ {
+ return(dummy->get_flag(flag));
+ }
+ return(cella[idx].get_flag(flag));
+}
+
+void
+cl_address_space::set_cell_flag(t_addr addr, bool set_to, enum cell_flag flag)
+{
+ t_addr idx= addr-start_address;
+ class cl_memory_cell *cell;
+
+ if (idx >= size ||
+ addr < start_address)
+ {
+ cell= dummy;
+ }
+ else
+ cell= &cella[idx];
+ cell->set_flag(flag, set_to);
+}
+
+void
+cl_address_space::set_cell_flag(t_addr start_addr, t_addr end_addr, bool set_to, enum cell_flag flag)
+{
+ t_addr a;
+
+ for (a= start_addr; a <= end_addr; a++)
+ set_cell_flag(a, set_to, flag);
+}
+
+class cl_memory_cell *
+cl_address_space::search_cell(enum cell_flag flag, bool value, t_addr *addr)
+{
+ int i;
+
+ for (i= 0; i < size; i++)
+ {
+ bool f= cella[i].get_flag(flag);
+ if ((f && value) ||
+ (!f && !value))
+ {
+ if (addr)
+ *addr= i;
+ return &cella[i];
+ }
+ }
+ return NULL;
+}
+
+bool
+cl_address_space::is_owned(class cl_memory_cell *cell, t_addr *addr)
+{
+ if (cell < cella)
+ return false;
+ if (cell > &cella[size-1])
+ return false;
+ int idx= cell - cella;
+ if (addr)
+ *addr= start_address+idx;
+ return true;
+}
+
+class cl_address_decoder *
+cl_address_space::get_decoder_of(t_addr addr)
+{
+ class cl_address_decoder *dc;
+ int i;
+ for (i= 0; i < decoders->count; i++)
+ {
+ dc= (class cl_address_decoder *)(decoders->at(i));
+ if (dc->covers(addr, addr))
+ return dc;
+ }
+ return NULL;
+}
+
+bool
+cl_address_space::decode_cell(t_addr addr,
+ class cl_memory_chip *chip, t_addr chipaddr)
+{
+ t_addr idx= addr-start_address;
+ if (idx >= size ||
+ addr < start_address)
+ return(false);
+ class cl_memory_cell *cell= &cella[idx];
+
+ if (!cell->get_flag(CELL_NON_DECODED))
+ {
+ // un-decode first!
+ cell->un_decode();
+ }
+ cell->decode(chip, chipaddr);
+
+ return(!cell->get_flag(CELL_NON_DECODED));
+}
+
+void
+cl_address_space::undecode_cell(t_addr addr)
+{
+ t_addr idx= addr-start_address;
+ if (idx >= size ||
+ addr < start_address)
+ return;
+ class cl_memory_cell *cell= &cella[idx];
+
+ cell->un_decode();
+}
+
+void
+cl_address_space::undecode_area(class cl_address_decoder *skip,
+ t_addr begin, t_addr end,
+ class cl_console_base *con)
+{
+#define D if (con) con->debug
+ //#define D printf
+ D("Undecoding area 0x%lx-0x%lx of %s (skip=%s)\n", begin, end, get_name(), skip?(skip->get_name()):"-");
+ int i;
+ for (i= 0; i < decoders->count; i++)
+ {
+ class cl_address_decoder *d=
+ dynamic_cast<class cl_address_decoder *>(decoders->object_at(i));
+ if (!d ||
+ d == skip)
+ continue;
+ D(" Checking decoder 0x%lx-0x%lx -> %s[0x%lx]\n",
+ d->as_begin, d->as_end, (d->memchip)?(d->memchip->get_name()):"(none)", d->chip_begin);
+ if (d->fully_covered_by(begin, end))
+ {
+ // decoder can be removed
+ D(" Can be removed\n");
+ decoders->disconn(d);
+ i--;
+ delete d;
+ if (decoders->count == 0)
+ break;
+ }
+ else if (d->covers(begin, end))
+ {
+ // decoder must be split
+ D(" Must be split\n");
+ class cl_address_decoder *nd= d->split(begin, end);
+ D(" After split:\n");
+ D(" 0x%lx-0x%lx -> %s[0x%lx]\n",
+ d->as_begin, d->as_end, (d->memchip)?(d->memchip->get_name()):"(none)", d->chip_begin);
+ if (nd)
+ {
+ decoders->add(nd);
+ D(" 0x%lx-0x%lx -> %s[0x%lx]\n",
+ nd->as_begin, nd->as_end, (nd->memchip)?(nd->memchip->get_name()):"none", nd->chip_begin);
+ nd->activate(con);
+ }
+ }
+ else if (d->is_in(begin, end))
+ {
+ // decoder sould shrink
+ D(" Sould shrink\n");
+ if (d->shrink_out_of(begin, end))
+ {
+ D(" Can be removed after shrink\n");
+ decoders->disconn(d);
+ i--;
+ delete d;
+ if (decoders->count == 0)
+ break;
+ }
+ else
+ {
+ D(" Shrinked to 0x%lx-0x%lx -> %s[0x%lx]\n",
+ d->as_begin, d->as_end, (d->memchip)?(d->memchip->get_name()):"(none)", d->chip_begin);
+ }
+ }
+ }
+#undef D
+}
+
+
+class cl_memory_cell *
+cl_address_space::register_hw(t_addr addr, class cl_hw *hw,
+ bool announce)
+{
+ t_addr idx= addr-start_address;
+ if (idx >= size ||
+ addr < start_address)
+ return(0);
+ class cl_memory_cell *cell= &cella[idx];
+ cell->add_hw(hw/*, addr*/);
+ if (announce)
+ ;//uc->sim->/*app->*/mem_cell_changed(this, addr);//FIXME
+ return(cell);
+}
+
+void
+cl_address_space::unregister_hw(class cl_hw *hw)
+{
+ t_addr idx;
+
+ for (idx= 0; idx < size; idx++)
+ {
+ class cl_memory_cell *cell= &cella[idx];
+ cell->remove_hw(hw);
+ }
+}
+
+void
+cl_address_space::set_brk(t_addr addr, class cl_brk *brk)
+{
+ t_addr idx= addr-start_address;
+ if (idx >= size ||
+ addr < start_address)
+ return;
+ class cl_memory_cell *cell= &cella[idx];
+ class cl_memory_operator *op;
+
+ switch (brk->get_event())
+ {
+ case brkWRITE: case brkWXRAM: case brkWIRAM: case brkWSFR:
+ //e= 'W';
+ op= new cl_write_operator(cell/*, addr*/, //cell->get_data(), cell->get_mask(),
+ uc, brk);
+ break;
+ case brkREAD: case brkRXRAM: case brkRCODE: case brkRIRAM: case brkRSFR:
+ //e= 'R';
+ op= new cl_read_operator(cell/*, addr*/, //cell->get_data(), cell->get_mask(),
+ uc, brk);
+ break;
+ case brkNONE:
+ set_cell_flag(addr, true, CELL_FETCH_BRK);
+ return;
+ break;
+ default:
+ //e= '.';
+ op= 0;
+ break;
+ }
+ if (op)
+ cell->append_operator(op);
+}
+
+void
+cl_address_space::del_brk(t_addr addr, class cl_brk *brk)
+{
+ t_addr idx= addr-start_address;
+ if (idx >= size ||
+ addr < start_address)
+ return;
+ class cl_memory_cell *cell= &cella[idx];
+
+ switch (brk->get_event())
+ {
+ case brkWRITE: case brkWXRAM: case brkWIRAM: case brkWSFR:
+ case brkREAD: case brkRXRAM: case brkRCODE: case brkRIRAM: case brkRSFR:
+ cell->del_operator(brk);
+ break;
+ case brkNONE:
+ set_cell_flag(addr, false, CELL_FETCH_BRK);
+ return;
+ break;
+ default:
+ break;
+ }
+}
+
+void
+cl_address_space::print_info(chars pre, class cl_console_base *con)
+{
+ char *n= (char*)(get_name());
+ if (!hidden)
+ {
+ con->dd_printf("%s0x%06x-0x%06x %8d %s (%d,%s,%s)\n", (char*)pre,
+ AU(get_start_address()),
+ AU(highest_valid_address()),
+ AU(get_size()),
+ n,
+ width, data_format, addr_format);
+ }
+}
+
+
+/*
+ * List of address spaces
+ */
+
+cl_address_space_list::cl_address_space_list(class cl_uc *the_uc):
+ cl_list(2, 2, "address spaces")
+{
+ uc= the_uc;
+}
+
+t_index
+cl_address_space_list::add(class cl_address_space *mem)
+{
+ mem->set_uc(uc);
+ t_index ret= cl_list::add(mem);
+ if (uc)
+ {
+ class cl_event_address_space_added e(mem);
+ uc->handle_event(e);
+ }
+ return(ret);
+}
+
+
+/*
+ * Memory chip
+ */
+
+cl_memory_chip::cl_memory_chip(const char *id,
+ int asize,
+ int awidth,
+ int initial):
+ cl_memory(id, asize, awidth)
+{
+ array= (t_mem *)malloc(size * sizeof(t_mem));
+ init_value= initial;
+ array_is_mine= true;
+}
+
+cl_memory_chip::cl_memory_chip(const char *id,
+ int asize,
+ int awidth,
+ t_mem *aarray):
+ cl_memory(id, asize, awidth)
+{
+ array= aarray;
+ init_value= 0;
+ array_is_mine= false;
+}
+
+cl_memory_chip::~cl_memory_chip(void)
+{
+ if (array &&
+ array_is_mine)
+ free(array);
+}
+
+int
+cl_memory_chip::init(void)
+{
+ cl_memory::init();
+ int i;
+ if (array_is_mine)
+ {
+ for (i= 0; i < size; i++)
+ set(i,
+ (init_value<0)?rand():(init_value)
+ );
+ }
+ return(0);
+}
+
+
+t_mem *
+cl_memory_chip::get_slot(t_addr addr)
+{
+ if (!array ||
+ size <= addr)
+ return(0);
+ return(&array[addr]);
+}
+
+t_addr
+cl_memory_chip::is_slot(t_mem *data_ptr)
+{
+ if (data_ptr < &(array[0]))
+ return -1;
+ if (data_ptr > &(array[size-1]))
+ return -2;
+ return data_ptr - &(array[0]);
+}
+
+t_mem
+cl_memory_chip::get(t_addr addr)
+{
+ if (!array ||
+ size <= addr)
+ return(0);
+ return(array[addr]);
+}
+
+void
+cl_memory_chip::set(t_addr addr, t_mem val)
+{
+ if (!array ||
+ size <= addr)
+ return;
+ array[addr]= val & data_mask;
+}
+
+void
+cl_memory_chip::set_bit1(t_addr addr, t_mem bits)
+{
+ if (!array ||
+ size <= addr)
+ return;
+ array[addr]|= (bits & data_mask);
+}
+
+void
+cl_memory_chip::set_bit0(t_addr addr, t_mem bits)
+{
+ if (!array ||
+ size <= addr)
+ return;
+ array[addr]&= ((~bits) & data_mask);
+}
+
+void
+cl_memory_chip::print_info(chars pre, class cl_console_base *con)
+{
+ char *n= (char*)(get_name());
+ if (!hidden)
+ {
+ //con->dd_printf(pre0);
+ con->dd_printf("%s0x%06x-0x%06x %8d %s (%d,%s,%s)\n", (char*)pre,
+ AU(get_start_address()),
+ AU(highest_valid_address()),
+ AU(get_size()),
+ n,
+ width, data_format, addr_format);
+ }
+}
+
+
+/*
+ * Address decoder
+ */
+
+cl_address_decoder::cl_address_decoder(class cl_memory *as,
+ class cl_memory *chip,
+ t_addr asb, t_addr ase, t_addr cb)
+{
+ if (as && (as->is_address_space()))
+ address_space= (class cl_address_space *)as;
+ else
+ address_space= 0;
+ if (chip && (chip->is_chip()))
+ memchip= (class cl_memory_chip *)chip;
+ else
+ memchip= 0;
+ as_begin= asb;
+ as_end= ase;
+ chip_begin= cb;
+ activated= false;
+}
+
+cl_address_decoder::~cl_address_decoder(void)
+{
+ t_addr a;
+ if (address_space)
+ for (a= as_begin; a <= as_end; a++)
+ address_space->undecode_cell(a);
+}
+
+int
+cl_address_decoder::init(void)
+{
+ return(0);
+}
+
+
+bool
+cl_address_decoder::activate(class cl_console_base *con)
+{
+#define D if (con) con->debug
+ //#define D printf
+ D("Activation of an address decoder %s (%s[%06lx-%06lx]\n", get_name(""), address_space->get_name(), as_begin, as_end);
+ if (activated)
+ {
+ D("Already activated\n");
+ return(false);
+ }
+ if (!address_space ||
+ !address_space->is_address_space())
+ {
+ D("No or non address space\n");
+ return(false);
+ }
+ if (!memchip ||
+ !memchip->is_chip())
+ {
+ D("No or non memory chip\n");
+ return(false);
+ }
+ if (as_begin > as_end)
+ {
+ D("Wrong address area specification\n");
+ return(false);
+ }
+ if (chip_begin >= memchip->get_size())
+ {
+ D("Wrong chip area specification\n");
+ return(false);
+ }
+ if (as_begin < address_space->start_address ||
+ as_end >= address_space->start_address + address_space->get_size())
+ {
+ D("Specified area is out of address space\n");
+ return(false);
+ }
+ if (as_end-as_begin > memchip->get_size()-chip_begin)
+ {
+ D("Specified area is out of chip size\n");
+ return(false);
+ }
+
+ address_space->undecode_area(this, as_begin, as_end, con);
+
+ D("Decoder maps %s[%06lx-%06lx] -> %s[%06lx]...\n",address_space->get_name(),as_begin,as_end,memchip->get_name(),chip_begin);
+ t_addr asa, ca;
+ for (asa= as_begin, ca= chip_begin;
+ asa <= as_end;
+ asa++, ca++)
+ {
+ if (!address_space->decode_cell(asa, memchip, ca))
+ {
+ D("Decoding 0x%06lx->0x%06lx failed\n", asa, ca);
+ }
+ }
+ activated= true;
+
+#undef D
+ return(activated);
+}
+
+/* Check if this DEC is fully within the specified area
+
+ as_begin....................as_end
+ ^ ^
+ begin end
+
+*/
+
+bool
+cl_address_decoder::fully_covered_by(t_addr begin, t_addr end)
+{
+ if (begin <= as_begin &&
+ end >= as_end)
+ return(true);
+ return(false);
+}
+
+/* Check if some part of this DEC is in the specified area:
+
+ as_begin......................as_end
+ ^ ^
+ begin end
+
+ as_begin......................as_end
+^ ^
+begin end
+
+*/
+
+bool
+cl_address_decoder::is_in(t_addr begin, t_addr end)
+{
+ if (begin >= as_begin &&
+ begin <= as_end)
+ return(true);
+ if (end >= as_begin &&
+ end <= as_end)
+ return(true);
+ return(false);
+}
+
+/* Check if this DEC covers the specified area:
+
+ as_begin....................as_end
+ ^ ^
+ begin end
+
+*/
+
+bool
+cl_address_decoder::covers(t_addr begin, t_addr end)
+{
+ if (begin >= as_begin &&
+ end <= as_end)
+ return(true);
+ return(false);
+}
+
+
+/* Returns TRUE if shrunken decoder is unnecessary */
+
+bool
+cl_address_decoder::shrink_out_of(t_addr begin, t_addr end)
+{
+ t_addr a= as_begin;
+
+ if (!address_space)
+ return(true);
+ if (begin > a)
+ a= begin;
+ while (a <= end &&
+ a <= as_end)
+ {
+ address_space->undecode_cell(a);
+ a++;
+ }
+ if (begin > as_begin)
+ as_end= begin-1;
+ if (as_end > end)
+ {
+ chip_begin+= (end-as_begin+1);
+ as_begin= end+1;
+ }
+ if (as_end < as_begin)
+ return(true);
+ return(false);
+}
+
+class cl_address_decoder *
+cl_address_decoder::split(t_addr begin, t_addr end)
+{
+ class cl_address_decoder *nd= 0;
+ if (begin > as_begin)
+ {
+ if (as_end > end)
+ nd= new cl_address_decoder(address_space, memchip,
+ end+1, as_end, chip_begin+(end-as_begin)+1);
+ shrink_out_of(begin, as_end);
+ }
+ else if (end < as_end)
+ {
+ if (as_begin < begin)
+ nd= new cl_address_decoder(address_space, memchip,
+ as_begin, begin-1, chip_begin);
+ shrink_out_of(as_begin, end);
+ }
+ if (nd)
+ nd->init();
+ return(nd);
+}
+
+void
+cl_address_decoder::print_info(chars pre, class cl_console_base *con)
+{
+ if (address_space &&
+ address_space->hidden)
+ return;
+ if (memchip &&
+ memchip->hidden)
+ return;
+ con->dd_printf(pre);
+ if (address_space)
+ {
+ con->dd_printf("%s ", address_space->get_name("unknown"));
+ con->dd_printf(address_space->addr_format, as_begin);
+ con->dd_printf(" ");
+ con->dd_printf(address_space->addr_format, as_end);
+ }
+ else
+ con->dd_printf("x");
+ con->dd_printf(" -> ");
+ if (memchip)
+ {
+ con->dd_printf("%s ", memchip->get_name("unknown"));
+ con->dd_printf(memchip->addr_format, chip_begin);
+ }
+ else
+ con->dd_printf("x");
+ con->dd_printf(" %s\n", (activated)?"activated":"inactive");
+}
+
+
+/*
+ * Bank switcher
+ */
+
+cl_banker::cl_banker(class cl_address_space *the_banker_as,
+ t_addr the_banker_addr,
+ t_mem the_banker_mask,
+ //int the_banker_shift,
+ class cl_address_space *the_as,
+ t_addr the_asb,
+ t_addr the_ase):
+ cl_address_decoder(the_as, NULL, the_asb, the_ase, (t_addr)-1)
+{
+ banker_as= the_banker_as;
+ banker_addr= the_banker_addr;
+ banker_mask= the_banker_mask;
+ //banker_shift= the_banker_shift;
+ banker2_as= NULL;
+ banker2_addr= 0;
+ banker2_mask= 0;
+ banker2_shift= 0;
+ nuof_banks= 0;
+ banks= 0;
+ //bank_ptrs= 0;
+ bank= -1;
+}
+
+cl_banker::cl_banker(class cl_address_space *the_banker_as,
+ t_addr the_banker_addr,
+ t_mem the_banker_mask,
+ //int the_banker_shift,
+ class cl_address_space *the_banker2_as,
+ t_addr the_banker2_addr,
+ t_mem the_banker2_mask,
+ int the_banker2_shift,
+ class cl_address_space *the_as,
+ t_addr the_asb,
+ t_addr the_ase):
+ cl_address_decoder(the_as, NULL, the_asb, the_ase, (t_addr)-1)
+{
+ banker_as= the_banker_as;
+ banker_addr= the_banker_addr;
+ banker_mask= the_banker_mask;
+ //banker_shift= the_banker_shift;
+ banker2_as= the_banker2_as;
+ banker2_addr= the_banker2_addr;
+ banker2_mask= the_banker2_mask;
+ banker2_shift= the_banker2_shift;
+ nuof_banks= 0;
+ banks= 0;
+ //bank_ptrs= 0;
+ bank= -1;
+}
+
+int
+cl_banker::init()
+{
+ int m= banker_mask;
+ int b, b2;
+
+ shift_by= 0;
+ shift2_by= 0;
+ if (m == 0)
+ nuof_banks= 0;
+ else
+ {
+ while ((m&1) == 0)
+ m>>= 1, shift_by++;
+ b= 1;
+ m>>= 1;
+ while ((m&1) != 0)
+ {
+ m>>= 1;
+ b++;
+ }
+ nuof_banks= 1 << b;
+ }
+ shift2_by= 0;
+ if (banker2_as &&
+ banker2_mask)
+ {
+ m= banker2_mask;
+ while ((m&1) == 0)
+ m>>=1, shift2_by++;
+ b2= 1;
+ m>>= 1;
+ while ((m&1) != 0)
+ m>>= 1, b2++;
+ if (b2)
+ nuof_banks*= (1 << b2);
+ }
+ if (nuof_banks > 0)
+ {
+ banks= (class cl_address_decoder **)malloc(nuof_banks * sizeof(class cl_address_decoder *));
+ //bank_ptrs= (t_mem **)calloc(nuof_banks*(as_end-as_begin+1), sizeof(t_mem *));
+ for (b= 0; b < nuof_banks; b++)
+ {
+ banks[b]= NULL;
+ }
+ }
+
+ class cl_memory_cell *c= banker_as->get_cell(banker_addr);
+ if (c)
+ {
+ class cl_bank_switcher_operator *o=
+ new cl_bank_switcher_operator(c/*, banker_addr*/, this);
+ c->prepend_operator(o);
+ }
+ if (banker2_as &&
+ banker2_mask)
+ {
+ c= banker2_as->get_cell(banker2_addr);
+ if (c)
+ {
+ class cl_bank_switcher_operator *o=
+ new cl_bank_switcher_operator(c/*, banker_addr*/, this);
+ c->prepend_operator(o);
+ }
+ }
+ return 0;
+}
+
+cl_banker::~cl_banker()
+{
+ int i;
+ if (banks)
+ {
+ for (i= 0; i < nuof_banks; i++)
+ {
+ if (banks[i])
+ delete banks[i];
+ }
+ free(banks);
+ }
+ //if (bank_ptrs) free(bank_ptrs);
+}
+
+void
+cl_banker::add_bank(int bank_nr, class cl_memory *chip, t_addr chip_start)
+{
+ if (!chip)
+ return;
+ if (!address_space)
+ return;
+ if (!chip->is_chip())
+ return;
+
+ if (bank_nr >= nuof_banks)
+ return;
+
+ class cl_address_decoder *ad= new cl_address_decoder(address_space,
+ chip,
+ as_begin, as_end,
+ chip_start);
+ ad->init();
+ if (banks[bank_nr])
+ {
+ delete banks[bank_nr];
+ banks[bank_nr]= 0;
+ }
+ banks[bank_nr]= ad;
+ /*
+ t_addr a, s, i;
+ s= as_end - as_begin + 1;
+ for (i= 0; i < s; i++)
+ {
+ a= chip_start + i;
+ //bank_ptrs[bank_nr*s + i]= ad->memchip->get_slot(a);
+ }
+ */
+ activate(0);
+}
+
+t_mem
+cl_banker::actual_bank()
+{
+ //t_mem m= banker_mask;
+ t_mem v= banker_as->read(banker_addr) & banker_mask;
+ t_mem v2;
+
+ v= (v >> shift_by);
+ if (banker2_as &&
+ banker2_mask)
+ {
+ v2= banker2_as->read(banker2_addr) & banker2_mask;
+ v2>>= shift2_by;
+ v2= v2 << banker2_shift;
+ v= v | v2;
+ }
+ return v;
+}
+
+bool
+cl_banker::activate(class cl_console_base *con)
+{
+ int b= actual_bank();
+ t_addr i, s;
+ t_mem *data;
+ class cl_memory_cell *c;
+
+ if (b == bank)
+ return true;
+ if (banks[b] == NULL)
+ return true;
+ s= as_end - as_begin + 1;
+ for (i= 0; i < s; i++)
+ {
+ t_addr ca= banks[b]->chip_begin + i;
+ data= banks[b]->memchip->get_slot(ca);
+ c= address_space->get_cell(as_begin+i);
+ c->decode(data);
+ }
+ bank= b;
+
+ return true;
+}
+
+bool
+cl_banker::switch_to(int bank_nr, class cl_console_base *con)
+{
+ int b= bank_nr;//actual_bank();
+ t_addr i, s;
+ t_mem *data;
+ class cl_memory_cell *c;
+
+ if (b == bank)
+ return true;
+ if (banks[b] == NULL)
+ return true;
+ s= as_end - as_begin + 1;
+ for (i= 0; i < s; i++)
+ {
+ t_addr ca= banks[b]->chip_begin + i;
+ data= banks[b]->memchip->get_slot(ca);
+ c= address_space->get_cell(as_begin+i);
+ c->decode(data);
+ }
+ bank= b;
+
+ return true;
+}
+
+void
+cl_banker::print_info(chars pre, class cl_console_base *con)
+{
+ int b;
+ con->dd_printf(pre);
+ //con->dd_printf(" banked area= ");
+ if (address_space)
+ {
+ con->dd_printf("%s ", address_space->get_name("unknown"));
+ con->dd_printf(address_space->addr_format, as_begin);
+ con->dd_printf(" ");
+ con->dd_printf(address_space->addr_format, as_end);
+ }
+ else
+ con->dd_printf("x");
+ con->dd_printf(" -> banked\n");
+
+ con->dd_printf(pre);
+ con->dd_printf(" bank selector: %s[", banker_as->get_name("unknown"));
+ con->dd_printf(banker_as->addr_format, banker_addr);
+ con->dd_printf("] mask=0x%x banks=%d act=%d\n",
+ banker_mask, nuof_banks,
+ b= actual_bank());
+
+ con->dd_printf(pre);
+ con->dd_printf(" banks:\n");
+
+ class cl_address_decoder *dc;
+ int i;
+ for (i= 0; i < nuof_banks; i++)
+ {
+ dc= (class cl_address_decoder *)(banks[i]);
+ con->dd_printf(pre);
+ con->dd_printf(" %c %2d. ", (b==i)?'*':' ', i);
+ if (dc)
+ {
+ if (dc->memchip)
+ {
+ con->dd_printf("%s ", dc->memchip->get_name("unknown"));
+ con->dd_printf(dc->memchip->addr_format, dc->chip_begin);
+ }
+ else
+ con->dd_printf("x");
+ }
+ else
+ con->dd_printf("-");
+ con->dd_printf("\n");
+ }
+}
+
+
+/*
+ * Bit bander
+ */
+
+cl_bander::cl_bander(class cl_address_space *the_as,
+ t_addr the_asb,
+ t_addr the_ase,
+ class cl_memory *the_chip,
+ t_addr the_cb,
+ int the_bpc,
+ int the_distance):
+ cl_address_decoder(the_as, the_chip, the_asb, the_ase, the_cb)
+{
+ bpc= the_bpc;
+ distance= the_distance;
+}
+
+bool
+cl_bander::activate(class cl_console_base *con)
+{
+ address_space->undecode_area(this, as_begin, as_end, con);
+
+ t_addr asa, ca;
+ int b, m;
+ for (asa= as_begin, ca= chip_begin, b= 0, m= 1;
+ asa <= as_end;
+ asa++)
+ {
+ if (b >= bpc)
+ {
+ ca+= distance;
+ b= 0;
+ m= 1;
+ }
+ t_mem *slot= memchip->get_slot(ca);
+ cl_memory_cell *c= address_space->get_cell(asa);
+ c->decode(slot, m);
+ b++;
+ m<<= 1;
+ }
+ return activated= true;
+}
+
+void
+cl_bander::print_info(chars pre, class cl_console_base *con)
+{
+ if (address_space &&
+ address_space->hidden)
+ return;
+ if (memchip &&
+ memchip->hidden)
+ return;
+ con->dd_printf(pre);
+ if (address_space)
+ {
+ con->dd_printf("%s ", address_space->get_name("unknown"));
+ con->dd_printf(address_space->addr_format, as_begin);
+ con->dd_printf(" ");
+ con->dd_printf(address_space->addr_format, as_end);
+ }
+ else
+ con->dd_printf("x");
+ con->dd_printf(" -> bander(%d/%d) ", bpc, distance);
+ if (memchip)
+ {
+ con->dd_printf("%s ", memchip->get_name("unknown"));
+ con->dd_printf(memchip->addr_format, chip_begin);
+ }
+ else
+ con->dd_printf("x");
+ con->dd_printf(" %s\n", (activated)?"activated":"inactive");
+}
+
+
+/*
+ * List of address decoders
+ */
+
+cl_decoder_list::cl_decoder_list(t_index alimit, t_index adelta, bool bychip):
+ cl_sorted_list(alimit, adelta, "decoder list")
+{
+ Duplicates= true;
+ by_chip= bychip;
+}
+
+void *
+cl_decoder_list::key_of(void *item)
+{
+ class cl_address_decoder *d= (class cl_address_decoder *)item;
+ if (by_chip)
+ return(&(d->chip_begin));
+ else
+ return(&(d->as_begin));
+}
+
+int
+cl_decoder_list::compare(void *key1, void *key2)
+{
+ t_addr k1= *((t_addr*)key1), k2= *((t_addr*)key2);
+ if (k1 == k2)
+ return(0);
+ else if (k1 > k2)
+ return(1);
+ return(-1);
+}
+
+
+/*
+ * Errors in memory handling
+ */
+
+/* All of memory errors */
+
+cl_error_mem::cl_error_mem(class cl_memory *amem, t_addr aaddr)
+{
+ mem= amem;
+ addr= aaddr;
+ classification= mem_error_registry.find("memory");
+}
+
+/* Invalid address in memory access */
+
+cl_error_mem_invalid_address::
+cl_error_mem_invalid_address(class cl_memory *amem, t_addr aaddr):
+ cl_error_mem(amem, aaddr)
+{
+ classification= mem_error_registry.find("invalid_address");
+}
+
+void
+cl_error_mem_invalid_address::print(class cl_commander_base *c)
+{
+ //FILE *f= c->get_fout();
+ /*cmd_fprintf(f,*/c->dd_printf("%s: invalid address ", get_type_name());
+ /*cmd_fprintf(f,*/c->dd_printf(mem->addr_format, addr);
+ /*cmd_fprintf(f,*/c->dd_printf(" in memory %s.\n", mem->get_name());
+}
+
+/* Non-decoded address space access */
+
+cl_error_mem_non_decoded::
+cl_error_mem_non_decoded(class cl_memory *amem, t_addr aaddr):
+ cl_error_mem(amem, aaddr)
+{
+ classification= mem_error_registry.find("non_decoded");
+}
+
+void
+cl_error_mem_non_decoded::print(class cl_commander_base *c)
+{
+ //FILE *f= c->get_fout();
+ /*cmd_fprintf(f,*/c->dd_printf("%s: access of non-decoded address ", get_type_name());
+ /*cmd_fprintf(f,*/c->dd_printf(mem->addr_format, addr);
+ /*cmd_fprintf(f,*/c->dd_printf(" in memory %s.\n", mem->get_name());
+}
+
+cl_mem_error_registry::cl_mem_error_registry(void)
+{
+ class cl_error_class *prev = mem_error_registry.find("non-classified");
+ prev = register_error(new cl_error_class(err_error, "memory", prev, ERROR_OFF));
+ prev = register_error(new cl_error_class(err_error, "invalid_address", prev));
+ prev = register_error(new cl_error_class(err_error, "non_decoded", prev));
+}
+
+/* End of mem.cc */
diff --git a/sim/ucsim/sim.src/mem.o b/sim/ucsim/sim.src/mem.o
new file mode 100644
index 0000000..fb791bc
--- /dev/null
+++ b/sim/ucsim/sim.src/mem.o
Binary files differ
diff --git a/sim/ucsim/sim.src/memcl.h b/sim/ucsim/sim.src/memcl.h
new file mode 100644
index 0000000..415ac2a
--- /dev/null
+++ b/sim/ucsim/sim.src/memcl.h
@@ -0,0 +1,644 @@
+/*
+ * Simulator of microcontrollers (sim.src/memcl.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 SIM_MEMCL_HEADER
+#define SIM_MEMCL_HEADER
+
+#include <stdio.h>
+
+#include "ddconfig.h"
+
+// prj
+#include "stypes.h"
+#include "pobjcl.h"
+
+// gui.src
+#include "guiobjcl.h"
+
+
+class cl_event_handler;
+
+// Cell flags
+enum cell_flag {
+ CELL_NONE = 0x00,
+ CELL_VAR = 0x01, /* At least one variable points to it */
+ CELL_INST = 0x04, /* Marked as instruction */
+ CELL_FETCH_BRK = 0x08, /* Fetch breakpoint */
+ CELL_READ_ONLY = 0x10, /* Cell is readonly */
+ CELL_NON_DECODED = 0x40 /* Cell is not decoded (yet) */
+};
+
+enum dump_format {
+ // main formats
+ df_format = 0x000f,
+ df_hex = 0x0001,
+ df_string = 0x0002,
+ df_ihex = 0x0003,
+ df_binary = 0x0004,
+ // modifiers
+ df_data_size = 0x00f0,
+ df_1 = 0x0010,
+ df_2 = 0x0020,
+ df_4 = 0x0040,
+ df_8 = 0x0080,
+ // endianes
+ df_endian = 0x0100,
+ df_little = 0x0000,
+ df_big = 0x0100,
+};
+
+#define CELL_GENERAL (CELL_NORMAL|CELL_INST|CELL_FETCH_BRK)
+
+
+/*
+ * 3rd version of memory system
+ */
+
+class cl_memory: public cl_base
+{
+public:
+ t_addr start_address;
+protected:
+ class cl_uc *uc;
+ t_addr size;
+public:
+ char *addr_format, *data_format;
+ int width; // in bits
+ t_mem data_mask;
+ bool hidden;
+protected:
+ t_addr dump_finished;
+public:
+ cl_memory(const char *id, t_addr asize, int awidth);
+ virtual ~cl_memory(void);
+ virtual int init(void);
+
+ t_addr get_start_address(void) { return(start_address); }
+ t_addr get_size(void) { return(size); }
+ virtual void set_uc(class cl_uc *auc) { uc= auc; }
+ virtual bool valid_address(t_addr addr);
+ virtual t_addr inc_address(t_addr addr, int val);
+ virtual t_addr inc_address(t_addr addr);
+ virtual t_addr validate_address(t_addr addr);
+
+ virtual bool is_chip(void) { return(false); }
+ virtual bool is_address_space(void) { return(false); }
+
+ virtual void err_inv_addr(t_addr addr);
+ virtual void err_non_decoded(t_addr addr);
+
+ virtual t_addr dump(t_addr start, t_addr stop, int bpl, /*class cl_f *f*/class cl_console_base *con);
+ virtual t_addr dump_s(t_addr start, t_addr stop, int bpl, /*class cl_f *f*/class cl_console_base *con);
+ virtual t_addr dump_b(t_addr start, t_addr stop, int bpl, /*class cl_f *f*/class cl_console_base *con);
+ virtual t_addr dump_i(t_addr start, t_addr stop, int bpl, /*class cl_f *f*/class cl_console_base *con);
+ virtual t_addr dump(/*class cl_f *f*/class cl_console_base *con);
+ virtual t_addr dump(enum dump_format fmt,
+ t_addr start, t_addr stop, int bpl,
+ /*class cl_f *f*/class cl_console_base *con);
+ virtual bool search_next(bool case_sensitive,
+ t_mem *array, int len, t_addr *addr);
+
+
+ virtual t_addr lowest_valid_address(void) { return(start_address); }
+ virtual t_addr highest_valid_address(void) { return(start_address+size-1); }
+
+ virtual t_mem read(t_addr addr)=0;
+ virtual t_mem read(t_addr addr, enum hw_cath skip)=0;
+ virtual t_mem get(t_addr addr)=0;
+ virtual t_mem write(t_addr addr, t_mem val)=0;
+ virtual void set(t_addr addr, t_mem val)=0;
+ virtual void set_bit1(t_addr addr, t_mem bits)=0;
+ virtual void set_bit0(t_addr addr, t_mem bits)=0;
+
+ virtual void print_info(chars pre, class cl_console_base *con);
+};
+
+
+/*
+ * Operators for memory cells
+ */
+
+class cl_banker;
+
+class cl_memory_operator: public cl_base
+{
+protected:
+ //t_addr address;
+ t_mem mask;
+ class cl_memory_operator *next_operator;
+ class cl_memory_cell *cell;
+public:
+ cl_memory_operator(class cl_memory_cell *acell/*, t_addr addr*/);
+
+ virtual class cl_memory_operator *get_next(void) { return(next_operator); }
+ virtual void set_next(class cl_memory_operator *next) { next_operator= next;}
+
+ virtual bool match(class cl_hw *the_hw) { return(false); }
+ virtual bool match(class cl_brk *brk) { return(false); }
+
+ virtual t_mem read(void);
+ virtual t_mem read(enum hw_cath skip) { return(read()); }
+ virtual t_mem write(t_mem val);
+
+ virtual class cl_banker *get_banker(void) { return NULL; }
+};
+
+class cl_bank_switcher_operator: public cl_memory_operator
+{
+ protected:
+ class cl_banker *banker;
+ public:
+ cl_bank_switcher_operator(class cl_memory_cell *acell/*, t_addr addr*/,
+ class cl_banker *the_banker);
+
+ virtual t_mem write(t_mem val);
+ virtual class cl_banker *get_banker(void) { return banker; }
+};
+
+class cl_hw_operator: public cl_memory_operator
+{
+protected:
+ class cl_hw *hw;
+public:
+ cl_hw_operator(class cl_memory_cell *acell/*, t_addr addr*/,
+ /*t_mem *data_place, t_mem the_mask,*/ class cl_hw *ahw);
+
+ virtual bool match(class cl_hw *the_hw) { return(hw == the_hw); }
+
+ virtual t_mem read(void);
+ virtual t_mem read(enum hw_cath skip);
+ virtual t_mem write(t_mem val);
+};
+
+class cl_event_break_operator: public cl_memory_operator
+{
+protected:
+ class cl_uc *uc;
+ class cl_brk *bp;
+public:
+ cl_event_break_operator(class cl_memory_cell *acell/*, t_addr addr*/,
+ class cl_uc *auc, class cl_brk *the_bp):
+ cl_memory_operator(acell/*, addr*/)
+ {
+ uc= auc;
+ bp= the_bp;
+ }
+
+ virtual bool match(class cl_brk *brk) { return(bp == brk); }
+};
+
+class cl_write_operator: public cl_event_break_operator
+{
+public:
+ cl_write_operator(class cl_memory_cell *acell/*, t_addr addr*/,
+ class cl_uc *auc, class cl_brk *the_bp);
+
+ virtual t_mem write(t_mem val);
+};
+
+class cl_read_operator: public cl_event_break_operator
+{
+public:
+ cl_read_operator(class cl_memory_cell *acell/*, t_addr addr*/,
+ class cl_uc *auc, class cl_brk *the_bp);
+
+ virtual t_mem read(void);
+};
+
+
+/*
+ * version 3 of cell
+ */
+
+class cl_cell_data: public cl_abs_base
+{
+ protected:
+ t_mem *data;
+ virtual t_mem d();
+ virtual void d(t_mem v);
+ virtual void dl(t_mem v);
+};
+
+class cl_memory_cell: public cl_cell_data
+{
+#ifdef STATISTIC
+ public:
+ unsigned long nuof_writes, nuof_reads;
+#endif
+ public:
+ t_mem mask;
+ t_mem def_data;
+ protected:
+ uchar width;
+ /*TYPE_UBYTE*/uchar flags;
+ class cl_memory_operator *operators;
+ public:
+ cl_memory_cell(uchar awidth);
+ virtual ~cl_memory_cell(void);
+ virtual int init(void);
+
+ virtual t_mem *get_data(void) { return(data); }
+ virtual t_mem get_mask(void) { return(mask); }
+ virtual void set_mask(t_mem m) { mask= m; }
+ virtual /*TYPE_UBYTE*/uchar get_flags(void);
+ virtual bool get_flag(enum cell_flag flag);
+ virtual void set_flags(/*TYPE_UBYTE*/uchar what);
+ virtual void set_flag(enum cell_flag flag, bool val);
+ virtual uchar get_width(void) { return width; }
+
+ virtual void un_decode(void);
+ virtual void decode(class cl_memory_chip *chip, t_addr addr);
+ virtual void decode(t_mem *data_ptr);
+ virtual void decode(t_mem *data_ptr, t_mem bit_mask);
+
+ virtual t_mem read(void);
+ virtual t_mem read(enum hw_cath skip);
+ virtual t_mem get(void);
+ virtual t_mem write(t_mem val);
+ virtual t_mem set(t_mem val);
+ virtual t_mem download(t_mem val);
+
+ virtual t_mem add(long what);
+ virtual t_mem wadd(long what);
+
+ virtual void set_bit1(t_mem bits);
+ virtual void write_bit1(t_mem bits);
+ virtual void set_bit0(t_mem bits);
+ virtual void write_bit0(t_mem bits);
+ virtual void toggle_bits(t_mem bits);
+ virtual void wtoggle_bits(t_mem bits);
+
+ virtual void append_operator(class cl_memory_operator *op);
+ virtual void prepend_operator(class cl_memory_operator *op);
+ virtual void del_operator(class cl_brk *brk);
+ virtual void del_operator(class cl_hw *hw);
+ virtual class cl_banker *get_banker(void);
+
+ virtual class cl_memory_cell *add_hw(class cl_hw *hw/*, t_addr addr*/);
+ virtual void remove_hw(class cl_hw *hw);
+ virtual class cl_event_handler *get_event_handler(void);
+
+ virtual void print_info(chars pre, class cl_console_base *con);
+ virtual void print_operators(cchars pre, class cl_console_base *con);
+};
+
+class cl_bit_cell: public cl_memory_cell
+{
+ public:
+ cl_bit_cell(uchar awidth): cl_memory_cell(awidth) {}
+ virtual t_mem d();
+ virtual void d(t_mem v);
+};
+
+class cl_cell8: public cl_memory_cell
+{
+ public:
+ cl_cell8(uchar awidth): cl_memory_cell(awidth) {}
+ virtual t_mem d();
+ virtual void d(t_mem v);
+};
+
+class cl_bit_cell8: public cl_memory_cell
+{
+ public:
+ cl_bit_cell8(uchar awidth): cl_memory_cell(awidth) {}
+ virtual t_mem d();
+ virtual void d(t_mem v);
+};
+
+class cl_cell16: public cl_memory_cell
+{
+ public:
+ cl_cell16(uchar awidth): cl_memory_cell(awidth) {}
+ virtual t_mem d();
+ virtual void d(t_mem v);
+};
+
+class cl_bit_cell16: public cl_memory_cell
+{
+ public:
+ cl_bit_cell16(uchar awidth): cl_memory_cell(awidth) {}
+ virtual t_mem d();
+ virtual void d(t_mem v);
+};
+
+
+class cl_dummy_cell: public cl_memory_cell
+{
+public:
+ cl_dummy_cell(uchar awidth): cl_memory_cell(awidth) {}
+
+ virtual t_mem write(t_mem val);
+ virtual t_mem set(t_mem val);
+};
+
+
+/*
+ * Address space
+ */
+
+class cl_memory_chip;
+
+class cl_address_space: public cl_memory
+{
+ public:
+ class cl_memory_cell /* **cells,*/ *dummy;
+ protected:
+ class cl_memory_cell *cella;
+ public:
+ class cl_decoder_list *decoders;
+ public:
+ cl_address_space(const char *id, t_addr astart, t_addr asize, int awidth);
+ virtual ~cl_address_space(void);
+
+ virtual bool is_address_space(void) { return(true); }
+
+ virtual t_mem read(t_addr addr);
+ virtual t_mem read(t_addr addr, enum hw_cath skip);
+ virtual t_mem get(t_addr addr);
+ virtual t_mem write(t_addr addr, t_mem val);
+ virtual void set(t_addr addr, t_mem val);
+ virtual void download(t_addr, t_mem val);
+
+ virtual t_mem wadd(t_addr addr, long what);
+ virtual void set_bit1(t_addr addr, t_mem bits);
+ virtual void set_bit0(t_addr addr, t_mem bits);
+
+ virtual class cl_memory_cell *get_cell(t_addr addr);
+ virtual int get_cell_flag(t_addr addr);
+ virtual bool get_cell_flag(t_addr addr, enum cell_flag flag);
+ virtual void set_cell_flag(t_addr addr, bool set_to, enum cell_flag flag);
+ virtual void set_cell_flag(t_addr start_addr, t_addr end_addr, bool set_to, enum cell_flag flag);
+ virtual class cl_memory_cell *search_cell(enum cell_flag flag, bool value,
+ t_addr *addr);
+ virtual bool is_owned(class cl_memory_cell *cell, t_addr *addr);
+
+ virtual class cl_address_decoder *get_decoder_of(t_addr addr);
+ virtual bool decode_cell(t_addr addr,
+ class cl_memory_chip *chip, t_addr chipaddr);
+ virtual void undecode_cell(t_addr addr);
+ virtual void undecode_area(class cl_address_decoder *skip,
+ t_addr begin, t_addr end, class cl_console_base *con);
+
+ virtual class cl_memory_cell *register_hw(t_addr addr, class cl_hw *hw,
+ bool announce);
+ virtual void unregister_hw(class cl_hw *hw);
+
+ virtual void set_brk(t_addr addr, class cl_brk *brk);
+ virtual void del_brk(t_addr addr, class cl_brk *brk);
+
+#ifdef STATISTIC
+ virtual unsigned long get_nuof_reads(void) { return(0); }
+ virtual unsigned long get_nuof_writes(void) { return(0); }
+ virtual void set_nuof_reads(unsigned long value) {}
+ virtual void set_nuof_writes(unsigned long value) {}
+#endif
+
+ virtual void print_info(chars pre, class cl_console_base *con);
+};
+
+class cl_address_space_list: public cl_list
+{
+protected:
+ class cl_uc *uc;
+public:
+ cl_address_space_list(class cl_uc *the_uc);
+ virtual t_index add(class cl_address_space *mem);
+};
+
+
+/*
+ * Memory chip (storage)
+ */
+
+class cl_memory_chip: public cl_memory
+{
+protected:
+ t_mem *array;
+ int init_value;
+ bool array_is_mine;
+public:
+ cl_memory_chip(const char *id, int asize, int awidth, int initial= -1);
+ cl_memory_chip(const char *id, int asize, int awidth, t_mem *aarray);
+ virtual ~cl_memory_chip(void);
+ virtual int init(void);
+
+ virtual bool is_chip(void) { return(true); }
+
+ virtual t_mem *get_slot(t_addr addr);
+ virtual t_addr is_slot(t_mem *data_ptr);
+
+ virtual t_mem read(t_addr addr) { return(get(addr)); }
+ virtual t_mem read(t_addr addr, enum hw_cath skip) { return(get(addr)); }
+ virtual t_mem get(t_addr addr);
+ virtual t_mem write(t_addr addr, t_mem val) { set(addr, val); return(val); }
+ virtual void set(t_addr addr, t_mem val);
+ virtual void set_bit1(t_addr addr, t_mem bits);
+ virtual void set_bit0(t_addr addr, t_mem bits);
+
+ virtual void print_info(chars pre, class cl_console_base *con);
+};
+
+
+/*
+ * Address decoder
+ */
+
+class cl_address_decoder: public cl_base
+{
+public:
+ class cl_address_space *address_space;
+ class cl_memory_chip *memchip;
+ t_addr as_begin, as_end;
+ t_addr chip_begin;
+ bool activated;
+public:
+ cl_address_decoder(class cl_memory *as, class cl_memory *chip,
+ t_addr asb, t_addr ase, t_addr cb);
+ virtual ~cl_address_decoder(void);
+ virtual int init(void);
+ virtual bool is_banker() { return false; }
+ virtual bool is_bander() { return false; }
+
+ virtual bool activate(class cl_console_base *con);
+
+ virtual bool fully_covered_by(t_addr begin, t_addr end);
+ virtual bool is_in(t_addr begin, t_addr end);
+ virtual bool covers(t_addr begin, t_addr end);
+
+ virtual bool shrink_out_of(t_addr begin, t_addr end);
+ virtual class cl_address_decoder *split(t_addr begin, t_addr end);
+
+ virtual void print_info(chars pre, class cl_console_base *con);
+};
+
+
+/*
+ * Address decoder with bank switching support
+ */
+
+class cl_banker: public cl_address_decoder
+{
+ protected:
+ class cl_address_space *banker_as, *banker2_as;
+ t_addr banker_addr, banker2_addr;
+ t_mem banker_mask, banker2_mask;
+ //int banker_shift;
+ int banker2_shift;
+ int nuof_banks;
+ int bank;
+ class cl_address_decoder **banks;
+ int shift_by, shift2_by;
+ public:
+ cl_banker(class cl_address_space *the_banker_as,
+ t_addr the_banker_addr,
+ t_mem the_banker_mask,
+ //int the_banker_shift,
+ class cl_address_space *the_as,
+ t_addr the_asb,
+ t_addr the_ase);
+ cl_banker(class cl_address_space *the_banker_as,
+ t_addr the_banker_addr,
+ t_mem the_banker_mask,
+ //int the_banker_shift,
+ class cl_address_space *the_banker2_as,
+ t_addr the_banker2_addr,
+ t_mem the_banker2_mask,
+ int the_banker2_shift,
+ class cl_address_space *the_as,
+ t_addr the_asb,
+ t_addr the_ase);
+ virtual ~cl_banker();
+ virtual int init();
+ virtual bool is_banker() { return true; }
+
+ virtual void add_bank(int bank_nr, class cl_memory *chip, t_addr chip_start);
+
+ virtual t_mem actual_bank();
+ virtual bool activate(class cl_console_base *con);
+ virtual bool switch_to(int bank_nr, class cl_console_base *con);
+
+ virtual void print_info(chars pre, class cl_console_base *con);
+};
+
+
+/*
+ * Address decoder which maps to individual bits
+ */
+
+class cl_bander: public cl_address_decoder
+{
+ protected:
+ int bpc; // bits_per_chip
+ int distance; // distance of next chip location
+ public:
+ cl_bander(class cl_address_space *the_as,
+ t_addr the_asb,
+ t_addr the_ase,
+ class cl_memory *the_chip,
+ t_addr the_cb,
+ int the_bpc,
+ int the_distance);
+ public:
+ virtual bool is_bander() { return true; }
+
+ virtual bool activate(class cl_console_base *con);
+ virtual void print_info(chars pre, class cl_console_base *con);
+};
+
+
+/* List of address decoders */
+
+class cl_decoder_list: public cl_sorted_list
+{
+protected:
+ bool by_chip;
+public:
+ cl_decoder_list(t_index alimit, t_index adelta, bool bychip);
+
+ virtual void *key_of(void *item);
+ virtual int compare(void *key1, void *key2);
+};
+
+
+/*
+ * Messages
+ */
+
+#include "eventcl.h"
+
+class cl_event_address_space_added: public cl_event
+{
+public:
+ class cl_address_space *as;
+ cl_event_address_space_added(class cl_address_space *the_as):
+ cl_event(ev_address_space_added)
+ { as= the_as; }
+};
+
+
+/*
+ * Errors in memory handling
+ */
+
+#include "errorcl.h"
+
+class cl_error_mem: public cl_error
+{
+protected:
+ class cl_memory *mem;
+ t_addr addr;
+public:
+ cl_error_mem(class cl_memory *amem, t_addr aaddr);
+};
+
+class cl_error_mem_invalid_address: public cl_error_mem
+{
+public:
+ cl_error_mem_invalid_address(class cl_memory *amem, t_addr aaddr);
+
+ virtual void print(class cl_commander_base *c);
+};
+
+ class cl_error_mem_non_decoded: public cl_error_mem
+{
+public:
+ cl_error_mem_non_decoded(class cl_memory *amem, t_addr aaddr);
+
+ virtual void print(class cl_commander_base *c);
+};
+
+class cl_mem_error_registry: public cl_error_registry
+{
+public:
+ cl_mem_error_registry(void);
+};
+
+
+#endif
+
+/* End of memcl.h */
diff --git a/sim/ucsim/sim.src/obsolete.cc b/sim/ucsim/sim.src/obsolete.cc
new file mode 100644
index 0000000..614551c
--- /dev/null
+++ b/sim/ucsim/sim.src/obsolete.cc
@@ -0,0 +1,1360 @@
+/*
+ * Memory location handled specially by a hw element
+ */
+
+/*cl_memloc::cl_memloc(t_addr addr):
+ cl_base()
+{
+ address= addr;
+ hws= new cl_list(2, 2);
+ hws->init();
+}*/
+
+/*cl_memloc::~cl_memloc(void)
+{
+ hws->disconn_all();
+ delete hws;
+}*/
+
+/*ulong
+cl_memloc::read(class cl_mem *mem)
+{
+ uchar ret= 0;
+ class cl_hw *hw;
+
+ if (!hws ||
+ hws->count == 0)
+ return(ret);
+ if ((hw= (class cl_hw *)(hws->at(0))))
+ ret= hw->read(mem, address);
+ return(ret);
+}*/
+
+/*void
+cl_memloc::write(class cl_mem *mem, t_addr addr, t_mem *val)
+{
+ class cl_hw *hw;
+ int i;
+
+ if (!hws)
+ return;
+ for (i= 0; i < hws->count; i++)
+ {
+ hw= (class cl_hw *)hws->at(0);
+ hw->write(mem, addr, val);
+ }
+}*/
+
+
+/* Sorted collection of memory locations */
+
+/*cl_memloc_coll::cl_memloc_coll(void):
+ cl_sorted_list(2, 2)
+{
+ Duplicates= DD_FALSE;
+}*/
+
+/*void *
+cl_memloc_coll::key_of(void *item)
+{
+ return(&(((class cl_memloc *)item)->address));
+}*/
+
+/*int
+cl_memloc_coll::compare(void *key1, void *key2)
+{
+ if (*(long*)key1 > *(long*)key2)
+ return(1);
+ else
+ if (*(long*)key1 < *(long*)key2)
+ return(-1);
+ else
+ return(0);
+}*/
+
+/*class cl_memloc *
+cl_memloc_coll::get_loc(t_addr address)
+{
+ t_index i;
+
+ if (search(&address, i))
+ return((class cl_memloc*)(at(i)));
+ return(0);
+}*/
+
+
+/*
+ * Memory
+ ******************************************************************************
+ */
+
+/*
+ * Bitmap
+ */
+
+/*cl_bitmap::cl_bitmap(t_addr asize):
+ cl_base()
+{
+ map= (uchar*)malloc(size= asize/(8*SIZEOF_CHAR));
+ memset(map, 0, size);
+}
+
+cl_bitmap::~cl_bitmap(void)
+{
+ free(map);
+}
+
+void
+cl_bitmap::set(t_addr pos)
+{
+ int i;
+
+ if ((i= pos/(8*SIZEOF_CHAR)) < size)
+ map[i]|= (1 << (pos & ((8*SIZEOF_CHAR)-1)));
+}
+
+void
+cl_bitmap::clear(t_addr pos)
+{
+ int i;
+
+ if ((i= pos/(8*SIZEOF_CHAR)) < size)
+ map[i]&= ~(1 << (pos & ((8*SIZEOF_CHAR)-1)));
+}
+
+bool
+cl_bitmap::get(t_addr pos)
+{
+ return(map[pos/(8*SIZEOF_CHAR)] & (1 << (pos & ((8*SIZEOF_CHAR)-1))));
+}
+
+bool
+cl_bitmap::empty(void)
+{
+ int i;
+
+ for (i= 0; i < size && map[i] == 0; i++) ;
+ return(i == size);
+}*/
+
+/*
+ * Special memory for code (ROM)
+ */
+
+/*cl_rom::cl_rom(t_addr asize, int awidth, class cl_uc *auc):
+ cl_mem(MEM_ROM, get_id_string(mem_classes, MEM_ROM), asize, awidth, auc)
+{
+ bp_map= new cl_bitmap(asize);
+ inst_map= new cl_bitmap(asize);
+}
+
+cl_rom::~cl_rom(void)
+{
+ delete bp_map;
+ delete inst_map;
+}*/
+
+
+cl_mem::cl_mem(enum mem_class atype, char *aclass_name,
+ t_addr asize, int awidth, class cl_uc *auc):
+ cl_guiobj()
+{
+ int i;
+
+ uc= auc;
+ type= atype;
+ class_name= aclass_name;
+ width= awidth;
+ size= asize;
+ mem= 0;
+ for (i= width, mask= 0; i; i--)
+ mask= (mask<<1) | 1;
+ if (width == 0 ||
+ size == 0)
+ mem= 0;
+ else if (width <= 8)
+ mem= (TYPE_UBYTE *)malloc(size);
+ else if (width <= 16)
+ mem= (TYPE_UWORD *)malloc(size*sizeof(TYPE_WORD));
+ else
+ mem= (TYPE_UDWORD *)malloc(size*sizeof(TYPE_DWORD));
+ //read_locs= new cl_memloc_coll();
+ //write_locs= new cl_memloc_coll();
+ dump_finished= 0;
+ addr_format= data_format= 0;
+}
+
+cl_mem::~cl_mem(void)
+{
+ if (mem)
+ free(mem);
+ if (addr_format)
+ free(addr_format);
+ if (data_format)
+ free(data_format);
+ //delete read_locs;
+ //delete write_locs;
+}
+
+int
+cl_mem::init(void)
+{
+ t_addr i;
+
+ addr_format= (char *)malloc(10);
+ sprintf(addr_format, "0x%%0%dx",
+ size-1<=0xf?1:
+ (size-1<=0xff?2:
+ (size-1<=0xfff?3:
+ (size-1<=0xffff?4:
+ (size-1<=0xfffff?5:
+ (size-1<=0xffffff?6:12))))));
+ data_format= (char *)malloc(10);
+ sprintf(data_format, "%%0%dx", width/4+((width%4)?1:0));
+
+ for (i= 0; i < size; i++)
+ set(i, (type==MEM_ROM)?(-1):0);
+ return(0);
+}
+
+char *
+cl_mem::id_string(void)
+{
+ char *s= get_id_string(mem_ids, type);
+
+ return(s?s:(char*)"NONE");
+}
+
+t_mem
+cl_mem::read(t_addr addr)
+{
+ //class cl_memloc *loc;
+
+ if (addr >= size)
+ {
+ //FIXME
+ fprintf(stderr, "Address 0x%06x is over 0x%06x\n",
+ (int)addr, (int)size);
+ return(0);
+ }
+ /*if ((loc= read_locs->get_loc(addr)))
+ return(loc->read(this));*/
+ if (width <= 8)
+ return((((TYPE_UBYTE*)mem)[addr])&mask);
+ else if (width <= 16)
+ return((((TYPE_UWORD*)mem)[addr])&mask);
+ else
+ return((((TYPE_UDWORD*)mem)[addr])&mask);
+}
+
+t_mem
+cl_mem::get(t_addr addr)
+{
+ if (addr >= size)
+ return(0);
+ if (width <= 8)
+ return((((TYPE_UBYTE*)mem)[addr])&mask);
+ else if (width <= 16)
+ return((((TYPE_UWORD*)mem)[addr])&mask);
+ else
+ return((((TYPE_UDWORD*)mem)[addr])&mask);
+}
+
+
+/*
+ * Modify memory location
+ */
+
+/* Write calls callbacks of HW elements */
+
+t_mem
+cl_mem::write(t_addr addr, t_mem val)
+{
+ /* class cl_memloc *loc;
+
+ if (addr >= size)
+ return;
+ if ((loc= write_locs->get_loc(addr)))
+ loc->write(this, addr, val);
+ if (width <= 8)
+ ((TYPE_UBYTE*)mem)[addr]= (*val)&mask;
+ else if (width <= 16)
+ ((TYPE_UWORD*)mem)[addr]= (*val)&mask;
+ else
+ ((TYPE_UDWORD*)mem)[addr]= (*val)&mask;*/
+ fprintf(stderr, "FIXME cl_mem::write(0x%06x, 0x%04x)\n",
+ (int)addr, (int)val);
+ return(0);
+}
+
+/* Set doesn't call callbacks */
+
+void
+cl_mem::set(t_addr addr, t_mem val)
+{
+ if (addr >= size)
+ return;
+ if (width <= 8)
+ ((TYPE_UBYTE*)mem)[addr]= val&mask;
+ else if (width <= 16)
+ ((TYPE_UWORD*)mem)[addr]= val&mask;
+ else
+ ((TYPE_UDWORD*)mem)[addr]= val&mask;
+}
+
+t_mem
+cl_mem::add(t_addr addr, long what)
+{
+ if (addr >= size)
+ return(0);
+ if (width <= 8)
+ {
+ ((TYPE_UBYTE*)mem)[addr]= ((TYPE_UBYTE*)mem)[addr] + what;
+ return(((TYPE_UBYTE*)mem)[addr]);
+ }
+ else if (width <= 16)
+ {
+ ((TYPE_UWORD*)mem)[addr]= ((TYPE_UWORD*)mem)[addr] + what;
+ return(((TYPE_UWORD*)mem)[addr]);
+ }
+ else
+ {
+ ((TYPE_UDWORD*)mem)[addr]= ((TYPE_UDWORD*)mem)[addr] + what;
+ return(((TYPE_UDWORD*)mem)[addr]);
+ }
+}
+
+t_addr
+cl_mem::dump(t_addr start, t_addr stop, int bpl, class cl_console *con)
+{
+ int i;
+
+ while ((start <= stop) &&
+ (start < size))
+ {
+ con->dd_printf(addr_format, start); con->dd_printf(" ");
+ for (i= 0;
+ (i < bpl) &&
+ (start+i < size) &&
+ (start+i <= stop);
+ i++)
+ {
+ con->dd_printf(data_format, /*read*/get(start+i)); con->dd_printf(" ");
+ }
+ while (i < bpl)
+ {
+ int j;
+ j= width/4 + ((width%4)?1:0) + 1;
+ while (j)
+ {
+ con->dd_printf(" ");
+ j--;
+ }
+ i++;
+ }
+ for (i= 0; (i < bpl) &&
+ (start+i < size) &&
+ (start+i <= stop);
+ i++)
+ {
+ long c= get(start+i);
+ con->dd_printf("%c", isprint(255&c)?(255&c):'.');
+ if (width > 8)
+ con->dd_printf("%c", isprint(255&(c>>8))?(255&(c>>8)):'.');
+ if (width > 16)
+ con->dd_printf("%c", isprint(255&(c>>16))?(255&(c>>16)):'.');
+ if (width > 24)
+ con->dd_printf("%c", isprint(255&(c>>24))?(255&(c>>24)):'.');
+ }
+ con->dd_printf("\n");
+ dump_finished= start+i;
+ start+= bpl;
+ }
+ return(dump_finished);
+}
+
+t_addr
+cl_mem::dump(class cl_console *con)
+{
+ return(dump(dump_finished, dump_finished+10*8-1, 8, con));
+}
+
+
+
+/*
+ */
+/*
+cl_mapped_cell::cl_mapped_cell(class cl_cell *realcell)
+{
+ real_cell= realcell;
+}
+
+cl_mapped_cell::~cl_mapped_cell(void)
+{}
+
+t_mem
+cl_mapped_cell::read(void)
+{
+ return(real_cell->read());
+}
+
+t_mem
+cl_mapped_cell::read(enum hw_cath skip)
+{
+ return(real_cell->read(skip));
+}
+
+t_mem
+cl_mapped_cell::get(void)
+{
+ return(real_cell->get());
+}
+
+t_mem
+cl_mapped_cell::write(t_mem val)
+{
+ return(real_cell->write(val));
+}
+
+t_mem
+cl_mapped_cell::set(t_mem val)
+{
+ return(real_cell->set(val));
+}
+
+t_mem
+cl_mapped_cell::add(long what)
+{
+ return(real_cell->add(what));
+}
+
+t_mem
+cl_mapped_cell::wadd(long what)
+{
+ return(real_cell->wadd(what));
+}
+
+void
+cl_mapped_cell::set_bit1(t_mem bits)
+{
+ return(real_cell->set_bit1(bits));
+}
+
+void
+cl_mapped_cell::set_bit0(t_mem bits)
+{
+ return(real_cell->set_bit0(bits));
+}
+
+class cl_cell *
+cl_mapped_cell::add_hw(class cl_hw *hw, int *ith)
+{
+ return(real_cell->add_hw(hw, ith));
+}
+
+class cl_hw *
+cl_mapped_cell::get_hw(int ith)
+{
+ return(real_cell->get_hw(ith));
+}
+
+class cl_event_handler *
+cl_mapped_cell::get_event_handler(void)
+{
+ return(real_cell->get_event_handler());
+}
+*/
+
+/*
+ */
+
+cl_m::cl_m(enum mem_class atype, char *aclass_name, t_addr asize, int awidth,
+ class cl_uc *auc):
+ cl_memory(aclass_name, asize, awidth)
+ //cl_mem(atype, aclass_name, 0, awidth, auc)
+{
+ t_addr a;
+
+ //size= asize;
+ width= awidth;
+ set_name(aclass_name);
+ uc= auc;
+ type= atype;
+
+ array= (class cl_cell **)calloc(size, sizeof(class cl_cell *));
+ for (a= 0; a < size; a++)
+ array[a]= new cl_normal_cell(width);
+ bus_mask= 0;
+ t_addr i;
+ for (i= 1; i < size; i<<=1)
+ bus_mask= (bus_mask<<1)|1;
+ dummy= new cl_normal_cell(width);
+ //mk_cell(size, 0);
+}
+
+cl_m::~cl_m(void)
+{
+ t_addr a;
+
+ for (a= 0; a < size; a++)
+ delete array[a];
+ free(array);
+ delete dummy;
+}
+
+int
+cl_m::init(void)
+{
+ t_addr i;
+
+ cl_memory::init();
+
+ for (i= 0; i < size; i++)
+ set(i, (type==MEM_ROM)?(-1):0);
+ return(0);
+}
+
+char *
+cl_m::id_string(void)
+{
+ char *s= get_id_string(mem_ids, type);
+
+ return(s?s:(char*)"NONE");
+}
+
+/*void
+cl_m::mk_cell(t_addr addr, class cl_cell *cell)
+{
+ if (!cell)
+ cell= new cl_cell(width);
+ class cl_cell *p;
+ if (addr >= size)
+ p= dummy;
+ else
+ p= array[addr];
+ if (p == 0)
+ {
+ p= (class cl_cell *)calloc(1, sizeof(*cell));
+ }
+ else
+ {
+ p->destroy();
+ p= (class cl_cell *)realloc(p, sizeof(cell));
+ }
+ memcpy(p, cell, sizeof(*cell));
+ cell->destroy();
+ delete cell;
+}*/
+
+t_mem
+cl_m::read(t_addr addr)
+{
+ //addr&= bus_mask;
+ if (addr >= size)
+ {
+ err_inv_addr(addr);
+ return(dummy->read());
+ }
+ return(array[addr]->read());
+}
+
+t_mem
+cl_m::read(t_addr addr, enum hw_cath skip)
+{
+ //addr&= bus_mask;
+ if (addr >= size)
+ {
+ err_inv_addr(addr);
+ return(dummy->read(skip));
+ }
+ return(array[addr]->read(skip));
+}
+
+t_mem
+cl_m::get(t_addr addr)
+{
+ addr&= bus_mask;
+ if (addr >= size)
+ {
+ err_inv_addr(addr);
+ return(dummy->get());
+ }
+ return(array[addr]->get());
+}
+
+t_mem
+cl_m::write(t_addr addr, t_mem val)
+{
+ //addr&= bus_mask;
+ if (addr >= size)
+ {
+ err_inv_addr(addr);
+ return(dummy->write(val));
+ }
+ return(array[addr]->write(val));
+}
+
+void
+cl_m::set(t_addr addr, t_mem val)
+{
+ if (addr >= size)
+ {
+ err_inv_addr(addr);
+ //addr&= bus_mask;
+ dummy->set(val);
+ return;
+ }
+ //addr&= bus_mask;
+ array[addr]->set(val);
+}
+
+class cl_cell *
+cl_m::get_cell(t_addr addr)
+{
+ //addr&= bus_mask;
+ if (addr >= size)
+ {
+ err_inv_addr(addr);
+ return(dummy);
+ }
+ return(array[addr]);
+}
+
+
+/* Set or clear bits, without callbacks */
+
+void
+cl_m::set_bit1(t_addr addr, t_mem bits)
+{
+ class cl_cell *cell;
+
+ addr&= bus_mask;
+ if (addr >= size)
+ {
+ err_inv_addr(addr);
+ cell= dummy;
+ }
+ else
+ cell= array[addr];
+ bits&= cell->get_mask();
+ cell->set(cell->get() | bits);
+}
+
+void
+cl_m::write_bit1(t_addr addr, t_mem bits)
+{
+ class cl_cell *cell;
+
+ addr&= bus_mask;
+ if (addr >= size)
+ {
+ err_inv_addr(addr);
+ cell= dummy;
+ }
+ else
+ cell= array[addr];
+ bits&= cell->get_mask();
+ cell->write(cell->get() | bits);
+}
+
+void
+cl_m::set_bit0(t_addr addr, t_mem bits)
+{
+ class cl_cell *cell;
+
+ addr&= bus_mask;
+ if (addr >= size)
+ {
+ err_inv_addr(addr);
+ cell= dummy;
+ }
+ else
+ cell= array[addr];
+ bits&= cell->get_mask();
+ cell->set(cell->get() & ~bits);
+}
+
+void
+cl_m::write_bit0(t_addr addr, t_mem bits)
+{
+ class cl_cell *cell;
+
+ addr&= bus_mask;
+ if (addr >= size)
+ {
+ err_inv_addr(addr);
+ cell =dummy;
+ }
+ else
+ cell= array[addr];
+ bits&= cell->get_mask();
+ cell->write(cell->get() & ~bits);
+}
+
+t_mem
+cl_m::add(t_addr addr, long what)
+{
+ addr&= bus_mask;
+ if (addr >= size)
+ {
+ err_inv_addr(addr);
+ return(dummy->add(what));
+ }
+ return(array[addr]->add(what));
+}
+
+t_mem
+cl_m::wadd(t_addr addr, long what)
+{
+ addr&= bus_mask;
+ if (addr >= size)
+ {
+ err_inv_addr(addr);
+ return(dummy->wadd(what));
+ }
+ return(array[addr]->wadd(what));
+}
+
+bool
+cl_m::search_next(bool case_sensitive, t_mem *array, int len, t_addr *addr)
+{
+ t_addr a;
+ int i;
+ bool found;
+
+ if (addr == NULL)
+ a= 0;
+ else
+ a= *addr;
+
+ if (a+len > size)
+ return(DD_FALSE);
+
+ found= DD_FALSE;
+ while (!found &&
+ a+len <= size)
+ {
+ bool match= DD_TRUE;
+ for (i= 0; i < len && match; i++)
+ {
+ t_mem d1, d2;
+ d1= get(a+i);
+ d2= array[i];
+ if (!case_sensitive)
+ {
+ if (/*d1 < 128*/isalpha(d1))
+ d1= toupper(d1);
+ if (/*d2 < 128*/isalpha(d2))
+ d2= toupper(d2);
+ }
+ match= d1 == d2;
+ }
+ found= match;
+ if (!found)
+ a++;
+ }
+
+ if (addr)
+ *addr= a;
+ return(found);
+}
+
+class cl_cell *
+cl_m::register_hw(t_addr addr, class cl_hw *hw, int *ith, bool announce)
+{
+ class cl_cell *cell, *nc;
+
+ addr&= bus_mask;
+ if (addr >= size)
+ cell= dummy;
+ else
+ cell= array[addr];
+
+ if (cell->get_type() & (CELL_HW_READ | CELL_HW_WRITE))
+ {
+ /* Already registered */
+ return(cell->add_hw(hw, ith));
+ }
+ else if (cell->get_type() & (CELL_READ_BRK | CELL_WRITE_BRK))
+ {
+ /* Event break is set on it, now register hw */
+ nc= new cl_ev_reg_cell(width, uc);
+ nc->set(cell->get());
+ nc->set_type(nc->get_type() &
+ ~(CELL_GENERAL|CELL_READ_BRK|CELL_WRITE_BRK));
+ nc->set_type(nc->get_type() | (cell->get_type() & CELL_GENERAL));
+ class cl_event_handler *eh= nc->get_event_handler();
+ if (eh)
+ nc->set_type(nc->get_type() | eh->copy_from(cell->get_event_handler()));
+ nc->add_hw(hw, ith);
+ }
+ else
+ {
+ /* Normal cell, register hw */
+ nc= new cl_registered_cell(width);
+ nc->set(cell->get());
+ nc->set_type(nc->get_type() & ~CELL_GENERAL);
+ nc->set_type(nc->get_type() | (cell->get_type() & CELL_GENERAL));
+ nc->add_hw(hw, ith);
+ }
+
+ if (addr >= size)
+ {
+ delete dummy;
+ dummy= nc;
+ }
+ else
+ {
+ delete array[addr];
+ array[addr]= nc;
+ }
+ if (announce)
+ uc->sim->/*app->*/mem_cell_changed(this, addr);
+ return(nc);
+}
+
+void
+cl_m::set_brk(t_addr addr, class cl_brk *brk)
+{
+ class cl_cell *cell, *nc;
+ char e= '_';
+
+ addr&= bus_mask;
+ if (addr >= size)
+ cell= dummy;
+ else
+ cell= array[addr];
+
+ switch (brk->get_event())
+ {
+ case brkWRITE: case brkWXRAM: case brkWIRAM: case brkWSFR:
+ e= 'W';
+ break;
+ case brkREAD: case brkRXRAM: case brkRCODE: case brkRIRAM: case brkRSFR:
+ e= 'R';
+ break;
+ case brkNONE:
+ set_cell_flag(addr, DD_TRUE, CELL_FETCH_BRK);
+ return;
+ break;
+ default: e= '.'; break;
+ }
+
+ if (cell->get_type() & (CELL_HW_READ | CELL_HW_WRITE))
+ {
+ /* Hw is registered on it, now set event break */
+ nc= new cl_ev_reg_cell(width, uc);
+ nc->set(cell->get());
+ nc->set_type(nc->get_type() & ~CELL_GENERAL);
+ nc->set_type(nc->get_type() | (cell->get_type() & CELL_GENERAL));
+ int i= 0;
+ class cl_hw *hw;
+ while ((hw= cell->get_hw(i)) != 0)
+ {
+ nc->add_hw(hw, 0);
+ i++;
+ }
+ if (((class cl_registered_cell *)cell)->hardwares)
+ {
+ free(((class cl_registered_cell *)cell)->hardwares);
+ ((class cl_registered_cell *)cell)->hardwares= 0;
+ }
+ class cl_event_handler *eh;
+ if ((eh= nc->get_event_handler()))
+ nc->set_type(nc->get_type() | eh->add_bp(brk));
+ }
+ else if (cell->get_type() & (CELL_READ_BRK | CELL_WRITE_BRK))
+ {
+ /* Break is already set on it */
+ class cl_event_handler *eh;
+ if ((eh= cell->get_event_handler()))
+ cell->set_type(cell->get_type() | eh->add_bp(brk));
+ return;
+ }
+ else
+ {
+ /* Normal cell, set event break */
+ nc= new cl_event_cell(width, uc);
+ nc->set(cell->get());
+ nc->set_type(nc->get_type() & ~CELL_GENERAL);
+ nc->set_type(nc->get_type() | (cell->get_type() & CELL_GENERAL));
+ class cl_event_handler *eh;
+ if ((eh= nc->get_event_handler()))
+ nc->set_type(nc->get_type() | eh->add_bp(brk));
+ }
+
+ if (addr >= size)
+ {
+ delete dummy;
+ dummy= nc;
+ }
+ else
+ {
+ delete array[addr];
+ array[addr]= nc;
+ }
+ uc->sim->/*app->*/mem_cell_changed(this, addr);
+}
+
+void
+cl_m::del_brk(t_addr addr, class cl_brk *brk)
+{
+ class cl_cell *cell, *nc;
+ char e= '_';
+
+ addr&= bus_mask;
+ if (addr >= size)
+ cell= dummy;
+ else
+ cell= array[addr];
+
+ switch (brk->get_event())
+ {
+ case brkWRITE: case brkWXRAM: case brkWIRAM: case brkWSFR: e= 'W'; break;
+ case brkREAD: case brkRXRAM: case brkRCODE: case brkRIRAM: case brkRSFR:
+ e= 'R';
+ break;
+ case brkNONE:
+ set_cell_flag(addr, DD_FALSE, CELL_FETCH_BRK);
+ return;
+ break;
+ default: e= '.'; break;
+ }
+
+ if (cell->get_type() & (CELL_HW_READ | CELL_HW_WRITE))
+ {
+ /* Hw is registered on it, delete event break */
+ class cl_event_handler *eh;
+ int t= CELL_NORMAL;
+ if ((eh= cell->get_event_handler()))
+ t= eh->del_bp(brk);
+ if (t & (CELL_READ_BRK|CELL_WRITE_BRK))
+ {
+ cell->set_type(cell->get_type() & ~(CELL_READ_BRK|CELL_WRITE_BRK));
+ cell->set_type(cell->get_type() | t);
+ return;
+ }
+ nc= new cl_registered_cell(width);
+ nc->set(cell->get());
+ nc->set_type(cell->get_type() & ~CELL_GENERAL);
+ nc->set_type(cell->get_type() | (cell->get_type() & CELL_GENERAL));
+ int i= 0;
+ class cl_hw *hw;
+ while ((hw= cell->get_hw(i)) != 0)
+ {
+ nc->add_hw(hw, 0);
+ i++;
+ }
+ if (((class cl_registered_cell *)cell)->hardwares)
+ free(((class cl_registered_cell *)cell)->hardwares);
+ }
+ else if (cell->get_type() & (CELL_READ_BRK | CELL_WRITE_BRK))
+ {
+ /* Break already set on it, delete brk */
+ class cl_event_handler *eh;
+ int t= CELL_NORMAL;
+ if ((eh= cell->get_event_handler()))
+ t= eh->del_bp(brk);
+ if (t & (CELL_READ_BRK|CELL_WRITE_BRK))
+ {
+ cell->set_type(cell->get_type() & ~(CELL_READ_BRK|CELL_WRITE_BRK));
+ cell->set_type(cell->get_type() | t);
+ return;
+ }
+ nc= new cl_normal_cell(width);
+ nc->set(cell->get());
+ nc->set_type(cell->get_type() & ~CELL_GENERAL);
+ nc->set_type(cell->get_type() | (cell->get_type() & CELL_GENERAL));
+ return;
+ }
+ else
+ {
+ /* Normal cell */
+ return;
+ }
+
+ if (addr >= size)
+ {
+ delete dummy;
+ dummy= nc;
+ }
+ else
+ {
+ delete array[addr];
+ array[addr]= nc;
+ }
+ uc->sim->/*app->*/mem_cell_changed(this, addr);
+}
+
+
+#ifdef STATISTIC
+unsigned long
+cl_m::get_nuof_reads(void)
+{
+ unsigned long res= 0;
+ t_addr i;
+ for (i= 0; i < size; i++)
+ res+= array[i]->nuof_reads;
+ return(res);
+}
+
+unsigned long
+cl_m::get_nuof_writes(void)
+{
+ unsigned long res= 0;
+ t_addr i;
+ for (i= 0; i < size; i++)
+ res+= array[i]->nuof_writes;
+ return(res);
+}
+
+void
+cl_m::set_nuof_reads(unsigned long value)
+{
+ t_addr i;
+ for (i= 0; i < size; i++)
+ array[i]->nuof_reads= value;
+ dummy->nuof_reads= value;
+}
+
+void
+cl_m::set_nuof_writes(unsigned long value)
+{
+ t_addr i;
+ for (i= 0; i < size; i++)
+ array[i]->nuof_writes= value;
+ dummy->nuof_writes= value;
+}
+#endif
+
+
+cl_normal_cell::cl_normal_cell(uchar awidth):
+ cl_cell()
+{
+ type= CELL_NORMAL;
+ data= 0;
+ mask= 1;
+ width= awidth;
+ for (--awidth; awidth; awidth--)
+ {
+ mask<<= 1;
+ mask|= 1;
+ }
+}
+
+t_mem
+cl_normal_cell::add(long what)
+{
+ t_mem d;
+
+ if (width <= 8)
+ d= /*TYPE_BYTE*/i8_t(data) + what;
+ else if (width <= 16)
+ d= /*TYPE_WORD*/i16_t(data) + what;
+ else
+ d= /*TYPE_DWORD*/i32_t(data) + what;
+ return(data= d & mask);
+}
+
+t_mem
+cl_normal_cell::wadd(long what)
+{
+ t_mem d;
+
+ if (width <= 8)
+ d= TYPE_BYTE(data) + what;
+ else if (width <= 16)
+ d= TYPE_WORD(data) + what;
+ else
+ d= TYPE_DWORD(data) + what;
+ return(write(d));
+}
+
+void
+cl_normal_cell::set_bit1(t_mem bits)
+{
+ bits&= mask;
+ data|= bits;
+}
+
+void
+cl_normal_cell::set_bit0(t_mem bits)
+{
+ bits&= mask;
+ data&= ~bits;
+}
+
+
+/*
+ */
+
+cl_registered_cell::cl_registered_cell(uchar awidth):
+ cl_normal_cell(awidth)
+{
+ type= CELL_HW_READ | CELL_HW_WRITE;
+ //hws= new cl_list(1, 1);
+ hardwares= 0;
+ nuof_hws= 0;
+}
+
+cl_registered_cell::~cl_registered_cell(void)
+{
+ if (hardwares)
+ free(hardwares);
+}
+
+/*void
+cl_registered_cell::destroy(void)
+{
+ hardwares= 0;
+ nuof_hws= 0;
+}*/
+
+t_mem
+cl_registered_cell::read(void)
+{
+ int i;
+ t_mem d= data;
+
+ if (nuof_hws)
+ for (i= 0; i < nuof_hws; i++)
+ {
+ d= hardwares[i]->read(this);
+ ;
+ }
+#ifdef STATISTIC
+ nuof_reads++;
+#endif
+ return(d & mask);
+}
+
+t_mem
+cl_registered_cell::read(enum hw_cath skip)
+{
+ int i;
+ t_mem d= data;
+
+ if (nuof_hws)
+ for (i= 0; i < nuof_hws; i++)
+ {
+ if ((skip & hardwares[i]->cathegory) == 0)
+ d= hardwares[i]->read(this);
+ ;
+ }
+#ifdef STATISTIC
+ nuof_reads++;
+#endif
+ return(d & mask);
+}
+
+t_mem
+cl_registered_cell::write(t_mem val)
+{
+ int i;
+
+ val&= mask;
+ if (nuof_hws)
+ for (i= 0; i < nuof_hws; i++)
+ {
+ hardwares[i]->write(this, &val);
+ ;
+ }
+#ifdef STATISTIC
+ nuof_writes++;
+#endif
+ return(data= val & mask);
+}
+
+class cl_cell *
+cl_registered_cell::add_hw(class cl_hw *hw, int *ith)
+{
+ if (!hw)
+ {
+ /* Whatta hell!? */
+ return(0);
+ }
+ if (!hardwares)
+ hardwares= (class cl_hw **)malloc(sizeof(class cl_hw *));
+ else
+ hardwares= (class cl_hw **)realloc(hardwares,
+ sizeof(class c_hw *) * (nuof_hws+1));
+ hardwares[nuof_hws]= hw;
+ nuof_hws++;
+ if (ith)
+ *ith= nuof_hws-1;
+ return(this);
+}
+
+class cl_hw *
+cl_registered_cell::get_hw(int ith)
+{
+ if (ith >= nuof_hws)
+ return(0);
+ return(hardwares[ith]);
+}
+
+
+/*
+ */
+
+cl_event_cell::cl_event_cell(uchar awidth, class cl_uc *auc):
+ cl_normal_cell(awidth)
+{
+ eh= new cl_event_handler(auc);
+}
+
+cl_event_cell::~cl_event_cell(void)
+{
+ delete eh;
+}
+
+t_mem
+cl_event_cell::read(void)
+{
+ if (type & CELL_READ_BRK)
+ eh->read();
+ return(cl_normal_cell::read());
+}
+
+t_mem
+cl_event_cell::write(t_mem val)
+{
+ if (type & CELL_WRITE_BRK)
+ eh->write();
+ return(cl_normal_cell::write(val));
+}
+
+
+/*
+ */
+
+cl_ev_reg_cell::cl_ev_reg_cell(uchar awidth, class cl_uc *auc):
+ cl_registered_cell(awidth)
+{
+ eh= new cl_event_handler(auc);
+}
+
+cl_ev_reg_cell::~cl_ev_reg_cell(void)
+{}
+
+t_mem
+cl_ev_reg_cell::read(void)
+{
+ if (type & CELL_READ_BRK)
+ eh->read();
+ return(cl_registered_cell::read());
+}
+
+t_mem
+cl_ev_reg_cell::write(t_mem val)
+{
+ if (type & CELL_WRITE_BRK)
+ eh->write();
+ return(cl_registered_cell::write(val));
+}
+
+
+/*
+ */
+
+cl_event_handler::cl_event_handler(class cl_uc *auc):
+ cl_base()
+{
+ uc= auc;
+ read_bps= new cl_list(1, 1);
+ write_bps= new cl_list(1, 1);
+}
+
+cl_event_handler::~cl_event_handler(void)
+{
+ read_bps->disconn_all();
+ write_bps->disconn_all();
+ delete read_bps;
+ delete write_bps;
+}
+
+void
+cl_event_handler::write(void)
+{
+ int i;
+
+ for (i= 0; i < write_bps->count; i++)
+ {
+ class cl_brk *bp= (class cl_brk *)(write_bps->at(i));
+ uc->events->add(bp);
+ }
+}
+
+void
+cl_event_handler::read(void)
+{
+ int i;
+
+ for (i= 0; i < read_bps->count; i++)
+ {
+ class cl_brk *bp= (class cl_brk *)(read_bps->at(i));
+ uc->events->add(bp);
+ }
+}
+
+int
+cl_event_handler::add_bp(class cl_brk *bp)
+{
+ int t= CELL_NORMAL;
+
+ if (!bp)
+ return(CELL_NORMAL);
+ switch (bp->get_event())
+ {
+ case brkWRITE: case brkWXRAM: case brkWIRAM: case brkWSFR:
+ t|= CELL_WRITE_BRK;
+ write_bps->add(bp);
+ break;
+ case brkREAD: case brkRXRAM: case brkRCODE: case brkRIRAM: case brkRSFR:
+ t|= CELL_READ_BRK;
+ read_bps->add(bp);
+ break;
+ default:
+ t|= CELL_READ_BRK | CELL_WRITE_BRK;
+ read_bps->add(bp);
+ write_bps->add(bp);
+ break;
+ }
+ return(t);
+}
+
+int
+cl_event_handler::copy_from(class cl_event_handler *eh)
+{
+ int i, t= CELL_NORMAL;
+
+ if (!eh)
+ return(t);
+ for (i= 0; i < eh->read_bps->count; i++)
+ {
+ class cl_brk *bp= (class cl_brk *)(eh->read_bps->at(i));
+ t|= add_bp(bp);
+ }
+ for (i= 0; i < eh->write_bps->count; i++)
+ {
+ class cl_brk *bp= (class cl_brk *)(eh->write_bps->at(i));
+ t|= add_bp(bp);
+ }
+ return(t);
+}
+
+int
+cl_event_handler::del_bp(class cl_brk *bp)
+{
+ int t= CELL_NORMAL;
+
+ write_bps->disconn(bp);
+ read_bps->disconn(bp);
+ if (write_bps->count)
+ t|= CELL_WRITE_BRK;
+ if (read_bps->count)
+ t|= CELL_READ_BRK;
+ return(t);
+}
+
+
diff --git a/sim/ucsim/sim.src/obsolete.h b/sim/ucsim/sim.src/obsolete.h
new file mode 100644
index 0000000..0acc1d1
--- /dev/null
+++ b/sim/ucsim/sim.src/obsolete.h
@@ -0,0 +1,286 @@
+/*
+class cl_mem: public cl_guiobj
+{
+public:
+ char *addr_format, *data_format;
+ ulong mask;
+ enum mem_class type;
+ char *class_name;
+ union {
+ void *mem;
+ uchar *umem8;
+ };
+ //class cl_memloc_coll *read_locs, *write_locs;
+ t_addr size;
+ int width; // in bits
+ class cl_uc *uc;
+ t_addr dump_finished;
+
+public:
+ cl_mem(enum mem_class atype, char *aclass_name, t_addr asize, int awidth,
+ class cl_uc *auc);
+ virtual ~cl_mem(void);
+ virtual int init(void);
+ virtual char *id_string(void);
+ virtual int get_cell_flag(t_addr //addr
+ ) { return(CELL_NORMAL); }
+ virtual bool get_cell_flag(t_addr //addr
+ , int //flag
+ )
+ { return(DD_FALSE); }
+ virtual void set_cell_flag(t_addr addr, bool set_to, int flag) {}
+
+ virtual t_mem read(t_addr addr);
+ virtual t_mem read(t_addr addr, enum hw_cath //skip
+ ) {return(read(addr));}
+ virtual t_mem get(t_addr addr);
+ virtual t_mem write(t_addr addr, t_mem val);
+ virtual void set(t_addr addr, t_mem val);
+ virtual void set_bit1(t_addr addr, t_mem bits);
+ virtual void set_bit0(t_addr addr, t_mem bits);
+ virtual void write_bit1(t_addr addr, t_mem bits) { set_bit1(addr, bits); }
+ virtual void write_bit0(t_addr addr, t_mem bits) { set_bit0(addr, bits); }
+ virtual t_mem add(t_addr addr, long what);
+ virtual t_mem wadd(t_addr addr, long what) { return(add(addr, what)); }
+ virtual t_addr dump(t_addr start, t_addr stop, int bpl,
+ class cl_console *con);
+ virtual t_addr dump(class cl_console *con);
+ virtual bool search_next(bool case_sensitive,
+ t_mem *array, int len, t_addr *addr);
+
+ virtual class cl_cell *get_cell(t_addr addr) {return(0);}
+ virtual class cl_cell *register_hw(t_addr addr, class cl_hw *hw, int *ith,
+ bool announce)
+ { return(0); }
+ virtual void set_brk(t_addr //addr
+ , class cl_brk *//brk
+ ) {}
+ virtual void del_brk(t_addr addr, class cl_brk *brk) {}
+#ifdef STATISTIC
+ virtual unsigned long get_nuof_reads(void) {return(0);}
+ virtual unsigned long get_nuof_writes(void) {return(0);}
+ virtual void set_nuof_reads(unsigned long value) {}
+ virtual void set_nuof_writes(unsigned long value) {}
+#endif
+};
+*/
+
+/*
+class cl_mapped_cell: public cl_cell
+{
+protected:
+ class cl_cell *real_cell;
+public:
+ cl_mapped_cell(class cl_cell *realcell);
+ virtual ~cl_mapped_cell(void);
+
+ virtual t_mem read(void);
+ virtual t_mem read(enum hw_cath skip);
+ virtual t_mem get(void);
+ virtual t_mem write(t_mem val);
+ virtual t_mem set(t_mem val);
+ virtual t_mem add(long what);
+ virtual t_mem wadd(long what);
+
+ virtual void set_bit1(t_mem bits);
+ virtual void set_bit0(t_mem bits);
+
+ virtual class cl_cell *add_hw(class cl_hw *hw, int *ith);
+ virtual class cl_hw *get_hw(int ith);
+ virtual class cl_event_handler *get_event_handler(void);
+};
+*/
+
+
+class cl_m: public cl_memory
+{
+protected:
+ class cl_cell **array;
+ class cl_cell *dummy;
+ t_addr bus_mask;
+public:
+ //t_addr size;
+ enum mem_class type;
+
+public:
+ cl_m(enum mem_class atype, char *aclass_name, t_addr asize, int awidth,
+ class cl_uc *auc);
+ cl_m(t_addr asize, int awidth);
+ virtual ~cl_m(void);
+ virtual int init(void);
+ virtual char *id_string(void);
+
+ virtual int get_cell_flag(t_addr addr);
+ virtual bool get_cell_flag(t_addr addr, int flag);
+ virtual void set_cell_flag(t_addr addr, bool set_to, int flag);
+
+ virtual t_mem read(t_addr addr);
+ virtual t_mem read(t_addr addr, enum hw_cath skip);
+ virtual t_mem get(t_addr addr);
+ virtual t_mem write(t_addr addr, t_mem val);
+ virtual void set(t_addr addr, t_mem val);
+ virtual class cl_cell *get_cell(t_addr addr);
+
+ virtual void set_bit1(t_addr addr, t_mem bits);
+ virtual void set_bit0(t_addr addr, t_mem bits);
+ virtual void write_bit1(t_addr addr, t_mem bits);
+ virtual void write_bit0(t_addr addr, t_mem bits);
+ virtual t_mem add(t_addr addr, long what);
+ virtual t_mem wadd(t_addr addr, long what);
+
+ virtual bool search_next(bool case_sensitive,
+ t_mem *array, int len, t_addr *addr);
+
+ virtual class cl_cell *register_hw(t_addr addr, class cl_hw *hw, int *ith,
+ bool announce);
+ virtual void set_brk(t_addr addr, class cl_brk *brk);
+ virtual void del_brk(t_addr addr, class cl_brk *brk);
+
+#ifdef STATISTIC
+ virtual unsigned long get_nuof_reads(void);
+ virtual unsigned long get_nuof_writes(void);
+ virtual void set_nuof_reads(unsigned long value);
+ virtual void set_nuof_writes(unsigned long value);
+#endif
+};
+
+
+class cl_normal_cell: public cl_cell
+{
+public:
+ t_mem data;
+ TYPE_UBYTE type; // See CELL_XXXX
+ //protected:
+
+public:
+ cl_normal_cell(uchar awidth);
+ //virtual void destroy(void) {}
+
+ virtual TYPE_UBYTE get_type(void) { return(type); }
+ virtual void set_type(TYPE_UBYTE what) { type= what; }
+
+ virtual t_mem read(void) {
+#ifdef STATISTIC
+ nuof_reads++;
+#endif
+ return(data);
+ }
+ virtual t_mem read(enum hw_cath skip) { return(data); }
+ virtual t_mem get(void) { return(data); }
+ virtual t_mem write(t_mem val) {
+ data= val & mask;
+#ifdef STATISTIC
+ nuof_writes++;
+#endif
+ return(data);
+ }
+ virtual t_mem set(t_mem val) { return(data= val & mask); }
+ virtual t_mem add(long what);
+ virtual t_mem wadd(long what);
+
+ virtual void set_bit1(t_mem bits);
+ virtual void set_bit0(t_mem bits);
+
+ virtual class cl_cell *add_hw(class cl_hw *hw, int *ith)
+ { return(0); }
+ virtual class cl_hw *get_hw(int ith) { return(0); }
+ //virtual class cl_brk *get_brk(void) { return(0); }
+ virtual class cl_event_handler *get_event_handler(void) { return(0); }
+};
+
+class cl_registered_cell: public cl_memory_cell
+{
+public:
+ //class cl_list *hws;
+ class cl_hw **hardwares;
+ int nuof_hws;
+public:
+ cl_registered_cell(uchar awidth);
+ virtual ~cl_registered_cell(void);
+ //virtual void destroy(void);
+
+ virtual t_mem read(void);
+ virtual t_mem read(enum hw_cath skip);
+ virtual t_mem write(t_mem val);
+
+ virtual class cl_cell *add_hw(class cl_hw *hw, int *ith);
+ virtual class cl_hw *get_hw(int ith);
+};
+
+class cl_event_cell: public cl_normal_cell
+{
+protected:
+ class cl_event_handler *eh;
+public:
+ cl_event_cell(uchar awidth, class cl_uc *auc);
+ virtual ~cl_event_cell(void);
+
+ virtual t_mem read(void);
+ virtual t_mem write(t_mem val);
+ //virtual void event(void);
+
+ //virtual class cl_brk *get_brk(void) { return(brk); }
+ virtual class cl_event_handler *get_event_handler(void) { return(eh); }
+};
+
+class cl_ev_reg_cell: public cl_registered_cell
+{
+protected:
+ class cl_event_handler *eh;
+public:
+ cl_ev_reg_cell(uchar awidth, class cl_uc *auc);
+ virtual ~cl_ev_reg_cell(void);
+
+ virtual t_mem read(void);
+ virtual t_mem write(t_mem val);
+ //virtual void event(void);
+
+ //virtual class cl_brk *get_brk(void) { return(brk); }
+ virtual class cl_event_handler *get_event_handler(void) { return(eh); }
+};
+
+/*
+ * 2nd version memory system
+ */
+class cl_cell: public cl_base
+{
+public:
+ cl_cell(void);
+public:
+
+ virtual t_mem read(void)= 0;
+ virtual t_mem read(enum hw_cath skip)=0;
+ virtual t_mem get(void)=0;
+ virtual t_mem write(t_mem val)=0;
+ virtual t_mem set(t_mem val)=0;
+ virtual t_mem add(long what)=0;
+ virtual t_mem wadd(long what)=0;
+
+ virtual void set_bit1(t_mem bits)=0;
+ virtual void set_bit0(t_mem bits)=0;
+
+ virtual class cl_cell *add_hw(class cl_hw *hw, int *ith)=0;
+ virtual class cl_hw *get_hw(int ith)=0;
+ virtual class cl_event_handler *get_event_handler(void)=0;
+};
+
+/*
+ */
+class cl_event_handler: public cl_base
+{
+public:
+ class cl_list *read_bps, *write_bps;
+ class cl_uc *uc;
+public:
+ cl_event_handler(class cl_uc *auc);
+ virtual ~cl_event_handler(void);
+
+ virtual void write(void);
+ virtual void read(void);
+
+ virtual int add_bp(class cl_brk *bp);
+ virtual int copy_from(class cl_event_handler *eh);
+ virtual bool del_bp(class cl_brk *bp);
+};
+
+
diff --git a/sim/ucsim/sim.src/port_hw.cc b/sim/ucsim/sim.src/port_hw.cc
new file mode 100644
index 0000000..4c365bc
--- /dev/null
+++ b/sim/ucsim/sim.src/port_hw.cc
@@ -0,0 +1,324 @@
+/*
+ * Simulator of microcontrollers (sim.src/port_hw.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@*/
+
+#include <ctype.h>
+
+#include "globals.h"
+
+#include "port_hwcl.h"
+
+
+const char *keysets[8]= {
+ "12345678",
+ "qwertyui",
+ "asdfghjk",
+ "zxcvbnm,",
+ "QWERTYUI",
+ "ASDFGHJK",
+ "ZXCVBNM,",
+ "9opl.OPL"
+};
+
+
+cl_port_ui::cl_port_ui(class cl_uc *auc, int aid, chars aid_string):
+ cl_hw(auc, HW_DUMMY, aid, aid_string)
+{
+ int i;
+
+ for (i= 0; i < NUOF_PORT_UIS; i++)
+ {
+ pd[i].init();
+ pd[i].cell_p= NULL;
+ pd[i].cell_in= NULL;
+ pd[i].cell_dir= NULL;
+ pd[i].cache_p= 0;
+ pd[i].cache_in= 0;
+ pd[i].cache_dir= 0;
+ pd[i].keyset= NULL;
+ }
+ act_port= -1;
+}
+
+
+bool
+cl_port_ui::add_port(class cl_port_data *p, int nr)
+{
+ if (nr >= NUOF_PORT_UIS)
+ return false;
+ if (pd[nr].cell_p)
+ return false;
+
+ if ((pd[nr].cell_p= p->cell_p))
+ pd[nr].cache_p= pd[nr].cell_p->get();
+ if ((pd[nr].cell_in= p->cell_in))
+ pd[nr].cache_in= pd[nr].cell_in->read();
+ if ((pd[nr].cell_dir= p->cell_dir))
+ pd[nr].cache_dir= pd[nr].cell_dir->read();
+ pd[nr].keyset = p->keyset;
+ pd[nr].basx = p->basx;
+ pd[nr].basy = p->basy;
+
+ pd[nr].set_name(p->get_name());
+
+ if (act_port < 0)
+ act_port= nr;
+
+ return true;
+}
+
+
+void
+cl_port_ui::make_io()
+{
+ if (!io)
+ {
+ io= new cl_port_io(this);
+ io->init();
+ application->get_commander()->add_console(io);
+ }
+}
+
+
+void
+cl_port_ui::new_io(class cl_f *f_in, class cl_f *f_out)
+{
+ cl_hw::new_io(f_in, f_out);
+ io->tu_mouse_on();
+ io->dd_printf("\033[2 q");
+ if (f_in)
+ f_in->set_escape(true);
+}
+
+
+bool
+cl_port_ui::proc_input(void)
+{
+ return cl_hw::proc_input();
+}
+
+bool
+cl_port_ui::handle_input(int c)
+{
+ class cl_port_io *pio= (class cl_port_io *)io;
+ int i;
+ i8_t i8= c;
+
+ if (i8 < 0)
+ {
+ //fprintf(stderr, "Port: spec key= %d\n", i8);
+ }
+ else
+ {
+ for (i= 0; i < NUOF_PORT_UIS; i++)
+ {
+ if (pd[i].cell_p == NULL)
+ continue;
+
+ if (pd[i].keyset != NULL)
+ {
+ int bit;
+ for (bit= 0; pd[i].keyset[bit]; bit++)
+ if (pd[i].keyset[bit] == c)
+ {
+ t_mem m= pd[i].cell_in->read();
+ pd[i].cell_in->write(m ^ (1<<(7-bit)));
+ pio->tu_go(1,1);
+ return true;
+ }
+ }
+ }
+ }
+ pio->tu_go(1,24);
+ pio->tu_cll();
+ int ret= cl_hw::handle_input(c); // handle default keys
+ pio->tu_go(1,1);
+ //pio->tu_cll();
+ if (!ret)
+ {
+ u8_t u= c;
+ //fprintf(stderr, "Unknown command: %c (%d,0x%x)\n", isprint(u)?u:'?', i8, c);
+ }
+ return ret;
+}
+
+void
+cl_port_ui::refresh_display(bool force)
+{
+ class cl_port_io *pio= (class cl_port_io *)io;
+ if (!io)
+ return;
+
+ int i, m;
+ bool pc= false, ic= false;
+ pio->tu_hide();
+ for (i= 0; i < NUOF_PORT_UIS; i++)
+ {
+ if (pd[i].cell_p == NULL)
+ continue;
+ // name
+ pio->tu_go(pd[i].basx, pd[i].basy);
+ pio->dd_printf("\033[%dm", (act_port == i)?7:0);
+ if (pd[i].have_name())
+ pio->dd_printf(pd[i].get_name());
+ else
+ pio->dd_printf("port_%d", i);
+
+ if (pd[i].cell_dir)
+ {
+ t_mem d= pd[i].cell_dir->get();
+ if (pd[i].cache_dir != d)
+ force= true;
+ pd[i].cache_dir= d;
+ }
+
+ pio->dd_printf("\033[0m");
+ if (force ||
+ (pd[i].cell_p->get() != pd[i].cache_p))
+ {
+ // Out
+ pd[i].cache_p= pd[i].cell_p->get();
+ pio->tu_go(pd[i].basx+4, pd[i].basy+1);
+ m= 0x80;
+ for ( ; m; m>>= 1)
+ {
+ char v= (pd[i].cache_p&m)?'*':'-';
+ if (pd[i].cell_dir != NULL)
+ {
+ if ((pd[i].cache_dir & m) == 0)
+ v= '.';
+ }
+ pio->dd_printf("%c", v);
+ }
+ pio->tu_go(pd[i].basx+4+8+1, pd[i].basy+1);
+ pio->dd_printf("%02x", pd[i].cache_p);
+ pc= true;
+ }
+ if (force ||
+ (pd[i].cell_in &&
+ (pd[i].cell_in->get() != pd[i].cache_in)))
+ {
+ // In
+ pd[i].cache_in= pd[i].cell_in->get();
+ pio->tu_go(pd[i].basx+4, pd[i].basy+3);
+ m= 0x80;
+ for ( ; m; m>>= 1)
+ pio->dd_printf("%c", (pd[i].cache_in&m)?'*':'-');
+ pio->tu_go(pd[i].basx+4+8+1, pd[i].basy+3);
+ pio->dd_printf("%02x", pd[i].cache_in);
+ ic= true;
+ }
+ if (force ||
+ ((pc || ic)/* &&
+ pd[i].cell_dir == NULL*/))
+ {
+ // port value on "Bits" line
+ int b, val, pval= pd[i].cache_in;
+ pio->tu_go(pd[i].basx+4, pd[i].basy+2);
+ for (b= 7; b>=0; b--)
+ {
+ m= 1<<b;
+ val= pd[i].cache_in & m;
+ if (pd[i].cell_dir == NULL)
+ val&= (pd[i].cache_p & m);
+ //if (val)
+ pio->dd_printf("\033[%dm", val?7:0);
+ //else
+ //pio->dd_printf("\033[0m");
+ pio->dd_printf("%d", b);
+ }
+ if (!pd[i].cell_dir)
+ pval&= pd[i].cache_p;
+ pio->dd_printf("\033[0m %02x", pval);
+ }
+ }
+ pio->tu_show();
+ cl_hw::refresh_display(force);
+ if (act_port >= 0)
+ pio->tu_go(pd[act_port].basx+4, pd[act_port].basy+1);
+ else
+ pio->tu_go(1, 1);
+}
+
+void
+cl_port_ui::draw_display(void)
+{
+ class cl_port_io *pio= (class cl_port_io *)io;
+ if (!io)
+ return;
+ pio->tu_cls();
+
+ cl_hw::draw_display();
+
+ int i;
+ for (i= 0; i < NUOF_PORT_UIS; i++)
+ {
+ if (pd[i].cell_p == NULL)
+ continue;
+
+ pio->tu_go(pd[i].basx, pd[i].basy+1);
+ pio->dd_printf("Out ");
+ pio->tu_go(pd[i].basx, pd[i].basy+2);
+ pio->dd_printf("Bit 76543210");
+ pio->tu_go(pd[i].basx, pd[i].basy+3);
+ pio->dd_printf("In ");
+ pio->tu_go(pd[i].basx, pd[i].basy+4);
+ if (pd[i].keyset)
+ pio->dd_printf("Key %s", pd[i].keyset);
+
+ pd[i].cache_p= pd[i].cell_p->get();
+ pd[i].cache_in= pd[i].cell_in->read();
+ }
+
+ refresh_display(true);
+}
+
+
+/* IO console for port display */
+
+cl_port_io::cl_port_io(class cl_hw *ihw):
+ cl_hw_io(ihw)
+{
+}
+
+int
+cl_port_io::init(void)
+{
+ cl_hw_io::init();
+ return 0;
+}
+
+/*
+bool
+cl_port_io::input_avail(void)
+{
+ if (hw)
+ hw->refresh_display(false);
+ return cl_console::input_avail();
+}
+*/
+
+/* End of sim.src/port_hw.cc */
diff --git a/sim/ucsim/sim.src/port_hw.o b/sim/ucsim/sim.src/port_hw.o
new file mode 100644
index 0000000..5745ade
--- /dev/null
+++ b/sim/ucsim/sim.src/port_hw.o
Binary files differ
diff --git a/sim/ucsim/sim.src/port_hwcl.h b/sim/ucsim/sim.src/port_hwcl.h
new file mode 100644
index 0000000..e47699d
--- /dev/null
+++ b/sim/ucsim/sim.src/port_hwcl.h
@@ -0,0 +1,79 @@
+/*
+ * Simulator of microcontrollers (sim.src/port_hwcl.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 PORT_HW_HEADER
+#define PORT_HW_HEADER
+
+#include "newcmdposixcl.h"
+
+#include "hwcl.h"
+
+
+extern const char *keysets[8];
+
+
+class cl_port_io: public cl_hw_io
+{
+ public:
+ cl_port_io(class cl_hw *ihw);
+ virtual int init(void);
+ //virtual bool input_avail(void);
+};
+
+class cl_port_data: public cl_base
+{
+ public:
+ class cl_memory_cell *cell_p, *cell_in, *cell_dir;
+ t_mem cache_p, cache_in, cache_dir, cache_value;
+ char *keyset;
+ int basx, basy;
+};
+
+enum { NUOF_PORT_UIS= 16 };
+
+class cl_port_ui: public cl_hw
+{
+ public:
+ class cl_port_data pd[16];
+ int act_port;
+ public:
+ cl_port_ui(class cl_uc *auc, int aid, chars aid_string);
+
+ virtual bool add_port(class cl_port_data *p, int nr);
+
+ virtual void make_io(void);
+ virtual void new_io(class cl_f *f_in, class cl_f *f_out);
+ virtual bool proc_input(void);
+ virtual bool handle_input(int c);
+ virtual void refresh_display(bool force);
+ virtual void draw_display(void);
+};
+
+
+#endif
+
+/* End of sim.src/port_hwcl.h */
diff --git a/sim/ucsim/sim.src/serial_hw.cc b/sim/ucsim/sim.src/serial_hw.cc
new file mode 100644
index 0000000..529b43d
--- /dev/null
+++ b/sim/ucsim/sim.src/serial_hw.cc
@@ -0,0 +1,511 @@
+/*
+ * Simulator of microcontrollers (sim.src/serial_hw.cc)
+ *
+ * Copyright (C) 2016,16 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@*/
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <ctype.h>
+
+#include "utils.h"
+#include "globals.h"
+#include "fiocl.h"
+
+#include "serial_hwcl.h"
+
+
+bool
+cl_serial_io::input_avail(void)
+{
+ return cl_hw_io::input_avail();
+}
+
+
+cl_serial_hw::cl_serial_hw(class cl_uc *auc, int aid, chars aid_string):
+ cl_hw(auc, HW_UART, aid, (const char *)aid_string)
+{
+ listener= 0;
+}
+
+cl_serial_hw::~cl_serial_hw(void)
+{
+ delete serial_in_file_option;
+ delete serial_out_file_option;
+ delete io;
+}
+
+int
+cl_serial_hw::init(void)
+{
+ char *s;
+
+ cl_hw::init();
+
+ make_io();
+ input_avail= false;
+
+ s= format_string("serial%d_in_file", id);
+ serial_in_file_option= new cl_optref(this);
+ serial_in_file_option->init();
+ serial_in_file_option->use(s);
+ free(s);
+ s= format_string("serial%d_out_file", id);
+ serial_out_file_option= new cl_optref(this);
+ serial_out_file_option->init();
+ serial_out_file_option->use(s);
+ free(s);
+
+ s= format_string("serial%d_port", id);
+ serial_port_option= new cl_optref(this);
+ serial_port_option->init();
+ class cl_option *o= serial_port_option->use(s);
+ free(s);
+
+ int port= -1;
+ if (o)
+ {
+ port= serial_port_option->get_value((long)0);
+ if (port < 0)
+ ;
+ }
+ if (port > 0)
+ {
+ listener= new cl_serial_listener(port, application, this, sl_io);
+ listener->init();
+ class cl_commander_base *c= application->get_commander();
+ c->add_console(listener);
+ }
+
+ o= NULL;
+ s= format_string("serial%d_iport", id);
+ serial_iport_option= new cl_optref(this);
+ serial_iport_option->init();
+ o= serial_iport_option->use(s);
+ free(s);
+
+ port= -1;
+ if (o)
+ {
+ port= serial_iport_option->get_value((long)0);
+ if (port < 0)
+ ;
+ }
+ if (port > 0)
+ {
+ listener= new cl_serial_listener(port, application, this, sl_i);
+ listener->init();
+ class cl_commander_base *c= application->get_commander();
+ c->add_console(listener);
+ }
+
+ o= NULL;
+ s= format_string("serial%d_oport", id);
+ serial_oport_option= new cl_optref(this);
+ serial_oport_option->init();
+ o= serial_oport_option->use(s);
+ free(s);
+
+ port= -1;
+ if (o)
+ {
+ port= serial_oport_option->get_value((long)0);
+ if (port < 0)
+ ;
+ }
+ if (port > 0)
+ {
+ listener= new cl_serial_listener(port, application, this, sl_o);
+ listener->init();
+ class cl_commander_base *c= application->get_commander();
+ c->add_console(listener);
+ }
+
+ char *f_serial_in = (char*)serial_in_file_option->get_value((char*)0);
+ char *f_serial_out= (char*)serial_out_file_option->get_value((char*)0);
+ class cl_f *fi, *fo;
+ if (f_serial_in)
+ {
+ if (f_serial_in[0] == '\001')
+ fi= (class cl_f *)(strtoll(&f_serial_in[1], 0, 0));
+ else
+ fi= mk_io(chars(f_serial_in), cchars("r"));
+ if (!fi->tty)
+ fprintf(stderr, "Warning: serial input interface connected to a "
+ "non-terminal file.\n");
+ }
+ else
+ fi= 0;//mk_io(chars(""), chars(""));
+ if (f_serial_out)
+ {
+ if (f_serial_out[0] == '\001')
+ fo= (class cl_f *)(strtoll(&f_serial_out[1], 0, 0));
+ else
+ fo= mk_io(chars(f_serial_out), "w");
+ if (!fo->tty)
+ fprintf(stderr, "Warning: serial output interface connected to a "
+ "non-terminal file.\n");
+ }
+ else
+ fo= 0;//mk_io(chars(""), chars(""));
+
+ io->replace_files(true, fi, fo);
+
+ if (fi)
+ {
+ fi->interactive(NULL);
+ fi->raw();
+ fi->echo(NULL);
+ }
+
+ menu= 0;
+
+ cfg_set(serconf_on, true);
+ cfg_set(serconf_check_often, false);
+ cfg_set(serconf_escape, 'x'-'a'+1);
+
+ cl_var *v;
+ chars pn(id_string);
+ pn.append("%d_", id);
+ uc->vars->add(v= new cl_var(pn+chars("on"), cfg, serconf_on,
+ cfg_help(serconf_on)));
+ v->init();
+ uc->vars->add(v= new cl_var(pn+chars("check_often"), cfg, serconf_check_often,
+ cfg_help(serconf_check_often)));
+ v->init();
+ uc->vars->add(v= new cl_var(pn+chars("esc_char"), cfg, serconf_escape,
+ cfg_help(serconf_escape)));
+ v->init();
+
+ uc->vars->add(v= new cl_var(pn+chars("received_char"), cfg, serconf_received,
+ cfg_help(serconf_received)));
+ v->init();
+
+ uc->vars->add(v= new cl_var(pn+chars("flowctrl"), cfg, serconf_flowctrl,
+ cfg_help(serconf_flowctrl)));
+ v->init();
+
+ uc->vars->add(v= new cl_var(pn+chars("able_receive"), cfg, serconf_able_receive,
+ cfg_help(serconf_able_receive)));
+ v->init();
+
+ cfg_set(serconf_able_receive, 1);
+ return 0;
+}
+
+char *
+cl_serial_hw::cfg_help(t_addr addr)
+{
+ switch (addr)
+ {
+ case serconf_on:
+ return (char*)"Turn simulation of UART on or off (bool, RW)";
+ case serconf_check_often:
+ return (char*)"Check input file at every cycle (bool, RW)";
+ case serconf_escape:
+ return (char*)"Escape char on display (int, RW)";
+ case serconf_common:
+ return (char*)"Not used";
+ case serconf_received:
+ return (char*)"Received char written by simulator (int, R)";
+ case serconf_flowctrl:
+ return (char*)"Flow-control simulation on/off (bool, RW)";
+ case serconf_able_receive:
+ return (char*)"UART enabled to receive by flow-control (bool, RW)";
+ }
+ return (char*)"Not used";
+}
+
+t_mem
+cl_serial_hw::conf_op(cl_memory_cell *cell, t_addr addr, t_mem *val)
+{
+ switch ((enum serial_cfg)addr)
+ {
+ case serconf_on: // turn this HW on/off
+ if (val)
+ {
+ if (*val)
+ on= true;
+ else
+ on= false;
+ }
+ else
+ {
+ cell->set(on?1:0);
+ }
+ break;
+ case serconf_check_often:
+ if (val)
+ {
+ cell->set(*val?1:0);
+ }
+ break;
+ case serconf_escape:
+ if (val)
+ {
+ char c= tolower(*val);
+ if ((c >= 'a') &&
+ (c <= 'z'))
+ cell->set(c - 'a'+1);
+ }
+ default:
+ break;
+ }
+ return cell->get();
+}
+
+void
+cl_serial_hw::make_io()
+{
+ if (!io)
+ {
+ io= new cl_serial_io(this);
+ application->get_commander()->add_console(io);
+ }
+}
+
+void
+cl_serial_hw::new_io(class cl_f *f_in, class cl_f *f_out)
+{
+ char esc= (char)cfg_get(serconf_escape);
+ cl_hw::new_io(f_in, f_out);
+ if (io)
+ io->dd_printf("%s[%d] terminal display, press ^%c to access control menu\n",
+ id_string, id,
+ 'a'+esc-1);
+ menu= 0;
+}
+
+bool
+cl_serial_hw::proc_input(void)
+{
+ int c;
+ char esc= (char)cfg_get(serconf_escape);
+ bool run= uc->sim->state & SIM_GO;
+ class cl_f *fin, *fout;
+ int flw= cfg_get(serconf_flowctrl);
+ int able= cfg_get(serconf_able_receive);
+
+ fin= io->get_fin();
+ fout= io->get_fout();
+
+ if (fin->eof())
+ {
+ if (fout &&
+ (fout->file_id == fin->file_id))
+ {
+ delete fout;
+ io->replace_files(false, fin, 0);
+ fout= 0;
+ }
+ delete fin;
+ io->replace_files(false, 0, fout);
+ return true;
+ }
+ if (menu == 0)
+ {
+ if (fin->tty && !flw)
+ {
+ if (fin->read(&c, 1))
+ {
+ if (c == esc)
+ {
+ menu= 'm';
+ io->dd_printf("\n");
+ io->dd_cprintf("ui_title", "Simulator control menu\n");
+ io->dd_cprintf("ui_mkey", " %c ", 'a'+esc-1);
+ io->dd_cprintf("ui_mitem", "Insert ^%c\n", 'a'+esc-1);
+ io->dd_cprintf("ui_mkey", " s,r,g ");
+ io->dd_cprintf("ui_mitem", "Start simulation\n");
+ io->dd_cprintf("ui_mkey", " p ");
+ io->dd_cprintf("ui_mitem", "Stop simulation\n");
+ io->dd_cprintf("ui_mkey", " T ");
+ io->dd_cprintf("ui_mitem", "Reset CPU\n");
+ io->dd_cprintf("ui_mkey", " q ");
+ io->dd_cprintf("ui_mitem", "Quit simulator\n");
+ io->dd_cprintf("ui_mkey", " o ");
+ io->dd_cprintf("ui_mitem", "Close serial terminal\n");
+ io->dd_cprintf("ui_mkey", " e ");
+ io->dd_cprintf("ui_mitem", "Exit menu\n");
+ io->dd_cprintf("ui_mkey", " n ");
+ io->dd_cprintf("ui_mitem", "Change display\n");
+ }
+ else if (!input_avail)
+ {
+ input= c;
+ input_avail= true;
+ }
+ }
+ }
+ else if (!input_avail)
+ {
+ if (!flw ||
+ able)
+ {
+ if (fin->read(&c, 1))
+ {
+ input= c;
+ input_avail= true;
+ cfg_set(serconf_able_receive, 0);
+ }
+ }
+ }
+ }
+ else
+ {
+ if (fin->read(&c, 1))
+ {
+ switch (menu)
+ {
+ case 'm':
+ if ((c == esc-1+'a') ||
+ (c == esc-1+'A') ||
+ (c == esc))
+ {
+ // insert ^esc
+ if (run && !input_avail)
+ {
+ input= esc, input_avail= true;
+ io->dd_printf("^%c enterted.\n", 'a'+esc-1);
+ }
+ else
+ io->dd_printf("Control menu exited.\n");
+ menu= 0;
+ }
+ switch (c)
+ {
+ case 'e': case 'E': case 'e'-'a'+1:
+ // exit menu
+ menu= 0;
+ io->dd_printf("Control menu exited.\n");
+ break;
+ case 's': case 'S': case 's'-'a'+1:
+ case 'r': case 'R': case 'r'-'a'+1:
+ case 'g': case 'G': case 'g'-'a'+1:
+ // start
+ uc->sim->start(0, 0);
+ menu= 0;
+ io->dd_printf("Simulation started.\n");
+ break;
+ case 'p': case 'P': case 'p'-'a'+1:
+ uc->sim->stop(resSIMIF);
+ // stop
+ menu= 0;
+ io->dd_printf("Simulation stopped.\n");
+ break;
+ case 'T':
+ uc->reset();
+ menu= 0;
+ io->dd_printf("CPU reset.\n");
+ break;
+ case 'q': case 'Q': case 'q'-'a'+1:
+ // kill
+ uc->sim->state|= SIM_QUIT;
+ menu= 0;
+ io->dd_printf("Exit simulator.\n");
+ break;
+ case 'o': case 'O': case 'o'-'a'+1:
+ {
+ // close
+ io->dd_printf("Closing terminal.\n");
+ menu= 0;
+ io->convert2console();
+ break;
+ }
+ case 'n': case 'N': case 'n'-'a'+1:
+ {
+ class cl_hw *h= next_displayer();
+ if (!h)
+ io->dd_printf("No other displayer.\n");
+ else
+ {
+ io->tu_reset();
+ io->tu_cls();
+ io->pass2hw(h);
+ }
+ menu= 0;
+ break;
+ }
+ default:
+ menu= 0;
+ io->dd_printf("Control menu closed (%d).\n", c);
+ break;
+ }
+ break;
+ }
+ }
+ }
+ return true;
+}
+
+void
+cl_serial_hw::reset(void)
+{
+ cfg_set(serconf_able_receive, 1);
+}
+
+cl_serial_listener::cl_serial_listener(int serverport, class cl_app *the_app,
+ class cl_serial_hw *the_serial,
+ enum ser_listener_for slf):
+ cl_listen_console(serverport, the_app)
+{
+ serial_hw= the_serial;
+ sl_for= slf;
+}
+
+int
+cl_serial_listener::init(void)
+{
+ if (serial_hw)
+ set_name(chars("", "serial_listener_%s_%d\n", serial_hw->get_name(), serial_hw->id));
+ return 0;
+}
+
+int
+cl_serial_listener::proc_input(class cl_cmdset *cmdset)
+{
+ class cl_f *i, *o;
+
+ switch (sl_for)
+ {
+ case sl_io:
+ srv_accept(fin, &i, &o);
+ i->set_telnet(true);
+ serial_hw->new_io(i, o);
+ break;
+ case sl_i:
+ srv_accept(fin, &i, NULL);
+ i->set_telnet(true);
+ serial_hw->new_i(i);
+ break;
+ case sl_o:
+ srv_accept(fin, NULL, &o);
+ serial_hw->new_o(o);
+ break;
+ }
+ return 0;
+}
+
+
+/* End of sim.src/serial_hw.cc */
diff --git a/sim/ucsim/sim.src/serial_hw.o b/sim/ucsim/sim.src/serial_hw.o
new file mode 100644
index 0000000..470f2e0
--- /dev/null
+++ b/sim/ucsim/sim.src/serial_hw.o
Binary files differ
diff --git a/sim/ucsim/sim.src/serial_hwcl.h b/sim/ucsim/sim.src/serial_hwcl.h
new file mode 100644
index 0000000..9001adc
--- /dev/null
+++ b/sim/ucsim/sim.src/serial_hwcl.h
@@ -0,0 +1,113 @@
+/*
+ * Simulator of microcontrollers (sim.src/serial_hwcl.h)
+ *
+ * Copyright (C) 2016,16 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 SERIAL_HWCL_HEADER
+#define SERIAL_HWCL_HEADER
+
+#include "newcmdposixcl.h"
+
+#include "hwcl.h"
+
+
+enum serial_cfg {
+ serconf_on = 0,
+ serconf_check_often = 1,
+ serconf_escape = 2,
+ serconf_common = 3,
+ serconf_received = 4,
+ serconf_flowctrl = 5,
+ serconf_able_receive = 6,
+ serconf_nr = 7
+};
+
+
+class cl_serial_io: public cl_hw_io
+{
+ public:
+ cl_serial_io(class cl_hw *ihw):
+ cl_hw_io(ihw)
+ {}
+ //virtual bool prevent_quit(void) { return true; }
+ virtual bool input_avail(void);
+};
+
+class cl_serial_hw: public cl_hw
+{
+ protected:
+ class cl_optref *serial_in_file_option;
+ class cl_optref *serial_out_file_option;
+ class cl_optref *serial_port_option;
+ class cl_optref *serial_iport_option;
+ class cl_optref *serial_oport_option;
+ class cl_serial_listener *listener;
+ //class cl_hw_io *io;
+ char input;
+ bool input_avail;
+ char menu;
+ public:
+ cl_serial_hw(class cl_uc *auc, int aid, chars aid_string);
+ virtual ~cl_serial_hw(void);
+ virtual int init(void);
+ virtual int cfg_size(void) { return serconf_nr; }
+ virtual char *cfg_help(t_addr addr);
+
+ virtual t_mem conf_op(cl_memory_cell *cell, t_addr addr, t_mem *val);
+
+ virtual void make_io(void);
+ virtual void new_io(class cl_f *f_in, class cl_f *f_out);
+ virtual bool proc_input(void);
+ virtual void refresh_display(bool force) {}
+ virtual void draw_display(void) {}
+
+ virtual void reset(void);
+};
+
+enum ser_listener_for
+ {
+ sl_io,
+ sl_i,
+ sl_o
+ };
+
+class cl_serial_listener: public cl_listen_console
+{
+protected:
+ enum ser_listener_for sl_for;
+ public:
+ class cl_serial_hw *serial_hw;
+ cl_serial_listener(int serverport, class cl_app *the_app,
+ class cl_serial_hw *the_serial,
+ enum ser_listener_for slf);
+ virtual int init(void);
+ virtual int proc_input(class cl_cmdset *cmdset);
+ virtual bool prevent_quit(void) { return false; }
+};
+
+
+#endif
+
+/* End of sim.src/serial_hwcl.h */
diff --git a/sim/ucsim/sim.src/sim.cc b/sim/ucsim/sim.src/sim.cc
new file mode 100644
index 0000000..9b71c3c
--- /dev/null
+++ b/sim/ucsim/sim.src/sim.cc
@@ -0,0 +1,372 @@
+/*
+ * Simulator of microcontrollers (sim.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@*/
+
+#include "ddconfig.h"
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <unistd.h>
+#include "i_string.h"
+
+// prj
+#include "globals.h"
+#include "utils.h"
+
+// cmd
+#include "cmd_execcl.h"
+#include "cmd_guicl.h"
+
+// local, sim.src
+#include "simcl.h"
+#include "appcl.h"
+#include "simifcl.h"
+
+
+/*
+ * Simulator
+ */
+
+cl_sim::cl_sim(class cl_app *the_app):
+ cl_base()
+{
+ app= the_app;
+ uc= 0;
+ state= SIM_NONE;
+ //arguments= new cl_list(2, 2);
+ //accept_args= more_args?strdup(more_args):0;
+ gui= new cl_gui(this);
+}
+
+int
+cl_sim::init(void)
+{
+ cl_base::init();
+ build_cmdset(app->get_commander()->cmdset);
+ if (!(uc= mk_controller()))
+ return(1);
+ uc->init();
+ simif= uc->get_hw(cchars("simif"), 0);
+ return(0);
+}
+
+cl_sim::~cl_sim(void)
+{
+ if (uc)
+ delete uc;
+}
+
+class cl_uc *
+cl_sim::mk_controller(void)
+{
+ return(new cl_uc(this));
+}
+
+
+int
+cl_sim::step(void)
+{
+ if (state & SIM_GO)
+ {
+ if (steps_done == 0)
+ {
+ start_at= dnow();
+ }
+ if (uc->do_inst(1) == resGO)
+ steps_done++;
+ if ((steps_todo > 0) &&
+ (steps_done >= steps_todo))
+ stop(resSTEP);
+ }
+ return(0);
+}
+
+/*int
+cl_sim::do_cmd(char *cmdstr, class cl_console *console)
+{
+ class cl_cmdline *cmdline;
+ class cl_cmd *cm;
+ int retval= 0;
+
+ cmdline= new cl_cmdline(cmdstr, console);
+ cmdline->init();
+ cm= cmd->cmdset->get_cmd(cmdline);
+ if (cm)
+ retval= cm->work(cmdline, console);
+ delete cmdline;
+ if (cm)
+ return(retval);
+ return(console->interpret(cmdstr));
+}*/
+
+void
+cl_sim::start(class cl_console_base *con, unsigned long steps_to_do)
+{
+ state|= SIM_GO;
+ if (con)
+ {
+ con->set_flag(CONS_FROZEN, true);
+ app->get_commander()->frozen_console= con;
+ app->get_commander()->update_active();
+ }
+ if (uc)
+ start_tick= uc->ticks->ticks;
+ steps_done= 0;
+ steps_todo= steps_to_do;
+}
+
+void
+cl_sim::stop(int reason, class cl_ev_brk *ebrk)
+{
+ class cl_commander_base *cmd= app->get_commander();
+ class cl_option *o= app->options->get_option("quit");
+ bool q_opt= false;
+
+ if (o)
+ o->get_value(&q_opt);
+
+ state&= ~SIM_GO;
+ stop_at= dnow();
+ if (simif)
+ simif->cfg_set(simif_reason, reason);
+
+ class cl_brk *b= NULL;
+ if (reason == resBREAKPOINT)
+ {
+ b= uc->fbrk_at(uc->PC);
+ }
+ else if (ebrk != NULL)
+ {
+ b= ebrk;
+ }
+ if (b)
+ {
+ if (!(b->commands.empty()))
+ {
+ class cl_option *o= app->options->get_option("echo_script");
+ bool e= false;
+ if (o) o->get_value(&e);
+ if (e)
+ cmd->dd_printf("%s\n", (char*)(b->commands));
+ application->exec(b->commands);
+ steps_done= 0;
+ }
+ }
+
+ if (!(state & SIM_GO) &&
+ cmd->frozen_console)
+ {
+ if (reason == resUSER &&
+ cmd->frozen_console->input_avail())
+ cmd->frozen_console->read_line();
+ cmd->frozen_console->un_redirect();
+ cmd->frozen_console->dd_color("debug");
+ cmd->frozen_console->dd_printf("Stop at 0x%06x: (%d) ", AU(uc->PC), reason);
+ switch (reason)
+ {
+ case resHALT:
+ cmd->frozen_console->dd_printf("Halted\n");
+ break;
+ case resINV_ADDR:
+ cmd->frozen_console->dd_printf("Invalid address\n");
+ break;
+ case resSTACK_OV:
+ cmd->frozen_console->dd_printf("Stack overflow\n");
+ break;
+ case resBREAKPOINT:
+ cmd->frozen_console->dd_printf("Breakpoint\n");
+ if (cmd->frozen_console)
+ uc->print_regs(cmd->frozen_console);
+ break;
+ case resEVENTBREAK:
+ cmd->frozen_console->dd_printf("Event break\n");
+ //uc->print_regs(cmd->frozen_console);
+ if (b)
+ {
+ class cl_ev_brk *eb= (cl_ev_brk*)b;
+ class cl_address_space *m= eb->get_mem();
+ cmd->frozen_console->dd_printf("Event `%s' at %s[0x%x]: 0x%x %s\n",
+ eb->id, m?(m->get_name()):"mem?",
+ AU(eb->addr),
+ AU(uc->instPC),
+ uc->disass(uc->instPC, " "));
+ }
+ break;
+ case resINTERRUPT:
+ cmd->frozen_console->dd_printf("Interrupt\n");
+ break;
+ case resWDTRESET:
+ cmd->frozen_console->dd_printf("Watchdog reset\n");
+ break;
+ case resUSER:
+ cmd->frozen_console->dd_printf("User stopped\n");
+ break;
+ case resINV_INST:
+ {
+ cmd->frozen_console->dd_printf("Invalid instruction");
+ if (uc->rom)
+ cmd->frozen_console->dd_printf(" 0x%04x\n",
+ MU32(uc->rom->get(uc->PC)));
+ }
+ break;
+ case resSTEP:
+ cmd->frozen_console->dd_printf("\n");
+ uc->print_regs(cmd->frozen_console);
+ break;
+ case resERROR:
+ // uc::check_error prints error messages...
+ break;
+ case resSIMIF:
+ cmd->frozen_console->dd_printf("Program stopped itself\n");
+ break;
+ default:
+ cmd->frozen_console->dd_printf("Unknown reason\n");
+ break;
+ }
+ cmd->frozen_console->dd_printf("F 0x%06x\n", AU(uc->PC)); // for sdcdb
+ unsigned long dt= uc?(uc->ticks->ticks - start_tick):0;
+ if ((reason != resSTEP) ||
+ (steps_done > 1))
+ cmd->frozen_console->dd_printf("Simulated %lu ticks in %f sec, rate=%f\n",
+ dt,
+ stop_at - start_at,
+ (dt*(1/uc->xtal)) / (stop_at - start_at));
+ //if (cmd->actual_console != cmd->frozen_console)
+ cmd->frozen_console->set_flag(CONS_FROZEN, false);
+ //cmd->frozen_console->dd_printf("_s_");
+ cmd->frozen_console->print_prompt();
+ cmd->frozen_console= 0;
+ }
+ if (!(state & SIM_GO) &&
+ q_opt)
+ state|= SIM_QUIT;
+ cmd->update_active();
+}
+/*
+void
+cl_sim::stop(class cl_ev_brk *brk)
+{
+ class cl_commander_base *cmd= app->get_commander();
+ class cl_option *o= app->options->get_option("quit");
+ bool q_opt= false;
+
+ if (o)
+ o->get_value(&q_opt);
+
+ //state&= ~SIM_GO;
+ if (simif)
+ simif->cfg_set(simif_reason, resEVENTBREAK);
+
+ if (brk)
+ {
+ if (!(brk->commands.empty()))
+ {
+ application->exec(brk->commands);
+ steps_done= 0;
+ printf("event brk PC=%ld, simgo=%d\n",uc->PC,state&SIM_GO);
+ }
+ }
+
+ if (!(state & SIM_GO) &&
+ cmd->frozen_console)
+ {
+ class cl_console_base *con= cmd->frozen_console;
+ con->dd_printf("Event `%s' at %s[0x%x]: 0x%x %s\n",
+ brk->id, brk->get_mem()->get_name(), (int)brk->addr,
+ (int)uc->instPC,
+ uc->disass(uc->instPC, " "));
+ }
+ if (!(state & SIM_GO) &&
+ q_opt)
+ state|= SIM_QUIT;
+}
+*/
+
+void
+cl_sim::change_run(int reason)
+{
+ if (state & SIM_GO)
+ stop(reason);
+ else
+ start(0, 0);
+}
+
+/*
+ */
+
+void
+cl_sim::build_cmdset(class cl_cmdset *cmdset)
+{
+ class cl_cmd *cmd;
+ //class cl_cmdset *cset;
+
+ cmdset->add(cmd= new cl_run_cmd("run", 0));
+ cmd->init();
+ cmd->add_name("go");
+ cmd->add_name("r");
+ cmd->add_name("continue");
+
+ cmdset->add(cmd= new cl_stop_cmd("stop", 0));
+ cmd->init();
+
+ cmdset->add(cmd= new cl_step_cmd("step", true));
+ cmd->init();
+ cmd->add_name("s");
+
+ cmdset->add(cmd= new cl_next_cmd("next", true));
+ cmd->init();
+ cmd->add_name("n");
+
+ /*{
+ cset= new cl_cmdset();
+ cset->init();
+ cset->add(cmd= new cl_gui_start_cmd("start", 0));
+ cmd->init();
+ cset->add(cmd= new cl_gui_stop_cmd("stop", 0));
+ cmd->init();
+ }
+ cmdset->add(cmd= new cl_super_cmd("gui", 0, cset));
+ cmd->init();
+ set_gui_help();
+ */
+}
+
+
+/*
+ * Messages to broadcast
+ */
+/*
+void
+cl_sim::mem_cell_changed(class cl_address_space *mem, t_addr addr)
+{
+ if (uc)
+ uc->mem_cell_changed(mem, addr);
+ else
+ printf("JAJ sim\n");
+}
+*/
+
+/* End of sim.src/sim.cc */
diff --git a/sim/ucsim/sim.src/sim.o b/sim/ucsim/sim.src/sim.o
new file mode 100644
index 0000000..599802e
--- /dev/null
+++ b/sim/ucsim/sim.src/sim.o
Binary files differ
diff --git a/sim/ucsim/sim.src/simcl.h b/sim/ucsim/sim.src/simcl.h
new file mode 100644
index 0000000..43c0b3c
--- /dev/null
+++ b/sim/ucsim/sim.src/simcl.h
@@ -0,0 +1,84 @@
+/*
+ * Simulator of microcontrollers (sim.src/simcl.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 SIM_SIMCL_HEADER
+#define SIM_SIMCL_HEADER
+
+#include <stdio.h>
+
+// prj
+#include "pobjcl.h"
+
+// cmd
+#include "newcmdcl.h"
+
+// gui
+#include "guicl.h"
+
+// local
+#include "uccl.h"
+#include "argcl.h"
+
+
+class cl_sim: public cl_base
+{
+public:
+ class cl_app *app;
+ int state; // See SIM_XXXX
+ int argc; char **argv;
+
+ //class cl_commander *cmd;
+ class cl_uc *uc;
+ class cl_gui *gui;
+ class cl_hw *simif;
+
+ double start_at, stop_at;
+ unsigned long start_tick;
+ unsigned long steps_done;
+ unsigned long steps_todo; // use this if not 0
+
+public:
+ cl_sim(class cl_app *the_app);
+ virtual ~cl_sim(void);
+ virtual int init(void);
+
+ virtual class cl_uc *mk_controller(void);
+ virtual void build_cmdset(class cl_cmdset *cmdset);
+
+ virtual class cl_uc *get_uc(void) { return(uc); }
+
+ virtual void start(class cl_console_base *con, unsigned long steps_to_do);
+ virtual void stop(int reason, class cl_ev_brk *ebrk= NULL);
+ virtual void change_run(int reason= resSIMIF);
+ //virtual void stop(class cl_ev_brk *brk);
+ virtual int step(void);
+};
+
+
+#endif
+
+/* End of simcl.h */
diff --git a/sim/ucsim/sim.src/simif.cc b/sim/ucsim/sim.src/simif.cc
new file mode 100644
index 0000000..6eefc66
--- /dev/null
+++ b/sim/ucsim/sim.src/simif.cc
@@ -0,0 +1,972 @@
+/*
+ * Simulator of microcontrollers (sim.src/simif.cc)
+ *
+ * Copyright (C) 2016,16 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@*/
+
+#include <stdlib.h>
+#include <string.h>
+#include <ctype.h>
+#include "i_string.h"
+
+// prj
+#include "globals.h"
+
+// sim
+#include "simcl.h"
+
+#include "simifcl.h"
+
+
+/* Interface command */
+
+cl_sif_command::cl_sif_command(enum sif_command cmd,
+ const char *the_name,
+ const char *the_description,
+ enum sif_answer_type the_answer_type,
+ int the_params_needed,
+ class cl_simulator_interface *the_sif):
+ cl_base()
+{
+ command= cmd;
+ set_name(the_name);
+ description= strdup(the_description);
+ answer_type= the_answer_type;
+ sif= the_sif;
+ parameters= 0;
+ answer= 0;
+ params_needed= the_params_needed;
+ nuof_params= params_received= 0;
+ answer_length= answered_bytes= 0;
+ answering= false;
+}
+
+cl_sif_command::~cl_sif_command(void)
+{
+ if (description)
+ free(description);
+ clear_params();
+ clear_answer();
+}
+
+int
+cl_sif_command::init(void)
+{
+ clear_params();
+ clear_answer();
+ return(0);
+}
+
+void
+cl_sif_command::clear_params(void)
+{
+ nuof_params= 0;
+ params_received= 0;
+ if (parameters)
+ free(parameters);
+}
+
+void
+cl_sif_command::clear_answer(void)
+{
+ answer_length= 0;
+ answered_bytes= 0;
+ if (answer)
+ free(answer);
+ answer= 0;
+}
+
+void
+cl_sif_command::clear(void)
+{
+ clear_params();
+ clear_answer();
+}
+
+
+bool
+cl_sif_command::get_parameter(int nr, t_mem *into)
+{
+ if (!parameters ||
+ nr >= nuof_params)
+ return(false);
+ if (into)
+ *into= parameters[nr];
+ return(true);
+}
+
+
+t_mem
+cl_sif_command::read(class cl_memory_cell *cel)
+{
+ t_mem ret= cel->get();
+
+ if (answering &&
+ answer)
+ {
+ if (answered_bytes < answer_length)
+ {
+ ret= answer[answered_bytes];
+ answered_bytes++;
+ }
+ if (answered_bytes >= answer_length)
+ {
+ sif->finish_command();
+ }
+ }
+ return(ret);
+}
+
+void
+cl_sif_command::write(class cl_memory_cell *cel, t_mem *val)
+{
+ if (nuof_params &&
+ params_received < nuof_params &&
+ parameters)
+ {
+ parameters[params_received]= *val;
+ params_received++;
+ if (params_received >= nuof_params)
+ {
+ produce_answer();
+ start_answer();
+ }
+ }
+}
+
+
+void
+cl_sif_command::start(void)
+{
+ need_params(params_needed);
+}
+
+void
+cl_sif_command::need_params(int nr)
+{
+ clear_params();
+ if (nr <= 0)
+ {
+ produce_answer();
+ start_answer();
+ }
+ nuof_params= nr;
+ params_received= 0;
+ parameters= (t_mem *)calloc(nr, sizeof(t_mem));
+}
+
+void
+cl_sif_command::produce_answer(void)
+{
+ clear_answer();
+}
+
+void
+cl_sif_command::set_answer(t_mem ans)
+{
+ clear_answer();
+ answer= (t_mem *)calloc(1, sizeof(t_mem));
+ answer[0]= ans;
+ answer_length= 1;
+}
+
+void
+cl_sif_command::set_answer(int nr, t_mem ans[])
+{
+ clear_answer();
+ answer= (t_mem *)calloc(nr+1, sizeof(t_mem));
+ answer[0]= nr;
+ int i;
+ for (i= 0; i < nr; i++)
+ answer[i+1]= ans[i];
+ answer_length= nr+1;
+}
+
+void
+cl_sif_command::set_answer(const char *ans)
+{
+ clear_answer();
+ if (ans &&
+ *ans)
+ {
+ answer= (t_mem *)calloc(strlen(ans)+2, sizeof(t_mem));
+ int i= 0;
+ answer[0]= strlen(ans)+1;
+ while (ans[i])
+ {
+ answer[i+1]= ans[i];
+ i++;
+ }
+ answer[i+1]= '\0';
+ answer_length= i+2;
+ }
+}
+
+void
+cl_sif_command::start_answer(void)
+{
+ if (answer_length)
+ answering= true;
+ else
+ {
+ answering= false;
+ sif->finish_command();
+ }
+}
+
+
+/* Command: get info about commands */
+
+void
+cl_sif_commands::produce_answer(void)
+{
+ int c, i;
+ if (!sif)
+ return;
+ c= sif->commands->count;
+ answer= (t_mem*)calloc(c+1, sizeof(t_mem));
+ answer[0]= c;
+ for (i= 0; i < c; i++)
+ {
+ answer[i+1]= 0;
+ class cl_sif_command *sc=
+ dynamic_cast<class cl_sif_command *>(sif->commands->object_at(i));
+ if (!sc)
+ continue;
+ answer[i+1]= sc->get_command();
+ }
+ answer_length= c+1;
+}
+
+
+/* Command: get info about a command */
+
+void
+cl_sif_cmdinfo::produce_answer(void)
+{
+ int i;
+ if (!sif)
+ return;
+ t_mem cm;
+ if (!get_parameter(0, &cm))
+ return;
+ answer= (t_mem*)calloc(1+2, sizeof(t_mem));
+ answer[0]= 2;
+ class cl_sif_command *about= 0;
+ for (i= 0; i < sif->commands->count; i++)
+ {
+ class cl_sif_command *sc=
+ dynamic_cast<class cl_sif_command *>(sif->commands->object_at(i));
+ if (sc->get_command() == (enum sif_command)cm)
+ {
+ about= sc;
+ break;
+ }
+ }
+ if (about)
+ {
+ answer[1]= about->get_params_needed();
+ answer[2]= about->get_answer_type();
+ }
+ answer_length= 3;
+}
+
+
+/* Command: get help about a command */
+
+void
+cl_sif_cmdhelp::produce_answer(void)
+{
+ int i;
+ if (!sif)
+ return;
+ t_mem cm;
+ if (!get_parameter(0, &cm))
+ return;
+ class cl_sif_command *about= 0;
+ for (i= 0; i < sif->commands->count; i++)
+ {
+ class cl_sif_command *sc=
+ dynamic_cast<class cl_sif_command *>(sif->commands->object_at(i));
+ if (sc->get_command() == (enum sif_command)cm)
+ {
+ about= sc;
+ break;
+ }
+ }
+ if (about)
+ set_answer(about->get_description());
+ else
+ set_answer((t_mem)0);
+}
+
+
+/* Command: stop simulation */
+
+void
+cl_sif_stop::produce_answer(void)
+{
+ class cl_sim *sim= 0;
+ if (sif)
+ if (sif->uc)
+ sim= sif->uc->sim;
+ set_answer(SIFCM_STOP);
+ if (sim)
+ sim->stop(resSIMIF);
+}
+
+
+/* Command: print character */
+
+void
+cl_sif_print::produce_answer(void)
+{
+ t_mem cm;
+ if (get_parameter(0, &cm))
+ {
+ //printf("** SIF_PRINT 0x%02x,'%c'\n", cm, cm);
+ putchar(cm);
+ fflush(stdout);
+ }
+ if (sif)
+ sif->finish_command();
+}
+
+
+/* Command: print character in hex */
+
+void
+cl_sif_hex::produce_answer(void)
+{
+ t_mem cm;
+ if (get_parameter(0, &cm))
+ {
+ //printf("** SIF_HEX 0x%02x,'%c'\n", cm, cm);
+ printf("%02x", cm);
+ fflush(stdout);
+ }
+ if (sif)
+ sif->finish_command();
+}
+
+
+/* Command: write character to output file */
+
+void
+cl_sif_write::produce_answer(void)
+{
+ t_mem cm;
+ if (sif)
+ {
+ if (get_parameter(0, &cm))
+ {
+ if (sif->fout)
+ {
+ char c= cm;
+ sif->fout->write(&c, 1);
+ }
+ }
+ }
+ if (sif)
+ sif->finish_command();
+}
+
+
+/* Command: check input file */
+
+void
+cl_sif_fin_check::produce_answer(void)
+{
+ int i= 0;
+ if (sif)
+ {
+ if (sif->fin)
+ {
+ i= sif->fin->input_avail();
+ if (i)
+ {
+ if (sif->fin->eof())
+ i= 0;
+ }
+ i= i?1:0;
+ }
+ }
+ set_answer(i);
+ answer_length= 1;
+}
+
+
+/* Command: read from input file */
+
+void
+cl_sif_read::produce_answer(void)
+{
+ int i= 0;
+ if (sif)
+ {
+ if (sif->fin)
+ {
+ int c;
+ if (sif->fin->input_avail())
+ {
+ i= sif->fin->read(&c, 1);
+ if (i != 0)
+ i= c;
+ }
+ }
+ }
+ set_answer(i);
+ answer_length= 1;
+}
+
+
+/* Command: reset */
+
+void
+cl_sif_reset::produce_answer(void)
+{
+ if (sif)
+ {
+ if (sif->uc)
+ sif->uc->reset();
+ sif->finish_command();
+ }
+}
+
+
+/*
+ * Virtual HW: simulator interface
+ */
+
+cl_simulator_interface::cl_simulator_interface(class cl_uc *auc):
+ cl_hw(auc, HW_SIMIF, 0, "simif")
+{
+ version= 1;
+ as_name= NULL;
+ addr= 0;
+ commands= new cl_list(2, 2, "sif_commands");
+ active_command= 0;
+}
+
+cl_simulator_interface::~cl_simulator_interface(void)
+{
+ if (as_name)
+ free((void*)as_name);
+ delete commands;
+}
+
+int
+cl_simulator_interface::init(void)
+{
+ cl_option *oas= application->options->get_option("simif_memory");
+ cl_option *oa = application->options->get_option("simif_address");
+ char *oas_v;
+ long oa_v;
+
+ cl_hw::init();
+ fin= fout= NULL;
+
+ if (oas &&
+ oa)
+ {
+ oas->get_value(&oas_v);
+ oa->get_value(&oa_v);
+ if (oas_v &&
+ (strlen(oas_v) > 0))
+ {
+ if (as_name)
+ free((void*)as_name);
+ as_name= strdup(oas_v);
+ addr= oa_v;
+ }
+ }
+
+ if (as_name)
+ {
+ as= uc->address_space(as_name);
+ if (as)
+ {
+ address= addr;
+ if (addr < 0)
+ address= as->highest_valid_address();
+ cell= register_cell(as, address);
+ }
+ else
+ fprintf(stderr, "Simif: %s is not a valid address space name\n", as_name);
+ }
+ else
+ {
+ as= NULL;
+ cell= NULL;
+ }
+
+ class cl_option *fo= application->options->get_option("simif_infile");
+ char *s;
+ if (fo)
+ {
+ fo->get_value(&s);
+ if (s &&
+ (strlen(s) > 0))
+ fin= mk_io(s, "r");
+ }
+ fo= application->options->get_option("simif_outfile");
+ if (fo)
+ {
+ fo->get_value(&s);
+ if (s &&
+ (strlen(s) > 0))
+ fout= mk_io(s, "w");
+ }
+
+ class cl_sif_command *c;
+ commands->add(c= new cl_sif_detect(this));
+ c->init();
+ commands->add(c= new cl_sif_commands(this));
+ c->init();
+ commands->add(c= new cl_sif_ifver(this));
+ c->init();
+ commands->add(c= new cl_sif_simver(this));
+ c->init();
+ commands->add(c= new cl_sif_ifreset(this));
+ c->init();
+ commands->add(c= new cl_sif_cmdinfo(this));
+ c->init();
+ commands->add(c= new cl_sif_cmdhelp(this));
+ c->init();
+ commands->add(c= new cl_sif_stop(this));
+ c->init();
+ commands->add(c= new cl_sif_print(this));
+ c->init();
+ commands->add(c= new cl_sif_hex(this));
+ c->init();
+ commands->add(c= new cl_sif_fin_check(this));
+ c->init();
+ commands->add(c= new cl_sif_read(this));
+ c->init();
+ commands->add(c= new cl_sif_write(this));
+ c->init();
+
+ cl_var *v;
+ uc->vars->add(v= new cl_var(cchars("simif_on"), cfg, simif_on,
+ cfg_help(simif_on)));
+ v->init();
+ cfg_set(simif_on, 1);
+ uc->vars->add(v= new cl_var(cchars("sim_run"), cfg, simif_run,
+ cfg_help(simif_run)));
+ v->init();
+ uc->vars->add(v= new cl_var(cchars("sim_start"), cfg, simif_start,
+ cfg_help(simif_start)));
+ v->init();
+ uc->vars->add(v= new cl_var(cchars("sim_stop"), cfg, simif_stop,
+ cfg_help(simif_stop)));
+ v->init();
+ uc->vars->add(v= new cl_var(cchars("sim_quit"), cfg, simif_quit,
+ cfg_help(simif_quit)));
+ v->init();
+ uc->vars->add(v= new cl_var(cchars("sim_reason"), cfg, simif_reason,
+ cfg_help(simif_reason)));
+ v->init();
+ uc->vars->add(v= new cl_var(cchars("sim_xtal"), cfg, simif_xtal,
+ cfg_help(simif_xtal)));
+ v->init();
+ uc->vars->add(v= new cl_var(cchars("sim_ticks"), cfg, simif_ticks,
+ cfg_help(simif_ticks)));
+ v->init();
+ uc->vars->add(v= new cl_var(cchars("sim_isr_ticks"), cfg, simif_isr_ticks,
+ cfg_help(simif_isr_ticks)));
+ v->init();
+ uc->vars->add(v= new cl_var(cchars("sim_idle_ticks"), cfg, simif_idle_ticks,
+ cfg_help(simif_idle_ticks)));
+ v->init();
+ uc->vars->add(v= new cl_var(cchars("sim_real_time"), cfg, simif_real_time,
+ cfg_help(simif_real_time)));
+ v->init();
+ uc->vars->add(v= new cl_var(cchars("sim_vclk"), cfg, simif_vclk,
+ cfg_help(simif_vclk)));
+ v->init();
+ uc->vars->add(v= new cl_var(cchars("PC"), cfg, simif_pc,
+ cfg_help(simif_pc)));
+ v->init();
+ uc->vars->add(v= new cl_var(cchars("sim_print"), cfg, simif_print,
+ cfg_help(simif_print)));
+ v->init();
+ uc->vars->add(v= new cl_var(cchars("sim_write"), cfg, simif_write,
+ cfg_help(simif_write)));
+ v->init();
+
+ return(0);
+}
+
+char *
+cl_simulator_interface::cfg_help(t_addr addr)
+{
+ switch (addr)
+ {
+ case simif_on : return (char*)"Turn simif on/off (bool, RW)";
+ case simif_run : return (char*)"WR: sets running state, RD: check if simulation is running";
+ case simif_start : return (char*)"WR: start simulation, RD: true if running";
+ case simif_stop : return (char*)"WR: stop simulation, RD: true if stopped";
+ case simif_quit : return (char*)"Quit simulator (any, WO)";
+ case simif_reason : return (char*)"Reason of last stop (int, RO)";
+ case simif_xtal : return (char*)"Xtal frequency in Hz (int, RW)";
+ case simif_ticks : return (char*)"Nuof ticks simulated so far (int, RO)";
+ case simif_isr_ticks: return (char*)"Ticks spent in ISR (int, RO)";
+ case simif_idle_ticks:return (char*)"Ticks spent in idle state (int, RO)";
+ case simif_real_time: return (char*)"Real time since reset in msec (int, RO)";
+ case simif_vclk : return (char*)"Nuof simulated virtual clocks (int, RO)";
+ case simif_pc : return (char*)"PC register (int, RW)";
+ case simif_print : return (char*)"Print char on stdout (int, WO)";
+ case simif_write : return (char*)"Write char to simif output (int, WO)";
+ }
+ return (char*)"Not used";
+}
+
+void
+cl_simulator_interface::set_cmd(class cl_cmdline *cmdline,
+ class cl_console_base *con)
+{
+ class cl_cmd_arg *params[2]= {
+ cmdline->param(0),
+ cmdline->param(1)
+ };
+
+ if (cmdline->syntax_match(uc, MEMORY ADDRESS))
+ {
+ class cl_memory *mem= params[0]->value.memory.memory;
+ t_addr a= params[1]->value.address;
+ if (!mem->is_address_space())
+ {
+ con->dd_printf("%s is not an address space\n");
+ return;
+ }
+ if (!mem->valid_address(a))
+ {
+ con->dd_printf("Address must be between 0x%x and 0x%x\n",
+ AU(mem->lowest_valid_address()),
+ AU(mem->highest_valid_address()));
+ return;
+ }
+ as_name= strdup((char*)mem->get_name());
+ addr= a;
+ if ((as= dynamic_cast<class cl_address_space *>(mem)) != 0)
+ {
+ address= addr;
+ if (addr < 0)
+ address= as->highest_valid_address();
+ if (cell != NULL)
+ unregister_cell(cell);
+ cell= register_cell(as, address);
+ }
+ }
+ else if (cmdline->syntax_match(uc, STRING STRING))
+ {
+ char *p1= params[0]->value.string.string;
+ char *p2= params[1]->value.string.string;
+ if (strcmp(p1, "fout") == 0)
+ {
+ if (fout)
+ delete fout;
+ fout= 0;
+ if ((strcmp(p2, "NULL") != 0) &&
+ (strcmp(p2, "(NULL)") != 0))
+ {
+ fout= mk_io(p2, "w");
+ }
+ }
+ else if (strcmp(p1, "fin") == 0)
+ {
+ if (fin)
+ delete fin;
+ fin= 0;
+ if ((strcmp(p2, "NULL") != 0) &&
+ (strcmp(p2, "(NULL)") != 0))
+ {
+ fin= mk_io(p2, "r");
+ }
+ }
+ }
+ else
+ {
+ con->dd_printf("set hardware simif memory address\n");
+ con->dd_printf("set hardware simif fin \"input_file_name\"\n");
+ con->dd_printf("set hardware simif fout \"output_file_name\"\n");
+ }
+}
+
+
+t_mem
+cl_simulator_interface::read(class cl_memory_cell *cel)
+{
+ if (conf(cel, NULL))
+ return cel->get();
+ if (!active_command)
+ {
+ t_mem d= cel->get();
+ return(~d & cel->get_mask());
+ }
+ else
+ {
+ t_mem ret= active_command->read(cel);
+ return(ret);
+ }
+ return(cel->get());
+}
+
+void
+cl_simulator_interface::write(class cl_memory_cell *cel, t_mem *val)
+{
+ if (conf(cel, val))
+ return;
+ if (!active_command)
+ {
+ int i;
+ for (i= 0; i < commands->count; i++)
+ {
+ class cl_sif_command *c=
+ dynamic_cast<class cl_sif_command *>(commands->object_at(i));
+ if (!c)
+ continue;
+ enum sif_command cm= c->get_command();
+ if ((enum sif_command)(*val) == cm)
+ {
+ active_command= c;
+ c->start();
+ return;
+ }
+ }
+ }
+ else
+ {
+ active_command->write(cel, val);
+ }
+}
+
+t_mem
+cl_simulator_interface::conf_op(cl_memory_cell *cell, t_addr addr, t_mem *val)
+{
+ switch ((enum simif_cfg)addr)
+ {
+ case simif_on: // turn this HW on/off
+ if (val)
+ {
+ if (*val)
+ on= true;
+ else
+ on= false;
+ }
+ else
+ {
+ cell->set(on?1:0);
+ }
+ break;
+ case simif_run: // simulator running: true= run, false= stop
+ if (val)
+ {
+ if (*val)
+ {
+ uc->sim->start(0, 0), *val= 1;
+ }
+ else
+ uc->sim->stop(resSIMIF), *val= 0;
+ }
+ else
+ {
+ int i= uc->sim->state;
+ i= i & SIM_GO;
+ cell->set(i?1:0);
+ }
+ break;
+ case simif_start: // start simulation
+ if (val)
+ uc->sim->start(0, 0), *val= 1;
+ else
+ {
+ int i= uc->sim->state;
+ i= i & SIM_GO;
+ cell->set(i?1:0);
+ }
+ break;
+ case simif_stop: // stop simulation
+ if (val)
+ uc->sim->stop(resSIMIF), *val= 1;
+ else
+ {
+ int i= uc->sim->state;
+ i= i & SIM_GO;
+ cell->set((!i)?1:0);
+ }
+ break;
+ case simif_quit: // quit
+ if (val)
+ uc->sim->state|= SIM_QUIT;
+ break;
+ case simif_reason: // reason of last stop
+ if (val)
+ *val= cell->get();
+ break;
+ case simif_xtal: // xtal frequ
+ if (val)
+ uc->xtal= *val;
+ cell->set(uc->xtal);
+ break;
+ case simif_ticks: // tick counter
+ if (val)
+ *val= cell->get();
+ cell->set(uc->ticks->ticks);
+ break;
+ case simif_isr_ticks: // isr tick counter
+ if (val)
+ *val= cell->get();
+ cell->set(uc->isr_ticks->ticks);
+ break;
+ case simif_idle_ticks: // idle tick counter
+ if (val)
+ *val= cell->get();
+ cell->set(uc->idle_ticks->ticks);
+ break;
+ case simif_real_time: // real time in msec
+ if (val)
+ *val= cell->get();
+ cell->set(uc->get_rtime() * 1000);
+ break;
+ case simif_vclk: // virtual clock
+ if (val)
+ *val= cell->get();
+ cell->set(uc->vc.fetch + uc->vc.rd + uc->vc.wr);
+ break;
+ case simif_pc: // PC of uc
+ if (val)
+ {
+ t_addr addr= *val;
+ class cl_address_space *rom= uc->rom;
+ if (rom)
+ {
+ if (addr > rom->highest_valid_address())
+ addr= rom->highest_valid_address();
+ }
+ uc->PC= addr;
+ }
+ cell->set(uc->PC);
+ break;
+ case simif_print:
+ if (val)
+ {
+ printf("%c", (char)(*val&0xff));
+ fflush(stdout);
+ }
+ break;
+ case simif_write:
+ if (val)
+ {
+ char c= *val & 0xff;
+ if (fout)
+ fout->write(&c, 1);
+ }
+ break;
+ case simif_nuof:
+ break;
+ }
+ return cell->get();
+}
+
+void
+cl_simulator_interface::finish_command(void)
+{
+ if (active_command)
+ {
+ active_command->clear_answer();
+ }
+ active_command= 0;
+}
+
+
+void
+cl_simulator_interface::print_info(class cl_console_base *con)
+{
+ con->dd_printf("uCsim simulator interface, version %d, ", version);
+ con->dd_printf("at %s[", as_name);
+ if (as)
+ con->dd_printf(as->addr_format, address);
+ else
+ con->dd_printf("0x%x", AU(address));
+ con->dd_printf("]\n");
+
+ con->dd_printf("Active command: ");
+ if (!active_command)
+ con->dd_printf("none.\n");
+ else
+ {
+ class cl_sif_command *c= active_command;
+ con->dd_printf("0x%02x %s %s\n", c->get_command(),
+ c->get_name(), c->get_description());
+ con->dd_printf("Parameters received %d bytes of %d\n",
+ c->get_params_received(), c->get_nuof_params());
+ if (c->get_nuof_params())
+ {
+ con->dd_printf(" ");
+ int i;
+ for (i= 0; i < c->get_nuof_params(); i++)
+ {
+ t_mem p;
+ if (c->get_parameter(i, &p))
+ con->dd_printf(" %02x", MU8(p));
+ else
+ con->dd_printf(" --");
+ }
+ con->dd_printf("\n");
+ }
+ con->dd_printf("Answered %d bytes of %d\n",
+ c->get_answered_bytes(), c->get_answer_length());
+ con->dd_printf("Answering: %s\n", (c->get_answering())?"yes":"no");
+ }
+
+ int i;
+ con->dd_printf("Known commands:\n");
+ for (i= 0; i < commands->count; i++)
+ {
+ class cl_sif_command *c=
+ dynamic_cast<class cl_sif_command *>(commands->object_at(i));
+ if (!c)
+ continue;
+ int cmd= c->get_command();
+ con->dd_printf("0x%02x/%c %s: %s\n", cmd,
+ isprint(cmd)?cmd:' ',
+ c->get_name(), c->get_description());
+ }
+
+ con->dd_printf("Input file: ");
+ if (fin)
+ con->dd_printf("%s", fin->get_file_name());
+ con->dd_printf("\n");
+
+ con->dd_printf("Output file: ");
+ if (fout)
+ con->dd_printf("%s", fout->get_file_name());
+ con->dd_printf("\n");
+
+ print_cfg_info(con);
+}
+
+
+/* End of sim.src/simif.cc */
diff --git a/sim/ucsim/sim.src/simif.o b/sim/ucsim/sim.src/simif.o
new file mode 100644
index 0000000..f75ace7
--- /dev/null
+++ b/sim/ucsim/sim.src/simif.o
Binary files differ
diff --git a/sim/ucsim/sim.src/simifcl.h b/sim/ucsim/sim.src/simifcl.h
new file mode 100644
index 0000000..ac67bc0
--- /dev/null
+++ b/sim/ucsim/sim.src/simifcl.h
@@ -0,0 +1,380 @@
+/*
+ * Simulator of microcontrollers (sim.src/simifcl.h)
+ *
+ * Copyright (C) 2016,16 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 SIMIFCL_HEADER
+#define SIMIFCL_HEADER
+
+// prj
+#include "fiocl.h"
+
+// local
+#include "uccl.h"
+#include "hwcl.h"
+
+
+#define SIMIF_VERSION 1
+
+enum sif_command {
+ DETECT_SIGN = '!', // answer to detect command
+
+ SIFCM_DETECT = '_', // detect the interface
+ // -> _
+ // <- !
+ SIFCM_COMMANDS = 'i', // get info about commands
+ // -> i
+ // <- nr list of command chars
+ SIFCM_IFVER = 'v', // interface version
+ // -> v
+ // <- 1 SIMIF_VERSION
+ SIFCM_SIMVER = 'V', // simulator version
+ // -> V
+ // <- len VERSIONSTR
+ SIFCM_IFRESET = '@', // reset the interface
+ // ?
+ // ?
+ SIFCM_CMDINFO = 'I', // info about a command
+ // -> I cmdchar
+ // <- 2 params_needed answer_type
+ SIFCM_CMDHELP = 'h', // help about a command
+ // -> h cmdchar
+ // <- string_length+1 string_of_help 0
+ SIFCM_STOP = 's', // stop simulation
+ // -> s
+ // -> s
+ SIFCM_PRINT = 'p', // print out a character
+ // -> p char
+ // <-
+ SIFCM_HEX = 'x', // print out a character in hex
+ // -> x char
+ // <-
+ SIFCM_FIN_CHECK = 'f', // check input file for input
+ // -> f
+ // <- 0|1
+ SIFCM_READ = 'r', // read from input file
+ // -> r
+ // <- char|0
+ SIFCM_WRITE = 'w', // write to output file
+ // -> w char
+ // <-
+ SIFCM_RESET = 'R', // reset CPU
+ // -> R
+ // <-
+};
+
+enum sif_answer_type {
+ SIFAT_UNKNOWN = 0x00, // we don't know...
+ SIFAT_BYTE = 0x01, // just a byte
+ SIFAT_ARRAY = 0x02, // array of some bytes
+ SIFAT_STRING = 0x03, // a string
+ SIFAT_NONE = 0x04 // no answer at all
+};
+
+enum simif_cfg {
+ simif_on = 0, // RW
+ simif_run = 1, // RW
+ simif_start = 2, // RW
+ simif_stop = 3, // RW
+ simif_quit = 4, // W
+ simif_reason = 5, // R
+ simif_xtal = 6, // RW
+ simif_ticks = 7, // R
+ simif_isr_ticks = 8, // R
+ simif_idle_ticks = 9, // R
+ simif_real_time = 10, // R
+ simif_vclk = 11, // R
+ simif_pc = 12, // RW
+ simif_print = 13, // W
+ simif_write = 14, // W
+
+ simif_nuof = 15
+};
+
+class cl_simulator_interface;
+
+/* Base of commands */
+
+class cl_sif_command: public cl_base
+{
+protected:
+ enum sif_command command;
+ char *description;
+ enum sif_answer_type answer_type;
+ class cl_simulator_interface *sif;
+ t_mem *parameters;
+ int params_needed, nuof_params, params_received;
+ t_mem *answer;
+ int answer_length, answered_bytes;
+ bool answering;
+public:
+ cl_sif_command(enum sif_command cmd,
+ const char *the_name,
+ const char *the_description,
+ enum sif_answer_type the_answer_type,
+ int the_params_needed,
+ class cl_simulator_interface *the_sif);
+ virtual ~cl_sif_command(void);
+ virtual int init(void);
+ virtual void clear_params(void);
+ virtual void clear_answer(void);
+ virtual void clear(void);
+
+ enum sif_command get_command(void) { return(command); }
+ char *get_description(void) { return(description); }
+ int get_nuof_params(void) { return(nuof_params); }
+ int get_params_received(void) { return(params_received); }
+ int get_answer_length(void) { return(answer_length); }
+ int get_answered_bytes(void) { return(answered_bytes); }
+ bool get_answering(void) { return(answering); }
+ enum sif_answer_type get_answer_type(void) { return(answer_type); }
+ int get_params_needed(void) { return(params_needed); }
+ bool get_parameter(int nr, t_mem *into);
+
+ virtual t_mem read(class cl_memory_cell *cel);
+ virtual void write(class cl_memory_cell *cel, t_mem *val);
+
+ virtual void start(void);
+ virtual void produce_answer(void);
+
+private:
+ virtual void need_params(int nr);
+public:
+ virtual void set_answer(t_mem ans);
+ virtual void set_answer(int nr, t_mem ans[]);
+ virtual void set_answer(const char *ans);
+ virtual void start_answer(void);
+};
+
+/* Command: detect */
+class cl_sif_detect: public cl_sif_command
+{
+public:
+ cl_sif_detect(class cl_simulator_interface *the_sif):
+ cl_sif_command(SIFCM_DETECT, "if_detect",
+ "Detect existence of interface",
+ SIFAT_BYTE, 0, the_sif)
+ {}
+ virtual void produce_answer(void) { set_answer(t_mem(DETECT_SIGN)); }
+};
+
+/* Command: interface version */
+class cl_sif_ifver: public cl_sif_command
+{
+public:
+ cl_sif_ifver(class cl_simulator_interface *the_sif):
+ cl_sif_command(SIFCM_IFVER, "if_ver",
+ "Get version of simulator interface",
+ SIFAT_BYTE, 0, the_sif)
+ {}
+ virtual void produce_answer(void) { set_answer(t_mem(SIMIF_VERSION)); }
+};
+
+/* Command: simulator version */
+class cl_sif_simver: public cl_sif_command
+{
+public:
+ cl_sif_simver(class cl_simulator_interface *the_sif):
+ cl_sif_command(SIFCM_SIMVER, "sim_ver",
+ "Get version of simulator",
+ SIFAT_STRING, 0, the_sif)
+ {}
+ virtual void produce_answer(void) { set_answer(VERSIONSTR); }
+};
+
+/* Command: reset interface */
+class cl_sif_ifreset: public cl_sif_command
+{
+public:
+ cl_sif_ifreset(class cl_simulator_interface *the_sif):
+ cl_sif_command(SIFCM_IFRESET, "if_reset",
+ "Reset interface to default state",
+ SIFAT_NONE, 0, the_sif)
+ {}
+};
+
+/* Command: get info about commands */
+class cl_sif_commands: public cl_sif_command
+{
+public:
+ cl_sif_commands(class cl_simulator_interface *the_sif):
+ cl_sif_command(SIFCM_COMMANDS, "commands",
+ "Get information about known commands",
+ SIFAT_ARRAY, 0, the_sif)
+ {}
+ virtual void produce_answer(void);
+};
+
+/* Command: get info about a command */
+class cl_sif_cmdinfo: public cl_sif_command
+{
+public:
+ cl_sif_cmdinfo(class cl_simulator_interface *the_sif):
+ cl_sif_command(SIFCM_CMDINFO, "cmdinfo",
+ "Get information about a command",
+ SIFAT_ARRAY, 1, the_sif)
+ {}
+ virtual void produce_answer(void);
+};
+
+/* Command: get info about a command */
+class cl_sif_cmdhelp: public cl_sif_command
+{
+public:
+ cl_sif_cmdhelp(class cl_simulator_interface *the_sif):
+ cl_sif_command(SIFCM_CMDHELP, "cmdhelp",
+ "Get help about a command",
+ SIFAT_STRING, 1, the_sif)
+ {}
+ virtual void produce_answer(void);
+};
+
+/* Command: stop simulation */
+class cl_sif_stop: public cl_sif_command
+{
+public:
+ cl_sif_stop(class cl_simulator_interface *the_sif):
+ cl_sif_command(SIFCM_STOP, "stop",
+ "Stop simulation",
+ SIFAT_BYTE, 0, the_sif)
+ {}
+ virtual void produce_answer(void);
+};
+
+/* Command: print character */
+class cl_sif_print: public cl_sif_command
+{
+public:
+ cl_sif_print(class cl_simulator_interface *the_sif):
+ cl_sif_command(SIFCM_PRINT, "print",
+ "Print character",
+ SIFAT_NONE, 1, the_sif)
+ {}
+ virtual void produce_answer(void);
+};
+
+
+/* Command: print character */
+class cl_sif_hex: public cl_sif_command
+{
+public:
+ cl_sif_hex(class cl_simulator_interface *the_sif):
+ cl_sif_command(SIFCM_HEX, "print_hex",
+ "Print character in hex",
+ SIFAT_NONE, 1, the_sif)
+ {}
+ virtual void produce_answer(void);
+};
+
+
+/* Command: write character to output file */
+class cl_sif_write: public cl_sif_command
+{
+public:
+ cl_sif_write(class cl_simulator_interface *the_sif):
+ cl_sif_command(SIFCM_WRITE, "write to output file",
+ "Write character to output file",
+ SIFAT_NONE, 1, the_sif)
+ {}
+ virtual void produce_answer(void);
+};
+
+
+/* Command: check input file */
+class cl_sif_fin_check: public cl_sif_command
+{
+public:
+ cl_sif_fin_check(class cl_simulator_interface *the_sif):
+ cl_sif_command(SIFCM_FIN_CHECK, "fin_check",
+ "Check input file if input available",
+ SIFAT_BYTE, 0, the_sif)
+ {}
+ virtual void produce_answer(void);
+};
+
+
+/* Command: read input file */
+class cl_sif_read: public cl_sif_command
+{
+public:
+ cl_sif_read(class cl_simulator_interface *the_sif):
+ cl_sif_command(SIFCM_READ, "read input file",
+ "Read character from input file",
+ SIFAT_BYTE, 0, the_sif)
+ {}
+ virtual void produce_answer(void);
+};
+
+
+/* Command: reset */
+class cl_sif_reset: public cl_sif_command
+{
+public:
+ cl_sif_reset(class cl_simulator_interface *the_sif):
+ cl_sif_command(SIFCM_RESET, "reset cpu",
+ "Reset CPU",
+ SIFAT_NONE, 0, the_sif)
+ {}
+ virtual void produce_answer(void);
+};
+
+
+/*
+ * Virtual hardware: simulator interface
+ */
+
+class cl_simulator_interface: public cl_hw
+{
+ private:
+ int version;
+ const char *as_name;
+ t_addr addr;
+ class cl_address_space *as;
+ t_addr address;
+ class cl_memory_cell *cell;
+ class cl_sif_command *active_command;
+ public:
+ class cl_f *fin, *fout;
+ public:
+ class cl_list *commands;
+ public:
+ cl_simulator_interface(class cl_uc *auc);
+ virtual ~cl_simulator_interface(void);
+ virtual int init(void);
+ virtual int cfg_size(void) { return simif_nuof; }
+ virtual char *cfg_help(t_addr addr);
+
+ virtual void set_cmd(class cl_cmdline *cmdline, class cl_console_base *con);
+ virtual t_mem read(class cl_memory_cell *cel);
+ virtual void write(class cl_memory_cell *cel, t_mem *val);
+ virtual t_mem conf_op(cl_memory_cell *cell, t_addr addr, t_mem *val);
+
+ virtual void finish_command(void);
+
+ virtual void print_info(class cl_console_base *con);
+};
+
+
+#endif
diff --git a/sim/ucsim/sim.src/stack.cc b/sim/ucsim/sim.src/stack.cc
new file mode 100644
index 0000000..062f6d4
--- /dev/null
+++ b/sim/ucsim/sim.src/stack.cc
@@ -0,0 +1,564 @@
+/*
+ * Simulator of microcontrollers (stack.cc)
+ *
+ * Copyright (C) 2000,00 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@*/
+
+#include <stdlib.h>
+
+// cmd.src
+#include "newcmdcl.h"
+
+// sim.src
+#include "uccl.h"
+
+#include "stackcl.h"
+
+
+static class cl_stack_error_registry stack_error_registry;
+
+cl_stack_op::cl_stack_op(enum stack_op op,
+ t_addr iPC,
+ t_addr iSP_before, t_addr iSP_after):
+ cl_base()
+{
+ operation= op;
+ PC= iPC;
+ //addr= iaddr;
+ //data= idata;
+ SP_before= iSP_before;
+ SP_after= iSP_after;
+}
+
+cl_stack_op::~cl_stack_op(void)
+{
+ //printf("stack op %p deleting...\n", this);
+}
+
+
+class cl_stack_op *
+cl_stack_op::mk_copy(void)
+{
+ class cl_stack_op *so= new cl_stack_op(*this);
+ return(so);
+}
+
+void
+cl_stack_op::info_head(class cl_console_base *con)
+{
+ con->dd_printf("OP SP before-after L DATA/ADDR INSTRUCTION\n");
+}
+
+void
+cl_stack_op::info(class cl_console_base *con, class cl_uc *uc)
+{
+ con->dd_printf("%-4s 0x%06x-0x%06x %ld ",
+ get_op_name(),
+ AU(SP_before), AU(SP_after), labs(SP_before-SP_after));
+ print_info(con);
+ con->dd_printf(" ");
+ uc->print_disass(PC, con);
+ //con->dd_printf("\n");
+}
+
+const char *
+cl_stack_op::get_op_name(void)
+{
+ return("op");
+}
+
+void
+cl_stack_op::print_info(class cl_console_base *con)
+{
+ con->dd_printf("-");
+}
+
+bool
+cl_stack_op::sp_increased(void)
+{
+ if (operation & stack_write_operation)
+ return(SP_after > SP_before);
+ else // read operation
+ return(SP_after < SP_before);
+}
+
+int
+cl_stack_op::data_size(void)
+{
+ int r= SP_after - SP_before;
+
+ return(r<0?-r:r);
+}
+
+bool
+cl_stack_op::match(class cl_stack_op *op)
+{
+ return(false);
+}
+
+bool bigbig= false;
+
+bool
+cl_stack_op::can_removed(class cl_stack_op *op)
+{
+ return false;
+ bool incr= sp_increased(); // FIXME
+ bool op_incr= op->sp_increased(); // FIXME
+
+ if ((incr && !op_incr) ||
+ (!incr && op_incr))
+ {
+ printf("BIGBIG ERROR!\n");
+ bigbig= true;
+ return(false);
+ }
+ if (incr)
+ {
+ t_mem opa= op->get_after();
+ return(SP_before >= opa);
+ }
+ else
+ {
+ t_mem opa= op->get_after();
+ return(SP_before <= opa);
+ }
+}
+
+
+/*
+ * CALL operation on stack
+ */
+
+cl_stack_call::cl_stack_call(t_addr iPC, t_addr called, t_addr pushed,
+ t_addr iSP_before, t_addr iSP_after):
+ cl_stack_op(stack_call, iPC, iSP_before, iSP_after)
+{
+ called_addr= called;
+ pushed_addr= pushed;
+}
+
+class cl_stack_op *
+cl_stack_call::mk_copy(void)
+{
+ class cl_stack_call *so= new cl_stack_call(*this);
+ return(so);
+}
+
+const char *
+cl_stack_call::get_op_name(void)
+{
+ return("call");
+}
+
+void
+cl_stack_call::print_info(class cl_console_base *con)
+{
+ con->dd_printf("0x%06x", AU(called_addr));
+}
+
+const char *
+cl_stack_call::get_matching_name(void)
+{
+ return("ret");
+}
+
+enum stack_op
+cl_stack_call::get_matching_op(void)
+{
+ return(stack_ret);
+}
+
+bool
+cl_stack_call::match(class cl_stack_op *op)
+{
+ return(op->get_op() == stack_ret);
+}
+
+
+/*
+ * INTERRUPT operation (call) on stack
+ */
+
+cl_stack_intr::cl_stack_intr(t_addr iPC, t_addr called, t_addr pushed,
+ t_addr iSP_before, t_addr iSP_after):
+ cl_stack_call(iPC, called, pushed, iSP_before, iSP_after)
+{
+ //called_addr= called;
+ //pushed_addr= pushed;
+ operation= stack_intr;
+}
+
+class cl_stack_op *
+cl_stack_intr::mk_copy(void)
+{
+ class cl_stack_intr *so= new cl_stack_intr(*this);
+ return(so);
+}
+
+const char *
+cl_stack_intr::get_op_name(void)
+{
+ return("intr");
+}
+
+void
+cl_stack_intr::print_info(class cl_console_base *con)
+{
+ con->dd_printf("0x%06x", AU(called_addr));
+}
+
+const char *
+cl_stack_intr::get_matching_name(void)
+{
+ return("iret");
+}
+
+enum stack_op
+cl_stack_intr::get_matching_op(void)
+{
+ return(stack_iret);
+}
+
+bool
+cl_stack_intr::match(class cl_stack_op *op)
+{
+ return(op->get_op() == stack_iret);
+}
+
+
+/*
+ * PUSH operation on stack
+ */
+
+cl_stack_push::cl_stack_push(t_addr iPC, t_mem idata,
+ t_addr iSP_before, t_addr iSP_after):
+ cl_stack_op(stack_push, iPC, iSP_before, iSP_after)
+{
+ data= idata;
+}
+
+class cl_stack_op *
+cl_stack_push::mk_copy(void)
+{
+ class cl_stack_push *so= new cl_stack_push(*this);
+ return(so);
+}
+
+const char *
+cl_stack_push::get_op_name(void)
+{
+ return("push");
+}
+
+const char *
+cl_stack_push::get_matching_name(void)
+{
+ return("pop");
+}
+
+enum stack_op
+cl_stack_push::get_matching_op(void)
+{
+ return(stack_pop);
+}
+
+void
+cl_stack_push::print_info(class cl_console_base *con)
+{
+ t_addr d= data;
+ con->dd_printf("0x%06x", AU(d));
+}
+
+bool
+cl_stack_push::match(class cl_stack_op *op)
+{
+ return(op->get_op() == stack_pop);
+}
+
+
+/*
+ * RETURN operation on stack
+ */
+
+cl_stack_ret::cl_stack_ret(t_addr iPC, t_addr iaddr,
+ t_addr iSP_before, t_addr iSP_after):
+ cl_stack_call(iPC, iaddr, 0, iSP_before, iSP_after)
+{
+ operation= stack_ret;
+}
+
+class cl_stack_op *
+cl_stack_ret::mk_copy(void)
+{
+ class cl_stack_ret *so= new cl_stack_ret(*this);
+ return(so);
+}
+
+const char *
+cl_stack_ret::get_op_name(void)
+{
+ return("ret");
+}
+
+const char *
+cl_stack_ret::get_matching_name(void)
+{
+ return("call");
+}
+
+enum stack_op
+cl_stack_ret::get_matching_op(void)
+{
+ return(stack_call);
+}
+
+bool
+cl_stack_ret::match(class cl_stack_op *op)
+{
+ return(op->get_op() == stack_call);
+}
+
+
+/*
+ * RETURN from interrupt operation on stack
+ */
+
+cl_stack_iret::cl_stack_iret(t_addr iPC, t_addr iaddr,
+ t_addr iSP_before, t_addr iSP_after):
+ cl_stack_ret(iPC, iaddr, iSP_before, iSP_after)
+{
+ operation= stack_iret;
+}
+
+class cl_stack_op *
+cl_stack_iret::mk_copy(void)
+{
+ class cl_stack_iret *so= new cl_stack_iret(*this);
+ return(so);
+}
+
+const char *
+cl_stack_iret::get_op_name(void)
+{
+ return("iret");
+}
+
+const char *
+cl_stack_iret::get_matching_name(void)
+{
+ return("intr");
+}
+
+enum stack_op
+cl_stack_iret::get_matching_op(void)
+{
+ return(stack_intr);
+}
+
+bool
+cl_stack_iret::match(class cl_stack_op *op)
+{
+ return(op->get_op() == stack_intr);
+}
+
+
+/*
+ * POP operation on stack
+ */
+
+cl_stack_pop::cl_stack_pop(t_addr iPC, t_mem idata,
+ t_addr iSP_before, t_addr iSP_after):
+ cl_stack_push(iPC, idata, iSP_before, iSP_after)
+{
+ operation= stack_pop;
+}
+
+class cl_stack_op *
+cl_stack_pop::mk_copy(void)
+{
+ class cl_stack_pop *so= new cl_stack_pop(*this);
+ return(so);
+}
+
+const char *
+cl_stack_pop::get_op_name(void)
+{
+ return("pop");
+}
+
+const char *
+cl_stack_pop::get_matching_name(void)
+{
+ return("push");
+}
+
+enum stack_op
+cl_stack_pop::get_matching_op(void)
+{
+ return(stack_push);
+}
+
+bool
+cl_stack_pop::match(class cl_stack_op *op)
+{
+ return(op->get_op() == stack_push);
+}
+
+
+/*
+ * Stack Errors
+ */
+
+cl_error_stack::cl_error_stack(void)
+{
+classification = stack_error_registry.find("stack");
+}
+
+/* Stack Tracker Errors */
+
+cl_error_stack_tracker::cl_error_stack_tracker(void)
+{
+classification = stack_error_registry.find("stack_tracker");
+}
+
+/* Stack Tracker: wrong handle */
+
+cl_error_stack_tracker_wrong_handle::cl_error_stack_tracker_wrong_handle(bool write_op):
+ cl_error_stack_tracker()
+{
+ write_operation= write_op;
+ classification= stack_error_registry.find("stack_tracker_wrong_handle");
+}
+
+void
+cl_error_stack_tracker_wrong_handle::print(class cl_commander_base *c)
+{
+ c->dd_printf("%s: wrong stack tracker handle called for %s operation\n",
+ get_type_name(), write_operation?"write":"read");
+}
+
+/* Stack Tracker: operation on empty stack */
+
+cl_error_stack_tracker_empty::
+cl_error_stack_tracker_empty(class cl_stack_op *op):
+ cl_error_stack_tracker()
+{
+ operation= op->mk_copy();
+ classification= stack_error_registry.find("operation_on_empty_stack");
+}
+
+cl_error_stack_tracker_empty::~cl_error_stack_tracker_empty(void)
+{
+ delete operation;
+}
+
+void
+cl_error_stack_tracker_empty::print(class cl_commander_base *c)
+{
+ c->dd_printf("%s(0x%06x): %s on empty stack, PC="
+ "0x06x, SP=0x%06x->0x%06x\n",
+ get_type_name(), AU(operation->get_pc()),
+ operation->get_op_name(),
+ AU(operation->get_pc()),
+ AU(operation->get_before()),
+ AU(operation->get_after()));
+}
+
+/* Stack Tracker: operation on empty stack */
+
+cl_error_stack_tracker_unmatch::
+cl_error_stack_tracker_unmatch(class cl_stack_op *Top, class cl_stack_op *op):
+ cl_error_stack_tracker()
+{
+ top= Top->mk_copy();
+ operation= op->mk_copy();
+ //printf("top=%p op=%p\n", top, operation);
+ classification=
+ stack_error_registry.find("stack_operation_unmatched_to_top_of_stack");
+}
+
+cl_error_stack_tracker_unmatch::~cl_error_stack_tracker_unmatch(void)
+{
+ //printf("trying delete stackop %p op\n", operation);
+ //printf("trying delete stackop %p top\n", top);
+ if (bigbig)
+ {
+ delete operation;
+ delete top;
+ }
+ else
+ {
+ delete operation;
+ delete top;
+ }
+}
+
+void
+cl_error_stack_tracker_unmatch::print(class cl_commander_base *c)
+{
+ c->dd_printf("%s(0x%06x): %s when %s expected, "
+ "SP=0x%06x->0x%06x\n",
+ get_type_name(), AU(operation->get_pc()),
+ operation->get_op_name(), top->get_matching_name(),
+ AU(operation->get_before()),
+ AU(operation->get_after()));
+}
+
+/* Stack Tracker: stack is inconsistent */
+
+cl_error_stack_tracker_inconsistent::
+cl_error_stack_tracker_inconsistent(class cl_stack_op *op,
+ int the_unread_data_size)
+{
+ operation= op->mk_copy();
+ unread_data_size= the_unread_data_size;
+ classification= stack_error_registry.find("stack_looks_corrupted");
+}
+
+cl_error_stack_tracker_inconsistent::~cl_error_stack_tracker_inconsistent(void)
+{
+ delete operation;
+}
+
+void
+cl_error_stack_tracker_inconsistent::print(class cl_commander_base *c)
+{
+ c->dd_printf("%s(0x%06x): %d byte(s) unread from the stack\n",
+ get_type_name(), AU(operation->get_pc()),
+ unread_data_size);
+}
+
+cl_stack_error_registry::cl_stack_error_registry(void)
+{
+ class cl_error_class *prev = stack_error_registry.find("non-classified");
+ prev = register_error(new cl_error_class(err_error, "stack", prev, ERROR_OFF));
+ prev = register_error(new cl_error_class(err_error, "stack_tracker", prev));
+ prev = register_error(new cl_error_class(err_error, "stack_tracker_wrong_handle", prev));
+ prev = register_error(new cl_error_class(err_error, "operation_on_empty_stack", prev));
+ prev = register_error(new cl_error_class(err_warning, "stack_operation_unmatched_to_top_of_stack", prev));
+ prev = register_error(new cl_error_class(err_warning, "stack_looks_corrupted", prev));
+}
+
+
+/* End of sim.src/stack.cc */
diff --git a/sim/ucsim/sim.src/stack.o b/sim/ucsim/sim.src/stack.o
new file mode 100644
index 0000000..9d1d173
--- /dev/null
+++ b/sim/ucsim/sim.src/stack.o
Binary files differ
diff --git a/sim/ucsim/sim.src/stackcl.h b/sim/ucsim/sim.src/stackcl.h
new file mode 100644
index 0000000..61138fc
--- /dev/null
+++ b/sim/ucsim/sim.src/stackcl.h
@@ -0,0 +1,249 @@
+/*
+ * Simulator of microcontrollers (sim.src/stackcl.h)
+ *
+ * Copyright (C) 2000,00 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 SIM_STACKCL_HEADER
+#define SIM_STACKCL_HEADER
+
+#include "stypes.h"
+#include "pobjcl.h"
+#include "errorcl.h"
+
+
+enum stack_op {
+ stack_call = 0x01,
+ stack_intr = 0x02,
+ stack_push = 0x04,
+ stack_ret = 0x08,
+ stack_iret = 0x10,
+ stack_pop = 0x20
+};
+
+const int stack_write_operation= (stack_call|stack_intr|stack_push);
+const int stack_read_operation = (stack_ret|stack_iret|stack_pop);
+
+/* Abstraction of a stack operation */
+class cl_stack_op: public cl_base
+{
+protected:
+ enum stack_op operation;
+ t_addr PC; // of instruction
+ t_addr SP_before;
+ t_addr SP_after;
+public:
+ cl_stack_op(enum stack_op op,
+ t_addr iPC, t_addr iSP_before, t_addr iSP_after);
+ virtual ~cl_stack_op(void);
+ virtual class cl_stack_op *mk_copy(void);
+ static void info_head(class cl_console_base *con);
+ virtual void info(class cl_console_base *con, class cl_uc *uc);
+protected:
+ virtual void print_info(class cl_console_base *con);
+public:
+ virtual const char *get_op_name(void);
+ virtual const char *get_matching_name(void) { return(cchars("unknown")); }
+ virtual bool sp_increased(void);
+ virtual int data_size(void);
+ virtual bool match(class cl_stack_op *op);
+ virtual enum stack_op get_op(void) { return(operation); }
+ virtual enum stack_op get_matching_op(void) { return(operation); }
+ virtual t_addr get_after(void) { return(SP_after); }
+ virtual t_addr get_before(void) { return(SP_before); }
+ virtual t_addr get_pc(void) { return(PC); }
+ virtual bool can_removed(class cl_stack_op *op);
+};
+
+/* Call of a subrutine, must match with RET */
+class cl_stack_call: public cl_stack_op
+{
+protected:
+ t_addr called_addr; // called routine
+ t_addr pushed_addr;
+public:
+ cl_stack_call(t_addr iPC, t_addr called, t_addr pushed,
+ t_addr iSP_before, t_addr iSP_after);
+ virtual class cl_stack_op *mk_copy(void);
+protected:
+ virtual const char *get_op_name(void);
+ virtual void print_info(class cl_console_base *con);
+public:
+ virtual const char *get_matching_name(void);
+ virtual enum stack_op get_matching_op(void);
+ virtual bool match(class cl_stack_op *op);
+};
+
+/* Call of an ISR, must match with IRET */
+class cl_stack_intr: public cl_stack_call
+{
+public:
+ cl_stack_intr(t_addr iPC, t_addr called, t_addr pushed,
+ t_addr iSP_before, t_addr iSP_after);
+ virtual class cl_stack_op *mk_copy(void);
+protected:
+ virtual const char *get_op_name(void);
+ virtual void print_info(class cl_console_base *con);
+public:
+ virtual const char *get_matching_name(void);
+ virtual enum stack_op get_matching_op(void);
+ virtual bool match(class cl_stack_op *op);
+};
+
+/* Push data to stack, must match with POP */
+class cl_stack_push: public cl_stack_op
+{
+protected:
+ t_mem data; // pushed data
+public:
+ cl_stack_push(t_addr iPC, t_mem idata, t_addr iSP_before, t_addr iSP_after);
+ virtual class cl_stack_op *mk_copy(void);
+protected:
+ virtual const char *get_op_name(void);
+ virtual void print_info(class cl_console_base *con);
+public:
+ virtual const char *get_matching_name(void);
+ virtual enum stack_op get_matching_op(void);
+ virtual bool match(class cl_stack_op *op);
+};
+
+/* Returning from a subroutine, tos must be CALL */
+class cl_stack_ret: public cl_stack_call
+{
+public:
+ cl_stack_ret(t_addr iPC, t_addr iaddr, t_addr iSP_before, t_addr iSP_after);
+ virtual class cl_stack_op *mk_copy(void);
+protected:
+ virtual const char *get_op_name(void);
+public:
+ virtual const char *get_matching_name(void);
+ virtual enum stack_op get_matching_op(void);
+ virtual bool match(class cl_stack_op *op);
+};
+
+/* Returning from an ISR, yos must be INTR */
+class cl_stack_iret: public cl_stack_ret
+{
+public:
+ cl_stack_iret(t_addr iPC, t_addr iaddr, t_addr iSP_before, t_addr iSP_after);
+ virtual class cl_stack_op *mk_copy(void);
+protected:
+ virtual const char *get_op_name(void);
+public:
+ virtual const char *get_matching_name(void);
+ virtual enum stack_op get_matching_op(void);
+ virtual bool match(class cl_stack_op *op);
+};
+
+/* Pop out data from stack, tos must be PUSH */
+class cl_stack_pop: public cl_stack_push
+{
+public:
+ cl_stack_pop(t_addr iPC, t_mem idata, t_addr iSP_before, t_addr iSP_after);
+ virtual class cl_stack_op *mk_copy(void);
+protected:
+ virtual const char *get_op_name(void);
+public:
+ virtual const char *get_matching_name(void);
+ virtual enum stack_op get_matching_op(void);
+ virtual bool match(class cl_stack_op *op);
+};
+
+
+/*
+ * All kind of stack errors
+ */
+class cl_error_stack: public cl_error
+{
+private:
+ static class cl_error_class *error_stack_class;
+public:
+ cl_error_stack(void);
+};
+
+/*
+ * All kind of stack tracker errors
+ */
+class cl_error_stack_tracker: public cl_error_stack
+{
+public:
+ cl_error_stack_tracker(void);
+};
+
+class cl_error_stack_tracker_wrong_handle: public cl_error_stack_tracker
+{
+public:
+ bool write_operation;
+public:
+ cl_error_stack_tracker_wrong_handle(bool write_op);
+
+ virtual void print(class cl_commander_base *c);
+};
+
+class cl_error_stack_tracker_empty: public cl_error_stack_tracker
+{
+protected:
+ class cl_stack_op *operation;
+public:
+ cl_error_stack_tracker_empty(class cl_stack_op *op);
+ virtual ~cl_error_stack_tracker_empty(void);
+
+ virtual void print(class cl_commander_base *c);
+};
+
+class cl_error_stack_tracker_unmatch: public cl_error_stack_tracker
+{
+protected:
+ class cl_stack_op *top, *operation;
+public:
+ cl_error_stack_tracker_unmatch(class cl_stack_op *Top,
+ class cl_stack_op *op);
+ virtual ~cl_error_stack_tracker_unmatch(void);
+
+ virtual void print(class cl_commander_base *c);
+};
+
+class cl_error_stack_tracker_inconsistent: public cl_error_stack_tracker
+{
+protected:
+ class cl_stack_op *operation;
+ int unread_data_size;
+public:
+ cl_error_stack_tracker_inconsistent(class cl_stack_op *op,
+ int the_unread_data_size);
+ virtual ~cl_error_stack_tracker_inconsistent(void);
+
+ virtual void print(class cl_commander_base *c);
+};
+
+class cl_stack_error_registry: public cl_error_registry
+{
+public:
+ cl_stack_error_registry(void);
+};
+
+
+#endif
+
+/* End of sim.src/stackcl.h */
diff --git a/sim/ucsim/sim.src/test_mem_speed.cc b/sim/ucsim/sim.src/test_mem_speed.cc
new file mode 100644
index 0000000..35f7673
--- /dev/null
+++ b/sim/ucsim/sim.src/test_mem_speed.cc
@@ -0,0 +1,99 @@
+#include <signal.h>
+#include <unistd.h>
+#include <stdio.h>
+
+#include "memcl.h"
+#include "hwcl.h"
+
+#include "newcmdcl.h"
+
+static int go;
+
+static void
+alarmed(int sig)
+{
+ go= 0;
+ signal(sig, alarmed);
+}
+
+class cl_hw_test: public cl_hw
+{
+public:
+ cl_hw_test(void): cl_hw(0, HW_PORT, 0, "0") {}
+ virtual t_mem r(class cl_cell *cell, t_addr addr);
+ virtual void write(class cl_mem *mem, t_addr addr, t_mem *val);
+};
+
+t_mem
+cl_hw_test::r(class cl_cell *cell, t_addr addr)
+{
+ return(cell->get());
+}
+
+void
+cl_hw_test::write(class cl_mem *mem, t_addr addr, t_mem *val)
+{
+}
+
+double
+do_rw_test(class cl_mem *mem, int time)
+{
+ double counter;
+ t_addr a;
+ t_mem d;
+
+ go= 1;
+ counter= 0;
+ alarm(time);
+ while (go)
+ for (a= 0; go && a < mem->size; a++)
+ {
+ t_mem d2;
+ for (d2= 0; go && d2 <= 255; d2++)
+ {
+ d2= mem->write(a, d2);
+ d= mem->read(a);
+ if (d != d2)
+ printf("%d written to mem and %d read back!\n", (int)d2, (int)d);
+ counter+= 1;
+ }
+ }
+ return(counter);
+}
+
+int
+main(void)
+{
+ int i;
+ class cl_mem *mem;
+ class cl_m *m2;
+ class cl_console *con;
+
+ signal(SIGALRM, alarmed);
+ con= new cl_console(stdin, stdout, 0);
+
+ mem= new cl_mem(MEM_SFR, "egy", 0x10000, 8, 0);
+ mem->init();
+ printf("%g operations on classic memory within 5 sec\n",
+ do_rw_test(mem, 5));
+ //mem->dump(con);
+
+ m2= new cl_m(MEM_TYPES, "test", 0x10000, 8, 0);
+ m2->init();
+ printf("%g operations on new memory within 5 sec\n",
+ do_rw_test(m2, 5));
+
+ class cl_hw_test *hw= new cl_hw_test();
+ for (i= 0; i < 0x10000; i++)
+ {
+ class cl_cell *c= m2->get_cell(i);
+ int dummy;
+ if (c)
+ c->add_hw(hw, &dummy);
+ }
+ printf("%g operations on new memory within 5 sec with hw read\n",
+ do_rw_test(m2, 5));
+ //m2->dump(con);
+
+ return(0);
+}
diff --git a/sim/ucsim/sim.src/uc.cc b/sim/ucsim/sim.src/uc.cc
new file mode 100644
index 0000000..983d2b6
--- /dev/null
+++ b/sim/ucsim/sim.src/uc.cc
@@ -0,0 +1,2616 @@
+/*
+ * Simulator of microcontrollers (uc.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@*/
+
+#include "ddconfig.h"
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <errno.h>
+#include <ctype.h>
+#include "i_string.h"
+
+// prj
+#include "globals.h"
+#include "utils.h"
+
+// cmd.src
+#include "newcmdcl.h"
+#include "cmdutil.h"
+#include "cmd_uccl.h"
+#include "cmd_bpcl.h"
+#include "cmd_getcl.h"
+#include "cmd_setcl.h"
+#include "cmd_infocl.h"
+#include "cmd_timercl.h"
+#include "cmd_statcl.h"
+#include "cmd_memcl.h"
+
+// local, sim.src
+#include "uccl.h"
+#include "hwcl.h"
+#include "memcl.h"
+#include "simcl.h"
+#include "itsrccl.h"
+#include "simifcl.h"
+#include "vcdcl.h"
+
+
+static class cl_uc_error_registry uc_error_registry;
+
+/*
+ * Clock counter
+ */
+
+cl_ticker::cl_ticker(int adir, int in_isr, const char *aname)
+{
+ options= TICK_RUN;
+ if (in_isr)
+ options|= TICK_INISR;
+ dir= adir;
+ ticks= 0;
+ set_name(aname);
+}
+
+cl_ticker::~cl_ticker(void) {}
+
+int
+cl_ticker::tick(int nr)
+{
+ if (options&TICK_RUN)
+ ticks+= dir*nr;
+ return(ticks);
+}
+
+double
+cl_ticker::get_rtime(double xtal)
+{
+ double d;
+
+ d= (double)ticks/xtal;
+ return(d);
+}
+
+void
+cl_ticker::dump(int nr, double xtal, class cl_console_base *con)
+{
+ con->dd_printf("timer #%d(\"%s\") %s%s: %g sec (%lu clks)\n",
+ nr, get_name("unnamed"),
+ (options&TICK_RUN)?"ON":"OFF",
+ (options&TICK_INISR)?",ISR":"",
+ get_rtime(xtal), ticks);
+}
+
+
+/*
+ * Options of uc
+ */
+
+cl_xtal_option::cl_xtal_option(class cl_uc *the_uc):
+ cl_optref(the_uc)
+{
+ uc= the_uc;
+}
+
+void
+cl_xtal_option::option_changed(void)
+{
+ if (!uc)
+ return;
+ double d;
+ option->get_value(&d);
+ uc->xtal= d;
+}
+
+
+/* Time measurer */
+
+cl_time_measurer::cl_time_measurer(class cl_uc *the_uc):
+ cl_base()
+{
+ to_reach= 0;
+ uc= the_uc;
+}
+
+void
+cl_time_measurer::set_reach(unsigned long val)
+{
+ to_reach= val;
+}
+
+void
+cl_time_measurer::from_now(unsigned long val)
+{
+ set_reach(now() + val);
+}
+
+bool
+cl_time_measurer::reached()
+{
+ return to_reach &&
+ (now() >= to_reach);
+}
+
+unsigned long
+cl_time_measurer::now()
+{
+ return 0;
+}
+
+
+/* value of xtal clock */
+
+unsigned long
+cl_time_clk::now()
+{
+ if (!uc) return 0;
+ return uc->ticks->ticks;
+}
+
+
+/* value of virtual clocks */
+
+unsigned long
+cl_time_vclk::now()
+{
+ if (!uc) return 0;
+ return uc->vc.fetch + uc->vc.rd + uc->vc.wr;
+}
+
+
+/* value of fetches */
+
+unsigned long
+cl_time_fclk::now()
+{
+ if (!uc) return 0;
+ return uc->vc.fetch;
+}
+
+
+/* value of reads */
+
+unsigned long
+cl_time_rclk::now()
+{
+ if (!uc) return 0;
+ return uc->vc.rd;
+}
+
+
+/* value of writes */
+
+unsigned long
+cl_time_wclk::now()
+{
+ if (!uc) return 0;
+ return uc->vc.wr;
+}
+
+
+/* OMF file record */
+
+cl_omf_rec::cl_omf_rec(void):
+ cl_base()
+{
+ offset= 0;
+ f_offset= 0;
+ type= 0;
+ len= 0;
+ rec= NULL;
+ chk= 0;
+}
+
+cl_omf_rec::~cl_omf_rec(void)
+{
+ if (rec)
+ free(rec);
+}
+
+unsigned char
+cl_omf_rec::g(cl_f *f)
+{
+ unsigned char c= f->get_c();
+ offset++;
+ return c;
+}
+
+u16_t
+cl_omf_rec::pick_word(int i)
+{
+ unsigned char h, l;
+ u16_t w;
+
+ if (i >= len-1)
+ return 0;
+ l= rec[i];
+ h= rec[i+1];
+ w= h*256+l;
+ return w;
+}
+
+chars
+cl_omf_rec::pick_str(int i)
+{
+ unsigned char l, j;
+ chars s= "";
+
+ if (i >= len-1)
+ return chars("");
+ l= rec[i];
+ j= 0;
+ while (l &&
+ (i < len))
+ {
+ s+= rec[i+1+j];
+ l--;
+ j++;
+ }
+ return s;
+}
+
+bool
+cl_omf_rec::read(cl_f *f)
+{
+ unsigned char c;
+ int i, l, h;
+
+ if (rec)
+ {
+ free(rec);
+ rec= NULL;
+ }
+ f_offset= offset;
+ if (f->eof())
+ return false;
+ c= g(f);
+ type= c;
+ if (f->eof())
+ return false;
+ c= g(f);
+ l= c;
+ //printf("l=%02x\n", c);
+ if (f->eof())
+ return false;
+ c= g(f);
+ h= c;
+ //printf("h=%02x\n", c);
+ if (f->eof())
+ return false;
+ len= h*256+l-1;
+ rec= (u8_t*)malloc(len);
+ for (i= 0; i < len; i++)
+ {
+ rec[i]= g(f);
+ if (f->eof())
+ return false;
+ }
+ chk= g(f);
+
+ return true;
+}
+
+
+/*
+ * Abstract microcontroller
+ ******************************************************************************
+ */
+
+cl_uc::cl_uc(class cl_sim *asim):
+ cl_base()
+{
+ type= NULL;
+ //int i;
+ sim = asim;
+ //mems= new cl_list(MEM_TYPES, 1);
+ memchips= new cl_list(2, 2, "memchips");
+ address_spaces= new cl_address_space_list(this);
+ //address_decoders= new cl_list(2, 2);
+ rom= 0;
+
+ hws = new cl_hws();
+ //options= new cl_list(2, 2);
+ //for (i= MEM_ROM; i < MEM_TYPES; i++) mems->add(0);
+ xtal_option= new cl_xtal_option(this);
+ xtal_option->init();
+ ticks= new cl_ticker(+1, 0, "time");
+ isr_ticks= new cl_ticker(+1, TICK_INISR, "isr");
+ idle_ticks= new cl_ticker(+1, TICK_IDLE, "idle");
+ counters= new cl_list(2, 2, "counters");
+ it_levels= new cl_list(2, 2, "it levels");
+ it_sources= new cl_irqs(2, 2);
+ class it_level *il= new it_level(-1, 0, 0, 0);
+ it_levels->push(il);
+ stack_ops= new cl_list(2, 2, "stack operations");
+ errors= new cl_list(2, 2, "errors in uc");
+ events= new cl_list(2, 2, "events in uc");
+ sp_max= 0;
+ sp_avg= 0;
+ inst_exec= false;
+}
+
+
+cl_uc::~cl_uc(void)
+{
+ //delete mems;
+ delete hws;
+ //delete options;
+ delete ticks;
+ delete isr_ticks;
+ delete idle_ticks;
+ delete counters;
+ events->disconn_all();
+ delete events;
+ delete fbrk;
+ delete ebrk;
+ delete it_levels;
+ delete it_sources;
+ delete stack_ops;
+ errors->free_all();
+ delete errors;
+ delete xtal_option;
+ delete address_spaces;
+ delete memchips;
+ //delete address_decoders;
+}
+
+
+int
+cl_uc::init(void)
+{
+ int i;
+
+ set_name("controller");
+ cl_base::init();
+ if (xtal_option->use("xtal"))
+ xtal= xtal_option->get_value(xtal);
+ else
+ xtal= 11059200;
+ vars= new cl_var_list();
+ make_variables();
+ make_memories();
+ if (rom == NULL)
+ rom= address_space(cchars("rom")/*MEM_ROM_ID*/);
+ ebrk= new brk_coll(2, 2, rom);
+ fbrk= new brk_coll(2, 2, rom);
+ fbrk->Duplicates= false;
+ brk_counter= 0;
+ stop_at_time= 0;
+ make_cpu_hw();
+ mk_hw_elements();
+ class cl_cmdset *cs= sim->app->get_commander()->cmdset;
+ build_cmdset(cs);
+ irq= false;
+ reset();
+
+ return 0;
+ for (i= 0; i < sim->app->in_files->count; i++)
+ {
+ char *fname= (char *)(sim->app->in_files->at(i));
+ long l;
+ if ((l= read_hex_file(fname)) >= 0)
+ {
+ /*sim->app->get_commander()->all_*/printf("%ld words read from %s\n",
+ l, fname);
+ }
+ }
+ return(0);
+}
+
+char *
+cl_uc::id_string(void)
+{
+ return((char*)"unknown microcontroller");
+}
+
+void
+cl_uc::reset(void)
+{
+ class it_level *il;
+
+ irq= false;
+ instPC= PC= 0;
+ state = stGO;
+ ticks->ticks= 0;
+ isr_ticks->ticks= 0;
+ idle_ticks->ticks= 0;
+ vc.inst= vc.fetch= vc.rd= vc.wr= 0;
+ /*FIXME should we clear user counters?*/
+ il= (class it_level *)(it_levels->top());
+ while (il &&
+ il->level >= 0)
+ {
+ il= (class it_level *)(it_levels->pop());
+ delete il;
+ il= (class it_level *)(it_levels->top());
+ }
+ sp_max= 0;
+ sp_avg= 0;
+
+ stack_ops->free_all();
+
+ int i;
+ for (i= 0; i < hws->count; i++)
+ {
+ class cl_hw *hw= (class cl_hw *)(hws->at(i));
+ hw->reset();
+ }
+}
+
+/*
+ * Making elements
+ */
+
+void
+cl_uc::make_memories(void)
+{
+}
+
+void
+cl_uc::make_variables(void)
+{
+ class cl_address_space *as;
+ class cl_option *o= sim->app->options->get_option("var_size");
+ long l, i;
+
+ if (o)
+ o->get_value(&l);
+ else
+ l= 0x100;
+
+ class cl_address_decoder *ad;
+ class cl_memory_chip *chip;
+
+ if (l > 0)
+ {
+ variables= as= new cl_address_space("variables", 0, l, 32);
+ as->init();
+ address_spaces->add(as);
+
+ chip= new cl_memory_chip("variable_storage", l, 32);
+ chip->init();
+ memchips->add(chip);
+ ad= new cl_address_decoder(variables, chip, 0, l-1, 0);
+ ad->init();
+ variables->decoders->add(ad);
+ ad->activate(0);
+
+ for (i= 0; i < l; i++)
+ variables->set(i, 0);
+ }
+}
+
+/*t_addr
+cl_uc::get_mem_size(char *id)
+{
+ class cl_memory *m= memory(id);
+ return(m?(m->get_size()):0);
+}
+
+int
+cl_uc::get_mem_width(char *id)
+{
+ class cl_memory *m= memory(id);
+ return(m?(m->width):8);
+}
+*/
+void
+cl_uc::make_cpu_hw(void)
+{
+ cpu= NULL;
+}
+
+void
+cl_uc::mk_hw_elements(void)
+{
+ class cl_hw *h;
+
+ add_hw(h= new cl_simulator_interface(this));
+ h->init();
+ add_hw(h= new cl_vcd(this, 0, "vcd"));
+ h->init();
+}
+
+void
+cl_uc::build_cmdset(class cl_cmdset *cmdset)
+{
+ class cl_cmd *cmd;
+ class cl_super_cmd *super_cmd;
+ class cl_cmdset *cset;
+
+ cmdset->add(cmd= new cl_state_cmd("state", 0));
+ cmd->init();
+
+#ifdef STATISTIC
+ cmdset->add(cmd= new cl_statistic_cmd("statistic", 0));
+ cmd->init();
+#endif
+
+ cmdset->add(cmd= new cl_file_cmd("file", 0));
+ cmd->init();
+ cmd->add_name("load");
+
+ cmdset->add(cmd= new cl_dl_cmd("download", 0));
+ cmd->init();
+ cmd->add_name("dl");
+
+ cmdset->add(cmd= new cl_pc_cmd("pc", 0));
+ cmd->init();
+
+ cmdset->add(cmd= new cl_reset_cmd("reset", 0));
+ cmd->init();
+
+ cmdset->add(cmd= new cl_dump_cmd("dump", true));
+ cmd->init();
+
+ cmdset->add(cmd= new cl_dch_cmd("dch", true));
+ cmd->init();
+
+ cmdset->add(cmd= new cl_dc_cmd("dc", true));
+ cmd->init();
+
+ cmdset->add(cmd= new cl_disassemble_cmd("disassemble", true));
+ cmd->init();
+
+ cmdset->add(cmd= new cl_fill_cmd("fill", 0));
+ cmd->init();
+
+ cmdset->add(cmd= new cl_where_cmd("where", 0));
+ cmd->init();
+
+ cmdset->add(cmd= new cl_Where_cmd("Where", 0));
+ cmd->init();
+
+ cmdset->add(cmd= new cl_hole_cmd("hole", 0));
+ cmd->init();
+
+ cmdset->add(cmd= new cl_break_cmd("break", 0));
+ cmd->init();
+
+ cmdset->add(cmd= new cl_tbreak_cmd("tbreak", 0));
+ cmd->init();
+
+ cmdset->add(cmd= new cl_clear_cmd("clear", 0));
+ cmd->init();
+
+ cmdset->add(cmd= new cl_delete_cmd("delete", 0));
+ cmd->init();
+
+ cmdset->add(cmd= new cl_commands_cmd("commands", 0));
+ cmd->init();
+
+ {
+ super_cmd= (class cl_super_cmd *)(cmdset->get_cmd("get"));
+ if (super_cmd)
+ cset= super_cmd->commands;
+ else {
+ cset= new cl_cmdset();
+ cset->init();
+ }
+ cset->add(cmd= new cl_get_sfr_cmd("sfr", 0));
+ cmd->init();
+ /*cset->add(cmd= new cl_get_option_cmd("option", 0));
+ cmd->init();*/
+ }
+ if (!super_cmd)
+ {
+ cmdset->add(cmd= new cl_super_cmd("get", 0, cset));
+ cmd->init();
+ set_get_help(cmd);
+ }
+
+ {
+ super_cmd= (class cl_super_cmd *)(cmdset->get_cmd("set"));
+ if (super_cmd)
+ cset= super_cmd->commands;
+ else {
+ cset= new cl_cmdset();
+ cset->init();
+ }
+ cset->add(cmd= new cl_set_mem_cmd("memory", 0));
+ cmd->init();
+ cset->add(cmd= new cl_set_bit_cmd("bit", 0));
+ cmd->init();
+ cset->add(cmd= new cl_set_hw_cmd("hardware", 0));
+ cmd->add_name("hw");
+ cmd->init();
+ }
+ if (!super_cmd)
+ {
+ cmdset->add(cmd= new cl_super_cmd("set", 0, cset));
+ cmd->init();
+ set_set_help(cmd);
+ }
+
+ { // info
+ super_cmd= (class cl_super_cmd *)(cmdset->get_cmd("info"));
+ if (super_cmd)
+ cset= super_cmd->get_subcommands();
+ else {
+ cset= new cl_cmdset();
+ cset->init();
+ }
+ cset->add(cmd= new cl_info_bp_cmd("breakpoints", 0));
+ cmd->add_name("bp");
+ cmd->init();
+ cset->add(cmd= new cl_info_reg_cmd("registers", 0));
+ cmd->init();
+ cset->add(cmd= new cl_info_hw_cmd("hardware", 0));
+ cmd->add_name("hw");
+ cmd->init();
+ /*
+ cset->add(cmd= new cl_info_stack_cmd("stack", 0,
+ "info stack Status of stack of the CPU",
+ "long help of info stack"));
+ cmd->init();
+ */
+ cset->add(cmd= new cl_info_memory_cmd("memory", 0));
+ cmd->init();
+ cset->add(cmd= new cl_info_var_cmd("variables", 0));
+ cmd->init();
+ cmd->add_name("vars");
+ }
+ if (!super_cmd) {
+ cmdset->add(cmd= new cl_super_cmd("info", 0, cset));
+ cmd->init();
+ set_info_help(cmd);
+ }
+
+ {
+ super_cmd= (class cl_super_cmd *)(cmdset->get_cmd("timer"));
+ if (super_cmd)
+ cset= super_cmd->get_subcommands();
+ else {
+ cset= new cl_cmdset();
+ cset->init();
+ }
+ cset->add(cmd= new cl_timer_add_cmd("add", 0));
+ cmd->init();
+ cmd->add_name("create");
+ cmd->add_name("make");
+ cset->add(cmd= new cl_timer_delete_cmd("delete", 0));
+ cmd->init();
+ cmd->add_name("remove");
+ cset->add(cmd= new cl_timer_get_cmd("get", 0));
+ cmd->init();
+ cset->add(cmd= new cl_timer_run_cmd("run", 0));
+ cmd->init();
+ cmd->add_name("start");
+ cset->add(cmd= new cl_timer_stop_cmd("stop", 0));
+ cmd->init();
+ cset->add(cmd= new cl_timer_value_cmd("set", 0));
+ cmd->init();
+ cmd->add_name("value");
+ }
+ if (!super_cmd) {
+ cmdset->add(cmd= new cl_super_cmd("timer", 0, cset));
+ cmd->init();
+ set_timer_help(cmd);
+ }
+
+ {
+ class cl_super_cmd *mem_create;
+ class cl_cmdset *mem_create_cset;
+ super_cmd= (class cl_super_cmd *)(cmdset->get_cmd("memory"));
+ if (super_cmd)
+ cset= super_cmd->get_subcommands();
+ else {
+ cset= new cl_cmdset();
+ cset->init();
+ }
+ /*
+ cset->add(cmd= new cl_memory_cmd("_no_parameters_", 0));
+ cmd->init();
+ */
+ mem_create= (class cl_super_cmd *)cset->get_cmd("create");
+ if (mem_create)
+ mem_create_cset= mem_create->get_subcommands();
+ else {
+ mem_create_cset= new cl_cmdset();
+ mem_create_cset->init();
+ }
+
+ mem_create_cset->add(cmd= new cl_memory_create_chip_cmd("chip", 0));
+ cmd->init();
+
+ mem_create_cset->add(cmd= new cl_memory_create_addressspace_cmd("addressspace", 0));
+ cmd->init();
+ cmd->add_name("addrspace");
+ cmd->add_name("aspace");
+ cmd->add_name("as");
+ cmd->add_name("addrs");
+ cmd->add_name("addr");
+
+ mem_create_cset->add(cmd= new cl_memory_create_addressdecoder_cmd("addressdecoder", 0));
+ cmd->init();
+ cmd->add_name("addrdecoder");
+ cmd->add_name("adecoder");
+ cmd->add_name("addressdec");
+ cmd->add_name("addrdec");
+ cmd->add_name("adec");
+ cmd->add_name("ad");
+
+ mem_create_cset->add(cmd= new cl_memory_create_banker_cmd("banker", 0));
+ cmd->init();
+ cmd->add_name("bankswitcher");
+ cmd->add_name("banksw");
+ cmd->add_name("bsw");
+ cmd->add_name("bs");
+
+ mem_create_cset->add(cmd= new cl_memory_create_bank_cmd("bank", 0));
+ cmd->init();
+
+ mem_create_cset->add(cmd= new cl_memory_create_bander_cmd("bander", 0));
+ cmd->init();
+ cmd->add_name("bitbander");
+ cmd->add_name("bitband");
+ cmd->add_name("band");
+ cmd->add_name("bb");
+
+ if (!mem_create)
+ cset->add(mem_create= new cl_super_cmd("create", 0, mem_create_cset));
+ mem_create->init();
+ mem_create->add_name("add");
+ set_memory_create_help(mem_create);
+
+ cset->add(cmd= new cl_info_memory_cmd("info", 0));
+ cmd->init();
+ cset->add(cmd= new cl_memory_cell_cmd("cell", 0));
+ cmd->init();
+ }
+ if (!super_cmd) {
+ cmdset->add(cmd= new cl_super_cmd("memory", 0, cset));
+ cmd->init();
+ set_memory_help(cmd);
+ }
+
+ cmdset->add(cmd= new cl_var_cmd("var", 0));
+ cmd->init();
+ cmd->add_name("variable");
+}
+
+
+/*
+ * Read/write simulated memory
+ */
+
+t_mem
+cl_uc::read_mem(char *id, t_addr addr)
+{
+ class cl_address_space *m= address_space(id);
+
+ return(m?(m->read(addr)):0);
+}
+
+t_mem
+cl_uc::get_mem(char *id, t_addr addr)
+{
+ class cl_address_space *m= address_space(id);
+
+ return(m?(m->get(addr)):0);
+}
+
+void
+cl_uc::write_mem(char *id, t_addr addr, t_mem val)
+{
+ class cl_address_space *m= address_space(id);
+
+ if (m)
+ m->write(addr, val);
+}
+
+void
+cl_uc::set_mem(char *id, t_addr addr, t_mem val)
+{
+ class cl_address_space *m= address_space(id);
+
+ if(m)
+ m->set(addr, val);
+}
+
+
+/*
+class cl_memory *
+cl_uc::mem(enum mem_class type)
+{
+ class cl_m *m;
+
+ if (mems->count < type)
+ m= (class cl_m *)(mems->at(MEM_DUMMY));
+ else
+ m= (class cl_m *)(mems->at(type));
+ return(m);
+}
+*/
+
+class cl_address_space *
+cl_uc::address_space(const char *id)
+{
+ int i;
+
+ if (!id ||
+ !(*id))
+ return(0);
+ for (i= 0; i < address_spaces->count; i++)
+ {
+ class cl_address_space *m= (cl_address_space *)(address_spaces->at(i));
+ if (!m ||
+ !m->have_real_name())
+ continue;
+ if (m->is_inamed(id))
+ return(m);
+ }
+ return(0);
+}
+
+class cl_address_space *
+cl_uc::address_space(class cl_memory_cell *cell)
+{
+ return(address_space(cell, (t_addr*)NULL));
+}
+
+class cl_address_space *
+cl_uc::address_space(class cl_memory_cell *cell, t_addr *addr)
+{
+ int i;
+
+ for (i= 0; i < address_spaces->count; i++)
+ {
+ class cl_address_space *m= (cl_address_space *)(address_spaces->at(i));
+ if (!m)
+ continue;
+ if (m->is_owned(cell, addr))
+ return(m);
+ }
+ return(0);
+}
+
+class cl_memory *
+cl_uc::memory(const char *id)
+{
+ int i;
+
+ if (!id ||
+ !(*id))
+ return(0);
+ for (i= 0; i < address_spaces->count; i++)
+ {
+ class cl_base *b= address_spaces->object_at(i);
+ class cl_memory *m= dynamic_cast<cl_memory *>(b);
+ if (!m ||
+ !m->have_real_name())
+ continue;
+ if (m->is_inamed(id))
+ return(m);
+ }
+ for (i= 0; i < memchips->count; i++)
+ {
+ class cl_memory *m= (cl_memory *)(memchips->at(i));
+ if (!m ||
+ !m->have_real_name())
+ continue;
+ if (m->is_inamed(id))
+ return(m);
+ }
+ return(0);
+}
+
+
+static long
+ReadInt(cl_f *f, bool *ok, int bytes)
+{
+ char s2[3];
+ long l= 0;
+ int c;
+
+ *ok= false;
+ while (bytes)
+ {
+ if (f->eof())
+ return(0);
+ c= f->get_c();
+ if ((c < 0) ||
+ (c == 0) ||
+ (c > 0xff))
+ return 0;
+ s2[0]= c;
+ if (f->eof())
+ return(0);
+ c= f->get_c();
+ if ((c < 0) ||
+ (c == 0) ||
+ (c > 0xff))
+ return 0;
+ s2[1]= c;
+ s2[2]= '\0';
+ l= l*256 + strtol(s2, NULL, 16);
+ bytes--;
+ }
+ *ok= true;
+ return(l);
+}
+
+
+/*
+ * Reading intel hexa file into EROM
+ *____________________________________________________________________________
+ *
+ * If parameter is a NULL pointer, this function reads data from `cmd_in'
+ *
+ */
+
+void
+cl_uc::set_rom(t_addr addr, t_mem val)
+{
+ //printf("rom[%06lx]=%02x\n", addr, val);
+ t_addr size= rom->get_size();
+ if (addr < size)
+ {
+ rom->download(addr, val);
+ return;
+ }
+ t_addr bank, caddr;
+ bank= addr / size;
+ caddr= addr % size;
+ //printf("getting decoder of %ld/%lx\n", bank, caddr);
+ class cl_banker *d= (class cl_banker *)(rom->get_decoder_of(caddr));
+ if (d)
+ {
+ if (!d->is_banker())
+ {
+ //printf("cell at %lx has no banker\n", caddr);
+ return;
+ }
+ //printf("setting %ld/rom[%lx]=%x\n", bank, caddr, val);
+ d->switch_to(bank, NULL);
+ rom->download(caddr, val);
+ d->activate(NULL);
+ }
+ else
+ ;//printf("no decoder at %lx\n", caddr);
+}
+
+long
+cl_uc::read_hex_file(const char *nam)
+{
+ cl_f *f;
+
+ if (!nam)
+ {
+ fprintf(stderr, "cl_uc::read_hex_file File name not specified\n");
+ return(-1);
+ }
+ else
+ if ((f= /*fopen*/mk_io(nam, "r")) == NULL)
+ {
+ fprintf(stderr, "Can't open `%s': %s\n", nam, strerror(errno));
+ return(-1);
+ }
+ long l= read_hex_file(f);
+ delete f;
+ return l;
+}
+
+long
+cl_uc::read_hex_file(cl_console_base *con)
+{
+ cl_f *f;
+ if (con == NULL)
+ return -1;
+ f= con->get_fin();
+ if (f == NULL)
+ return -1;
+ long l= read_hex_file(f);
+ return l;
+}
+
+long
+cl_uc::read_hex_file(cl_f *f)
+{
+ int c;
+ long written= 0, recnum= 0;
+
+ uint base= 0; // extended address, added to every adress
+ uchar dnum; // data number
+ uchar rtyp=0; // record type
+ uint addr= 0; // address
+ uchar rec[300]; // data record
+ uchar sum ; // checksum
+ uchar chk ; // check
+ int i;
+ bool ok, get_low= 1;
+ uchar low= 0, high;
+
+ if (!rom)
+ {
+ sim->app->get_commander()->
+ dd_printf("No ROM address space to read in.\n");
+ return(-1);
+ }
+
+ //memset(inst_map, '\0', sizeof(inst_map));
+ ok= true;
+ while (ok &&
+ rtyp != 1)
+ {
+ while (((c= /*getc(f)*/f->get_c()) != ':') &&
+ (/*c != EOF*/!f->eof())) /*printf("search_record=%c\n",c)*/;
+ if (c != ':')
+ {fprintf(stderr, ": not found\n");break;}
+ recnum++;
+ dnum= ReadInt(f, &ok, 1);//printf("%ld:dnum=%02x ",recnum,dnum);
+ chk = dnum;
+ addr= ReadInt(f, &ok, 2);//printf("%ld:addr=%04x ",recnum,addr);
+ chk+= (addr & 0xff);
+ chk+= ((addr >> 8) & 0xff);
+ rtyp= ReadInt(f, &ok, 1);//printf("%ld:rtyp=%02x ",recnum,rtyp);
+ chk+= rtyp;
+ for (i= 0; ok && (i < dnum); i++)
+ {
+ rec[i]= ReadInt(f, &ok, 1);//printf("%02x",rec[i]);
+ chk+= rec[i];
+ }
+ if (ok)
+ {
+ sum= ReadInt(f, &ok, 1);//printf(" %ld:sum=%02x\n",recnum,sum);
+ if (ok)
+ {
+ if (((sum + chk) & 0xff) == 0)
+ {
+ if (rtyp == 0)
+ {
+ if (rom->width > 8)
+ addr/= 2;
+ for (i= 0; i < dnum; i++)
+ {
+ if (rom->width <= 8)
+ {
+ set_rom(base+addr, rec[i]);
+ addr++;
+ written++;
+ }
+ else if (rom->width <= 16)
+ {
+ if (get_low)
+ {
+ low= rec[i];
+ get_low= 0;
+ }
+ else
+ {
+ high= rec[i];
+ set_rom(base+addr, (high*256)+low);
+ addr++;
+ written++;
+ get_low= 1;
+ }
+ }
+ }
+ }
+ else if (rtyp == 4)
+ {
+ //printf("hex record type=4\n");
+ if (dnum >= 2)
+ {
+ base= (rec[0]*256+rec[1]) << 16;
+ //printf("hex base=%x\n", base);
+ }
+ }
+ else
+ if (rtyp != 1)
+ /*application->debug*/fprintf(stderr, "Unknown record type %d(0x%x)\n",
+ rtyp, rtyp);
+ }
+ else
+ /*application->debug*/fprintf(stderr, "Checksum error (%x instead of %x) in "
+ "record %ld.\n", chk, sum, recnum);
+ }
+ else
+ /*application->debug*/fprintf(stderr, "Read error in record %ld.\n", recnum);
+ }
+ }
+ if (rom->width > 8 &&
+ !get_low)
+ rom->set(addr, low);
+
+ analyze(0);
+ return(written);
+}
+
+long
+cl_uc::read_omf_file(cl_f *f)
+{
+ long written= 0;
+ class cl_omf_rec rec;
+ while (rec.read(f))
+ {
+ if (rec.type == 0x06)
+ {
+ // content
+ u16_t addr= rec.pick_word(1);
+ int i= 3;
+ while (i < rec.len)
+ {
+ set_rom(addr+i, rec.rec[i]);
+ written++;
+ i++;
+ }
+ }
+ }
+ return (written);
+}
+
+long
+cl_uc::read_cdb_file(cl_f *f)
+{
+ class cl_cdb_recs *fns= new cl_cdb_recs();
+ chars ln;
+ char *lc;
+ long cnt= 0;
+ class cl_cdb_rec *r;
+ class cl_var *v;
+
+ ln= f->get_s();
+ while (!ln.empty())
+ {
+ //printf("CBD LN=%s\n",(char*)ln);
+ lc= (char*)ln;
+ if (lc[0] == 'F')
+ {
+ if (ln.len() > 5)
+ {
+ if ((lc[1] == ':') &&
+ (lc[2] == 'G'))
+ {
+ ln.start_parse(4);
+ chars n= ln.token("$");
+ if ((r= fns->rec(n)) != NULL)
+ {
+ vars->add(v= new cl_var(n, rom, r->addr, ""));
+ v->init();
+ fns->del(n);
+ cnt++;
+ }
+ else
+ fns->add(new cl_cdb_rec(n));
+ }
+ }
+ }
+ else if (lc[0] == 'L')
+ {
+ if (ln.len() > 5)
+ {
+ if ((ln[1] == ':') &&
+ (lc[2] == 'G'))
+ {
+ ln.start_parse(4);
+ chars n= ln.token("$");
+ chars t= ln.token(":");
+ t= ln.token(" ");
+ t_addr a= strtol((char*)t, 0, 16);
+ if ((r= fns->rec(n)) != NULL)
+ {
+ fns->del(n);
+ vars->add(v= new cl_var(n, rom, a, ""));
+ v->init();
+ cnt++;
+ }
+ else
+ fns->add(new cl_cdb_rec(n, a));
+ }
+ }
+ }
+ ln= f->get_s();
+ }
+ fns->free_all();
+ delete fns;
+ return cnt;
+}
+
+cl_f *
+cl_uc::find_loadable_file(chars nam)
+{
+ cl_f *f;
+ bool o;
+ chars c;
+
+ f= mk_io(nam, "r");
+ o= (f->opened());
+ if (o)
+ return f;
+
+ c= chars("", "%s.ihx", (char*)nam);
+ f->open(c, chars("r"));
+ o= (f->opened());
+ if (o)
+ return f;
+ c= chars("", "%s.hex", (char*)nam);
+ f->open(c, chars("r"));
+ o= (f->opened());
+ if (o)
+ return f;
+ c= chars("", "%s.ihex", (char*)nam);
+ f->open(c, chars("r"));
+ o= (f->opened());
+ if (o)
+ return f;
+
+ c= chars("", "%s.omf", (char*)nam);
+ f->open(c, chars("r"));
+ o= (f->opened());
+ if (o)
+ return f;
+
+ delete f;
+ return NULL;
+}
+
+long
+cl_uc::read_file(chars nam, class cl_console_base *con)
+{
+ cl_f *f= find_loadable_file(nam);
+ long l= 0;
+
+ if (!f)
+ {
+ if (con) con->dd_printf("no loadable file found\n");
+ return 0;
+ }
+ /*if (con) con->dd_*/printf("Loading from %s\n", f->get_file_name());
+ if (is_hex_file(f))
+ {
+ l= read_hex_file(f);
+ printf("%ld words read from %s\n", l, f->get_fname());
+ }
+ else if (is_omf_file(f))
+ {
+ l= read_omf_file(f);
+ printf("%ld words read from %s\n", l, f->get_fname());
+ }
+ else if (is_cdb_file(f))
+ {
+ l= read_cdb_file(f);
+ printf("%ld symbols read from %s\n", l, f->get_fname());
+ }
+ if (strcmp(nam, f->get_fname()) != 0)
+ {
+ chars n= nam;
+ n+= (char*)".cdb";
+ cl_f *c= mk_io(n, "r");
+ if (c->opened())
+ {
+ l= read_cdb_file(c);
+ printf("%ld symbols read from %s\n", l, c->get_fname());
+ }
+ delete c;
+ }
+ delete f;
+ return l;
+}
+
+
+/*
+ * Handling instruction map
+ *
+ * `inst_at' is checking if the specified address is in instruction
+ * map and `set_inst_at' marks the address in the map and
+ * `del_inst_at' deletes the mark. `there_is_inst' cheks if there is
+ * any mark in the map
+ */
+
+bool
+cl_uc::inst_at(t_addr addr)
+{
+ if (!rom)
+ return(0);
+ return(rom->get_cell_flag(addr, CELL_INST));
+}
+
+void
+cl_uc::set_inst_at(t_addr addr)
+{
+ if (rom)
+ rom->set_cell_flag(addr, true, CELL_INST);
+}
+
+void
+cl_uc::del_inst_at(t_addr addr)
+{
+ if (rom)
+ rom->set_cell_flag(addr, false, CELL_INST);
+}
+
+bool
+cl_uc::there_is_inst(void)
+{
+ if (!rom)
+ return(0);
+ bool got= false;
+ t_addr addr;
+ for (addr= 0; rom->valid_address(addr) && !got; addr++)
+ got= rom->get_cell_flag(addr, CELL_INST);
+ return(got);
+}
+
+
+/*
+ * Manipulating HW elements of the CPU
+ *****************************************************************************
+ */
+
+/* Register callback hw objects for mem read/write */
+
+/*void
+cl_uc::register_hw_read(enum mem_class type, t_addr addr, class cl_hw *hw)
+{
+ class cl_m *m;
+ class cl_memloc *l;
+
+ if ((m= (class cl_m*)mems->at(type)))
+ {
+ if ((l= m->read_locs->get_loc(addr)) == 0)
+ {
+ l= new cl_memloc(addr);
+ l->init();
+ m->read_locs->add(l);
+ }
+ l->hws->add(hw);
+ }
+ else
+ printf("cl_uc::register_hw_read TROUBLE\n");
+}*/
+
+/*void
+cl_uc::register_hw_write(enum mem_class type, t_addr addr, class cl_hw *hw)
+{
+}*/
+
+void
+cl_uc::add_hw(class cl_hw *hw)
+{
+ int i;
+ for (i= 0; i < hws->count; i++)
+ {
+ class cl_hw *h= (class cl_hw *)(hws->at(i));
+ h->new_hw_adding(hw);
+ }
+ hws->add(hw);
+ for (i= 0; i < hws->count; i++)
+ {
+ class cl_hw *h= (class cl_hw *)(hws->at(i));
+ if (h != hw)
+ h->new_hw_added(hw);
+ }
+}
+
+int
+cl_uc::nuof_hws(void)
+{
+ return hws->count;
+}
+
+/* Looking for a specific HW element */
+
+class cl_hw *
+cl_uc::get_hw(int idx)
+{
+ if (idx >= hws->count)
+ return NULL;
+ return (class cl_hw *)(hws->at(idx));
+}
+
+class cl_hw *
+cl_uc::get_hw(enum hw_cath cath, int *idx)
+{
+ class cl_hw *hw= 0;
+ int i= 0;
+
+ if (idx)
+ i= *idx;
+ for (; i < hws->count; i++)
+ {
+ hw= (class cl_hw *)(hws->at(i));
+ if (hw->cathegory == cath)
+ break;
+ }
+ if (i >= hws->count)
+ return(0);
+ if (idx)
+ *idx= i;
+ return(hw);
+}
+
+class cl_hw *
+cl_uc::get_hw(char *id_string, int *idx)
+{
+ class cl_hw *hw= 0;
+ int i= 0;
+
+ if (idx)
+ i= *idx;
+ for (; i < hws->count; i++)
+ {
+ hw= (class cl_hw *)(hws->at(i));
+ if (strstr(hw->id_string, id_string) == hw->id_string)
+ break;
+ }
+ if (i >= hws->count)
+ return(0);
+ if (idx)
+ *idx= i;
+ return(hw);
+}
+
+class cl_hw *
+cl_uc::get_hw(enum hw_cath cath, int hwid, int *idx)
+{
+ class cl_hw *hw;
+ int i= 0;
+
+ if (idx)
+ i= *idx;
+ hw= get_hw(cath, &i);
+ while (hw &&
+ hw->id != hwid)
+ {
+ i++;
+ hw= get_hw(cath, &i);
+ }
+ if (hw &&
+ idx)
+ *idx= i;
+ return(hw);
+}
+
+class cl_hw *
+cl_uc::get_hw(char *id_string, int hwid, int *idx)
+{
+ class cl_hw *hw;
+ int i= 0;
+
+ if (idx)
+ i= *idx;
+ hw= get_hw(id_string, &i);
+ while (hw &&
+ hw->id != hwid)
+ {
+ i++;
+ hw= get_hw(id_string, &i);
+ }
+ if (hw &&
+ idx)
+ *idx= i;
+ return(hw);
+}
+
+int
+cl_uc::get_max_hw_id(enum hw_cath cath)
+{
+ class cl_hw *hw;
+ int i, max= -1;
+
+ for (i= 0; i < hws->count; i++)
+ {
+ hw= (class cl_hw *)(hws->at(i));
+ if (hw->id > max)
+ max= hw->id;
+ }
+ return max;
+}
+
+/*
+ * Help of the command interpreter
+ */
+
+struct dis_entry *
+cl_uc::dis_tbl(void)
+{
+ static struct dis_entry empty= { 0, 0, 0, 0, NULL };
+ return(&empty);
+}
+
+char *
+cl_uc::disass(t_addr addr, const char *sep)
+{
+ char *buf;
+
+ buf= (char*)malloc(100);
+ strcpy(buf, "uc::disass() unimplemented\n");
+ return(buf);
+}
+
+void
+cl_uc::print_disass(t_addr addr, class cl_console_base *con)
+{
+ char *dis;
+ class cl_brk *b;
+ int i, l;
+
+ if (!rom)
+ return;
+
+ t_mem code= rom->get(addr);
+ b= fbrk_at(addr);
+ dis= disass(addr, NULL);
+ if (b)
+ con->dd_cprintf("answer", "%c", (b->perm == brkFIX)?'F':'D');
+ else
+ con->dd_printf(" ");
+ con->dd_cprintf("answer", "%c ", inst_at(addr)?' ':'?');
+ con->dd_cprintf("dump_address", rom->addr_format, addr); con->dd_printf(" ");
+ con->dd_cprintf("dump_number", rom->data_format, code);
+ l= inst_length(addr);
+ for (i= 1; i < l; i++)
+ {
+ con->dd_printf(" ");
+ con->dd_cprintf("dump_number", rom->data_format, rom->get(addr+i));
+ }
+ int li= longest_inst();
+ while (i < li)
+ {
+ int j;
+ j= rom->width/4 + ((rom->width%4)?1:0) + 1;
+ while (j)
+ con->dd_printf(" "), j--;
+ i++;
+ }
+ con->dd_cprintf("dump_char", " %s\n", dis);
+ free((char *)dis);
+}
+
+void
+cl_uc::print_regs(class cl_console_base *con)
+{
+ con->dd_printf("No registers\n");
+}
+
+int
+cl_uc::inst_length(t_addr addr)
+{
+ struct dis_entry *tabl= dis_tbl();
+ int i;
+ t_mem code;
+
+ if (!rom)
+ return(0);
+
+ code = rom->get(addr);
+ for (i= 0; tabl[i].mnemonic && (code & tabl[i].mask) != tabl[i].code; i++) ;
+ return(tabl[i].mnemonic?tabl[i].length:1);
+}
+
+int
+cl_uc::inst_branch(t_addr addr)
+{
+ struct dis_entry *tabl= dis_tbl();
+ int i;
+ t_mem code;
+
+ if (!rom)
+ return(0);
+
+ code = rom->get(addr);
+ for (i= 0; tabl[i].mnemonic && (code & tabl[i].mask) != tabl[i].code; i++)
+ ;
+ return tabl[i].branch;
+}
+
+bool
+cl_uc::is_call(t_addr addr)
+{
+ struct dis_entry *tabl= dis_tbl();
+ int i;
+ t_mem code;
+
+ if (!rom)
+ return(0);
+
+ code = rom->get(addr);
+ for (i= 0; tabl[i].mnemonic && (code & tabl[i].mask) != tabl[i].code; i++)
+ ;
+ return tabl[i].is_call;
+}
+
+int
+cl_uc::longest_inst(void)
+{
+ struct dis_entry *de= dis_tbl();
+ int max= 0;
+
+ while (de &&
+ de->mnemonic)
+ {
+ if (de->length > max)
+ max= de->length;
+ de++;
+ }
+ return(max);
+}
+
+bool
+cl_uc::addr_name(t_addr addr, class cl_address_space *as, char *buf)
+{
+ t_index i;
+
+ for (i= 0; i < vars->count; i++)
+ {
+ class cl_var *v= (cl_var *)(vars->at(i));
+ if ((v->as == as) &&
+ (v->addr == addr))
+ {
+ strcpy(buf, v->get_name());
+ return true;
+ }
+ }
+ unsigned int a= addr;
+ sprintf(buf, "%02x", a);
+ return false;
+}
+
+bool
+cl_uc::addr_name(t_addr addr, class cl_address_space *as, int bitnr, char *buf)
+{
+ t_index i;
+
+ for (i= 0; i < vars->count; i++)
+ {
+ class cl_var *v= (cl_var *)(vars->at(i));
+ if ((v->as == as) &&
+ (v->addr == addr) &&
+ (v->bitnr == bitnr))
+ {
+ strcpy(buf, v->get_name());
+ return true;
+ }
+ }
+ unsigned int a= addr;
+ sprintf(buf, "%02x.%d", a, bitnr);
+ return false;
+}
+
+bool
+cl_uc::symbol2address(char *sym,
+ class cl_address_space **as,
+ t_addr *addr)
+{
+ class cl_var *v;
+ t_index i;
+
+ if (!sym ||
+ !*sym)
+ return false;
+ if (vars->search(sym, i))
+ {
+ v= (class cl_var *)(vars->at(i));
+ if (v->bitnr >= 0)
+ return false;
+ if (as)
+ *as= v->as;
+ if (addr)
+ *addr= v->addr;
+ return true;
+ }
+ return false;
+}
+
+char *
+cl_uc::symbolic_bit_name(t_addr bit_address,
+ class cl_memory *mem,
+ t_addr mem_addr,
+ t_mem bit_mask)
+{
+ //char *sym_name= 0;
+ int i;
+ chars c= chars("", mem?(mem->addr_format):"0x%06lx", (unsigned long)mem_addr);
+ /*if (!sym_name)
+ {
+ sym_name= (char *)malloc(16);
+ sprintf(sym_name, mem?(mem->addr_format):"0x%06lx", (unsigned long)mem_addr);
+ }*/
+ /*sym_name= (char *)realloc(sym_name, strlen(sym_name)+2);
+ strcat(sym_name, ".");*/
+ c+= cchars(".");
+ i= 0;
+ while (bit_mask > 1)
+ {
+ bit_mask>>=1;
+ i++;
+ }
+ //char bitnumstr[10];
+ /*sprintf(bitnumstr, "%1d", i);
+ strcat(sym_name, bitnumstr);*/
+ c.append("%d", i);
+ return(/*sym_name*/strdup((char*)c));
+}
+
+
+/*
+ * Searching for a name in the specified table
+ */
+
+struct name_entry *
+cl_uc::get_name_entry(struct name_entry tabl[], char *name)
+{
+ int i= 0;
+ char *p;
+
+ if (!tabl ||
+ !name ||
+ !(*name))
+ return(0);
+ for (p= name; *p; *p= toupper(*p), p++);
+ while (tabl[i].name &&
+ (!(tabl[i].cpu_type & type->type) ||
+ (strcmp(tabl[i].name, name) != 0)))
+ {
+ //printf("tabl[%d].name=%s <-> %s\n",i,tabl[i].name,name);
+ i++;
+ }
+ if (tabl[i].name != NULL)
+ return(&tabl[i]);
+ else
+ return(0);
+}
+
+chars
+cl_uc::cell_name(class cl_memory_cell *cell)
+{
+ if (cell == NULL)
+ return chars("");
+ if (cell->get_flag(CELL_VAR))
+ {
+ int i;
+ for (i= 0; i < vars->count; i++)
+ {
+ class cl_var *v= (cl_var*)(vars->at(i));
+ if (v->get_cell() &&
+ (cell == v->get_cell()))
+ return chars(v->get_name());
+ }
+ }
+ class cl_address_space *as;
+ t_addr a;
+ as= address_space(cell, &a);
+ if (as == NULL)
+ return chars("");
+ return chars("", "%s_%06x", as->get_name(), a);
+}
+
+class cl_var *
+cl_uc::var(char *nam)
+{
+ if (!vars)
+ return NULL;
+ t_index i;
+ if (!vars->search(nam, i))
+ return NULL;
+ class cl_var *v= (cl_var*)(vars->at(i));
+ return v;
+}
+
+
+/*
+ * Messages to broadcast
+ */
+
+bool
+cl_uc::handle_event(class cl_event &event)
+{
+ switch (event.what)
+ {
+ case ev_address_space_added:
+ {
+ try {
+ class cl_event_address_space_added &e=
+ dynamic_cast<class cl_event_address_space_added &>(event);
+ address_space_added(e.as);
+ e.handle();
+ }
+ catch (...)
+ { break; }
+ break;
+ }
+ default:
+ return(pass_event_down(event));
+ break;
+ }
+ return(false);
+}
+
+/*
+void
+cl_uc::mem_cell_changed(class cl_address_space *mem, t_addr addr)
+{
+ if (hws)
+ hws->mem_cell_changed(mem, addr);
+ else
+ printf("JAJ uc\n");//FIXME
+ if (mems &&
+ mems->count)
+ {
+ int i;
+ for (i= 0; i < mems->count; i++)
+ {
+ }
+ }
+}
+*/
+
+void
+cl_uc::address_space_added(class cl_address_space *as)
+{
+ /*
+ if (hws)
+ hws->address_space_added(as);
+ else
+ printf("JAJ uc\n");//FIXME
+ */
+}
+
+
+/*
+ * Error handling
+ */
+
+void
+cl_uc::error(class cl_error *error)
+{
+ //printf("error adding: %s...\n", error->get_class()->get_name());
+ errors->add(error);
+ if ((error->inst= inst_exec))
+ error->PC= instPC;
+}
+
+void
+cl_uc::check_errors(void)
+{
+ int i;
+ class cl_commander_base *c= sim->app->get_commander();
+ bool must_stop= false;
+
+ if (c)
+ {
+ //printf("error list: %d items\n", errors->count);
+ for (i= 0; i < errors->count; i++)
+ {
+ class cl_error *error= (class cl_error *)(errors->at(i));
+ if (!error->is_on())
+ continue;
+ error->print(c);
+ must_stop= must_stop || (error->get_type() & err_stop);
+ if (error->inst)
+ {
+ class cl_console_base *con;
+ con= c->actual_console;
+ if (!con)
+ con= c->frozen_console;
+ if (con)
+ {
+ con->dd_printf("Erronouse instruction: ");
+ print_disass(error->PC, con);
+ }
+ }
+ }
+ errors->free_all();
+ }
+ else
+ fprintf(stderr, "no actual console, %d errors\n", errors->count);
+ if (must_stop)
+ sim->stop(resERROR);
+}
+
+
+/*
+ * Converting bit address into real memory
+ */
+
+class cl_address_space *
+cl_uc::bit2mem(t_addr bitaddr, t_addr *memaddr, t_mem *bitmask)
+{
+ if (memaddr)
+ *memaddr= bitaddr;
+ if (bitmask)
+ *bitmask= 1 << (bitaddr & 0x7);
+ return(0); // abstract...
+}
+
+
+/*
+ * Execution
+ */
+
+int
+cl_uc::tick_hw(int cycles)
+{
+ class cl_hw *hw;
+ int i;//, cpc= clock_per_cycle();
+
+ // tick hws
+ for (i= 0; i < hws->count; i++)
+ {
+ hw= (class cl_hw *)(hws->at(i));
+ if ((hw->flags & HWF_INSIDE) &&
+ (hw->on))
+ hw->tick(cycles);
+ }
+ do_extra_hw(cycles);
+ return(0);
+}
+
+void
+cl_uc::do_extra_hw(int cycles)
+{}
+
+int
+cl_uc::tick(int cycles)
+{
+ //class cl_hw *hw;
+ int i, cpc= clock_per_cycle();
+
+ // increase time
+ ticks->tick(cycles * cpc);
+ class it_level *il= (class it_level *)(it_levels->top());
+ if (il->level >= 0)
+ isr_ticks->tick(cycles * cpc);
+ if (state == stIDLE)
+ idle_ticks->tick(cycles * cpc);
+ for (i= 0; i < counters->count; i++)
+ {
+ class cl_ticker *t= (class cl_ticker *)(counters->at(i));
+ if (t)
+ {
+ if ((t->options&TICK_INISR) ||
+ il->level < 0)
+ t->tick(cycles * cpc);
+ }
+ }
+
+ // tick for hardwares
+ inst_ticks+= cycles;
+ return(0);
+}
+
+class cl_ticker *
+cl_uc::get_counter(int nr)
+{
+ if (nr >= counters->count)
+ return(0);
+ return((class cl_ticker *)(counters->at(nr)));
+}
+
+class cl_ticker *
+cl_uc::get_counter(const char *nam)
+{
+ int i;
+
+ if (!nam)
+ return(0);
+ for (i= 0; i < counters->count; i++)
+ {
+ class cl_ticker *t= (class cl_ticker *)(counters->at(i));
+ if (t &&
+ t->get_name() &&
+ strcmp(t->get_name(), nam) == 0)
+ return(t);
+ }
+ return(0);
+}
+
+void
+cl_uc::add_counter(class cl_ticker *ticker, int nr)
+{
+ while (counters->count <= nr)
+ counters->add(0);
+ counters->put_at(nr, ticker);
+}
+
+void
+cl_uc::add_counter(class cl_ticker *ticker, const char */*nam*/)
+{
+ int i;
+
+ if (counters->count < 1)
+ counters->add(0);
+ for (i= 1; i < counters->count; i++)
+ {
+ class cl_ticker *t= (class cl_ticker *)(counters->at(i));
+ if (!t)
+ {
+ counters->put_at(i, ticker);
+ return;
+ }
+ }
+ counters->add(ticker);
+}
+
+void
+cl_uc::del_counter(int nr)
+{
+ class cl_ticker *t;
+
+ if (nr >= counters->count)
+ return;
+ if ((t= (class cl_ticker *)(counters->at(0))) != 0)
+ delete t;
+ counters->put_at(nr, 0);
+}
+
+void
+cl_uc::del_counter(const char *nam)
+{
+ int i;
+
+ if (!nam)
+ return;
+ for (i= 0; i < counters->count; i++)
+ {
+ class cl_ticker *t= (class cl_ticker *)(counters->at(i));
+ if (t &&
+ t->get_name() &&
+ strcmp(t->get_name(), nam) == 0)
+ {
+ delete t;
+ counters->put_at(i, 0);
+ return;
+ }
+ }
+}
+
+/*
+ * Fetch without checking for breakpoint hit
+ */
+
+t_mem
+cl_uc::fetch(void)
+{
+ ulong code;
+
+ if (!rom)
+ return(0);
+
+ code= rom->read(PC);
+ PC= rom->inc_address(PC);
+ vc.fetch++;
+ return(code);
+}
+
+/*
+ * Fetch but checking for breakpoint hit first, returns TRUE if
+ * a breakpoint is hit
+ */
+
+bool
+cl_uc::fetch(t_mem *code)
+{
+ class cl_brk *brk;
+ int idx;
+
+ if (!code)
+ return(0);
+ if ((sim->state & SIM_GO) &&
+ rom &&
+ (sim->steps_done > 0))
+ {
+ if (rom->get_cell_flag(PC, CELL_FETCH_BRK))
+ if ((brk= fbrk->get_bp(PC, &idx)))
+ if (brk->do_hit())
+ {
+ if (brk->perm == brkDYNAMIC)
+ fbrk->del_bp(PC);
+ return(1);
+ }
+ }
+ *code= fetch();
+ return(0);
+}
+
+int
+cl_uc::do_inst(int step)
+{
+ t_addr PCsave;
+ int res= resGO;
+
+ if (step < 0)
+ step= 1;
+ while (step-- &&
+ res == resGO)
+ {
+ pre_inst();
+ PCsave = PC;
+ res= exec_inst();
+
+ if (res == resINV_INST)
+ /* backup to start of instruction */
+ PC = PCsave;
+
+ post_inst();
+
+ if ((res == resGO) &&
+ irq)
+ {
+ //printf("DO INTERRUPT PC=%lx\n", PC);
+ int r= do_interrupt();
+ if (r != resGO)
+ res= r;
+ }
+
+ if (stop_at_time &&
+ stop_at_time->reached())
+ {
+ delete stop_at_time;
+ stop_at_time= NULL;
+ res= resBREAKPOINT;
+ }
+ }
+ if (res != resGO)
+ sim->stop(res);
+ return(res);
+}
+
+void
+cl_uc::pre_inst(void)
+{
+ inst_exec= true;
+ inst_ticks= 0;
+ events->disconn_all();
+ vc.inst++;
+}
+
+int
+cl_uc::exec_inst(void)
+{
+ instPC= PC;
+ return(resGO);
+}
+
+int
+cl_uc::exec_inst_tab(instruction_wrapper_fn itab[])
+{
+ t_mem c;
+ int res= resGO;
+ instPC= PC;
+ if (fetch(&c))
+ return resBREAKPOINT;
+ if (itab[c] == NULL)
+ {
+ PC= instPC;
+ return resNOT_DONE;
+ }
+ res= itab[c](this, c);
+ if (res == resNOT_DONE)
+ {
+ PC= instPC;
+ return res;
+ }
+ tick(1);
+ return res;
+}
+
+
+void
+cl_uc::post_inst(void)
+{
+ tick_hw(inst_ticks);
+ if (errors->count)
+ check_errors();
+ if (events->count)
+ check_events();
+ inst_exec= false;
+}
+
+
+/*
+ * Interrupt processing
+ */
+
+int
+cl_uc::do_interrupt(void)
+{
+ int i;
+ // NMI?
+
+ // Maskable interrupts
+ if (!it_enabled())
+ {
+ //printf("do_interrupt skip (it disabled)\n");
+ return resGO;
+ }
+ class it_level *il= (class it_level *)(it_levels->top()), *IL= 0;
+ irq= false;
+ //printf("Checking IRQs...\n");
+ for (i= 0; i < it_sources->count; i++)
+ {
+ class cl_it_src *is= (class cl_it_src *)(it_sources->at(i));
+ if (is->is_active() &&
+ is->enabled() &&
+ is->pending())
+ {
+ int pr= priority_of(is->nuof);
+ int ap;
+ irq= true;
+ if (il &&
+ il->level >= 0)
+ ap= il->level;
+ else
+ ap= priority_main();
+ if (ap >= pr)
+ continue;
+ is->clear();
+ sim->app->get_commander()->
+ debug("%g sec (%d clks): Accepting interrupt `%s' PC= 0x%06x\n",
+ get_rtime(), ticks->ticks, object_name(is), PC);
+ IL= new it_level(pr, is->addr, PC, is);
+ return(accept_it(IL));
+ }
+ }
+ return resGO;
+}
+
+int
+cl_uc::accept_it(class it_level *il)
+{
+ it_levels->push(il);
+ return resGO;
+}
+
+
+/*
+ * Time related functions
+ */
+
+double
+cl_uc::get_rtime(void)
+{
+ /* double d;
+
+ d= (double)ticks/xtal;
+ return(d);*/
+ return(ticks->get_rtime(xtal));
+}
+
+unsigned long
+cl_uc::clocks_of_time(double t)
+{
+ return (unsigned long)(t * xtal);
+}
+
+int
+cl_uc::clock_per_cycle(void)
+{
+ return(1);
+}
+
+void
+cl_uc::touch(void)
+{
+ class cl_hw *hw;
+ int i;
+ for (i= 0; i < hws->count; i++)
+ {
+ hw= (class cl_hw *)(hws->at(i));
+ hw->touch();
+ }
+}
+
+
+/*
+ * Stack tracking system
+ */
+
+void
+cl_uc::stack_write(class cl_stack_op *op)
+{
+ delete op;
+ return ;
+ if (op->get_op() & stack_read_operation)
+ {
+ class cl_error_stack_tracker_wrong_handle *e= new
+ cl_error_stack_tracker_wrong_handle(false);
+ e->init();
+ error(e);
+ return;
+ }
+ stack_ops->push(op);
+}
+
+void
+cl_uc::stack_read(class cl_stack_op *op)
+{
+ delete op;
+ return ;
+ class cl_stack_op *top= (class cl_stack_op *)(stack_ops->top());
+
+ if (op->get_op() & stack_write_operation)
+ {
+ class cl_error_stack_tracker_wrong_handle *e= new
+ cl_error_stack_tracker_wrong_handle(true);
+ e->init();
+ error(e);
+ return;
+ }
+ if (!top)
+ {
+ class cl_error *e= new cl_error_stack_tracker_empty(op);
+ e->init();
+ error(e);
+ return;
+ }
+
+ if (top)
+ {
+ if (!top->match(op))
+ {
+ class cl_error *e= new cl_error_stack_tracker_unmatch(top, op);
+ e->init();
+ error(e);
+ }
+ int top_size= top->data_size(), op_size= op->data_size();
+ if (top_size != op_size)
+ {
+ application->debug("0x%06x %d bytes to read out of stack "
+ "but %d was pushed in last operation\n",
+ (int)op->get_pc(), op_size, top_size);
+ }
+ }
+
+ int removed= 0;
+ while (top &&
+ top->can_removed(op))
+ {
+ top= (class cl_stack_op *)stack_ops->pop();
+ delete top;
+ top= (class cl_stack_op *)stack_ops->top();
+ removed++;
+ }
+ if (removed != 1)
+ {
+ application->debug("0x%06x %d ops removed from stack-tracker "
+ "when %s happened, top pc=0x%06x "
+ "top before=0x%06x op after=0x%06x\n",
+ (int)op->get_pc(), removed, op->get_op_name(),
+ top?((int)top->get_pc()):0,
+ top?((int)top->get_before()):0,
+ (int)op->get_after());
+ }
+
+ if (top)
+ {
+ int ta= top->get_after(), oa= op->get_after();
+ if (ta != oa)
+ {
+ application->debug("0x%06x stack still inconsistent after %s, "
+ "%d byte(s) should be read out; top after"
+ "=0x%06x op after=0x%06x\n",
+ (int)op->get_pc(),
+ op->get_op_name(),
+ abs(ta-oa),
+ ta, oa);
+ class cl_error *e=
+ new cl_error_stack_tracker_inconsistent(op, abs(ta-oa));
+ e->init();
+ error(e);
+ }
+ }
+
+ delete op;
+}
+
+/*
+ * Breakpoint handling
+ */
+
+class cl_fetch_brk *
+cl_uc::fbrk_at(t_addr addr)
+{
+ int idx;
+
+ return((class cl_fetch_brk *)(fbrk->get_bp(addr, &idx)));
+}
+
+class cl_ev_brk *
+cl_uc::ebrk_at(t_addr addr, char *id)
+{
+ int i;
+ class cl_ev_brk *eb;
+
+ for (i= 0; i < ebrk->count; i++)
+ {
+ eb= (class cl_ev_brk *)(ebrk->at(i));
+ if (eb->addr == addr &&
+ !strcmp(eb->id, id))
+ return(eb);
+ }
+ return(0);
+}
+
+/*void
+cl_uc::rm_fbrk(long addr)
+{
+ fbrk->del_bp(addr);
+}*/
+
+/* Get a breakpoint specified by its number */
+
+class cl_brk *
+cl_uc::brk_by_nr(int nr)
+{
+ class cl_brk *bp;
+
+ if ((bp= fbrk->get_bp(nr)))
+ return(bp);
+ if ((bp= ebrk->get_bp(nr)))
+ return(bp);
+ return(0);
+}
+
+/* Get a breakpoint from the specified collection by its number */
+
+class cl_brk *
+cl_uc::brk_by_nr(class brk_coll *bpcoll, int nr)
+{
+ class cl_brk *bp;
+
+ if ((bp= bpcoll->get_bp(nr)))
+ return(bp);
+ return(0);
+}
+
+/* Remove an event breakpoint specified by its address and id */
+
+void
+cl_uc::rm_ebrk(t_addr addr, char *id)
+{
+ int i;
+ class cl_ev_brk *eb;
+
+ for (i= 0; i < ebrk->count; i++)
+ {
+ eb= (class cl_ev_brk *)(ebrk->at(i));
+ if (eb->addr == addr &&
+ !strcmp(eb->id, id))
+ ebrk->del_bp(i, 0);
+ }
+}
+
+/* Remove a breakpoint specified by its number */
+
+bool
+cl_uc::rm_brk(int nr)
+{
+ class cl_brk *bp;
+
+ if ((bp= brk_by_nr(fbrk, nr)))
+ {
+ fbrk->del_bp(bp->addr);
+ return(true);
+ }
+ else if ((bp= brk_by_nr(ebrk, nr)))
+ {
+ ebrk->del_bp(ebrk->index_of(bp), 0);
+ return(true);
+ }
+ return(false);
+}
+
+void
+cl_uc::put_breaks(void)
+{}
+
+/* Remove all fetch and event breakpoints */
+
+void
+cl_uc::remove_all_breaks(void)
+{
+ while (fbrk->count)
+ {
+ class cl_brk *brk= (class cl_brk *)(fbrk->at(0));
+ fbrk->del_bp(brk->addr);
+ }
+ while (ebrk->count)
+ ebrk->del_bp(ebrk->count-1, 0);
+}
+
+int
+cl_uc::make_new_brknr(void)
+{
+ if (brk_counter == 0)
+ return(brk_counter= 1);
+ if (fbrk->count == 0 &&
+ ebrk->count == 0)
+ return(brk_counter= 1);
+ return(++brk_counter);
+}
+
+class cl_ev_brk *
+cl_uc::mk_ebrk(enum brk_perm perm, class cl_address_space *mem,
+ char op, t_addr addr, int hit)
+{
+ class cl_ev_brk *b;
+ op= toupper(op);
+
+ b= new cl_ev_brk(mem, make_new_brknr(), addr, perm, hit, op);
+ b->init();
+ return(b);
+}
+
+void
+cl_uc::check_events(void)
+{
+ int i;
+ //sim->stop(resEVENTBREAK);
+ for (i= 0; i < events->count; i++)
+ {
+ class cl_ev_brk *brk=
+ dynamic_cast<class cl_ev_brk *>(events->object_at(i));
+ sim->stop(resEVENTBREAK, brk);
+ }
+}
+
+void
+cl_uc::stop_when(class cl_time_measurer *t)
+{
+ if (stop_at_time != NULL)
+ delete stop_at_time;
+ stop_at_time= t;
+}
+
+
+/*
+ * Errors
+ *----------------------------------------------------------------------------
+ */
+
+cl_error_unknown_code::cl_error_unknown_code(class cl_uc *the_uc)
+{
+ uc= the_uc;
+ classification= uc_error_registry.find("unknown_code");
+}
+
+void
+cl_error_unknown_code::print(class cl_commander_base *c)
+{
+ //FILE *f= c->get_out();
+ /*cmd_fprintf(f,*/c->dd_printf("%s: unknown instruction code at ", get_type_name());
+ if (uc->rom)
+ {
+ /*cmd_fprintf(f,*/c->dd_printf(uc->rom->addr_format, PC);
+ /*cmd_fprintf(f,*/c->dd_printf(" (");
+ /*cmd_fprintf(f,*/c->dd_printf(uc->rom->data_format, uc->rom->get(PC));
+ /*cmd_fprintf(f,*/c->dd_printf(")");
+ }
+ else
+ /*cmd_fprintf(f,*/c->dd_printf("0x%06x", AU(PC));
+ /*cmd_fprintf(f,*/c->dd_printf("\n");
+}
+
+
+cl_uc_error_registry::cl_uc_error_registry(void)
+{
+ class cl_error_class *prev = uc_error_registry.find("non-classified");
+ prev = register_error(new cl_error_class(err_error, "unknown_code", prev, ERROR_OFF));
+}
+
+/* End of uc.cc */
diff --git a/sim/ucsim/sim.src/uc.o b/sim/ucsim/sim.src/uc.o
new file mode 100644
index 0000000..f750e37
--- /dev/null
+++ b/sim/ucsim/sim.src/uc.o
Binary files differ
diff --git a/sim/ucsim/sim.src/uccl.h b/sim/ucsim/sim.src/uccl.h
new file mode 100644
index 0000000..4aad069
--- /dev/null
+++ b/sim/ucsim/sim.src/uccl.h
@@ -0,0 +1,413 @@
+/*
+ * Simulator of microcontrollers (sim.src/uccl.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 SIM_UCCL_HEADER
+#define SIM_UCCL_HEADER
+
+// prj
+#include "stypes.h"
+#include "pobjcl.h"
+#include "pobjt.h"
+
+// sim
+#include "hwcl.h"
+#include "memcl.h"
+#include "brkcl.h"
+#include "stackcl.h"
+#include "varcl.h"
+
+
+class cl_uc;
+
+typedef int (*instruction_wrapper_fn)(class cl_uc *uc, t_mem code);
+
+/* Counter to count clock ticks */
+
+#define TICK_RUN 0x01
+#define TICK_INISR 0x02
+#define TICK_IDLE 0x03
+
+class cl_ticker: public cl_base
+{
+public:
+ unsigned long ticks;
+ int options; // see TICK_XXX above
+ int dir;
+ //char *name;
+
+ cl_ticker(int adir, int in_isr, const char *aname);
+ virtual ~cl_ticker(void);
+
+ virtual int tick(int nr);
+ virtual double get_rtime(double xtal);
+ virtual void dump(int nr, double xtal, class cl_console_base *con);
+};
+
+
+/* Options of the microcontroller */
+class cl_xtal_option: public cl_optref
+{
+protected:
+ class cl_uc *uc;
+public:
+ cl_xtal_option(class cl_uc *the_uc);
+ virtual void option_changed(void);
+};
+
+struct vcounter_t {
+ t_mem inst;
+ t_mem fetch;
+ t_mem rd;
+ t_mem wr;
+};
+
+class cl_time_measurer: public cl_base
+{
+public:
+ unsigned long to_reach;
+ class cl_uc *uc;
+public:
+ cl_time_measurer(class cl_uc *the_uc);
+ virtual void set_reach(unsigned long val);
+ virtual void from_now(unsigned long val);
+ virtual bool reached();
+ virtual unsigned long now();
+};
+
+class cl_time_clk: public cl_time_measurer
+{
+public:
+ cl_time_clk(class cl_uc *the_uc): cl_time_measurer(the_uc) { set_name("clk"); }
+ virtual unsigned long now();
+};
+
+class cl_time_vclk: public cl_time_measurer
+{
+public:
+ cl_time_vclk(class cl_uc *the_uc): cl_time_measurer(the_uc) { set_name("vclk"); }
+ virtual unsigned long now();
+};
+
+class cl_time_fclk: public cl_time_measurer
+{
+public:
+ cl_time_fclk(class cl_uc *the_uc): cl_time_measurer(the_uc) { set_name("fclk"); }
+ virtual unsigned long now();
+};
+
+class cl_time_rclk: public cl_time_measurer
+{
+public:
+ cl_time_rclk(class cl_uc *the_uc): cl_time_measurer(the_uc) { set_name("rclk"); }
+ virtual unsigned long now();
+};
+
+class cl_time_wclk: public cl_time_measurer
+{
+public:
+ cl_time_wclk(class cl_uc *the_uc): cl_time_measurer(the_uc) { set_name("wclk"); }
+ virtual unsigned long now();
+};
+
+
+class cl_omf_rec: public cl_base
+{
+ protected:
+ unsigned int f_offset, offset;
+ public:
+ u8_t type;
+ u16_t len;
+ u8_t *rec;
+ u8_t chk;
+ public:
+ cl_omf_rec(void);
+ virtual ~cl_omf_rec(void);
+ virtual unsigned char g(cl_f *f);
+ virtual u16_t pick_word(int i);
+ virtual chars pick_str(int i);
+ virtual bool read(cl_f *f);
+};
+
+class cl_cdb_rec: public cl_base
+{
+ public:
+ chars fname;
+ t_addr addr;
+ public:
+ cl_cdb_rec(chars fn): cl_base() { fname= fn; }
+ cl_cdb_rec(chars fn, t_addr a): cl_base() { fname= fn; addr= a; }
+};
+
+class cl_cdb_recs: public cl_sorted_list
+{
+ public:
+ cl_cdb_recs(): cl_sorted_list(2,2,"cdb_recs_list") {}
+ virtual void *key_of(void *item)
+ { return (char*)(((cl_cdb_rec *)item)->fname); }
+ virtual int compare(void *k1, void *k2) {
+ return strcmp((char*)k1,(char*)k2);
+ }
+ virtual cl_cdb_rec *rec(chars n) {
+ t_index i;
+ if (search((char*)n, i))
+ return (cl_cdb_rec*)(at(i));
+ return NULL;
+ }
+ virtual void del(chars n) {
+ t_index i;
+ if (search((char*)n,i))
+ free_at(i);
+ }
+};
+
+/* Abstract microcontroller */
+
+class cl_uc: public cl_base
+{
+public:
+ struct cpu_entry *type;
+ //enum cpu_type type; // CPU family
+ //int technology; // CMOS, HMOS
+ int state; // GO, IDLE, PD
+ //class cl_list *options;
+ class cl_xtal_option *xtal_option;
+
+ t_addr PC, instPC; // Program Counter
+ bool inst_exec; // Instruction is executed
+ class cl_ticker *ticks; // Nr of XTAL clocks
+ class cl_ticker *isr_ticks; // Time in ISRs
+ class cl_ticker *idle_ticks; // Time in idle mode
+ class cl_list *counters; // User definable timers (tickers)
+ int inst_ticks; // ticks of an instruction
+ double xtal; // Clock speed
+ struct vcounter_t vc; // Virtual clk counter
+
+ int brk_counter; // Number of breakpoints
+ class brk_coll *fbrk; // Collection of FETCH break-points
+ class brk_coll *ebrk; // Collection of EVENT breakpoints
+ class cl_sim *sim;
+ //class cl_list *mems;
+ class cl_time_measurer *stop_at_time;
+ public:
+ class cl_hw *cpu;
+ class cl_hws *hws;
+
+ public:
+ class cl_list *memchips; // v3
+ class cl_address_space_list *address_spaces;
+ class cl_address_space *rom; // Required for almost every uc
+ //class cl_list *address_decoders;
+ class cl_address_space *variables;
+ class cl_var_list *vars;
+
+ bool irq;
+ class cl_irqs *it_sources; // Sources of interrupts
+ class cl_list *it_levels; // Follow interrupt services
+ class cl_list *stack_ops; // Track stack operations
+
+ class cl_list *errors; // Errors of instruction execution
+ class cl_list *events; // Events happened during inst exec
+
+ t_addr sp_max;
+ t_addr sp_avg;
+
+public:
+ cl_uc(class cl_sim *asim);
+ virtual ~cl_uc(void);
+ virtual int init(void);
+ virtual char *id_string(void);
+ virtual void reset(void);
+
+ // making objects
+ virtual void make_memories(void);
+ virtual void make_variables(void);
+ virtual void make_cpu_hw(void);
+ virtual void mk_hw_elements(void);
+ virtual void build_cmdset(class cl_cmdset *cmdset);
+
+ // manipulating memories
+ virtual t_mem read_mem(char *id, t_addr addr);
+ virtual t_mem get_mem(char *id, t_addr addr);
+ virtual void write_mem(char *id, t_addr addr, t_mem val);
+ virtual void set_mem(char *id, t_addr addr, t_mem val);
+ virtual class cl_address_space *address_space(const char *id);
+ virtual class cl_address_space *address_space(class cl_memory_cell *cell);
+ virtual class cl_address_space *address_space(class cl_memory_cell *cell, t_addr *addr);
+ virtual class cl_memory *memory(const char *id);
+
+ // file handling
+ virtual void set_rom(t_addr addr, t_mem val);
+ virtual long read_hex_file(const char *nam);
+ virtual long read_hex_file(cl_console_base *con);
+ virtual long read_hex_file(cl_f *f);
+ virtual long read_omf_file(cl_f *f);
+ virtual long read_cdb_file(cl_f *f);
+ virtual cl_f *find_loadable_file(chars nam);
+ virtual long read_file(chars nam, class cl_console_base *con);
+
+ // instructions, code analyzer
+ virtual void analyze(t_addr addr) {}
+ virtual bool inst_at(t_addr addr);
+ virtual void set_inst_at(t_addr addr);
+ virtual void del_inst_at(t_addr addr);
+ virtual bool there_is_inst(void);
+
+ // manipulating hw elements
+ virtual void add_hw(class cl_hw *hw);
+ virtual int nuof_hws(void);
+ virtual class cl_hw *get_hw(int idx);
+ virtual class cl_hw *get_hw(enum hw_cath cath, int *idx);
+ virtual class cl_hw *get_hw(char *id_string, int *idx);
+ virtual class cl_hw *get_hw(enum hw_cath cath, int hwid, int *idx);
+ virtual class cl_hw *get_hw(char *id_string, int hwid, int *idx);
+ virtual int get_max_hw_id(enum hw_cath cath);
+
+ // "virtual" timers
+ virtual int tick_hw(int cycles);
+ virtual void do_extra_hw(int cycles);
+ virtual int tick(int cycles);
+ virtual class cl_ticker *get_counter(int nr);
+ virtual class cl_ticker *get_counter(const char *nam);
+ virtual void add_counter(class cl_ticker *ticker, int nr);
+ virtual void add_counter(class cl_ticker *ticker, const char *nam);
+ virtual void del_counter(int nr);
+ virtual void del_counter(const char *nam);
+ virtual double get_rtime(void);
+ virtual unsigned long clocks_of_time(double t);
+ virtual int clock_per_cycle(void);
+ virtual void touch(void);
+
+ // execution
+ virtual t_mem fetch(void);
+ virtual bool fetch(t_mem *code);
+ virtual int do_inst(int step);
+ virtual void pre_inst(void);
+ virtual int exec_inst(void);
+ virtual int exec_inst_tab(instruction_wrapper_fn itab[]);
+ virtual void post_inst(void);
+
+ virtual int do_interrupt(void);
+ virtual int priority_of(uchar nuof_it) {return(0);}
+ virtual int priority_main() { return 0; }
+ virtual int accept_it(class it_level *il);
+ virtual bool it_enabled(void) { return false; }
+
+#include "uccl_instructions.h"
+
+ // stack tracking
+ virtual void stack_write(class cl_stack_op *op);
+ virtual void stack_read(class cl_stack_op *op);
+
+ // breakpoints
+ virtual class cl_fetch_brk *fbrk_at(t_addr addr);
+ virtual class cl_ev_brk *ebrk_at(t_addr addr, char *id);
+ virtual class cl_brk *brk_by_nr(int nr);
+ virtual class cl_brk *brk_by_nr(class brk_coll *bpcoll, int nr);
+ virtual void rm_ebrk(t_addr addr, char *id);
+ virtual bool rm_brk(int nr);
+ virtual void put_breaks(void);
+ virtual void remove_all_breaks(void);
+ virtual int make_new_brknr(void);
+ virtual class cl_ev_brk *mk_ebrk(enum brk_perm perm,
+ class cl_address_space *mem,
+ char op, t_addr addr, int hit);
+ virtual void check_events(void);
+ virtual void stop_when(class cl_time_measurer *t);
+
+ // disassembling and symbol recognition
+ virtual char *disass(t_addr addr, const char *sep);
+ virtual struct dis_entry *dis_tbl(void);
+ virtual void print_disass(t_addr addr, class cl_console_base *con);
+ virtual void print_regs(class cl_console_base *con);
+ virtual int inst_length(t_addr addr);
+ virtual int inst_branch(t_addr addr);
+ virtual bool is_call(t_addr addr);
+ virtual int longest_inst(void);
+ virtual bool addr_name(t_addr addr, class cl_address_space *as, char *buf);
+ virtual bool addr_name(t_addr addr, class cl_address_space *as, int bitnr, char *buf);
+ virtual bool symbol2address(char *sym,
+ class cl_address_space **as,
+ t_addr *addr);
+ virtual char *symbolic_bit_name(t_addr bit_address,
+ class cl_memory *mem,
+ t_addr mem_addr,
+ t_mem bit_mask);
+ virtual name_entry *get_name_entry(struct name_entry tabl[],
+ char *name);
+ virtual chars cell_name(class cl_memory_cell *cell);
+ virtual class cl_var *var(char *nam);
+
+ /* Converting abstract address spaces into real ones */
+ virtual class cl_address_space *bit2mem(t_addr bitaddr,
+ t_addr *memaddr,
+ t_mem *bitmask);
+ virtual t_addr bit_address(class cl_memory *mem,
+ t_addr mem_address,
+ int bit_number) { return(-1); }
+
+ // messages from app to handle and broadcast
+ virtual bool handle_event(class cl_event &event);
+ virtual void address_space_added(class cl_address_space *as);
+
+ // Error handling
+ virtual void error(class cl_error *error);
+ virtual void check_errors(void);
+
+ /* Following fields and virtual methods defined in uc51 I don't have
+ energy to redesign them:-( */
+public:
+ virtual void eram2xram(void) {} // Dirty hack for 51R
+ virtual void xram2eram(void) {}
+};
+
+
+/*
+ * Errors
+ */
+
+#include "errorcl.h"
+
+class cl_error_unknown_code: public cl_error
+{
+ protected:
+ class cl_uc *uc;
+ public:
+ cl_error_unknown_code(class cl_uc *the_uc);
+
+ virtual void print(class cl_commander_base *c);
+};
+
+class cl_uc_error_registry: public cl_error_registry
+{
+public:
+ cl_uc_error_registry(void);
+};
+
+
+#endif
+
+/* End of uccl.h */
diff --git a/sim/ucsim/sim.src/uccl_instructions.h b/sim/ucsim/sim.src/uccl_instructions.h
new file mode 100644
index 0000000..0873dea
--- /dev/null
+++ b/sim/ucsim/sim.src/uccl_instructions.h
@@ -0,0 +1,256 @@
+virtual int instruction_00(t_mem code) { return resNOT_DONE; }
+virtual int instruction_01(t_mem code) { return resNOT_DONE; }
+virtual int instruction_02(t_mem code) { return resNOT_DONE; }
+virtual int instruction_03(t_mem code) { return resNOT_DONE; }
+virtual int instruction_04(t_mem code) { return resNOT_DONE; }
+virtual int instruction_05(t_mem code) { return resNOT_DONE; }
+virtual int instruction_06(t_mem code) { return resNOT_DONE; }
+virtual int instruction_07(t_mem code) { return resNOT_DONE; }
+virtual int instruction_08(t_mem code) { return resNOT_DONE; }
+virtual int instruction_09(t_mem code) { return resNOT_DONE; }
+virtual int instruction_0a(t_mem code) { return resNOT_DONE; }
+virtual int instruction_0b(t_mem code) { return resNOT_DONE; }
+virtual int instruction_0c(t_mem code) { return resNOT_DONE; }
+virtual int instruction_0d(t_mem code) { return resNOT_DONE; }
+virtual int instruction_0e(t_mem code) { return resNOT_DONE; }
+virtual int instruction_0f(t_mem code) { return resNOT_DONE; }
+virtual int instruction_10(t_mem code) { return resNOT_DONE; }
+virtual int instruction_11(t_mem code) { return resNOT_DONE; }
+virtual int instruction_12(t_mem code) { return resNOT_DONE; }
+virtual int instruction_13(t_mem code) { return resNOT_DONE; }
+virtual int instruction_14(t_mem code) { return resNOT_DONE; }
+virtual int instruction_15(t_mem code) { return resNOT_DONE; }
+virtual int instruction_16(t_mem code) { return resNOT_DONE; }
+virtual int instruction_17(t_mem code) { return resNOT_DONE; }
+virtual int instruction_18(t_mem code) { return resNOT_DONE; }
+virtual int instruction_19(t_mem code) { return resNOT_DONE; }
+virtual int instruction_1a(t_mem code) { return resNOT_DONE; }
+virtual int instruction_1b(t_mem code) { return resNOT_DONE; }
+virtual int instruction_1c(t_mem code) { return resNOT_DONE; }
+virtual int instruction_1d(t_mem code) { return resNOT_DONE; }
+virtual int instruction_1e(t_mem code) { return resNOT_DONE; }
+virtual int instruction_1f(t_mem code) { return resNOT_DONE; }
+virtual int instruction_20(t_mem code) { return resNOT_DONE; }
+virtual int instruction_21(t_mem code) { return resNOT_DONE; }
+virtual int instruction_22(t_mem code) { return resNOT_DONE; }
+virtual int instruction_23(t_mem code) { return resNOT_DONE; }
+virtual int instruction_24(t_mem code) { return resNOT_DONE; }
+virtual int instruction_25(t_mem code) { return resNOT_DONE; }
+virtual int instruction_26(t_mem code) { return resNOT_DONE; }
+virtual int instruction_27(t_mem code) { return resNOT_DONE; }
+virtual int instruction_28(t_mem code) { return resNOT_DONE; }
+virtual int instruction_29(t_mem code) { return resNOT_DONE; }
+virtual int instruction_2a(t_mem code) { return resNOT_DONE; }
+virtual int instruction_2b(t_mem code) { return resNOT_DONE; }
+virtual int instruction_2c(t_mem code) { return resNOT_DONE; }
+virtual int instruction_2d(t_mem code) { return resNOT_DONE; }
+virtual int instruction_2e(t_mem code) { return resNOT_DONE; }
+virtual int instruction_2f(t_mem code) { return resNOT_DONE; }
+virtual int instruction_30(t_mem code) { return resNOT_DONE; }
+virtual int instruction_31(t_mem code) { return resNOT_DONE; }
+virtual int instruction_32(t_mem code) { return resNOT_DONE; }
+virtual int instruction_33(t_mem code) { return resNOT_DONE; }
+virtual int instruction_34(t_mem code) { return resNOT_DONE; }
+virtual int instruction_35(t_mem code) { return resNOT_DONE; }
+virtual int instruction_36(t_mem code) { return resNOT_DONE; }
+virtual int instruction_37(t_mem code) { return resNOT_DONE; }
+virtual int instruction_38(t_mem code) { return resNOT_DONE; }
+virtual int instruction_39(t_mem code) { return resNOT_DONE; }
+virtual int instruction_3a(t_mem code) { return resNOT_DONE; }
+virtual int instruction_3b(t_mem code) { return resNOT_DONE; }
+virtual int instruction_3c(t_mem code) { return resNOT_DONE; }
+virtual int instruction_3d(t_mem code) { return resNOT_DONE; }
+virtual int instruction_3e(t_mem code) { return resNOT_DONE; }
+virtual int instruction_3f(t_mem code) { return resNOT_DONE; }
+virtual int instruction_40(t_mem code) { return resNOT_DONE; }
+virtual int instruction_41(t_mem code) { return resNOT_DONE; }
+virtual int instruction_42(t_mem code) { return resNOT_DONE; }
+virtual int instruction_43(t_mem code) { return resNOT_DONE; }
+virtual int instruction_44(t_mem code) { return resNOT_DONE; }
+virtual int instruction_45(t_mem code) { return resNOT_DONE; }
+virtual int instruction_46(t_mem code) { return resNOT_DONE; }
+virtual int instruction_47(t_mem code) { return resNOT_DONE; }
+virtual int instruction_48(t_mem code) { return resNOT_DONE; }
+virtual int instruction_49(t_mem code) { return resNOT_DONE; }
+virtual int instruction_4a(t_mem code) { return resNOT_DONE; }
+virtual int instruction_4b(t_mem code) { return resNOT_DONE; }
+virtual int instruction_4c(t_mem code) { return resNOT_DONE; }
+virtual int instruction_4d(t_mem code) { return resNOT_DONE; }
+virtual int instruction_4e(t_mem code) { return resNOT_DONE; }
+virtual int instruction_4f(t_mem code) { return resNOT_DONE; }
+virtual int instruction_50(t_mem code) { return resNOT_DONE; }
+virtual int instruction_51(t_mem code) { return resNOT_DONE; }
+virtual int instruction_52(t_mem code) { return resNOT_DONE; }
+virtual int instruction_53(t_mem code) { return resNOT_DONE; }
+virtual int instruction_54(t_mem code) { return resNOT_DONE; }
+virtual int instruction_55(t_mem code) { return resNOT_DONE; }
+virtual int instruction_56(t_mem code) { return resNOT_DONE; }
+virtual int instruction_57(t_mem code) { return resNOT_DONE; }
+virtual int instruction_58(t_mem code) { return resNOT_DONE; }
+virtual int instruction_59(t_mem code) { return resNOT_DONE; }
+virtual int instruction_5a(t_mem code) { return resNOT_DONE; }
+virtual int instruction_5b(t_mem code) { return resNOT_DONE; }
+virtual int instruction_5c(t_mem code) { return resNOT_DONE; }
+virtual int instruction_5d(t_mem code) { return resNOT_DONE; }
+virtual int instruction_5e(t_mem code) { return resNOT_DONE; }
+virtual int instruction_5f(t_mem code) { return resNOT_DONE; }
+virtual int instruction_60(t_mem code) { return resNOT_DONE; }
+virtual int instruction_61(t_mem code) { return resNOT_DONE; }
+virtual int instruction_62(t_mem code) { return resNOT_DONE; }
+virtual int instruction_63(t_mem code) { return resNOT_DONE; }
+virtual int instruction_64(t_mem code) { return resNOT_DONE; }
+virtual int instruction_65(t_mem code) { return resNOT_DONE; }
+virtual int instruction_66(t_mem code) { return resNOT_DONE; }
+virtual int instruction_67(t_mem code) { return resNOT_DONE; }
+virtual int instruction_68(t_mem code) { return resNOT_DONE; }
+virtual int instruction_69(t_mem code) { return resNOT_DONE; }
+virtual int instruction_6a(t_mem code) { return resNOT_DONE; }
+virtual int instruction_6b(t_mem code) { return resNOT_DONE; }
+virtual int instruction_6c(t_mem code) { return resNOT_DONE; }
+virtual int instruction_6d(t_mem code) { return resNOT_DONE; }
+virtual int instruction_6e(t_mem code) { return resNOT_DONE; }
+virtual int instruction_6f(t_mem code) { return resNOT_DONE; }
+virtual int instruction_70(t_mem code) { return resNOT_DONE; }
+virtual int instruction_71(t_mem code) { return resNOT_DONE; }
+virtual int instruction_72(t_mem code) { return resNOT_DONE; }
+virtual int instruction_73(t_mem code) { return resNOT_DONE; }
+virtual int instruction_74(t_mem code) { return resNOT_DONE; }
+virtual int instruction_75(t_mem code) { return resNOT_DONE; }
+virtual int instruction_76(t_mem code) { return resNOT_DONE; }
+virtual int instruction_77(t_mem code) { return resNOT_DONE; }
+virtual int instruction_78(t_mem code) { return resNOT_DONE; }
+virtual int instruction_79(t_mem code) { return resNOT_DONE; }
+virtual int instruction_7a(t_mem code) { return resNOT_DONE; }
+virtual int instruction_7b(t_mem code) { return resNOT_DONE; }
+virtual int instruction_7c(t_mem code) { return resNOT_DONE; }
+virtual int instruction_7d(t_mem code) { return resNOT_DONE; }
+virtual int instruction_7e(t_mem code) { return resNOT_DONE; }
+virtual int instruction_7f(t_mem code) { return resNOT_DONE; }
+virtual int instruction_80(t_mem code) { return resNOT_DONE; }
+virtual int instruction_81(t_mem code) { return resNOT_DONE; }
+virtual int instruction_82(t_mem code) { return resNOT_DONE; }
+virtual int instruction_83(t_mem code) { return resNOT_DONE; }
+virtual int instruction_84(t_mem code) { return resNOT_DONE; }
+virtual int instruction_85(t_mem code) { return resNOT_DONE; }
+virtual int instruction_86(t_mem code) { return resNOT_DONE; }
+virtual int instruction_87(t_mem code) { return resNOT_DONE; }
+virtual int instruction_88(t_mem code) { return resNOT_DONE; }
+virtual int instruction_89(t_mem code) { return resNOT_DONE; }
+virtual int instruction_8a(t_mem code) { return resNOT_DONE; }
+virtual int instruction_8b(t_mem code) { return resNOT_DONE; }
+virtual int instruction_8c(t_mem code) { return resNOT_DONE; }
+virtual int instruction_8d(t_mem code) { return resNOT_DONE; }
+virtual int instruction_8e(t_mem code) { return resNOT_DONE; }
+virtual int instruction_8f(t_mem code) { return resNOT_DONE; }
+virtual int instruction_90(t_mem code) { return resNOT_DONE; }
+virtual int instruction_91(t_mem code) { return resNOT_DONE; }
+virtual int instruction_92(t_mem code) { return resNOT_DONE; }
+virtual int instruction_93(t_mem code) { return resNOT_DONE; }
+virtual int instruction_94(t_mem code) { return resNOT_DONE; }
+virtual int instruction_95(t_mem code) { return resNOT_DONE; }
+virtual int instruction_96(t_mem code) { return resNOT_DONE; }
+virtual int instruction_97(t_mem code) { return resNOT_DONE; }
+virtual int instruction_98(t_mem code) { return resNOT_DONE; }
+virtual int instruction_99(t_mem code) { return resNOT_DONE; }
+virtual int instruction_9a(t_mem code) { return resNOT_DONE; }
+virtual int instruction_9b(t_mem code) { return resNOT_DONE; }
+virtual int instruction_9c(t_mem code) { return resNOT_DONE; }
+virtual int instruction_9d(t_mem code) { return resNOT_DONE; }
+virtual int instruction_9e(t_mem code) { return resNOT_DONE; }
+virtual int instruction_9f(t_mem code) { return resNOT_DONE; }
+virtual int instruction_a0(t_mem code) { return resNOT_DONE; }
+virtual int instruction_a1(t_mem code) { return resNOT_DONE; }
+virtual int instruction_a2(t_mem code) { return resNOT_DONE; }
+virtual int instruction_a3(t_mem code) { return resNOT_DONE; }
+virtual int instruction_a4(t_mem code) { return resNOT_DONE; }
+virtual int instruction_a5(t_mem code) { return resNOT_DONE; }
+virtual int instruction_a6(t_mem code) { return resNOT_DONE; }
+virtual int instruction_a7(t_mem code) { return resNOT_DONE; }
+virtual int instruction_a8(t_mem code) { return resNOT_DONE; }
+virtual int instruction_a9(t_mem code) { return resNOT_DONE; }
+virtual int instruction_aa(t_mem code) { return resNOT_DONE; }
+virtual int instruction_ab(t_mem code) { return resNOT_DONE; }
+virtual int instruction_ac(t_mem code) { return resNOT_DONE; }
+virtual int instruction_ad(t_mem code) { return resNOT_DONE; }
+virtual int instruction_ae(t_mem code) { return resNOT_DONE; }
+virtual int instruction_af(t_mem code) { return resNOT_DONE; }
+virtual int instruction_b0(t_mem code) { return resNOT_DONE; }
+virtual int instruction_b1(t_mem code) { return resNOT_DONE; }
+virtual int instruction_b2(t_mem code) { return resNOT_DONE; }
+virtual int instruction_b3(t_mem code) { return resNOT_DONE; }
+virtual int instruction_b4(t_mem code) { return resNOT_DONE; }
+virtual int instruction_b5(t_mem code) { return resNOT_DONE; }
+virtual int instruction_b6(t_mem code) { return resNOT_DONE; }
+virtual int instruction_b7(t_mem code) { return resNOT_DONE; }
+virtual int instruction_b8(t_mem code) { return resNOT_DONE; }
+virtual int instruction_b9(t_mem code) { return resNOT_DONE; }
+virtual int instruction_ba(t_mem code) { return resNOT_DONE; }
+virtual int instruction_bb(t_mem code) { return resNOT_DONE; }
+virtual int instruction_bc(t_mem code) { return resNOT_DONE; }
+virtual int instruction_bd(t_mem code) { return resNOT_DONE; }
+virtual int instruction_be(t_mem code) { return resNOT_DONE; }
+virtual int instruction_bf(t_mem code) { return resNOT_DONE; }
+virtual int instruction_c0(t_mem code) { return resNOT_DONE; }
+virtual int instruction_c1(t_mem code) { return resNOT_DONE; }
+virtual int instruction_c2(t_mem code) { return resNOT_DONE; }
+virtual int instruction_c3(t_mem code) { return resNOT_DONE; }
+virtual int instruction_c4(t_mem code) { return resNOT_DONE; }
+virtual int instruction_c5(t_mem code) { return resNOT_DONE; }
+virtual int instruction_c6(t_mem code) { return resNOT_DONE; }
+virtual int instruction_c7(t_mem code) { return resNOT_DONE; }
+virtual int instruction_c8(t_mem code) { return resNOT_DONE; }
+virtual int instruction_c9(t_mem code) { return resNOT_DONE; }
+virtual int instruction_ca(t_mem code) { return resNOT_DONE; }
+virtual int instruction_cb(t_mem code) { return resNOT_DONE; }
+virtual int instruction_cc(t_mem code) { return resNOT_DONE; }
+virtual int instruction_cd(t_mem code) { return resNOT_DONE; }
+virtual int instruction_ce(t_mem code) { return resNOT_DONE; }
+virtual int instruction_cf(t_mem code) { return resNOT_DONE; }
+virtual int instruction_d0(t_mem code) { return resNOT_DONE; }
+virtual int instruction_d1(t_mem code) { return resNOT_DONE; }
+virtual int instruction_d2(t_mem code) { return resNOT_DONE; }
+virtual int instruction_d3(t_mem code) { return resNOT_DONE; }
+virtual int instruction_d4(t_mem code) { return resNOT_DONE; }
+virtual int instruction_d5(t_mem code) { return resNOT_DONE; }
+virtual int instruction_d6(t_mem code) { return resNOT_DONE; }
+virtual int instruction_d7(t_mem code) { return resNOT_DONE; }
+virtual int instruction_d8(t_mem code) { return resNOT_DONE; }
+virtual int instruction_d9(t_mem code) { return resNOT_DONE; }
+virtual int instruction_da(t_mem code) { return resNOT_DONE; }
+virtual int instruction_db(t_mem code) { return resNOT_DONE; }
+virtual int instruction_dc(t_mem code) { return resNOT_DONE; }
+virtual int instruction_dd(t_mem code) { return resNOT_DONE; }
+virtual int instruction_de(t_mem code) { return resNOT_DONE; }
+virtual int instruction_df(t_mem code) { return resNOT_DONE; }
+virtual int instruction_e0(t_mem code) { return resNOT_DONE; }
+virtual int instruction_e1(t_mem code) { return resNOT_DONE; }
+virtual int instruction_e2(t_mem code) { return resNOT_DONE; }
+virtual int instruction_e3(t_mem code) { return resNOT_DONE; }
+virtual int instruction_e4(t_mem code) { return resNOT_DONE; }
+virtual int instruction_e5(t_mem code) { return resNOT_DONE; }
+virtual int instruction_e6(t_mem code) { return resNOT_DONE; }
+virtual int instruction_e7(t_mem code) { return resNOT_DONE; }
+virtual int instruction_e8(t_mem code) { return resNOT_DONE; }
+virtual int instruction_e9(t_mem code) { return resNOT_DONE; }
+virtual int instruction_ea(t_mem code) { return resNOT_DONE; }
+virtual int instruction_eb(t_mem code) { return resNOT_DONE; }
+virtual int instruction_ec(t_mem code) { return resNOT_DONE; }
+virtual int instruction_ed(t_mem code) { return resNOT_DONE; }
+virtual int instruction_ee(t_mem code) { return resNOT_DONE; }
+virtual int instruction_ef(t_mem code) { return resNOT_DONE; }
+virtual int instruction_f0(t_mem code) { return resNOT_DONE; }
+virtual int instruction_f1(t_mem code) { return resNOT_DONE; }
+virtual int instruction_f2(t_mem code) { return resNOT_DONE; }
+virtual int instruction_f3(t_mem code) { return resNOT_DONE; }
+virtual int instruction_f4(t_mem code) { return resNOT_DONE; }
+virtual int instruction_f5(t_mem code) { return resNOT_DONE; }
+virtual int instruction_f6(t_mem code) { return resNOT_DONE; }
+virtual int instruction_f7(t_mem code) { return resNOT_DONE; }
+virtual int instruction_f8(t_mem code) { return resNOT_DONE; }
+virtual int instruction_f9(t_mem code) { return resNOT_DONE; }
+virtual int instruction_fa(t_mem code) { return resNOT_DONE; }
+virtual int instruction_fb(t_mem code) { return resNOT_DONE; }
+virtual int instruction_fc(t_mem code) { return resNOT_DONE; }
+virtual int instruction_fd(t_mem code) { return resNOT_DONE; }
+virtual int instruction_fe(t_mem code) { return resNOT_DONE; }
+virtual int instruction_ff(t_mem code) { return resNOT_DONE; }
diff --git a/sim/ucsim/sim.src/var.cc b/sim/ucsim/sim.src/var.cc
new file mode 100644
index 0000000..2649f49
--- /dev/null
+++ b/sim/ucsim/sim.src/var.cc
@@ -0,0 +1,108 @@
+/*
+ * Simulator of microcontrollers (sim.src/var.cc)
+ *
+ * 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.
+*/
+/*@1@*/
+
+#include "varcl.h"
+
+
+cl_var::cl_var(const char *iname, class cl_address_space *ias, t_addr iaddr, chars adesc, int ibitnr):
+ cl_base()
+{
+ as= ias;
+ addr= iaddr;
+ bitnr= ibitnr;
+ desc= adesc;
+
+ set_name(iname);
+
+ cell= NULL;
+}
+
+int
+cl_var::init(void)
+{
+ if (!as ||
+ !as->is_address_space() ||
+ !as->valid_address(addr))
+ return 0;
+ cell= as->get_cell(addr);
+ if (cell && (bitnr < 0))
+ cell->set_flag(CELL_VAR, true);
+ return 0;
+}
+
+
+void
+cl_var::print_info(cl_console_base *con)
+{
+ con->dd_printf("%s ", get_name("?"));
+ if (cell)
+ {
+ t_mem v= cell->read();
+ con->dd_printf("%s", as->get_name("?"));
+ con->dd_printf("[");
+ con->dd_printf(as->addr_format, addr);
+ con->dd_printf("] ");
+ if (bitnr >= 0)
+ {
+ con->dd_printf(".%d", bitnr);
+ con->dd_printf("= %d", (v & (1<<bitnr))?1:0);
+ }
+ else
+ {
+ con->dd_printf("= ");
+ con->dd_printf(as->data_format, v);
+ }
+ }
+ con->dd_printf("\n");
+ if (!desc.empty())
+ con->dd_printf(" %s\n", (char*)desc);
+}
+
+
+void *
+cl_var_list::key_of(void *item)
+{
+ class cl_var *v= (class cl_var *)item;
+ return (void*)v->get_name();
+}
+
+int
+cl_var_list::compare(void *key1, void *key2)
+{
+ char *k1, *k2;
+
+ k1= (char*)key1;
+ k2= (char*)key2;
+ if (k1 && k2)
+ return strcmp(k1, k2);
+ return 0;
+}
+
+
+/* End of sim.src/var.cc */
diff --git a/sim/ucsim/sim.src/var.o b/sim/ucsim/sim.src/var.o
new file mode 100644
index 0000000..0e7be41
--- /dev/null
+++ b/sim/ucsim/sim.src/var.o
Binary files differ
diff --git a/sim/ucsim/sim.src/varcl.h b/sim/ucsim/sim.src/varcl.h
new file mode 100644
index 0000000..cfb7e4a
--- /dev/null
+++ b/sim/ucsim/sim.src/varcl.h
@@ -0,0 +1,71 @@
+/*
+ * Simulator of microcontrollers (sim.src/varcl.h)
+ *
+ * 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.
+*/
+/*@1@*/
+
+#ifndef SIM_VARCL_HEADER
+#define SIM_VARCL_HEADER
+
+
+#include "pobjcl.h"
+
+#include "newcmdcl.h"
+
+#include "memcl.h"
+
+
+class cl_var: public cl_base
+{
+ public:
+ class cl_address_space *as; // reference
+ t_addr addr;
+ int bitnr;
+ chars desc;
+ protected:
+ class cl_memory_cell *cell;
+ public:
+ cl_var(const char *iname, class cl_address_space *ias, t_addr iaddr, chars adesc, int ibitnr= -1);
+ virtual int init(void);
+ virtual class cl_memory_cell *get_cell(void) { return cell; }
+
+ virtual void print_info(cl_console_base *con);
+};
+
+
+class cl_var_list: public cl_sorted_list
+{
+ public:
+ cl_var_list(): cl_sorted_list(10, 10, "symlist") {}
+ public:
+ virtual void *key_of(void *item);
+ virtual int compare(void *key1, void *key2);
+};
+
+
+#endif
+
+/* End of sim.src/varcl.h */
diff --git a/sim/ucsim/sim.src/vcd.cc b/sim/ucsim/sim.src/vcd.cc
new file mode 100644
index 0000000..69dea2b
--- /dev/null
+++ b/sim/ucsim/sim.src/vcd.cc
@@ -0,0 +1,464 @@
+/*
+ * Simulator of microcontrollers (sim.src/vcd.cc)
+ *
+ * Copyright (C) 2017,17 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@*/
+
+#include <time.h>
+
+// prj
+#include "utils.h"
+
+// sim
+#include "argcl.h"
+
+// local
+#include "vcdcl.h"
+
+
+cl_vcd::cl_vcd(class cl_uc *auc, int aid, chars aid_string):
+ cl_hw(auc, HW_DUMMY, aid, aid_string)
+{
+ locs= new cl_list(2, 2, "vcd_locs");
+ started= false;
+ paused= false;
+ fout= 0;
+ change= 0;
+ modul= chars("", "ucsim_vcd_%d", id);
+}
+
+void
+cl_vcd::add(class cl_memory_cell *cell)
+{
+ if (!cell)
+ return;
+ if (!locs->index_of(cell, NULL))
+ {
+ locs->add(cell);
+ register_cell(cell);
+ }
+}
+
+void
+cl_vcd::del(class cl_memory_cell *cell)
+{
+ if (!cell)
+ return;
+ if (locs->index_of(cell, NULL))
+ {
+ unregister_cell(cell);
+ locs->disconn(cell);
+ }
+}
+
+bool
+cl_vcd::add(class cl_memory *m, t_addr a, class cl_console_base *con)
+{
+ if (!m->is_address_space())
+ {
+ if (con) con->dd_printf("%s is not an address space\n");
+ return false;
+ }
+ if (!m->valid_address(a))
+ {
+ if (con) con->dd_printf("Address must be between 0x%x and 0x%x\n",
+ AU(m->lowest_valid_address()),
+ AU(m->highest_valid_address()));
+ return false;
+ }
+ cl_memory_cell *c= ((cl_address_space*)m)->get_cell(a);
+ if (c->get_flag(CELL_NON_DECODED))
+ {
+ if (con) con->dd_printf("Cell is not decoded\n");
+ return false;
+ }
+ add(c);
+ return true;
+}
+
+bool
+cl_vcd::del(class cl_memory *m, t_addr a, class cl_console_base *con)
+{
+ if (!m->is_address_space())
+ {
+ if (con) con->dd_printf("%s is not an address space\n");
+ return false;
+ }
+ if (!m->valid_address(a))
+ {
+ if (con) con->dd_printf("Address must be between 0x%x and 0x%x\n",
+ AU(m->lowest_valid_address()),
+ AU(m->highest_valid_address()));
+ return false;
+ }
+ del(((cl_address_space*)m)->get_cell(a));
+ return true;
+}
+
+void
+cl_vcd::set_cmd(class cl_cmdline *cmdline, class cl_console_base *con)
+{
+ class cl_cmd_arg *params[3]= {
+ cmdline->param(0),
+ cmdline->param(1),
+ cmdline->param(2)
+ };
+
+ if (cmdline->syntax_match(uc, MEMORY ADDRESS)) // ADD
+ {
+ if (started)
+ {
+ con->dd_printf("Already started\n");
+ return;
+ }
+ class cl_memory *mem= params[0]->value.memory.memory;
+ t_addr a= params[1]->value.address;
+ if (!mem->is_address_space())
+ {
+ con->dd_printf("%s is not an address space\n");
+ return;
+ }
+ if (!mem->valid_address(a))
+ {
+ con->dd_printf("Address must be between 0x%x and 0x%x\n",
+ AU(mem->lowest_valid_address()),
+ AU(mem->highest_valid_address()));
+ return;
+ }
+ add(mem, a, con);
+ return;
+ }
+ else if (cmdline->syntax_match(uc, CELL)) // ADD
+ {
+ if (started)
+ {
+ con->dd_printf("Already started\n");
+ return;
+ }
+ if (params[0]->value.cell->get_flag(CELL_NON_DECODED))
+ con->dd_printf("Cell is not decoded\n");
+ else
+ add(params[0]->value.cell);
+ return;
+ }
+ else if (cmdline->syntax_match(uc, STRING MEMORY ADDRESS)) // DEL|ADD
+ {
+ if (started)
+ {
+ con->dd_printf("Already started\n");
+ return;
+ }
+ params[0]->as_string();
+ char *p1= params[0]->value.string.string;
+ if (p1 && *p1)
+ {
+ if (strcmp(p1, "add") == 0)
+ {
+ if (add(params[1]->value.memory.memory, params[2]->value.address, con))
+ return;
+ }
+ if (strstr(p1, "del") == p1)
+ {
+ if (del(params[1]->value.memory.memory, params[2]->value.address, con))
+ return;
+ }
+ }
+ }
+ else if (cmdline->syntax_match(uc, STRING CELL)) // DEL|ADD
+ {
+ if (started)
+ {
+ con->dd_printf("Already started\n");
+ return;
+ }
+ params[0]->as_string();
+ char *p1= params[0]->value.string.string;
+ if (p1 && *p1)
+ {
+ if (strcmp(p1, "add") == 0)
+ {
+ if (params[1]->value.cell->get_flag(CELL_NON_DECODED))
+ con->dd_printf("Cell is not decoded\n");
+ else
+ add(params[1]->value.cell);
+ return;
+ }
+ if (strstr(p1, "del") == p1)
+ {
+ del(params[1]->value.cell);
+ return;
+ }
+ }
+ }
+ else if (cmdline->syntax_match(uc, STRING NUMBER)) // NEW id
+ {
+ params[0]->as_string();
+ char *p1= params[0]->value.string.string;
+ if (p1 && *p1 &&
+ (strcmp(p1, "new") == 0))
+ {
+ params[1]->as_number();
+ int nid= params[1]->value.number;
+ if (uc->get_hw((char*)id_string, nid, NULL) != NULL)
+ {
+ con->dd_printf("Already exists\n");
+ return;
+ }
+ cl_hw *h= new cl_vcd(uc, nid, id_string);
+ h->init();
+ uc->add_hw(h);
+ return;
+ }
+ }
+ else if (cmdline->syntax_match(uc, STRING STRING)) // FILE, MOD
+ {
+ params[0]->as_string();
+ params[1]->as_string();
+ char *p1= params[0]->value.string.string;
+ char *p2= params[1]->value.string.string;
+ if (started)
+ {
+ con->dd_printf("Already started\n");
+ return;
+ }
+ if (p1 && *p1)
+ {
+ if (!p2 || !*p2)
+ {
+ con->dd_printf("Name missing\n");
+ return;
+ }
+ if ((strcmp(p1, "fout") == 0) ||
+ (strcmp(p1, "file") == 0))
+ {
+ if ((fout= mk_io(p2, "w")) == NULL)
+ con->dd_printf("File open error\n");
+ return;
+ }
+ if (strstr(p1, "mod") == p1)
+ {
+ modul= chars(p2);
+ return;
+ }
+ }
+ }
+ else if (cmdline->syntax_match(uc, STRING)) // [RE]START, PAUSE, STOP
+ {
+ params[0]->as_string();
+ char *p1= params[0]->value.string.string;
+ if (p1 && *p1)
+ {
+ if ((strstr(p1, "re") == p1) ||
+ (strcmp(p1, "start") == 0))
+ {
+ if (started)
+ paused= false;
+ else
+ {
+ if (!fout)
+ con->dd_printf("Output unspecified\n");
+ else
+ {
+ // generate vcd file header
+ time_t t= time(NULL);
+ fout->write_str("$date\n");
+ fout->write_str(ctime(&t));
+ fout->write_str("$end\n");
+ fout->write_str("$version\n");
+ fout->prntf("ucsim\n");
+ fout->write_str("$end\n");
+ fout->write_str("$timescale 1ns $end\n");
+ fout->prntf("$scope module %s $end\n", (char*)modul);
+ int i;
+ for (i= 0; i < locs->count; i++)
+ {
+ cl_memory_cell *c= (cl_memory_cell *)
+ (locs->at(i));
+ chars n= uc->cell_name(c);
+ fout->prntf("$var wire %d %c %s $end\n",
+ c->get_width(), 33+i,
+ (char*)n);
+ }
+ fout->write_str("$upscope $end\n");
+ fout->write_str("$enddefinitions $end\n");
+ fout->write_str("$dumpvars\n");
+ for (i= 0; i < locs->count; i++)
+ {
+ cl_memory_cell *c= (cl_memory_cell *)
+ (locs->at(i));
+ report(c, i);
+ }
+ fout->write_str("$end\n");
+ started= true;
+ paused= false;
+ change= false;
+ }
+ }
+ return;
+ }
+ if (strstr(p1, "paus") == p1)
+ {
+ if (started)
+ paused= !paused;
+ return;
+ }
+ if (strcmp(p1, "stop") == 0)
+ {
+ if (started)
+ {
+ if (fout)
+ delete fout;
+ fout= NULL;
+ }
+ started= paused= change= false;
+ return;
+ }
+ if (strcmp(p1, "info") == 0)
+ {
+ print_info(con);
+ return;
+ }
+ }
+ }
+ //else
+ {
+ con->dd_printf("set hardware vcd[id] [add] memory address\n");
+ con->dd_printf("set hardware vcd[id] del[ete] memory address\n");
+ con->dd_printf("set hardware vcd[id] fout|file \"vcd_file_name\"|gtkwave\n");
+ con->dd_printf("set hardware vcd[id] mod[ule] module_name\n");
+ con->dd_printf("set hardware vcd[id] start\n");
+ con->dd_printf("set hardware vcd[id] pause\n");
+ con->dd_printf("set hardware vcd[id] [re]start\n");
+ con->dd_printf("set hardware vcd[id] stop\n");
+ con->dd_printf("set hardware vcd[id] new id\n");
+ }
+}
+
+t_mem
+cl_vcd::read(class cl_memory_cell *cell)
+{
+
+ conf(cell, NULL);
+ return cell->get();
+}
+
+void
+cl_vcd::write(class cl_memory_cell *cell, t_mem *val)
+{
+ if (started &&
+ !paused)
+ {
+ if (cell->def_data != *val)
+ {
+ //change_time= uc->get_rtime();
+ change= true;
+ }
+ }
+ if (conf(cell, val))
+ return;
+}
+
+t_mem
+cl_vcd::conf_op(cl_memory_cell *cell, t_addr addr, t_mem *val)
+{
+ if (addr >= 1)
+ return cell->get();
+ switch (addr)
+ {
+ }
+ return cell->get();
+}
+
+char *
+cl_vcd::cfg_help(t_addr addr)
+{
+ return (char*)"Not used";
+}
+
+void
+cl_vcd::report(class cl_memory_cell *cell, int nr)
+{
+ t_mem v= cell->get();
+ if (fout)
+ {
+ int w= cell->get_width();
+ if (w == 1)
+ {
+ fout->prntf("%d%c\n", v?1:0, nr+33);
+ }
+ else
+ {
+ fout->write((char*)"b", 1);
+ fout->prntf("%s %c\n", (char*)cbin(v, w), nr+33);
+ }
+ }
+ cell->def_data= v;
+}
+
+int
+cl_vcd::tick(int cycles)
+{
+ if (change)
+ {
+ int i;
+ change_time= uc->get_rtime();
+ if (fout)
+ fout->prntf("#%lu\n", (unsigned long)(change_time * 1000000000));
+ for (i= 0; i < locs->count; i++)
+ {
+ class cl_memory_cell *c= (cl_memory_cell*)(locs->at(i));
+ if (c->get() != c->def_data)
+ {
+ report(c, i);
+ }
+ }
+ change= false;
+ }
+ return 0;
+}
+
+void
+cl_vcd::print_info(class cl_console_base *con)
+{
+ int i;
+ con->dd_printf("%s[%d] value change dump\n", id_string, id);
+ con->dd_printf("Started: %s Paused: %s\n",
+ started?"YES":"no",
+ paused?"YES":"no");
+ const char *fn= fout?(fout->get_file_name()):"(none)";
+ con->dd_printf("Modul: %s File: %s\n", (char*)modul, fn);
+ con->dd_printf("Memory cells:\n");
+ for (i= 0; i < locs->count; i++)
+ {
+ cl_memory_cell *c= (cl_memory_cell*)(locs->at(i));
+ cl_address_space *as;
+ t_addr a= 0;
+ as= uc->address_space(c, &a);
+ con->dd_printf(" %s[0x%x] %s\n", as?(as->get_name()):"?", AU(a), (char*)(uc->cell_name(c)));
+ }
+ print_cfg_info(con);
+}
+
+
+/* End of sim.src/vcd.cc */
diff --git a/sim/ucsim/sim.src/vcd.o b/sim/ucsim/sim.src/vcd.o
new file mode 100644
index 0000000..b67e33d
--- /dev/null
+++ b/sim/ucsim/sim.src/vcd.o
Binary files differ
diff --git a/sim/ucsim/sim.src/vcdcl.h b/sim/ucsim/sim.src/vcdcl.h
new file mode 100644
index 0000000..6816b5c
--- /dev/null
+++ b/sim/ucsim/sim.src/vcdcl.h
@@ -0,0 +1,66 @@
+/*
+ * Simulator of microcontrollers (sim.src/vcdcl.h)
+ *
+ * Copyright (C) 2017,17 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 VCDCL_HEADER
+#define VCDCL_HEADER
+
+#include "hwcl.h"
+
+
+class cl_vcd: public cl_hw
+{
+ protected:
+ class cl_list *locs;
+ bool started, paused;
+ class cl_f *fout;
+ bool change;
+ double change_time;
+ chars modul;
+ public:
+ cl_vcd(class cl_uc *auc, int aid, chars aid_string);
+
+ virtual void add(class cl_memory_cell *cell);
+ virtual bool add(class cl_memory *m, t_addr a, class cl_console_base *con);
+ virtual void del(class cl_memory_cell *cell);
+ virtual bool del(class cl_memory *m, t_addr a, class cl_console_base *con);
+ virtual void set_cmd(class cl_cmdline *cmdline, class cl_console_base *con);
+
+ virtual t_mem read(class cl_memory_cell *cell);
+ virtual void write(class cl_memory_cell *cell, t_mem *val);
+ virtual t_mem conf_op(cl_memory_cell *cell, t_addr addr, t_mem *val);
+ virtual char *cfg_help(t_addr addr);
+
+ virtual void report(class cl_memory_cell *cell, int nr);
+ virtual int tick(int cycles);
+
+ virtual void print_info(class cl_console_base *con);
+};
+
+
+#endif
+
+/* End of sim.src/vcdcl.h */