diff options
| author | Xavier ASUS <xavi92psx@gmail.com> | 2019-10-18 00:31:54 +0200 |
|---|---|---|
| committer | Xavier ASUS <xavi92psx@gmail.com> | 2019-10-18 00:31:54 +0200 |
| commit | 268a53de823a6750d6256ee1fb1e7707b4b45740 (patch) | |
| tree | 42c1799a9a82b2f7d9790ee9fe181d72a7274751 /sim/ucsim/sim.src | |
| download | sdcc-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')
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 Binary files differnew file mode 100644 index 0000000..4773caa --- /dev/null +++ b/sim/ucsim/sim.src/arg.o 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 Binary files differnew file mode 100644 index 0000000..baa285c --- /dev/null +++ b/sim/ucsim/sim.src/brk.o 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 Binary files differnew file mode 100644 index 0000000..bf50ecf --- /dev/null +++ b/sim/ucsim/sim.src/guiobj.o 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 Binary files differnew file mode 100644 index 0000000..dad0dd4 --- /dev/null +++ b/sim/ucsim/sim.src/hw.o 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 Binary files differnew file mode 100644 index 0000000..df35fde --- /dev/null +++ b/sim/ucsim/sim.src/itsrc.o 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 Binary files differnew file mode 100644 index 0000000..4895f2e --- /dev/null +++ b/sim/ucsim/sim.src/iwrap.o 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 Binary files differnew file mode 100644 index 0000000..fb791bc --- /dev/null +++ b/sim/ucsim/sim.src/mem.o 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 Binary files differnew file mode 100644 index 0000000..5745ade --- /dev/null +++ b/sim/ucsim/sim.src/port_hw.o 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 Binary files differnew file mode 100644 index 0000000..470f2e0 --- /dev/null +++ b/sim/ucsim/sim.src/serial_hw.o 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 Binary files differnew file mode 100644 index 0000000..599802e --- /dev/null +++ b/sim/ucsim/sim.src/sim.o 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 Binary files differnew file mode 100644 index 0000000..f75ace7 --- /dev/null +++ b/sim/ucsim/sim.src/simif.o 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 Binary files differnew file mode 100644 index 0000000..9d1d173 --- /dev/null +++ b/sim/ucsim/sim.src/stack.o 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 Binary files differnew file mode 100644 index 0000000..f750e37 --- /dev/null +++ b/sim/ucsim/sim.src/uc.o 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 Binary files differnew file mode 100644 index 0000000..0e7be41 --- /dev/null +++ b/sim/ucsim/sim.src/var.o 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 Binary files differnew file mode 100644 index 0000000..b67e33d --- /dev/null +++ b/sim/ucsim/sim.src/vcd.o 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 */ |
