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/pdk.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/pdk.src')
24 files changed, 2967 insertions, 0 deletions
diff --git a/sim/ucsim/pdk.src/Makefile b/sim/ucsim/pdk.src/Makefile new file mode 100644 index 0000000..67b9006 --- /dev/null +++ b/sim/ucsim/pdk.src/Makefile @@ -0,0 +1,182 @@ +# +# uCsim pdk.src/Makefile +# +# (c) Drotos Daniel, Talker Bt. 1997 +# + +STARTYEAR = 2019 + +SHELL = /bin/sh +CXX = g++ +CPP = gcc -E +CXXCPP = g++ -E +RANLIB = ranlib +INSTALL = /usr/bin/install -c +STRIP = strip +MAKEDEP = g++ -MM +SREC_CAT = + +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)/sim.src \ + -I$(top_srcdir)/gui.src +CFLAGS = -g -O2 -Wall +CXXFLAGS = -g -O2 -g -Wall +LDFLAGS = +PICOPT = -fPIC -DPIC +SHAREDLIB = yes + +EXEEXT = + +LIBS = -L$(top_builddir) -lsim -lucsimutil -lguiucsim -lcmd -lsim -lrt -lnsl +DL = -ldl +dl_ok = yes + +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_SHARED = glob.o port.o \ + inst.o \ + simpdk.o pdk.o +OBJECTS_EXE = spdk.o +OBJECTS = $(OBJECTS_SHARED) $(OBJECTS_EXE) + +STM8ASM = + +enable_dlso = no +dlso_ok = no + +#TEST_OBJ = test_bit.hex test_dis.hex test_mov.hex test_jmp.hex \ +# test_arith.hex + +# Compiling entire program or any subproject +# ------------------------------------------ +all: checkconf otherlibs pdk.src + +tests: $(TEST_OBJ) + + +# Compiling and installing everything and runing test +# --------------------------------------------------- +install: all installdirs + $(INSTALL) spdk$(EXEEXT) $(DESTDIR)$(bindir)/`echo spdk|sed '$(transform)'`$(EXEEXT) + $(STRIP) $(DESTDIR)$(bindir)/`echo spdk|sed '$(transform)'`$(EXEEXT) + + +# Deleting all the installed files +# -------------------------------- +uninstall: + rm -f $(DESTDIR)$(bindir)/`echo spdk|sed '$(transform)'`$(EXEEXT) + + +# Performing self-test +# -------------------- +check: test + +test: + + +# Performing installation test +# ---------------------------- +installcheck: + + +# Creating installation directories +# --------------------------------- +installdirs: + test -d $(DESTDIR)$(bindir) || $(INSTALL) -d $(DESTDIR)$(bindir) + + +# Creating dependencies +# --------------------- +dep: Makefile.dep + +Makefile.dep: $(srcdir)/*.cc $(srcdir)/*.h + $(MAKEDEP) $(CPPFLAGS) $(filter %.cc,$^) >Makefile.dep + +-include Makefile.dep +include $(srcdir)/clean.mk + +# My rules +# -------- +.SUFFIXES: .asm .hex + +pdk.src: spdk$(EXEEXT) shared_lib + +spdk$(EXEEXT): $(OBJECTS) $(top_builddir)/libcmd.a $(top_builddir)/libguiucsim.a $(top_builddir)/libsim.a $(top_builddir)/libucsimutil.a + $(CXX) $(CXXFLAGS) $(LDFLAGS) $(OBJECTS) $(LIBS) -o $@ + +ifeq ($(dlso_ok),yes) +shared_lib: $(top_builddir)/spdk.so +else +shared_lib: + @$(top_srcdir)/mkecho $(top_builddir) "No pdk shared lib made." + @$(top_srcdir)/mkecho $(top_builddir) "(SHAREDLIB="$(SHAREDLIB)",dl_ok="$(dl_ok)",enable_dlso="$(enable_dlso)")" +endif + +$(top_builddir)/spdk.so: $(OBJECTS_SHARED) + $(CXX) -shared $(LDFLAGS) $(OBJECTS_SHARED) -o $(top_builddir)/spdk.so + +otherlibs: $(top_builddir)/libcmd.a $(top_builddir)/libguiucsim.a $(top_builddir)/libsim.a $(top_builddir)/libucsimutil.a + +$(top_builddir)/libcmd.a: + $(MAKE) -C $(top_builddir)/cmd.src all + +$(top_builddir)/libguiucsim.a: + $(MAKE) -C $(top_builddir)/gui.src checkconf ucsim_lib + +$(top_builddir)/libsim.a: + $(MAKE) -C $(top_builddir)/sim.src all + +$(top_builddir)/libucsimutil.a: + $(MAKE) -C $(top_builddir) -f main.mk + +.cc.o: + $(CXX) $(CXXFLAGS) $(PICOPT) $(CPPFLAGS) $(TARGET_ARCH) -c $< -o $@ + +.asm.hex: + $(STM8ASM) -l $< -o $@ -e $<.lst + + +# Remaking configuration +# ---------------------- +checkconf: + @if [ -f $(top_builddir)/devel ]; then\ + $(MAKE) -C $(top_builddir) -f conf.mk srcdir="$(srcdir)" top_builddir="$(top_builddir)" freshconf;\ + fi + +#bl_l15x46.hex: bl_l15x46.asc +# $(SREC_CAT) $< -Ascii_Hex -Output $@ -Intel + +#bl_l15x46.cc: bl_l15x46.asc +# $(SREC_CAT) $< -Ascii_Hex -Output $@ -C-Array bl_l15x46 -INClude -No-CONST + +#bl_s105.hex: bl_s105.asc +# $(SREC_CAT) $< -Ascii_Hex -Output $@ -Intel + +#bl_s105.cc: bl_s105.asc +# $(SREC_CAT) $< -Ascii_Hex -Output $@ -C-Array bl_s105 -INClude -No-CONST + +#bl_source: bl.cc bl.h + +#bl.cc: bl_head.cc bl_l15x46.cc bl_s105.cc +# cat bl_head.cc bl_l15x46.cc bl_s105.cc|sed 's/unsigned char/t_mem/' >$@ + +#bl.h: bl_l15x46.h bl_s105.h +# cat bl_l15x46.h bl_s105.h|sed 's/unsigned char/t_mem/' >$@ + +# End of pdk.src/Makefile.in diff --git a/sim/ucsim/pdk.src/Makefile.dep b/sim/ucsim/pdk.src/Makefile.dep new file mode 100644 index 0000000..2b199cb --- /dev/null +++ b/sim/ucsim/pdk.src/Makefile.dep @@ -0,0 +1,52 @@ +spdk.o: spdk.cc ../globals.h ../ddconfig.h ../stypes.h ../appcl.h \ + ../pobjcl.h ../pobjt.h ../eventcl.h ../charscl.h ../optioncl.h \ + ../sim.src/argcl.h ../pobjcl.h ../stypes.h ../sim.src/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 \ + ../sim.src/guiobjcl.h ../sim.src/uccl.h ../pobjt.h ../sim.src/hwcl.h \ + ../sim.src/guiobjcl.h ../cmd.src/newcmdposixcl.h ../fiocl.h \ + ../cmd.src/cmdutil.h ../sim.src/memcl.h ../eventcl.h ../errorcl.h \ + ../sim.src/brkcl.h ../sim.src/stackcl.h ../sim.src/varcl.h \ + ../sim.src/uccl_instructions.h ../sim.src/argcl.h ../appcl.h simpdkcl.h +simpdk.o: simpdk.cc ../globals.h ../ddconfig.h ../stypes.h ../appcl.h \ + ../pobjcl.h ../pobjt.h ../eventcl.h ../charscl.h ../optioncl.h \ + ../sim.src/argcl.h ../pobjcl.h ../stypes.h ../sim.src/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 \ + ../sim.src/guiobjcl.h ../sim.src/uccl.h ../pobjt.h ../sim.src/hwcl.h \ + ../sim.src/guiobjcl.h ../cmd.src/newcmdposixcl.h ../fiocl.h \ + ../cmd.src/cmdutil.h ../sim.src/memcl.h ../eventcl.h ../errorcl.h \ + ../sim.src/brkcl.h ../sim.src/stackcl.h ../sim.src/varcl.h \ + ../sim.src/uccl_instructions.h ../sim.src/argcl.h simpdkcl.h pdkcl.h \ + ../sim.src/uccl.h ../sim.src/itsrccl.h regspdk.h instcl.h +port.o: port.cc portcl.h ../sim.src/port_hwcl.h \ + ../cmd.src/newcmdposixcl.h ../fiocl.h ../charscl.h ../pobjcl.h \ + ../ddconfig.h ../pobjt.h ../eventcl.h ../cmd.src/newcmdcl.h \ + ../ddconfig.h ../pobjcl.h ../optioncl.h ../stypes.h \ + ../cmd.src/commandcl.h ../cmd.src/cmdutil.h ../sim.src/hwcl.h \ + ../stypes.h ../sim.src/guiobjcl.h ../cmd.src/newcmdcl.h \ + ../sim.src/memcl.h ../eventcl.h ../errorcl.h ../sim.src/uccl.h \ + ../pobjt.h ../sim.src/brkcl.h ../sim.src/stackcl.h ../sim.src/varcl.h \ + ../sim.src/uccl_instructions.h +pdk.o: pdk.cc ../ddconfig.h ../i_string.h ../ddconfig.h ../globals.h \ + ../stypes.h ../appcl.h ../pobjcl.h ../pobjt.h ../eventcl.h ../charscl.h \ + ../optioncl.h ../sim.src/argcl.h ../pobjcl.h ../stypes.h \ + ../sim.src/simcl.h ../cmd.src/newcmdcl.h ../optioncl.h \ + ../cmd.src/commandcl.h ../cmd.src/newcmdcl.h ../gui.src/guicl.h \ + ../gui.src/ifcl.h ../sim.src/guiobjcl.h ../sim.src/uccl.h ../pobjt.h \ + ../sim.src/hwcl.h ../sim.src/guiobjcl.h ../cmd.src/newcmdposixcl.h \ + ../fiocl.h ../cmd.src/cmdutil.h ../sim.src/memcl.h ../eventcl.h \ + ../errorcl.h ../sim.src/brkcl.h ../sim.src/stackcl.h ../sim.src/varcl.h \ + ../sim.src/uccl_instructions.h ../sim.src/argcl.h glob.h pdkcl.h \ + ../sim.src/uccl.h ../sim.src/itsrccl.h regspdk.h instcl.h portcl.h \ + ../sim.src/port_hwcl.h +glob.o: glob.cc ../stypes.h ../ddconfig.h +inst.o: inst.cc ../ddconfig.h pdkcl.h ../sim.src/uccl.h ../stypes.h \ + ../ddconfig.h ../pobjcl.h ../pobjt.h ../eventcl.h ../charscl.h \ + ../pobjt.h ../sim.src/hwcl.h ../sim.src/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 ../sim.src/memcl.h ../eventcl.h ../errorcl.h \ + ../sim.src/uccl.h ../sim.src/brkcl.h ../sim.src/stackcl.h \ + ../sim.src/varcl.h ../sim.src/uccl_instructions.h ../sim.src/itsrccl.h \ + regspdk.h instcl.h diff --git a/sim/ucsim/pdk.src/Makefile.in b/sim/ucsim/pdk.src/Makefile.in new file mode 100644 index 0000000..01cc96a --- /dev/null +++ b/sim/ucsim/pdk.src/Makefile.in @@ -0,0 +1,182 @@ +# +# uCsim pdk.src/Makefile +# +# (c) Drotos Daniel, Talker Bt. 1997 +# + +STARTYEAR = 2019 + +SHELL = /bin/sh +CXX = @CXX@ +CPP = @CPP@ +CXXCPP = @CXXCPP@ +RANLIB = @RANLIB@ +INSTALL = @INSTALL@ +STRIP = @STRIP@ +MAKEDEP = @MAKEDEP@ +SREC_CAT = @SREC_CAT@ + +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)/sim.src \ + -I$(top_srcdir)/gui.src +CFLAGS = @CFLAGS@ @WALL_FLAG@ +CXXFLAGS = @CXXFLAGS@ @WALL_FLAG@ +LDFLAGS = @LDFLAGS@ +PICOPT = @PICOPT@ +SHAREDLIB = @SHAREDLIB@ + +EXEEXT = @EXEEXT@ + +LIBS = -L$(top_builddir) -lsim -lucsimutil -lguiucsim -lcmd -lsim @LIBS@ +DL = @DL@ +dl_ok = @dl_ok@ + +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_SHARED = glob.o port.o \ + inst.o \ + simpdk.o pdk.o +OBJECTS_EXE = spdk.o +OBJECTS = $(OBJECTS_SHARED) $(OBJECTS_EXE) + +STM8ASM = + +enable_dlso = @enable_dlso@ +dlso_ok = @dlso_ok@ + +#TEST_OBJ = test_bit.hex test_dis.hex test_mov.hex test_jmp.hex \ +# test_arith.hex + +# Compiling entire program or any subproject +# ------------------------------------------ +all: checkconf otherlibs pdk.src + +tests: $(TEST_OBJ) + + +# Compiling and installing everything and runing test +# --------------------------------------------------- +install: all installdirs + $(INSTALL) spdk$(EXEEXT) $(DESTDIR)$(bindir)/`echo spdk|sed '$(transform)'`$(EXEEXT) + $(STRIP) $(DESTDIR)$(bindir)/`echo spdk|sed '$(transform)'`$(EXEEXT) + + +# Deleting all the installed files +# -------------------------------- +uninstall: + rm -f $(DESTDIR)$(bindir)/`echo spdk|sed '$(transform)'`$(EXEEXT) + + +# Performing self-test +# -------------------- +check: test + +test: + + +# Performing installation test +# ---------------------------- +installcheck: + + +# Creating installation directories +# --------------------------------- +installdirs: + test -d $(DESTDIR)$(bindir) || $(INSTALL) -d $(DESTDIR)$(bindir) + + +# Creating dependencies +# --------------------- +dep: Makefile.dep + +Makefile.dep: $(srcdir)/*.cc $(srcdir)/*.h + $(MAKEDEP) $(CPPFLAGS) $(filter %.cc,$^) >Makefile.dep + +-include Makefile.dep +include $(srcdir)/clean.mk + +# My rules +# -------- +.SUFFIXES: .asm .hex + +pdk.src: spdk$(EXEEXT) shared_lib + +spdk$(EXEEXT): $(OBJECTS) $(top_builddir)/libcmd.a $(top_builddir)/libguiucsim.a $(top_builddir)/libsim.a $(top_builddir)/libucsimutil.a + $(CXX) $(CXXFLAGS) $(LDFLAGS) $(OBJECTS) $(LIBS) -o $@ + +ifeq ($(dlso_ok),yes) +shared_lib: $(top_builddir)/spdk.so +else +shared_lib: + @$(top_srcdir)/mkecho $(top_builddir) "No pdk shared lib made." + @$(top_srcdir)/mkecho $(top_builddir) "(SHAREDLIB="$(SHAREDLIB)",dl_ok="$(dl_ok)",enable_dlso="$(enable_dlso)")" +endif + +$(top_builddir)/spdk.so: $(OBJECTS_SHARED) + $(CXX) -shared $(LDFLAGS) $(OBJECTS_SHARED) -o $(top_builddir)/spdk.so + +otherlibs: $(top_builddir)/libcmd.a $(top_builddir)/libguiucsim.a $(top_builddir)/libsim.a $(top_builddir)/libucsimutil.a + +$(top_builddir)/libcmd.a: + $(MAKE) -C $(top_builddir)/cmd.src all + +$(top_builddir)/libguiucsim.a: + $(MAKE) -C $(top_builddir)/gui.src checkconf ucsim_lib + +$(top_builddir)/libsim.a: + $(MAKE) -C $(top_builddir)/sim.src all + +$(top_builddir)/libucsimutil.a: + $(MAKE) -C $(top_builddir) -f main.mk + +.cc.o: + $(CXX) $(CXXFLAGS) $(PICOPT) $(CPPFLAGS) $(TARGET_ARCH) -c $< -o $@ + +.asm.hex: + $(STM8ASM) -l $< -o $@ -e $<.lst + + +# Remaking configuration +# ---------------------- +checkconf: + @if [ -f $(top_builddir)/devel ]; then\ + $(MAKE) -C $(top_builddir) -f conf.mk srcdir="$(srcdir)" top_builddir="$(top_builddir)" freshconf;\ + fi + +#bl_l15x46.hex: bl_l15x46.asc +# $(SREC_CAT) $< -Ascii_Hex -Output $@ -Intel + +#bl_l15x46.cc: bl_l15x46.asc +# $(SREC_CAT) $< -Ascii_Hex -Output $@ -C-Array bl_l15x46 -INClude -No-CONST + +#bl_s105.hex: bl_s105.asc +# $(SREC_CAT) $< -Ascii_Hex -Output $@ -Intel + +#bl_s105.cc: bl_s105.asc +# $(SREC_CAT) $< -Ascii_Hex -Output $@ -C-Array bl_s105 -INClude -No-CONST + +#bl_source: bl.cc bl.h + +#bl.cc: bl_head.cc bl_l15x46.cc bl_s105.cc +# cat bl_head.cc bl_l15x46.cc bl_s105.cc|sed 's/unsigned char/t_mem/' >$@ + +#bl.h: bl_l15x46.h bl_s105.h +# cat bl_l15x46.h bl_s105.h|sed 's/unsigned char/t_mem/' >$@ + +# End of pdk.src/Makefile.in diff --git a/sim/ucsim/pdk.src/clean.mk b/sim/ucsim/pdk.src/clean.mk new file mode 100644 index 0000000..0215de0 --- /dev/null +++ b/sim/ucsim/pdk.src/clean.mk @@ -0,0 +1,26 @@ +# Deleting all files created by building the program +# -------------------------------------------------- +clean: + rm -f *core *[%~] *.[oa] + rm -f .[a-z]*~ + rm -f spdk$(EXEEXT) + + +# Deleting all files created by configuring or building the program +# ----------------------------------------------------------------- +distclean: clean + rm -f config.cache config.log config.status + rm -f Makefile *.dep + + +# Like clean but some files may still exist +# ----------------------------------------- +mostlyclean: clean + + +# Deleting everything that can reconstructed by this Makefile. It deletes +# everything deleted by distclean plus files created by bison, etc. +# ----------------------------------------------------------------------- +realclean: distclean + +# End of pdk.src/clean.mk diff --git a/sim/ucsim/pdk.src/conf.mk b/sim/ucsim/pdk.src/conf.mk new file mode 100644 index 0000000..322b1ea --- /dev/null +++ b/sim/ucsim/pdk.src/conf.mk @@ -0,0 +1,10 @@ +# +# Makefile targets to remake configuration +# + +freshconf: Makefile + +Makefile: $(srcdir)/Makefile.in $(top_srcdir)/configure.ac + cd $(top_builddir) && $(SHELL) ./config.status + +# End of pdk.src/conf.mk diff --git a/sim/ucsim/pdk.src/glob.cc b/sim/ucsim/pdk.src/glob.cc new file mode 100644 index 0000000..0a90b60 --- /dev/null +++ b/sim/ucsim/pdk.src/glob.cc @@ -0,0 +1,362 @@ +/* + * Simulator of microcontrollers (glob.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 "stypes.h" + +/* PDK14 instructions described in PFS154. */ + + +/* +%k - immediate addressing +%m - memory addressing +%mn - memory addressing when using N-bit +%i - IO addressing +%in - IO addressing when using N-bit +%n - N-bit addressing +*/ + +/* uint code, mask; char branch; uchar length; char *mnemonic; */ + +struct dis_entry disass_pdk_13[]= { + { 0x0000, ~0x0000, ' ', 2, "nop" }, + { 0x003A, ~0x0000, ' ', 2, "ret" }, + { 0x0100, ~0x00FF, ' ', 2, "ret %k" }, + { 0x003B, ~0x0000, ' ', 2, "reti" }, + { 0x1700, ~0x00FF, ' ', 2, "mov a, %k" }, + { 0x0080, ~0x001F, ' ', 2, "mov %i, a" }, + { 0x00A0, ~0x001F, ' ', 2, "mov a, %i" }, + { 0x05C0, ~0x003F, ' ', 2, "mov %m, a" }, + { 0x07C0, ~0x003F, ' ', 2, "mov a, %m" }, + { 0x00C1, ~0x001E, ' ', 2, "ldt16 %m" }, + { 0x00C0, ~0x001E, ' ', 2, "stt16 %m" }, + { 0x00E1, ~0x001E, ' ', 2, "idxm a, %m" }, + { 0x00E0, ~0x001E, ' ', 2, "idxm %m, a" }, + { 0x09C0, ~0x003F, ' ', 2, "xch %m" }, + { 0x0032, ~0x0000, ' ', 2, "push af" }, + { 0x0033, ~0x0000, ' ', 2, "pop af" }, + + { 0x1000, ~0x00FF, ' ', 2, "add %k" }, + { 0x0400, ~0x003F, ' ', 2, "add %m, a" }, + { 0x0600, ~0x003F, ' ', 2, "add a, %m" }, + { 0x1100, ~0x00FF, ' ', 2, "sub %k" }, + { 0x0440, ~0x003F, ' ', 2, "sub %m, a" }, + { 0x0640, ~0x003F, ' ', 2, "sub a, %m" }, + { 0x0010, ~0x0000, ' ', 2, "addc" }, + { 0x0480, ~0x003F, ' ', 2, "addc %m, a" }, + { 0x0680, ~0x003F, ' ', 2, "addc a, %m" }, + { 0x0800, ~0x003F, ' ', 2, "addc %m" }, + { 0x0011, ~0x0000, ' ', 2, "subc" }, + { 0x04C0, ~0x003F, ' ', 2, "subc %m, a" }, + { 0x06C0, ~0x003F, ' ', 2, "subc a, %m" }, + { 0x0840, ~0x007F, ' ', 2, "subc %m" }, + + { 0x0900, ~0x003F, ' ', 2, "inc %m" }, + { 0x0940, ~0x003F, ' ', 2, "dec %m" }, + { 0x0980, ~0x003F, ' ', 2, "clear %m" }, + { 0x001A, ~0x0000, ' ', 2, "sr" }, + { 0x0A80, ~0x003F, ' ', 2, "sr %m" }, + { 0x001B, ~0x0000, ' ', 2, "sl" }, + { 0x0AC0, ~0x003F, ' ', 2, "sl %m" }, + { 0x001C, ~0x0000, ' ', 2, "src" }, + { 0x0B00, ~0x003F, ' ', 2, "src %m"}, + { 0x001D, ~0x0000, ' ', 2, "slc" }, + { 0x0B40, ~0x003F, ' ', 2, "slc %m" }, + + { 0x1400, ~0x00FF, ' ', 2, "and %k" }, + { 0x0500, ~0x003F, ' ', 2, "and %m, a" }, + { 0x0700, ~0x003F, ' ', 2, "and a, %m" }, + { 0x1500, ~0x00FF, ' ', 2, "or %k" }, + { 0x0540, ~0x003F, ' ', 2, "or %m, a" }, + { 0x0740, ~0x003F, ' ', 2, "or a, %m" }, + { 0x1600, ~0x00FF, ' ', 2, "xor %k" }, + { 0x0580, ~0x003F, ' ', 2, "xor %m, a" }, + { 0x0780, ~0x003F, ' ', 2, "xor a, %m" }, + { 0x0060, ~0x001F, ' ', 2, "xor %i, a" }, + + { 0x0018, ~0x0000, ' ', 2, "not" }, + { 0x0A00, ~0x003F, ' ', 2, "not %m" }, + { 0x0019, ~0x0000, ' ', 2, "neg" }, + { 0x0A40, ~0x003F, ' ', 2, "neg %m" }, + + { 0x0E00, ~0x00FF, ' ', 2, "set0 %in, %n" }, + { 0x0300, ~0x00FE, ' ', 2, "set0 %mn, %n" }, + { 0x0F00, ~0x00FF, ' ', 2, "set1 %in, %n" }, + { 0x0301, ~0x00FE, ' ', 2, "set1 %mn, %n" }, + { 0x0C00, ~0x00FF, ' ', 2, "t0sn %in, %n" }, + { 0x0200, ~0x00FE, ' ', 2, "t0sn %mn, %n" }, + { 0x0D00, ~0x00FF, ' ', 2, "t1sn %in, %n" }, + { 0x0201, ~0x00FE, ' ', 2, "t1sn %mn, %n" }, + + { 0x1200, ~0x00FF, ' ', 2, "ceqsn %k" }, + { 0x0B80, ~0x003F, ' ', 2, "ceqsn %m" }, + { 0x1300, ~0x00FF, ' ', 2, "cneqsn %k" }, + { 0x0BC0, ~0x003F, ' ', 2, "cneqsn %m" }, + + { 0x0012, ~0x0000, ' ', 2, "izsn" }, + { 0x0880, ~0x003F, ' ', 2, "izsn %m" }, + { 0x0013, ~0x0000, ' ', 2, "dzsn" }, + { 0x08C0, ~0x003F, ' ', 2, "dzsn %m" }, + + { 0x1C00, ~0x03FF, ' ', 2, "call %k" }, + { 0x1800, ~0x03FF, ' ', 2, "goto %k" }, + + { 0x001E, ~0x0000, ' ', 2, "swap" }, + { 0x0017, ~0x0000, ' ', 2, "pcadd" }, + { 0x0038, ~0x0000, ' ', 2, "engint" }, + { 0x0039, ~0x0000, ' ', 2, "disint" }, + { 0x0036, ~0x0000, ' ', 2, "stopsys" }, + { 0x0037, ~0x0000, ' ', 2, "stopexe" }, + { 0x0035, ~0x0000, ' ', 2, "reset" }, + { 0x0030, ~0x0000, ' ', 2, "wdreset" }, + { 0x0006, ~0x0000, ' ', 2, "ldsptl" }, + { 0x0007, ~0x0000, ' ', 2, "ldspth" }, + { 0x003C, ~0x0000, ' ', 2, "mul" }, + + { 0xFF00, ~0x0000, ' ', 2, "putchar" }, + + { 0, 0, 0, 0, NULL } +}; + +struct dis_entry disass_pdk_14[]= { + { 0x0000, ~0x0000, ' ', 2, "nop" }, + { 0x007A, ~0x0000, ' ', 2, "ret" }, + { 0x0200, ~0x00FF, ' ', 2, "ret %k" }, + { 0x007B, ~0x0000, ' ', 2, "reti" }, + { 0x2F00, ~0x00FF, ' ', 2, "mov a, %k" }, + { 0x0180, ~0x003F, ' ', 2, "mov %i, a" }, + { 0x01C0, ~0x003F, ' ', 2, "mov a, %i" }, + { 0x0B80, ~0x007F, ' ', 2, "mov %m, a" }, + { 0x0F80, ~0x007F, ' ', 2, "mov a, %m" }, + { 0x0301, ~0x007E, ' ', 2, "ldt16 %m" }, + { 0x0300, ~0x007E, ' ', 2, "stt16 %m" }, + { 0x0381, ~0x007E, ' ', 2, "idxm a, %m" }, + { 0x0380, ~0x007E, ' ', 2, "idxm %m, a" }, + { 0x1380, ~0x007F, ' ', 2, "xch %m" }, + { 0x0072, ~0x0000, ' ', 2, "push af" }, + { 0x0073, ~0x0000, ' ', 2, "pop af" }, + + { 0x2800, ~0x00FF, ' ', 2, "add %k" }, + { 0x0800, ~0x007F, ' ', 2, "add %m, a" }, + { 0x0C00, ~0x007F, ' ', 2, "add a, %m" }, + { 0x2900, ~0x00FF, ' ', 2, "sub %k" }, + { 0x0880, ~0x007F, ' ', 2, "sub %m, a" }, + { 0x0C80, ~0x007F, ' ', 2, "sub a, %m" }, + { 0x0060, ~0x0000, ' ', 2, "addc" }, + { 0x0900, ~0x007F, ' ', 2, "addc %m, a" }, + { 0x0D00, ~0x007F, ' ', 2, "addc a, %m" }, + { 0x1000, ~0x007F, ' ', 2, "addc %m" }, + { 0x0061, ~0x0000, ' ', 2, "subc" }, + { 0x0980, ~0x007F, ' ', 2, "subc %m, a" }, + { 0x0D80, ~0x007F, ' ', 2, "subc a, %m" }, + { 0x1080, ~0x007F, ' ', 2, "subc %m" }, + + { 0x1200, ~0x007F, ' ', 2, "inc %m" }, + { 0x1280, ~0x007F, ' ', 2, "dec %m" }, + { 0x1300, ~0x007F, ' ', 2, "clear %m" }, + { 0x006A, ~0x0000, ' ', 2, "sr" }, + { 0x1500, ~0x007F, ' ', 2, "sr %m" }, + { 0x006B, ~0x0000, ' ', 2, "sl" }, + { 0x1580, ~0x007F, ' ', 2, "sl %m" }, + { 0x006C, ~0x0000, ' ', 2, "src" }, + { 0x1600, ~0x007F, ' ', 2, "src %m"}, + { 0x006D, ~0x0000, ' ', 2, "slc" }, + { 0x1680, ~0x007F, ' ', 2, "slc %m" }, + + { 0x2C00, ~0x00FF, ' ', 2, "and %k" }, + { 0x0A00, ~0x007F, ' ', 2, "and %m, a" }, + { 0x0E00, ~0x007F, ' ', 2, "and a, %m" }, + { 0x2D00, ~0x00FF, ' ', 2, "or %k" }, + { 0x0A80, ~0x007F, ' ', 2, "or %m, a" }, + { 0x0E80, ~0x007F, ' ', 2, "or a, %m" }, + { 0x2E00, ~0x00FF, ' ', 2, "xor %k" }, + { 0x0B00, ~0x007F, ' ', 2, "xor %m, a" }, + { 0x0F00, ~0x007F, ' ', 2, "xor a, %m" }, + { 0x00C0, ~0x003F, ' ', 2, "xor %i, a" }, + + { 0x0068, ~0x0000, ' ', 2, "not" }, + { 0x1400, ~0x007F, ' ', 2, "not %m" }, + { 0x0069, ~0x0000, ' ', 2, "neg" }, + { 0x1480, ~0x007F, ' ', 2, "neg %m" }, + + { 0x1C00, ~0x01FF, ' ', 2, "set0 %in, %n" }, + { 0x2400, ~0x01FF, ' ', 2, "set0 %mn, %n" }, + { 0x1E00, ~0x01FF, ' ', 2, "set1 %in, %n" }, + { 0x2600, ~0x01FF, ' ', 2, "set1 %mn, %n" }, + { 0x1800, ~0x01FF, ' ', 2, "t0sn %in, %n" }, + { 0x2000, ~0x01FF, ' ', 2, "t0sn %mn, %n" }, + { 0x1A00, ~0x01FF, ' ', 2, "t1sn %in, %n" }, + { 0x2200, ~0x01FF, ' ', 2, "t1sn %mn, %n" }, + + { 0x2A00, ~0x00FF, ' ', 2, "ceqsn %k" }, + { 0x1700, ~0x007F, ' ', 2, "ceqsn %m" }, + { 0x2B00, ~0x00FF, ' ', 2, "cneqsn %k" }, + { 0x1780, ~0x007F, ' ', 2, "cneqsn %m" }, + + { 0x0062, ~0x0000, ' ', 2, "izsn" }, + { 0x1100, ~0x007F, ' ', 2, "izsn %m" }, + { 0x0063, ~0x0000, ' ', 2, "dzsn" }, + { 0x1180, ~0x007F, ' ', 2, "dzsn %m" }, + + { 0x3800, ~0x07FF, ' ', 2, "call %k" }, + { 0x3000, ~0x07FF, ' ', 2, "goto %k" }, + + { 0x0600, ~0x007F, ' ', 2, "comp a, %m" }, + { 0x6800, ~0x007F, ' ', 2, "comp %m, a" }, + { 0x0700, ~0x007F, ' ', 2, "nadd a, %m" }, + { 0x0780, ~0x007F, ' ', 2, "nadd %m, a" }, + + { 0x006E, ~0x0000, ' ', 2, "swap" }, + { 0x0067, ~0x0000, ' ', 2, "pcadd" }, + { 0x0078, ~0x0000, ' ', 2, "engint" }, + { 0x0079, ~0x0000, ' ', 2, "disint" }, + { 0x0076, ~0x0000, ' ', 2, "stopsys" }, + { 0x0077, ~0x0000, ' ', 2, "stopexe" }, + { 0x0075, ~0x0000, ' ', 2, "reset" }, + { 0x0070, ~0x0000, ' ', 2, "wdreset" }, + { 0x0400, ~0x01FF, ' ', 2, "swapc %in, %n" }, + { 0x0006, ~0x0000, ' ', 2, "ldsptl" }, + { 0x0007, ~0x0000, ' ', 2, "ldspth" }, + { 0x007C, ~0x0000, ' ', 2, "mul" }, + + { 0xFF00, ~0x0000, ' ', 2, "putchar" }, + + { 0, 0, 0, 0, NULL } +}; + +struct dis_entry disass_pdk_15[]= { + { 0x0000, ~0x0000, ' ', 2, "nop" }, + { 0x007A, ~0x0000, ' ', 2, "ret" }, + { 0x0200, ~0x00FF, ' ', 2, "ret %k" }, + { 0x007B, ~0x0000, ' ', 2, "reti" }, + { 0x5700, ~0x00FF, ' ', 2, "mov a, %k" }, + { 0x0100, ~0x007F, ' ', 2, "mov %i, a" }, + { 0x0180, ~0x007F, ' ', 2, "mov a, %i" }, + { 0x1700, ~0x00FF, ' ', 2, "mov %m, a" }, + { 0x1F00, ~0x00FF, ' ', 2, "mov a, %m" }, + { 0x0601, ~0x00FE, ' ', 2, "ldt16 %m" }, + { 0x0600, ~0x00FE, ' ', 2, "stt16 %m" }, + { 0x0701, ~0x00FE, ' ', 2, "idxm a, %m" }, + { 0x0700, ~0x00FE, ' ', 2, "idxm %m, a" }, + { 0x2700, ~0x00FF, ' ', 2, "xch %m" }, + { 0x0072, ~0x0000, ' ', 2, "push af" }, + { 0x0073, ~0x0000, ' ', 2, "pop af" }, + + { 0x5000, ~0x00FF, ' ', 2, "add %k" }, + { 0x1000, ~0x00FF, ' ', 2, "add %m, a" }, + { 0x1800, ~0x00FF, ' ', 2, "add a, %m" }, + { 0x5100, ~0x00FF, ' ', 2, "sub %k" }, + { 0x1100, ~0x00FF, ' ', 2, "sub %m, a" }, + { 0x1900, ~0x00FF, ' ', 2, "sub a, %m" }, + { 0x0060, ~0x0000, ' ', 2, "addc" }, + { 0x1200, ~0x00FF, ' ', 2, "addc %m, a" }, + { 0x1A00, ~0x00FF, ' ', 2, "addc a, %m" }, + { 0x2000, ~0x00FF, ' ', 2, "addc %m" }, + { 0x0061, ~0x0000, ' ', 2, "subc" }, + { 0x1300, ~0x00FF, ' ', 2, "subc %m, a" }, + { 0x1B00, ~0x00FF, ' ', 2, "subc a, %m" }, + { 0x2100, ~0x00FF, ' ', 2, "subc %m" }, + + { 0x2400, ~0x00FF, ' ', 2, "inc %m" }, + { 0x2500, ~0x00FF, ' ', 2, "dec %m" }, + { 0x2600, ~0x00FF, ' ', 2, "clear %m" }, + { 0x006A, ~0x0000, ' ', 2, "sr" }, + { 0x2A00, ~0x00FF, ' ', 2, "sr %m" }, + { 0x006B, ~0x0000, ' ', 2, "sl" }, + { 0x2B00, ~0x00FF, ' ', 2, "sl %m" }, + { 0x006C, ~0x0000, ' ', 2, "src" }, + { 0x2C00, ~0x00FF, ' ', 2, "src %m"}, + { 0x006D, ~0x0000, ' ', 2, "slc" }, + { 0x2D00, ~0x00FF, ' ', 2, "slc %m" }, + + { 0x5400, ~0x00FF, ' ', 2, "and %k" }, + { 0x1400, ~0x00FF, ' ', 2, "and %m, a" }, + { 0x1C00, ~0x00FF, ' ', 2, "and a, %m" }, + { 0x5500, ~0x00FF, ' ', 2, "or %k" }, + { 0x1500, ~0x00FF, ' ', 2, "or %m, a" }, + { 0x1D00, ~0x00FF, ' ', 2, "or a, %m" }, + { 0x5600, ~0x00FF, ' ', 2, "xor %k" }, + { 0x1600, ~0x00FF, ' ', 2, "xor %m, a" }, + { 0x1E00, ~0x00FF, ' ', 2, "xor a, %m" }, + { 0x0080, ~0x007F, ' ', 2, "xor %i, a" }, + + { 0x0068, ~0x0000, ' ', 2, "not" }, + { 0x2800, ~0x00FF, ' ', 2, "not %m" }, + { 0x0069, ~0x0000, ' ', 2, "neg" }, + { 0x2900, ~0x00FF, ' ', 2, "neg %m" }, + + { 0x3800, ~0x03FF, ' ', 2, "set0 %in, %n" }, + { 0x4800, ~0x03FF, ' ', 2, "set0 %mn, %n" }, + { 0x3C00, ~0x03FF, ' ', 2, "set1 %in, %n" }, + { 0x4C00, ~0x03FF, ' ', 2, "set1 %mn, %n" }, + { 0x3000, ~0x03FF, ' ', 2, "t0sn %in, %n" }, + { 0x4000, ~0x03FF, ' ', 2, "t0sn %mn, %n" }, + { 0x3400, ~0x03FF, ' ', 2, "t1sn %in, %n" }, + { 0x4400, ~0x03FF, ' ', 2, "t1sn %mn, %n" }, + + { 0x5200, ~0x00FF, ' ', 2, "ceqsn %k" }, + { 0x2E00, ~0x00FF, ' ', 2, "ceqsn %m" }, + { 0x5300, ~0x00FF, ' ', 2, "cneqsn %k" }, + { 0x2F00, ~0x00FF, ' ', 2, "cneqsn %m" }, + + { 0x0062, ~0x0000, ' ', 2, "izsn" }, + { 0x2200, ~0x00FF, ' ', 2, "izsn %m" }, + { 0x0063, ~0x0000, ' ', 2, "dzsn" }, + { 0x2300, ~0x00FF, ' ', 2, "dzsn %m" }, + + { 0x7000, ~0x0FFF, ' ', 2, "call %k" }, + { 0x6000, ~0x0FFF, ' ', 2, "goto %k" }, + + { 0x0C00, ~0x00FF, ' ', 2, "comp a, %m" }, + { 0x0D00, ~0x00FF, ' ', 2, "comp %m, a" }, + { 0x0E00, ~0x00FF, ' ', 2, "nadd a, %m" }, + { 0x0F00, ~0x00FF, ' ', 2, "nadd %m, a" }, + + { 0x006E, ~0x0000, ' ', 2, "swap" }, + { 0x0067, ~0x0000, ' ', 2, "pcadd" }, + { 0x0078, ~0x0000, ' ', 2, "engint" }, + { 0x0079, ~0x0000, ' ', 2, "disint" }, + { 0x0076, ~0x0000, ' ', 2, "stopsys" }, + { 0x0077, ~0x0000, ' ', 2, "stopexe" }, + { 0x0075, ~0x0000, ' ', 2, "reset" }, + { 0x0070, ~0x0000, ' ', 2, "wdreset" }, + { 0x5C00, ~0x03FF, ' ', 2, "swapc %in, %n" }, + { 0x0006, ~0x0000, ' ', 2, "ldsptl" }, + { 0x0007, ~0x0000, ' ', 2, "ldspth" }, + { 0x007C, ~0x0000, ' ', 2, "mul" }, + + { 0x0500, ~0x00FF, ' ', 2, "ldtabl %m" }, + { 0x0501, ~0x00FF, ' ', 2, "ldtabh %m" }, + + { 0xFF00, ~0x0000, ' ', 2, "putchar" }, + + { 0, 0, 0, 0, NULL } +}; + + +/* glob.cc */ diff --git a/sim/ucsim/pdk.src/glob.h b/sim/ucsim/pdk.src/glob.h new file mode 100644 index 0000000..68745c6 --- /dev/null +++ b/sim/ucsim/pdk.src/glob.h @@ -0,0 +1,44 @@ +/* + * Simulator of microcontrollers (glob.h) + * + * Copyright (C) 1999,99 Drotos Daniel, Talker Bt. + * + * To contact author send email to drdani@mazsola.iit.uni-miskolc.hu + * + */ + +/* This file is part of microcontroller simulator: ucsim. + +UCSIM is free software; you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation; either version 2 of the License, or +(at your option) any later version. + +UCSIM is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU General Public License for more details. + +You should have received a copy of the GNU General Public License +along with UCSIM; see the file COPYING. If not, write to the Free +Software Foundation, 59 Temple Place - Suite 330, Boston, MA +02111-1307, USA. */ +/*@1@*/ + +#ifndef GLOB_HEADER +#define GLOB_HEADER + +#include "stypes.h" + + +extern struct dis_entry disass_pdk_13[]; + +extern struct dis_entry disass_pdk_14[]; + +extern struct dis_entry disass_pdk_15[]; + +/*extern struct dis_entry disass_pdk_16[];*/ + +#endif + +/* End of pdk.src/glob.h */ diff --git a/sim/ucsim/pdk.src/glob.o b/sim/ucsim/pdk.src/glob.o Binary files differnew file mode 100644 index 0000000..fca8ec1 --- /dev/null +++ b/sim/ucsim/pdk.src/glob.o diff --git a/sim/ucsim/pdk.src/inst.cc b/sim/ucsim/pdk.src/inst.cc new file mode 100644 index 0000000..522b6b5 --- /dev/null +++ b/sim/ucsim/pdk.src/inst.cc @@ -0,0 +1,1157 @@ +/* + * Simulator of microcontrollers (inst.cc) + */ +/* 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 <cassert> +#include "ddconfig.h" +#include "stdio.h" + +// local +#include "pdkcl.h" +#include "regspdk.h" + +#define CODE_MASK(op, m) ((code & ~(m)) == (op)) + +unsigned char cl_pdk::add_to(unsigned char initial, int value, bool carry) { + store_flag(flag_z, initial + value + carry == 0); + store_flag(flag_c, initial + value + carry > 0xFF); + store_flag(flag_ac, (initial & 0xF) + (value & 0xF) + carry > 0xF); + store_flag( + flag_ov, + get_flag(flag_c) ^ ((initial & 0x7F) + (value & 0x7F) + carry > 0x7F)); + + return initial + value + carry; +} + +unsigned char cl_pdk::sub_to(unsigned char initial, int value, bool carry) { + store_flag(flag_z, initial - value - carry == 0); + store_flag(flag_c, initial < value + carry); + store_flag(flag_ac, (value & 0xF) > (initial & 0xF) - carry); + store_flag( + flag_ov, + get_flag(flag_c) ^ ((initial & 0x7F) - (value & 0x7F) - carry < 0)); + + return initial - value - carry; +} + +int cl_pdk::get_mem(unsigned int addr) { + vc.rd++; + return ram->read((t_addr)(addr)); +} + +unsigned char cl_pdk::get_io(t_addr addr) { + return regs8->get(addr); +} + +void cl_pdk::store_io(t_addr addr, unsigned char value) { + regs8->set(addr, value); + if (get_SP() > sp_max) + sp_max = get_SP(); +} + +unsigned char cl_pdk::get_SP() { + return get_io(0x02); +} + +unsigned char cl_pdk::get_flags() { + return get_io(0x00); +} + +void cl_pdk::set_flags(unsigned char flags) { + return store_io(0x00, flags); +} + +int cl_pdk::get_flag(flag n) { + switch (n) { + case flag_z: return get_flags() & BIT_Z; + case flag_c: return (get_flags() & BIT_C) >> 1; + case flag_ac: return (get_flags() & BIT_AC) >> 2; + case flag_ov: return (get_flags() & BIT_OV) >> 3; + default: + assert(!"invalid bit access to FLAG"); + } + return 0; +} + +void cl_pdk::store_flag(flag n, int value) { + switch (n) { + case flag_z: set_flags((get_flags() & ~1) | value); break; + case flag_c: set_flags((get_flags() & ~2) | (value << 1)); break; + case flag_ac: set_flags((get_flags() & ~4) | (value << 2)); break; + case flag_ov: set_flags((get_flags() & ~8) | (value << 3)); break; + default: + assert(!"invalid bit store to FLAG"); + } +} + +int cl_pdk::execute(unsigned int code) { + switch (type->type) { + case CPU_PDK13: + return(execute_pdk13(code)); + case CPU_PDK14: + return(execute_pdk14(code)); + case CPU_PDK15: + return(execute_pdk15(code)); + default: + __builtin_unreachable(); + } +} + +int cl_pdk::execute_pdk14(unsigned int code) { + if (code == 0x0000) { + // nop + } else if (CODE_MASK(0x0200, 0xFF)) { + // ret k + regs.a = code & 0xFF; + store_io(0x2, get_SP() - 2); + PC = get_mem(get_SP()) | (get_mem(get_SP() + 1) << 8); + } else if (code == 0x007A) { + // ret + store_io(0x2, get_SP() - 2); + PC = get_mem(get_SP()) | (get_mem(get_SP() + 1) << 8); + } else if (CODE_MASK(0x2F00, 0xFF)) { + // mov a, k + regs.a = code & 0xFF; + } else if (CODE_MASK(0x0180, 0x3F)) { + // mov i, a + store_io(code & 0x3F, regs.a); + } else if (CODE_MASK(0x01C0, 0x3F)) { + // mov a, i + regs.a = get_io(code & 0x3F); + } else if (CODE_MASK(0x0B80, 0x7F)) { + // mov m, a + ram->write(code & 0x7F, regs.a); + } else if (CODE_MASK(0x0F80, 0x7F)) { + // mov a, m + regs.a = get_mem(code & 0x7F); + } else if (CODE_MASK(0x0301, 0x7E)) { + // TODO: ldt16 + } else if (CODE_MASK(0x0300, 0x7E)) { + // TODO: stt16 + } else if ((CODE_MASK(0x381, 0x7E))) { + // idxm a, m + regs.a = get_mem(get_mem(code & 0x7E)); + } else if ((CODE_MASK(0x380, 0x7E))) { + // idxm m, a + ram->write(get_mem(code & 0x7E), regs.a); + } else if (CODE_MASK(0x1380, 0x7F)) { + // xch m + int mem = get_mem(code & 0x7F); + ram->write(code & 0x7F, regs.a); + regs.a = mem; + } else if (code == 0x0072) { + // pushaf + ram->write(get_SP(), regs.a); + ram->write(get_SP() + 1, get_flags()); + store_io(0x2, get_SP() + 2); + } else if (code == 0x0073) { + // popaf + set_flags(get_mem(get_SP() - 1)); + regs.a = get_mem(get_SP() - 2); + store_io(0x2, get_SP() - 2); + } else if (CODE_MASK(0x2800, 0xFF)) { + // add a, k + regs.a = add_to(regs.a, code & 0xFF); + } else if (CODE_MASK(0x0C00, 0x7F)) { + // add a, m + regs.a = add_to(regs.a, get_mem(code & 0x7F)); + } else if (CODE_MASK(0x0800, 0x7F)) { + // add m, a + int addr = code & 0x7F; + ram->write(addr, add_to(regs.a, get_mem(addr))); + } else if (CODE_MASK(0x2900, 0xFF)) { + // sub a, k + regs.a = sub_to(regs.a, code & 0xFF); + } else if (CODE_MASK(0x0C80, 0x7F)) { + // sub a, m + regs.a = sub_to(regs.a, get_mem(code & 0x7F)); + } else if (CODE_MASK(0x0880, 0x7F)) { + // sub m, a + int addr = code & 0x7F; + ram->write(addr, sub_to(get_mem(addr), regs.a)); + } else if (CODE_MASK(0x0D00, 0x7F)) { + // addc a, m + regs.a = add_to(regs.a, get_mem(code & 0x7F), get_flag(flag_c)); + } else if (CODE_MASK(0x0900, 0x7F)) { + // addc m, a + int addr = code & 0x7F; + ram->write(addr, add_to(regs.a, get_mem(addr), get_flag(flag_c))); + } else if (code == 0x0060) { + // addc a + regs.a = add_to(regs.a, get_flag(flag_c)); + } else if (CODE_MASK(0x1000, 0x7F)) { + // addc m + int addr = code & 0x7F; + ram->write(addr, add_to(get_mem(addr), get_flag(flag_c))); + } else if (CODE_MASK(0x0D80, 0x7F)) { + // subc a, m + regs.a = sub_to(regs.a, get_mem(code & 0x7F), get_flag(flag_c)); + } else if (CODE_MASK(0x0980, 0x7F)) { + // subc m, a + int addr = code & 0x7F; + ram->write(addr, sub_to(get_mem(addr), regs.a, get_flag(flag_c))); + } else if (code == 0x0061) { + // subc a + regs.a = sub_to(regs.a, get_flag(flag_c)); + } else if (CODE_MASK(0x1080, 0x7F)) { + // subc m + int addr = code & 0x7F; + ram->write(addr, sub_to(get_mem(addr), get_flag(flag_c))); + } else if (CODE_MASK(0x1200, 0x7F)) { + // inc m + int addr = code & 0x7F; + ram->write(addr, add_to(get_mem(addr), 1)); + } else if (CODE_MASK(0x1280, 0x7F)) { + // dec m + int addr = code & 0x7F; + ram->write(addr, sub_to(get_mem(addr), 1)); + } else if (CODE_MASK(0x1300, 0x7F)) { + // clear m + ram->write(code & 0x7F, 0); + } else if (code == 0x006A) { + // sr a + store_flag(flag_c, regs.a & 1); + regs.a >>= 1; + } else if (CODE_MASK(0x1500, 0x7F)) { + // sr m + int value = get_mem(code & 0x7F); + store_flag(flag_c, value & 1); + ram->write(code & 0x7F, value >> 1); + } else if (code == 0x006B) { + // sl a + store_flag(flag_c, (regs.a & 0x80) >> 7); + regs.a <<= 1; + } else if (CODE_MASK(0x1580, 0x7F)) { + // sl m + int value = get_mem(code & 0x7F); + store_flag(flag_c, (value & 0x80) >> 7); + ram->write(code & 0x7F, value << 1); + } else if (code == 0x006C) { + // src a + int c = regs.a & 1; + regs.a >>= 1; + regs.a |= get_flag(flag_c) << 7; + store_flag(flag_c, c); + } else if (CODE_MASK(0x1600, 0x7F)) { + // src m + int value = get_mem(code & 0x7F); + int c = value & 1; + ram->write(code & 0x7F, (value >> 1) | (get_flag(flag_c) << 7)); + store_flag(flag_c, c); + } else if (code == 0x006D) { + // slc a + int c = (regs.a & 0x80) >> 7; + regs.a <<= 1; + regs.a |= get_flag(flag_c); + store_flag(flag_c, c); + } else if (CODE_MASK(0x1680, 0x7F)) { + // slc m + int value = get_mem(code & 0x7F); + int c = (value & 0x80) >> 7; + ram->write(code & 0x7F, (value << 1) | get_flag(flag_c)); + store_flag(flag_c, c); + } else if (CODE_MASK(0x2C00, 0xFF)) { + // and a, k + regs.a &= code & 0xFF; + store_flag(flag_z, !regs.a); + } else if (CODE_MASK(0x0E00, 0x7F)) { + // and a, m + regs.a &= get_mem(code & 0x7F); + store_flag(flag_z, !regs.a); + } else if (CODE_MASK(0x0A00, 0x7F)) { + // and m, a + int store = regs.a & get_mem(code & 0x7F); + store_flag(flag_z, !store); + ram->write(code & 0x7F, store); + } else if (CODE_MASK(0x2D00, 0xFF)) { + // or a, k + regs.a |= code & 0xFF; + store_flag(flag_z, !regs.a); + } else if (CODE_MASK(0x0E80, 0x7F)) { + // or a, m + regs.a |= get_mem(code & 0x7F); + store_flag(flag_z, !regs.a); + } else if (CODE_MASK(0x0A80, 0x7F)) { + // or m, a + int store = regs.a | get_mem(code & 0x7F); + store_flag(flag_z, !store); + ram->write(code & 0x7F, store); + } else if (CODE_MASK(0x2E00, 0xFF)) { + // xor a, k + regs.a ^= code & 0xFF; + store_flag(flag_z, !regs.a); + } else if (CODE_MASK(0x0F00, 0x7F)) { + // xor a, m + regs.a ^= get_mem(code & 0x7F); + store_flag(flag_z, !regs.a); + } else if (CODE_MASK(0x0B00, 0x7F)) { + // xor m, a + int store = regs.a ^ get_mem(code & 0x7F); + store_flag(flag_z, !store); + ram->write(code & 0x7F, store); + } else if (CODE_MASK(0x00C0, 0x3F)) { + // xor io, a + store_io(code & 0x3F, regs.a ^ get_io(code & 0x3F)); + } else if (code == 0x0068) { + // not a + regs.a = ~regs.a; + } else if (CODE_MASK(0x1400, 0x7F)) { + // not m + ram->write(code & 0x7F, ~get_mem(code & 0x7F)); + } else if (code == 0x0069) { + // neg a + regs.a = -regs.a; + } else if (CODE_MASK(0x1480, 0x7F)) { + // neg m + ram->write(code & 0x7F, -get_mem(code & 0x7F)); + } else if (CODE_MASK(0x1C00, 0x1FF)) { + // set0 io, k + const u8_t bit = (code & 0x1C0) >> 6; + const u8_t addr = code & 0x3F; + store_io(addr, get_io(addr) & ~(1 << bit)); + } else if (CODE_MASK(0x2400, 0x1FF)) { + // set0 m, k + const u8_t bit = (code & 0x1C0) >> 6; + const u8_t addr = code & 0x3F; + ram->write(addr, get_mem(addr) & ~(1 << bit)); + } else if (CODE_MASK(0x1E00, 0x1FF)) { + // set1 io, k + const u8_t bit = (code & 0x1C0) >> 6; + const u8_t addr = code & 0x3F; + store_io(addr, get_io(addr) | (1 << bit)); + } else if (CODE_MASK(0x2600, 0x1FF)) { + // set1 m, k + const u8_t bit = (code & 0x1C0) >> 6; + const u8_t addr = code & 0x3F; + ram->write(addr, get_mem(addr) | (1 << bit)); + } else if (CODE_MASK(0x1800, 0x1FF)) { + // t0sn io, k + int n = (code & 0x1C0) >> 6; + if (!(get_io(code & 0x3F) & (1 << n))) + ++PC; + } else if (CODE_MASK(0x2000, 0x1FF)) { + // t0sn m, k + int n = (code & 0x1C0) >> 6; + if (!(get_mem(code & 0x3F) & (1 << n))) + ++PC; + } else if (CODE_MASK(0x1A00, 0x1FF)) { + // t1sn io, k + int n = (code & 0x1C0) >> 6; + if (get_io(code & 0x3F) & (1 << n)) + ++PC; + } else if (CODE_MASK(0x2200, 0x1FF)) { + // t1sn m, k + int n = (code & 0x1C0) >> 6; + if (get_mem(code & 0x3F) & (1 << n)) + ++PC; + } else if (CODE_MASK(0x2A00, 0xFF)) { + // ceqsn a, k + sub_to(regs.a, code & 0xFF); + if (regs.a == (code & 0xFF)) + ++PC; + } else if (CODE_MASK(0x1700, 0x7F)) { + // ceqsn a, m + int addr = code & 0x7F; + sub_to(regs.a, get_mem(addr)); + if (regs.a == get_mem(addr)) + ++PC; + } else if (CODE_MASK(0x2B00, 0xFF)) { + // cneqsn a, k + sub_to(regs.a, code & 0xFF); + if (regs.a != (code & 0xFF)) + ++PC; + } else if (CODE_MASK(0x1780, 0x7F)) { + // cneqsn a, m + int addr = code & 0x7F; + sub_to(regs.a, get_mem(addr)); + if (regs.a != get_mem(addr)) + ++PC; + } else if (code == 0x0062) { + // izsn + regs.a = add_to(regs.a, 1); + if (!regs.a) + ++PC; + } else if (CODE_MASK(0x1100, 0x7F)) { + // izsn m + const int addr = code & 0x7F; + int result = add_to(get_mem(addr), 1); + ram->write(addr, result); + if (!result) + ++PC; + } else if (code == 0x0063) { + // dzsn + regs.a = sub_to(regs.a, 1); + if (!regs.a) + ++PC; + } else if (CODE_MASK(0x1180, 0x7F)) { + // dzsn m + const int addr = code & 0x7F; + int result = sub_to(get_mem(addr), 1); + ram->write(addr, result); + if (!result) + ++PC; + } else if (CODE_MASK(0x3800, 0x7FF)) { + // call k + ram->write(get_SP(), PC); + ram->write(get_SP() + 1, PC >> 8); + PC = code & 0x7FF; + store_io(0x2, get_SP() + 2); + } else if (CODE_MASK(0x3000, 0x7FF)) { + // goto k + PC = code & 0x7FF; + } else if (CODE_MASK(0x0600, 0x7F)) { + // comp a, m + sub_to(regs.a, get_mem(code & 0x7F)); + } else if (CODE_MASK(0x0680, 0x7F)) { + // comp m, a + sub_to(get_mem(code & 0x7F), regs.a); + } else if (CODE_MASK(0x0700, 0x7F)) { + // nadd a, m + regs.a = add_to(get_mem(code & 0x7F), -regs.a); + } else if (CODE_MASK(0x0780, 0x7F)) { + // nadd m, a + int addr = code & 0x7F; + ram->write(addr, add_to(-get_mem(addr), regs.a)); + } else if (code == 0x006E) { + // swap + int high = regs.a & 0xF; + regs.a = (high << 4) | (regs.a >> 4); + } else if (code == 0x0067) { + // pcadd + PC += regs.a - 1; + } + // TODO: engint + // TODO: disint + else if (code == 0x0076) { + // stopsys + return (resHALT); + } + // TODO: stopexe + // TODO: reset + // TODO: wdreset + // TODO: swapc IO, k + else if (code == 0x0006) { + // ldsptl + regs.a = rom->get(get_SP()) & 0xFF; + } else if (code == 0x0007) { + // ldspth + regs.a = (rom->get(get_SP()) & 0xFF00) >> 8; + } else if (code == 0x007C) { + // mul + unsigned result = regs.a * get_io(0x08); + regs.a = result & 0xFF; + store_io(0x08, (result & 0xFF00) >> 8); + } else if (code == 0xFF00) { + // putchar - usim specific instruction + putchar(regs.a); + fflush(stdout); + } else { + return (resINV_INST); + } + return (resGO); +} + +int cl_pdk::execute_pdk13(unsigned int code) { + if (code == 0x0000) { + // nop + } else if (CODE_MASK(0x0100, 0xFF)) { + // ret k + regs.a = code & 0xFF; + store_io(0x2, get_SP() - 2); + PC = get_mem(get_SP()) | (get_mem(get_SP() + 1) << 8); + } else if (code == 0x003A) { + // ret + store_io(0x2, get_SP() - 2); + PC = get_mem(get_SP()) | (get_mem(get_SP() + 1) << 8); + } else if (CODE_MASK(0x1700, 0xFF)) { + // mov a, k + regs.a = code & 0xFF; + } else if (CODE_MASK(0x0080, 0x1F)) { + // mov i, a + store_io(code & 0x1F, regs.a); + } else if (CODE_MASK(0x00A0, 0x1F)) { + // mov a, i + regs.a = get_io(code & 0x1F); + } else if (CODE_MASK(0x05C0, 0x3F)) { + // mov m, a + ram->write(code & 0x3F, regs.a); + } else if (CODE_MASK(0x07C0, 0x3F)) { + // mov a, m + regs.a = get_mem(code & 0x3F); + } else if (CODE_MASK(0x00C1, 0x1E)) { + // TODO: ldt16 + } else if (CODE_MASK(0x0C00, 0x1E)) { + // TODO: stt16 + } else if ((CODE_MASK(0x0E1, 0x1E))) { + // idxm a, m + regs.a = get_mem(get_mem(code & 0x1E)); + } else if ((CODE_MASK(0x0E0, 0x1E))) { + // idxm m, a + ram->write(get_mem(code & 0x1E), regs.a); + } else if (CODE_MASK(0x09C0, 0x3F)) { + // xch m + int mem = get_mem(code & 0x3F); + ram->write(code & 0x3F, regs.a); + regs.a = mem; + } else if (code == 0x0032) { + // pushaf + ram->write(get_SP(), regs.a); + ram->write(get_SP() + 1, get_flags()); + store_io(0x2, get_SP() + 2); + } else if (code == 0x0033) { + // popaf + set_flags(get_mem(get_SP() - 1)); + regs.a = get_mem(get_SP() - 2); + store_io(0x2, get_SP() - 2); + } else if (CODE_MASK(0x1000, 0xFF)) { + // add a, k + regs.a = add_to(regs.a, code & 0xFF); + } else if (CODE_MASK(0x0600, 0x3F)) { + // add a, m + regs.a = add_to(regs.a, get_mem(code & 0x3F)); + } else if (CODE_MASK(0x0400, 0x3F)) { + // add m, a + int addr = code & 0x3F; + ram->write(addr, add_to(regs.a, get_mem(addr))); + } else if (CODE_MASK(0x1100, 0xFF)) { + // sub a, k + regs.a = sub_to(regs.a, code & 0xFF); + } else if (CODE_MASK(0x0640, 0x3F)) { + // sub a, m + regs.a = sub_to(regs.a, get_mem(code & 0x3F)); + } else if (CODE_MASK(0x0440, 0x3F)) { + // sub m, a + int addr = code & 0x3F; + ram->write(addr, sub_to(get_mem(addr), regs.a)); + } else if (CODE_MASK(0x0680, 0x3F)) { + // addc a, m + regs.a = add_to(regs.a, get_mem(code & 0x3F), get_flag(flag_c)); + } else if (CODE_MASK(0x0480, 0x3F)) { + // addc m, a + int addr = code & 0x3F; + ram->write(addr, add_to(regs.a, get_mem(addr), get_flag(flag_c))); + } else if (code == 0x0010) { + // addc a + regs.a = add_to(regs.a, get_flag(flag_c)); + } else if (CODE_MASK(0x0800, 0x3F)) { + // addc m + int addr = code & 0x3F; + ram->write(addr, add_to(get_mem(addr), get_flag(flag_c))); + } else if (CODE_MASK(0x06C0, 0x3F)) { + // subc a, m + regs.a = sub_to(regs.a, get_mem(code & 0x3F), get_flag(flag_c)); + } else if (CODE_MASK(0x04C0, 0x3F)) { + // subc m, a + int addr = code & 0x3F; + ram->write(addr, sub_to(get_mem(addr), regs.a, get_flag(flag_c))); + } else if (code == 0x0011) { + // subc a + regs.a = sub_to(regs.a, get_flag(flag_c)); + } else if (CODE_MASK(0x0840, 0x3F)) { + // subc m + int addr = code & 0x3F; + ram->write(addr, sub_to(get_mem(addr), get_flag(flag_c))); + } else if (CODE_MASK(0x0900, 0x3F)) { + // inc m + int addr = code & 0x3F; + ram->write(addr, add_to(get_mem(addr), 1)); + } else if (CODE_MASK(0x0940, 0x3F)) { + // dec m + int addr = code & 0x3F; + ram->write(addr, sub_to(get_mem(addr), 1)); + } else if (CODE_MASK(0x0980, 0x3F)) { + // clear m + ram->write(code & 0x3F, 0); + } else if (code == 0x001A) { + // sr a + store_flag(flag_c, regs.a & 1); + regs.a >>= 1; + } else if (CODE_MASK(0x0A80, 0x3F)) { + // sr m + int value = get_mem(code & 0x3F); + store_flag(flag_c, value & 1); + ram->write(code & 0x3F, value >> 1); + } else if (code == 0x001B) { + // sl a + store_flag(flag_c, (regs.a & 0x80) >> 7); + regs.a <<= 1; + } else if (CODE_MASK(0x0AC0, 0x3F)) { + // sl m + int value = get_mem(code & 0x3F); + store_flag(flag_c, (value & 0x80) >> 7); + ram->write(code & 0x3F, value << 1); + } else if (code == 0x001C) { + // src a + int c = regs.a & 1; + regs.a >>= 1; + regs.a |= get_flag(flag_c) << 7; + store_flag(flag_c, c); + } else if (CODE_MASK(0x0B00, 0x3F)) { + // src m + int value = get_mem(code & 0x3F); + int c = value & 1; + ram->write(code & 0x3F, (value >> 1) | (get_flag(flag_c) << 7)); + store_flag(flag_c, c); + } else if (code == 0x001D) { + // slc a + int c = (regs.a & 0x80) >> 7; + regs.a <<= 1; + regs.a |= get_flag(flag_c); + store_flag(flag_c, c); + } else if (CODE_MASK(0x0B40, 0x3F)) { + // slc m + int value = get_mem(code & 0x3F); + int c = (value & 0x80) >> 7; + ram->write(code & 0x3F, (value << 1) | get_flag(flag_c)); + store_flag(flag_c, c); + } else if (CODE_MASK(0x1400, 0xFF)) { + // and a, k + regs.a &= code & 0xFF; + store_flag(flag_z, !regs.a); + } else if (CODE_MASK(0x0700, 0x3F)) { + // and a, m + regs.a &= get_mem(code & 0x3F); + store_flag(flag_z, !regs.a); + } else if (CODE_MASK(0x0500, 0x3F)) { + // and m, a + int store = regs.a & get_mem(code & 0x3F); + store_flag(flag_z, !store); + ram->write(code & 0x3F, store); + } else if (CODE_MASK(0x1500, 0xFF)) { + // or a, k + regs.a |= code & 0xFF; + store_flag(flag_z, !regs.a); + } else if (CODE_MASK(0x0740, 0x3F)) { + // or a, m + regs.a |= get_mem(code & 0x3F); + store_flag(flag_z, !regs.a); + } else if (CODE_MASK(0x0540, 0x3F)) { + // or m, a + int store = regs.a | get_mem(code & 0x3F); + store_flag(flag_z, !store); + ram->write(code & 0x3F, store); + } else if (CODE_MASK(0x1600, 0xFF)) { + // xor a, k + regs.a ^= code & 0xFF; + store_flag(flag_z, !regs.a); + } else if (CODE_MASK(0x0780, 0x3F)) { + // xor a, m + regs.a ^= get_mem(code & 0x3F); + store_flag(flag_z, !regs.a); + } else if (CODE_MASK(0x0580, 0x3F)) { + // xor m, a + int store = regs.a ^ get_mem(code & 0x3F); + store_flag(flag_z, !store); + ram->write(code & 0x3F, store); + } else if (CODE_MASK(0x0060, 0x1F)) { + // xor io, a + store_io(code & 0x1F, regs.a ^ get_io(code & 0x1F)); + } else if (code == 0x0018) { + // not a + regs.a = ~regs.a; + } else if (CODE_MASK(0x0A00, 0x3F)) { + // not m + ram->write(code & 0x3F, ~get_mem(code & 0x3F)); + } else if (code == 0x0019) { + // neg a + regs.a = -regs.a; + } else if (CODE_MASK(0x0A40, 0x3F)) { + // neg m + ram->write(code & 0x3F, -get_mem(code & 0x3F)); + } else if (CODE_MASK(0x0E00, 0xFF)) { + // set0 io, k + const u8_t bit = (code & 0xE0) >> 5; + const u8_t addr = code & 0x1F; + store_io(addr, get_io(addr) & ~(1 << bit)); + } else if (CODE_MASK(0x0300, 0xFE)) { + // set0 m, k + const u8_t bit = (code & 0xE0) >> 5; + const u8_t addr = (code & 0xFE) >> 1; + ram->write(addr, get_mem(addr) & ~(1 << bit)); + } else if (CODE_MASK(0x0F00, 0xFF)) { + // set1 io, k + const u8_t bit = (code & 0xE0) >> 5; + const u8_t addr = code & 0x1F; + store_io(addr, get_io(addr) | (1 << bit)); + } else if (CODE_MASK(0x0301, 0xFE)) { + // set1 m, k + const u8_t bit = (code & 0xE0) >> 5; + const u8_t addr = (code & 0x1E) >> 1; + ram->write(addr, get_mem(addr) | (1 << bit)); + } else if (CODE_MASK(0x0C00, 0xFF)) { + // t0sn io, k + int n = (code & 0xE0) >> 5; + if (!(get_io(code & 0x1F) & (1 << n))) + ++PC; + } else if (CODE_MASK(0x0200, 0xFE)) { + // t0sn m, k + int n = (code & 0xE0) >> 5; + if (!(get_mem((code & 0xFE) >> 1) & (1 << n))) + ++PC; + } else if (CODE_MASK(0x0D00, 0xFF)) { + // t1sn io, k + int n = (code & 0xE0) >> 5; + if (get_io(code & 0x1F) & (1 << n)) + ++PC; + } else if (CODE_MASK(0x0201, 0xFE)) { + // t1sn m, k + int n = (code & 0xE0) >> 5; + if (get_mem((code & 0xFE) >> 1) & (1 << n)) + ++PC; + } else if (CODE_MASK(0x1200, 0xFF)) { + // ceqsn a, k + sub_to(regs.a, code & 0xFF); + if (regs.a == (code & 0xFF)) + ++PC; + } else if (CODE_MASK(0x0B80, 0x3F)) { + // ceqsn a, m + int addr = code & 0x3F; + sub_to(regs.a, get_mem(addr)); + if (regs.a == get_mem(addr)) + ++PC; + } else if (code == 0x0012) { + // izsn + regs.a = add_to(regs.a, 1); + if (!regs.a) + ++PC; + } else if (CODE_MASK(0x0880, 0x3F)) { + // izsn m + const int addr = code & 0x3F; + int result = add_to(get_mem(addr), 1); + ram->write(addr, result); + if (!result) + ++PC; + } else if (code == 0x0013) { + // dzsn + regs.a = sub_to(regs.a, 1); + if (!regs.a) + ++PC; + } else if (CODE_MASK(0x08C0, 0x3F)) { + // dzsn m + const int addr = code & 0x3F; + int result = sub_to(get_mem(addr), 1); + ram->write(addr, result); + if (!result) + ++PC; + } else if (CODE_MASK(0x1C00, 0x3FF)) { + // call k + ram->write(get_SP(), PC); + ram->write(get_SP() + 1, PC >> 8); + PC = code & 0x3FF; + store_io(0x2, get_SP() + 2); + } else if (CODE_MASK(0x1800, 0x3FF)) { + // goto k + PC = code & 0x3FF; + } else if (code == 0x001E) { + // swap + int high = regs.a & 0xF; + regs.a = (high << 4) | (regs.a >> 4); + } else if (code == 0x0017) { + // pcadd + PC += regs.a - 1; + } + // TODO: engint + // TODO: disint + else if (code == 0x0036) { + // stopsys + return (resHALT); + } + // TODO: stopexe + // TODO: reset + // TODO: wdreset + // TODO: swapc IO, k + else if (code == 0x0006) { + // ldsptl + regs.a = rom->get(get_SP()) & 0xFF; + } else if (code == 0x0007) { + // ldregs[0x02]th + regs.a = (rom->get(get_SP()) & 0xFF00) >> 8; + } else if (code == 0x003C) { + // mul + unsigned result = regs.a * get_io(0x08); + regs.a = result & 0xFF; + store_io(0x08, (result & 0xFF00) >> 8); + } else if (code == 0xFF00) { + // putchar - usim specific instruction + putchar(regs.a); + fflush(stdout); + } else { + return (resINV_INST); + } + return (resGO); +} + +int cl_pdk::execute_pdk15(unsigned int code) { + if (code == 0x0000) { + // nop + } else if (CODE_MASK(0x0200, 0xFF)) { + // ret k + regs.a = code & 0xFF; + store_io(0x2, get_SP() - 2); + PC = get_mem(get_SP()) | (get_mem(get_SP() + 1) << 8); + } else if (code == 0x007A) { + // ret + store_io(0x2, get_SP() - 2); + PC = get_mem(get_SP()) | (get_mem(get_SP() + 1) << 8); + } else if (CODE_MASK(0x5700, 0xFF)) { + // mov a, k + regs.a = code & 0xFF; + } else if (CODE_MASK(0x0100, 0x7F)) { + // mov i, a + store_io(code & 0x7F, regs.a); + } else if (CODE_MASK(0x0180, 0x7F)) { + // mov a, i + regs.a = get_io(code & 0x7F); + } else if (CODE_MASK(0x1700, 0xFF)) { + // mov m, a + ram->write(code & 0xFF, regs.a); + } else if (CODE_MASK(0x1F00, 0xFF)) { + // mov a, m + regs.a = get_mem(code & 0xFF); + } else if (CODE_MASK(0x0601, 0xFE)) { + // TODO: ldt16 + } else if (CODE_MASK(0x0600, 0xFE)) { + // TODO: stt16 + } else if ((CODE_MASK(0x701, 0xFE))) { + // idxm a, m + regs.a = get_mem(get_mem(code & 0xFE)); + } else if ((CODE_MASK(0x700, 0xFE))) { + // idxm m, a + ram->write(get_mem(code & 0xFE), regs.a); + } else if (CODE_MASK(0x2700, 0xFF)) { + // xch m + int mem = get_mem(code & 0xFF); + ram->write(code & 0xFF, regs.a); + regs.a = mem; + } else if (code == 0x0072) { + // pushaf + ram->write(get_SP(), regs.a); + ram->write(get_SP() + 1, get_flags()); + store_io(0x2, get_SP() + 2); + } else if (code == 0x0073) { + // popaf + set_flags(get_mem(get_SP() - 1)); + regs.a = get_mem(get_SP() - 2); + store_io(0x2, get_SP() - 2); + } else if (CODE_MASK(0x5000, 0xFF)) { + // add a, k + regs.a = add_to(regs.a, code & 0xFF); + } else if (CODE_MASK(0x1800, 0xFF)) { + // add a, m + regs.a = add_to(regs.a, get_mem(code & 0xFF)); + } else if (CODE_MASK(0x1000, 0xFF)) { + // add m, a + int addr = code & 0xFF; + ram->write(addr, add_to(regs.a, get_mem(addr))); + } else if (CODE_MASK(0x5100, 0xFF)) { + // sub a, k + regs.a = sub_to(regs.a, code & 0xFF); + } else if (CODE_MASK(0x1900, 0xFF)) { + // sub a, m + regs.a = sub_to(regs.a, get_mem(code & 0xFF)); + } else if (CODE_MASK(0x1100, 0xFF)) { + // sub m, a + int addr = code & 0xFF; + ram->write(addr, sub_to(get_mem(addr), regs.a)); + } else if (CODE_MASK(0x1A00, 0xFF)) { + // addc a, m + regs.a = add_to(regs.a, get_mem(code & 0xFF), get_flag(flag_c)); + } else if (CODE_MASK(0x1200, 0xFF)) { + // addc m, a + int addr = code & 0xFF; + ram->write(addr, add_to(regs.a, get_mem(addr), get_flag(flag_c))); + } else if (code == 0x0060) { + // addc a + regs.a = add_to(regs.a, get_flag(flag_c)); + } else if (CODE_MASK(0x2000, 0xFF)) { + // addc m + int addr = code & 0xFF; + ram->write(addr, add_to(get_mem(addr), get_flag(flag_c))); + } else if (CODE_MASK(0x1B00, 0xFF)) { + // subc a, m + regs.a = sub_to(regs.a, get_mem(code & 0xFF), get_flag(flag_c)); + } else if (CODE_MASK(0x1300, 0xFF)) { + // subc m, a + int addr = code & 0xFF; + ram->write(addr, sub_to(get_mem(addr), regs.a, get_flag(flag_c))); + } else if (code == 0x0061) { + // subc a + regs.a = sub_to(regs.a, get_flag(flag_c)); + } else if (CODE_MASK(0x2100, 0xFF)) { + // subc m + int addr = code & 0xFF; + ram->write(addr, sub_to(get_mem(addr), get_flag(flag_c))); + } else if (CODE_MASK(0x2400, 0xFF)) { + // inc m + int addr = code & 0xFF; + ram->write(addr, add_to(get_mem(addr), 1)); + } else if (CODE_MASK(0x2500, 0xFF)) { + // dec m + int addr = code & 0xFF; + ram->write(addr, sub_to(get_mem(addr), 1)); + } else if (CODE_MASK(0x2600, 0xFF)) { + // clear m + ram->write(code & 0xFF, 0); + } else if (code == 0x006A) { + // sr a + store_flag(flag_c, regs.a & 1); + regs.a >>= 1; + } else if (CODE_MASK(0x2A00, 0xFF)) { + // sr m + int value = get_mem(code & 0xFF); + store_flag(flag_c, value & 1); + ram->write(code & 0xFF, value >> 1); + } else if (code == 0x006B) { + // sl a + store_flag(flag_c, (regs.a & 0x80) >> 7); + regs.a <<= 1; + } else if (CODE_MASK(0x2B00, 0xFF)) { + // sl m + int value = get_mem(code & 0xFF); + store_flag(flag_c, (value & 0x80) >> 7); + ram->write(code & 0xFF, value << 1); + } else if (code == 0x006C) { + // src a + int c = regs.a & 1; + regs.a >>= 1; + regs.a |= get_flag(flag_c) << 7; + store_flag(flag_c, c); + } else if (CODE_MASK(0x2C00, 0xFF)) { + // src m + int value = get_mem(code & 0xFF); + int c = value & 1; + ram->write(code & 0xFF, (value >> 1) | (get_flag(flag_c) << 7)); + store_flag(flag_c, c); + } else if (code == 0x006D) { + // slc a + int c = (regs.a & 0x80) >> 7; + regs.a <<= 1; + regs.a |= get_flag(flag_c); + store_flag(flag_c, c); + } else if (CODE_MASK(0x2D00, 0xFF)) { + // slc m + int value = get_mem(code & 0xFF); + int c = (value & 0x80) >> 7; + ram->write(code & 0xFF, (value << 1) | get_flag(flag_c)); + store_flag(flag_c, c); + } else if (CODE_MASK(0x5400, 0xFF)) { + // and a, k + regs.a &= code & 0xFF; + store_flag(flag_z, !regs.a); + } else if (CODE_MASK(0x1C00, 0xFF)) { + // and a, m + regs.a &= get_mem(code & 0xFF); + store_flag(flag_z, !regs.a); + } else if (CODE_MASK(0x1400, 0xFF)) { + // and m, a + int store = regs.a & get_mem(code & 0xFF); + store_flag(flag_z, !store); + ram->write(code & 0xFF, store); + } else if (CODE_MASK(0x5500, 0xFF)) { + // or a, k + regs.a |= code & 0xFF; + store_flag(flag_z, !regs.a); + } else if (CODE_MASK(0x1D00, 0xFF)) { + // or a, m + regs.a |= get_mem(code & 0xFF); + store_flag(flag_z, !regs.a); + } else if (CODE_MASK(0x1500, 0xFF)) { + // or m, a + int store = regs.a | get_mem(code & 0xFF); + store_flag(flag_z, !store); + ram->write(code & 0xFF, store); + } else if (CODE_MASK(0x5600, 0xFF)) { + // xor a, k + regs.a ^= code & 0xFF; + store_flag(flag_z, !regs.a); + } else if (CODE_MASK(0x1E00, 0xFF)) { + // xor a, m + regs.a ^= get_mem(code & 0xFF); + store_flag(flag_z, !regs.a); + } else if (CODE_MASK(0x1600, 0xFF)) { + // xor m, a + int store = regs.a ^ get_mem(code & 0xFF); + store_flag(flag_z, !store); + ram->write(code & 0xFF, store); + } else if (CODE_MASK(0x0080, 0x7F)) { + // xor io, a + store_io(code & 0x3F, regs.a ^ get_io(code & 0x3F)); + } else if (code == 0x0068) { + // not a + regs.a = ~regs.a; + } else if (CODE_MASK(0x2800, 0xFF)) { + // not m + ram->write(code & 0xFF, ~get_mem(code & 0xFF)); + } else if (code == 0x0069) { + // neg a + regs.a = -regs.a; + } else if (CODE_MASK(0x2900, 0xFF)) { + // neg m + ram->write(code & 0xFF, -get_mem(code & 0xFF)); + } else if (CODE_MASK(0x3800, 0x3FF)) { + // set0 io, k + const u8_t bit = (code & 0x380) >> 7; + const u8_t addr = code & 0x7F; + store_io(addr, get_io(addr) & ~(1 << bit)); + } else if (CODE_MASK(0x4800, 0x3FF)) { + // set0 m, k + const u8_t bit = (code & 0x380) >> 7; + const u8_t addr = code & 0x7F; + ram->write(addr, get_mem(addr) & ~(1 << bit)); + } else if (CODE_MASK(0x3C00, 0x3FF)) { + // set1 io, k + const u8_t bit = (code & 0x380) >> 7; + const u8_t addr = code & 0x7F; + store_io(addr, get_io(addr) | (1 << bit)); + } else if (CODE_MASK(0x4C00, 0x3FF)) { + // set1 m, k + const u8_t bit = (code & 0x380) >> 7; + const u8_t addr = code & 0x7F; + ram->write(addr, get_mem(addr) | (1 << bit)); + } else if (CODE_MASK(0x3000, 0x3FF)) { + // t0sn io, k + int n = (code & 0x380) >> 7; + if (!(get_io(code & 0x7F) & (1 << n))) + ++PC; + } else if (CODE_MASK(0x4000, 0x3FF)) { + // t0sn m, k + int n = (code & 0x380) >> 7; + if (!(get_mem(code & 0x7F) & (1 << n))) + ++PC; + } else if (CODE_MASK(0x3400, 0x3FF)) { + // t1sn io, k + int n = (code & 0x380) >> 7; + if (get_io(code & 0x7F) & (1 << n)) + ++PC; + } else if (CODE_MASK(0x4400, 0x3FF)) { + // t1sn m, k + int n = (code & 0x380) >> 7; + if (get_mem(code & 0x7F) & (1 << n)) + ++PC; + } else if (CODE_MASK(0x5200, 0xFF)) { + // ceqsn a, k + sub_to(regs.a, code & 0xFF); + if (regs.a == (code & 0xFF)) + ++PC; + } else if (CODE_MASK(0x2E00, 0xFF)) { + // ceqsn a, m + int addr = code & 0xFF; + sub_to(regs.a, get_mem(addr)); + if (regs.a == get_mem(addr)) + ++PC; + } else if (CODE_MASK(0x5300, 0xFF)) { + // cneqsn a, k + sub_to(regs.a, code & 0xFF); + if (regs.a != (code & 0xFF)) + ++PC; + } else if (CODE_MASK(0x2F00, 0xFF)) { + // cneqsn a, m + int addr = code & 0xFF; + sub_to(regs.a, get_mem(addr)); + if (regs.a != get_mem(addr)) + ++PC; + } else if (code == 0x0062) { + // izsn + regs.a = add_to(regs.a, 1); + if (!regs.a) + ++PC; + } else if (CODE_MASK(0x2200, 0xFF)) { + // izsn m + const int addr = code & 0xFF; + int result = add_to(get_mem(addr), 1); + ram->write(addr, result); + if (!result) + ++PC; + } else if (code == 0x0063) { + // dzsn + regs.a = sub_to(regs.a, 1); + if (!regs.a) + ++PC; + } else if (CODE_MASK(0x2300, 0xFF)) { + // dzsn m + const int addr = code & 0xFF; + int result = sub_to(get_mem(addr), 1); + ram->write(addr, result); + if (!result) + ++PC; + } else if (CODE_MASK(0x7000, 0xFFF)) { + // call k + ram->write(get_SP(), PC); + ram->write(get_SP() + 1, PC >> 8); + PC = code & 0xFFF; + store_io(0x2, get_SP() + 2); + } else if (CODE_MASK(0x6000, 0xFFF)) { + // goto k + PC = code & 0xFFF; + } else if (CODE_MASK(0x0C00, 0xFF)) { + // comp a, m + sub_to(regs.a, get_mem(code & 0xFF)); + } else if (CODE_MASK(0x0D00, 0xFF)) { + // comp m, a + sub_to(get_mem(code & 0xFF), regs.a); + } else if (CODE_MASK(0x0E00, 0xFF)) { + // nadd a, m + regs.a = add_to(get_mem(code & 0xFF), -regs.a); + } else if (CODE_MASK(0x0F00, 0xFF)) { + // nadd m, a + int addr = code & 0xFF; + ram->write(addr, add_to(-get_mem(addr), regs.a)); + } else if (code == 0x006E) { + // swap + int high = regs.a & 0xF; + regs.a = (high << 4) | (regs.a >> 4); + } else if (code == 0x0067) { + // pcadd + PC += regs.a - 1; + } + // TODO: engint + // TODO: disint + else if (code == 0x0076) { + // stopsys + return (resHALT); + } + // TODO: stopexe + // TODO: reset + // TODO: wdreset + // TODO: swapc IO, k + else if (code == 0x0006) { + // ldsptl + regs.a = rom->get(get_SP()) & 0xFF; + } else if (code == 0x0007) { + // ldspth + regs.a = (rom->get(get_SP()) & 0xFF00) >> 8; + } else if (code == 0x007C) { + // mul + unsigned result = regs.a * get_io(0x08); + regs.a = result & 0xFF; + store_io(0x08, (result & 0xFF00) >> 8); + } else if (code == 0xFF00) { + // putchar - usim specific instruction + putchar(regs.a); + fflush(stdout); + } else { + return (resINV_INST); + } + return (resGO); +} + +/* End of pdk.src/inst.cc */ +/* End of pdk.src/inst.cc */ diff --git a/sim/ucsim/pdk.src/inst.o b/sim/ucsim/pdk.src/inst.o Binary files differnew file mode 100644 index 0000000..cd60cc8 --- /dev/null +++ b/sim/ucsim/pdk.src/inst.o diff --git a/sim/ucsim/pdk.src/instcl.h b/sim/ucsim/pdk.src/instcl.h new file mode 100644 index 0000000..054c2fb --- /dev/null +++ b/sim/ucsim/pdk.src/instcl.h @@ -0,0 +1,26 @@ +/* pdk.src/instcl.h */ + +int get_mem(unsigned int addr); +unsigned char add_to(unsigned char initial, int value, bool carry = false); +unsigned char sub_to(unsigned char initial, int value, bool carry = false); +unsigned char get_io(t_addr addr); +void store_io(t_addr addr, unsigned char value); +unsigned char get_SP(); +unsigned char get_flags(); +void set_flags(unsigned char flags); + +enum flag { + flag_z, + flag_c, + flag_ac, + flag_ov, +}; +int get_flag(flag n); +void store_flag(flag n, int value); + +int execute(unsigned int code); +int execute_pdk13(unsigned int code); +int execute_pdk14(unsigned int code); +int execute_pdk15(unsigned int code); + +/* End of pdk.src/instcl.h */ diff --git a/sim/ucsim/pdk.src/pdk.cc b/sim/ucsim/pdk.src/pdk.cc new file mode 100644 index 0000000..52a6541 --- /dev/null +++ b/sim/ucsim/pdk.src/pdk.cc @@ -0,0 +1,415 @@ +/* + * Simulator of microcontrollers (pdk.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 <stdarg.h> /* for va_list */ +#include <cassert> +#include <stdio.h> +#include <stdlib.h> +#include "i_string.h" + +// prj +#include "globals.h" +#include "pobjcl.h" + +// sim +#include "simcl.h" + +// local +#include "glob.h" +#include "pdkcl.h" +#include "portcl.h" +#include "regspdk.h" + +/*******************************************************************/ + +/* + * Base type of PDK controllers + */ + +cl_pdk::cl_pdk(struct cpu_entry *IType, class cl_sim *asim) : cl_uc(asim) { + type = IType; +} + +int cl_pdk::init(void) { + cl_uc::init(); /* Memories now exist */ + + xtal = 8000000; + sp_max = 0x00; + + // rom = address_space(MEM_ROM_ID); + // ram = mem(MEM_XRAM); + // ram = rom; + + // zero out ram(this is assumed in regression tests) + // for (int i = 0x0; i < 0x8000; i++) { + // ram->set((t_addr)i, 0); + // } + + return (0); +} + +void cl_pdk::reset(void) { + cl_uc::reset(); + + PC = 0x0000; + regs.a = 0; + for (size_t i = 0; i < io_size; ++i) { + store_io(i, 0); + } +} + +char *cl_pdk::id_string(void) { + switch (type->type) { + case CPU_PDK13: + return((char *)"pdk13"); + case CPU_PDK14: + return((char *)"pdk14"); + case CPU_PDK15: + return((char *)"pdk15"); + default: + return((char*)"unknown pdk"); + } +} + +/* + * Making elements of the controller + */ +/* +t_addr +cl_pdk::get_mem_size(enum mem_class type) +{ + switch(type) + { + case MEM_ROM: return(0x10000); + case MEM_XRAM: return(0x10000); + default: return(0); + } + return(cl_uc::get_mem_size(type)); +} +*/ + +void cl_pdk::mk_hw_elements(void) { + // TODO: Add hardware stuff here. + cl_uc::mk_hw_elements(); +} + +class cl_memory_chip *c; + +void cl_pdk::make_memories(void) { + class cl_address_space *as; + + int rom_storage, ram_storage; + switch (type->type) { + case CPU_PDK13: + rom_storage = 0x400; + ram_storage = 0x40; + break; + case CPU_PDK14: + rom_storage = 0x800; + ram_storage = 0x80; + break; + case CPU_PDK15: + rom_storage = 0x1000; + ram_storage = 0x100; + break; + default: + __builtin_unreachable(); + } + rom = as = new cl_address_space("rom", 0, rom_storage, 16); + as->init(); + address_spaces->add(as); + ram = as = new cl_address_space("ram", 0, ram_storage, 8); + as->init(); + address_spaces->add(as); + regs8 = as = new cl_address_space("regs8", 0, io_size + 1, 8); + as->init(); + address_spaces->add(as); + + { + class cl_address_decoder *ad; + class cl_memory_chip *chip; + + chip = new cl_memory_chip("rom_chip", rom_storage, 16); + chip->init(); + memchips->add(chip); + + ad = new cl_address_decoder(as = address_space("rom"), chip, 0, rom_storage, 0); + ad->init(); + as->decoders->add(ad); + ad->activate(0); + } + { + // extra byte of the IO memory will point to the A register just for the debugger + regs8->get_cell(io_size)->decode(&(regs._a)); + } + + class cl_var *v; + vars->add(v = new cl_var(cchars("flag"), regs8, 0, "")); + v->init(); + vars->add(v = new cl_var(cchars("sp"), regs8, 1, "")); + v->init(); +} + +/* + * Help command interpreter + */ + +struct dis_entry *cl_pdk::dis_tbl(void) { + switch (type->type) { + case CPU_PDK13: + return (disass_pdk_13); + case CPU_PDK14: + return (disass_pdk_14); + case CPU_PDK15: + return (disass_pdk_15); + default: + __builtin_unreachable(); + } +} + +/*struct name_entry * +cl_pdk::sfr_tbl(void) +{ + return(0); +}*/ + +/*struct name_entry * +cl_pdk::bit_tbl(void) +{ + //FIXME + return(0); +}*/ + +int cl_pdk::inst_length(t_addr /*addr*/) { + return 1; +} +int cl_pdk::inst_branch(t_addr addr) { + int b; + + get_disasm_info(addr, NULL, &b, NULL, NULL); + + return b; +} + +bool cl_pdk::is_call(t_addr addr) { + struct dis_entry *e; + + get_disasm_info(addr, NULL, NULL, NULL, &e); + + return e ? (e->is_call) : false; +} + +int cl_pdk::longest_inst(void) { return 1; } + +const char *cl_pdk::get_disasm_info(t_addr addr, int *ret_len, int *ret_branch, + int *immed_offset, + struct dis_entry **dentry) { + const char *b = NULL; + int immed_n = 0; + int start_addr = addr; + struct dis_entry *instructions; + + switch (type->type) { + /* Dispatch to appropriate pdk port. */ + case CPU_PDK13: + instructions = disass_pdk_13; + break; + + case CPU_PDK14: + instructions = disass_pdk_14; + break; + + case CPU_PDK15: + instructions = disass_pdk_15; + break; + + default: + __builtin_unreachable(); + } + + uint code = rom->get(addr++); + int i = 0; + while ((code & instructions[i].mask) != instructions[i].code && + instructions[i].mnemonic) + i++; + dis_entry *dis_e = &instructions[i]; + b = instructions[i].mnemonic; + + if (ret_branch) { + *ret_branch = dis_e->branch; + } + + if (immed_offset) { + if (immed_n > 0) + *immed_offset = immed_n; + else + *immed_offset = (addr - start_addr); + } + + if (ret_len) *ret_len = 1; + + if (dentry) *dentry = dis_e; + + return b; +} + +char *cl_pdk::disass(t_addr addr, const char *sep) { + char work[256], temp[20]; + const char *b; + char *buf, *p, *t; + int len = 0; + int immed_offset = 0; + struct dis_entry *dis_e; + + p = work; + + b = get_disasm_info(addr, &len, NULL, &immed_offset, &dis_e); + + if (b == NULL) { + buf = (char *)malloc(30); + strcpy(buf, "UNKNOWN/INVALID"); + return (buf); + } + + while (*b) { + if (*b == '%') { + b++; + uint code = rom->get(addr) & ~(uint)dis_e->mask; + switch (*(b++)) { + case 'k': // k immediate addressing + sprintf(temp, "#%u", code); + break; + case 'm': // m memory addressing + if (*b == 'n') { + code &= 0x3F; + ++b; + } + sprintf(temp, "%u", code); + break; + case 'i': // i IO addressing + // TODO: Maybe add pretty printing. + if (*b == 'n') { + switch (type->type) { + case CPU_PDK13: + code &= 0x1F; + break; + case CPU_PDK14: + code &= 0x3F; + break; + case CPU_PDK15: + code &= 0x7F; + break; + default: + __builtin_unreachable(); + } + + ++b; + } + sprintf(temp, "[%u]", code); + break; + case 'n': // n N-bit addressing + uint n; + switch (type->type) { + case CPU_PDK13: + n = (code & 0xE0) >> 5; + break; + case CPU_PDK14: + n = (code & 0x1C0) >> 6; + break; + case CPU_PDK15: + n = (code & 0x380) >> 7; + break; + default: + __builtin_unreachable(); + } + sprintf(temp, "#%u", n); + break; + default: + strcpy(temp, "%?"); + break; + } + t = temp; + while (*t) *(p++) = *(t++); + } else + *(p++) = *(b++); + } + *p = '\0'; + + p = strchr(work, ' '); + if (!p) { + buf = strdup(work); + return (buf); + } + if (sep == NULL) + buf = (char *)malloc(6 + strlen(p) + 1); + else + buf = (char *)malloc((p - work) + strlen(sep) + strlen(p) + 1); + for (p = work, t = buf; *p != ' '; p++, t++) *t = *p; + p++; + *t = '\0'; + if (sep == NULL) { + while (strlen(buf) < 6) strcat(buf, " "); + } else + strcat(buf, sep); + strcat(buf, p); + return (buf); +} + +void cl_pdk::print_regs(class cl_console_base *con) { + con->dd_printf("A= 0x%02x(%3d)\n", regs.a, regs.a); + con->dd_printf("Flag= 0x%02x(%3d) \n", get_flags(), get_flags()); + con->dd_printf("SP= 0x%02x(%3d)\n", get_SP(), get_SP()); + + print_disass(PC, con); +} + +/* + * Execution + */ + +int cl_pdk::exec_inst(void) { + t_mem code; + + if (fetch(&code)) { + return (resBREAKPOINT); + } + tick(1); + + int status = execute(code); + if (status == resINV_INST) { + PC = rom->inc_address(PC, -1); + + sim->stop(resINV_INST); + return (resINV_INST); + } + return (status); +} + +/* End of pdk.src/pdk.cc */ diff --git a/sim/ucsim/pdk.src/pdk.o b/sim/ucsim/pdk.src/pdk.o Binary files differnew file mode 100644 index 0000000..bf8852b --- /dev/null +++ b/sim/ucsim/pdk.src/pdk.o diff --git a/sim/ucsim/pdk.src/pdkcl.h b/sim/ucsim/pdk.src/pdkcl.h new file mode 100644 index 0000000..9bf21a2 --- /dev/null +++ b/sim/ucsim/pdk.src/pdkcl.h @@ -0,0 +1,97 @@ +/* + * Simulator of microcontrollers (pdkcl.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 PDKCL_HEADER +#define PDKCL_HEADER + +#include "uccl.h" +#include "itsrccl.h" + +#include "regspdk.h" + + +/* + * Base type of STM8 microcontrollers + */ + +class cl_pdk: public cl_uc +{ +public: + class cl_memory *ram; + class cl_memory *rom; + class cl_address_space *regs8; + union t_regs regs; +public: + cl_pdk(struct cpu_entry *IType, class cl_sim *asim); + virtual int init(void); + virtual char *id_string(void); + + //virtual t_addr get_mem_size(enum mem_class type); + //virtual void mk_port(t_addr base, chars n); + virtual void mk_hw_elements(void); + virtual void make_memories(void); + + virtual struct dis_entry *dis_tbl(void); + virtual int inst_length(t_addr addr); + virtual int inst_branch(t_addr addr); + virtual int longest_inst(void); + virtual char *disass(t_addr addr, const char *sep); + virtual void print_regs(class cl_console_base *con); + + virtual int exec_inst(void); + + virtual const char *get_disasm_info(t_addr addr, + int *ret_len, + int *ret_branch, + int *immed_offset, + struct dis_entry **dentry); + virtual bool is_call(t_addr addr); + + virtual void reset(void); + +#include "instcl.h" +}; + + +class cl_pdk_cpu: public cl_hw +{ + protected: + class cl_memory_cell *regs[11]; + public: + cl_pdk_cpu(class cl_uc *auc); + virtual int init(void); + virtual int cfg_size(void) { return 2; } + + virtual void write(class cl_memory_cell *cell, t_mem *val); + virtual t_mem read(class cl_memory_cell *cell); + virtual t_mem conf_op(cl_memory_cell *cell, t_addr addr, t_mem *val); +}; + + +#endif + +/* End of pdk.src/pdkcl.h */ diff --git a/sim/ucsim/pdk.src/port.cc b/sim/ucsim/pdk.src/port.cc new file mode 100644 index 0000000..44019a8 --- /dev/null +++ b/sim/ucsim/pdk.src/port.cc @@ -0,0 +1,130 @@ +/* + * Simulator of microcontrollers (pdk.src/port.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 "portcl.h" + +cl_port::cl_port(class cl_uc *auc, t_addr abase/*, int aid*/, const char *aname): + cl_hw(auc, HW_PORT, /*aid*/0, aname) +{ + base = abase; + set_name(aname); +} + +int +cl_port::init(void) +{ + cl_hw::init(); + // ODR + cell_p= register_cell(uc->rom, base + 0); + // IDR + cell_in= register_cell(uc->rom, base + 1); + // DDR: 0=input, 1=output + cell_dir= register_cell(uc->rom, base + 2); + + cl_var *v; + chars pn= cchars(get_name()); + uc->vars->add(v= new cl_var(pn+chars("_ddr"), uc->rom, base+2, + "Direction register")); + v->init(); + uc->vars->add(v= new cl_var(pn+chars("_odr"), uc->rom, base+0, + "Output data register")); + v->init(); + uc->vars->add(v= new cl_var(pn+chars("_idr"), uc->rom, base+1, + "Input data register (outside value of port pins)")); + v->init(); + uc->vars->add(v= new cl_var(pn+chars("_pin"), uc->rom, base+1, + "Outside value of port pins")); + v->init(); + uc->vars->add(v= new cl_var(pn+chars("_pins"), uc->rom, base+1, + "Outside value of port pins")); + v->init(); + + return 0; +} + +void +cl_port::reset(void) +{ + cell_dir->write(0); + cell_p->write(0); + cell_in->write(0); +} + +void +cl_port::write(class cl_memory_cell *cell, t_mem *val) +{ + if ((cell == cell_p) || + (cell == cell_in) || + (cell == cell_dir)) + { + cell->set(*val); + t_mem p= cell_p->get(); + t_mem i= cell_in->get(); + t_mem d= cell_dir->get(); + i&= ~d; + i|= (p & d); + cell_in->set(i); + if (cell == cell_in) + *val= i; + } +} + +void +cl_port::print_info(class cl_console_base *con) +{ + int m; + t_mem o= cell_p->get(), + i= cell_in->get(), + d= cell_dir->get(); + con->dd_printf("%s at 0x%04x\n", get_name(), base); + con->dd_printf("dir: 0x%02x ", d); + for (m= 0x80; m; m>>= 1) + con->dd_printf("%c", (d & m)?'O':'I'); + con->dd_printf("\n"); + con->dd_printf("out: 0x%02x ", o); + for (m= 0x80; m; m>>= 1) + { + if (d & m) + con->dd_printf("%c", (o & m)?'1':'0'); + else + con->dd_printf("-"); + } + con->dd_printf("\n"); + con->dd_printf("in : 0x%02x ", i); + for (m= 0x80; m; m>>= 1) + { + //if (!(d & m)) + con->dd_printf("%c", (i & m)?'1':'0'); + //else + //con->dd_printf("-"); + } + con->dd_printf("\n"); + print_cfg_info(con); +} + + +/* End of pdk.src/port.cc */ diff --git a/sim/ucsim/pdk.src/port.o b/sim/ucsim/pdk.src/port.o Binary files differnew file mode 100644 index 0000000..c27ad76 --- /dev/null +++ b/sim/ucsim/pdk.src/port.o diff --git a/sim/ucsim/pdk.src/portcl.h b/sim/ucsim/pdk.src/portcl.h new file mode 100644 index 0000000..8b0c309 --- /dev/null +++ b/sim/ucsim/pdk.src/portcl.h @@ -0,0 +1,52 @@ +/* + * Simulator of microcontrollers (pdk.src/portcl.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 PORTCL_HEADER +#define PORTCL_HEADER + +#include "port_hwcl.h" + + +class cl_port: public cl_hw +{ + public: + class cl_memory_cell *cell_p, *cell_in, *cell_dir; + t_addr base; + public: + cl_port(class cl_uc *auc, t_addr abase/*, int aid*/, const char *aname); + virtual int init(void); + virtual void reset(void); + + virtual void write(class cl_memory_cell *cell, t_mem *val); + + virtual void print_info(class cl_console_base *con); +}; + + +#endif + +/* End of pdk.src/portcl.h */ diff --git a/sim/ucsim/pdk.src/regspdk.h b/sim/ucsim/pdk.src/regspdk.h new file mode 100644 index 0000000..41d0e6d --- /dev/null +++ b/sim/ucsim/pdk.src/regspdk.h @@ -0,0 +1,55 @@ +/* + * Simulator of microcontrollers (regspdk.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 REGPDK_HEADER +#define REGPDK_HEADER + +#include "ddconfig.h" + + +const int io_size = 64; +union t_regs +{ + u8_t a; + + t_mem _a; +}; + +#define BIT_Z 0x01 // zero status, 1=zero, 0=nonzero +#define BIT_C 0x02 // carry status(addition and subtraction) +#define BIT_AC 0x04 // sign, 1=negative, 0=positive (or zero) +#define BIT_OV 0x08 // signed overflow, 1=overflow, 0=no overflow +#define BIT_ALL (BIT_Z | BIT_C | BIT_AC | BIT_OV) // all bits + +#define BITPOS_Z 0 // 1 +#define BITPOS_C 1 // 2H +#define BITPOS_AC 2 // 4H +#define BITPOS_OV 3 // 8H + +#endif + +/* End of pdk.src/regspdk.h */ diff --git a/sim/ucsim/pdk.src/simpdk.cc b/sim/ucsim/pdk.src/simpdk.cc new file mode 100644 index 0000000..58ad48a --- /dev/null +++ b/sim/ucsim/pdk.src/simpdk.cc @@ -0,0 +1,75 @@ +/* + * Simulator of microcontrollers (simpdk.cc) + * + * Copyright (C) 1999,99 Drotos Daniel, Talker Bt. + * + * To contact author send email to drdani@mazsola.iit.uni-miskolc.hu + * + */ + +/* This file is part of microcontroller simulator: ucsim. + +UCSIM is free software; you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation; either version 2 of the License, or +(at your option) any later version. + +UCSIM is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU General Public License for more details. + +You should have received a copy of the GNU General Public License +along with UCSIM; see the file COPYING. If not, write to the Free +Software Foundation, 59 Temple Place - Suite 330, Boston, MA +02111-1307, USA. */ +/*@1@*/ + +// prj +#include "globals.h" + +// local +#include "simpdkcl.h" +#include "pdkcl.h" + + +cl_simpdk::cl_simpdk(class cl_app *the_app): + cl_sim(the_app) +{} + +class cl_uc * +cl_simpdk::mk_controller(void) +{ + int i; + char *typ= 0; + class cl_optref type_option(this); + + type_option.init(); + type_option.use(cchars("cpu_type")); + i= 0; + if ((typ= type_option.get_value(typ)) == 0) + typ= cchars("PDK14"); + while ((cpus_pdk[i].type_str != NULL) && + (strcasecmp(typ, cpus_pdk[i].type_str) != 0)) + i++; + if (cpus_pdk[i].type_str == NULL) + { + fprintf(stderr, "Unknown processor type. " + "Use -H option to see known types.\n"); + return(NULL); + } + switch (cpus_pdk[i].type) + { + case CPU_PDK13: + case CPU_PDK14: + case CPU_PDK15: + return(new cl_pdk(&cpus_pdk[i], this)); + default: + fprintf(stderr, "Unknown processor type\n"); + return NULL; + } + return NULL; +} + + +/* End of pdk.src/simpdk.cc */ diff --git a/sim/ucsim/pdk.src/simpdk.o b/sim/ucsim/pdk.src/simpdk.o Binary files differnew file mode 100644 index 0000000..52ba1ea --- /dev/null +++ b/sim/ucsim/pdk.src/simpdk.o diff --git a/sim/ucsim/pdk.src/simpdkcl.h b/sim/ucsim/pdk.src/simpdkcl.h new file mode 100644 index 0000000..b89490e --- /dev/null +++ b/sim/ucsim/pdk.src/simpdkcl.h @@ -0,0 +1,45 @@ +/* + * Simulator of microcontrollers (simpdkcl.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 SIMSTM8CL_HEADER +#define SIMSTM8CL_HEADER + +#include "simcl.h" + + +class cl_simpdk: public cl_sim +{ +public: + cl_simpdk(class cl_app *the_app); + + virtual class cl_uc *mk_controller(void); +}; + + +#endif + +/* End of pdk.src/simpdkcl.h */ diff --git a/sim/ucsim/pdk.src/spdk b/sim/ucsim/pdk.src/spdk Binary files differnew file mode 100755 index 0000000..15ec910 --- /dev/null +++ b/sim/ucsim/pdk.src/spdk diff --git a/sim/ucsim/pdk.src/spdk.cc b/sim/ucsim/pdk.src/spdk.cc new file mode 100644 index 0000000..c4e76a6 --- /dev/null +++ b/sim/ucsim/pdk.src/spdk.cc @@ -0,0 +1,57 @@ +/* + * Simulator of microcontrollers (spdk.cc) + * + * Copyright (C) 1999,99 Drotos Daniel, Talker Bt. + * + * To contact author send email to drdani@mazsola.iit.uni-miskolc.hu + * + */ + +/* This file is part of microcontroller simulator: ucsim. + +UCSIM is free software; you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation; either version 2 of the License, or +(at your option) any later version. + +UCSIM is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU General Public License for more details. + +You should have received a copy of the GNU General Public License +along with UCSIM; see the file COPYING. If not, write to the Free +Software Foundation, 59 Temple Place - Suite 330, Boston, MA +02111-1307, USA. */ +/*@1@*/ + +// prj +#include "globals.h" + +// sim.src +#include "appcl.h" + +// local +#include "simpdkcl.h" + + +int +main(int argc, char *argv[]) +{ + class cl_sim *sim; + + cpus= cpus_pdk; + application= new cl_app(); + application->init(argc, argv); + sim= new cl_simpdk(application); + if (sim->init()) + sim->state|= SIM_QUIT; + application->set_simulator(sim); + application->run(); + application->done(); + delete application; + return(0); +} + + +/* End of pdk.src/spdk.cc */ diff --git a/sim/ucsim/pdk.src/spdk.o b/sim/ucsim/pdk.src/spdk.o Binary files differnew file mode 100644 index 0000000..b3891b3 --- /dev/null +++ b/sim/ucsim/pdk.src/spdk.o |
