From 5f4c7aeda2b5672d87d0805103a394b62e3904c2 Mon Sep 17 00:00:00 2001 From: epetrich Date: Wed, 15 Oct 2003 05:14:36 +0000 Subject: [PATCH] Initial import git-svn-id: https://sdcc.svn.sourceforge.net/svnroot/sdcc/trunk/sdcc@2940 4a8a32a2-be11-0410-ad9d-d568d2c75423 --- sim/ucsim/hc08.src/(c).1 | 25 + sim/ucsim/hc08.src/Makefile.in | 144 ++++ sim/ucsim/hc08.src/clean.mk | 26 + sim/ucsim/hc08.src/conf.mk | 10 + sim/ucsim/hc08.src/glob.cc | 380 +++++++++++ sim/ucsim/hc08.src/glob.h | 41 ++ sim/ucsim/hc08.src/hc08.cc | 582 ++++++++++++++++ sim/ucsim/hc08.src/hc08cl.h | 75 +++ sim/ucsim/hc08.src/hc08mac.h | 46 ++ sim/ucsim/hc08.src/inst.cc | 1154 ++++++++++++++++++++++++++++++++ sim/ucsim/hc08.src/instcl.h | 61 ++ sim/ucsim/hc08.src/regshc08.h | 80 +++ sim/ucsim/hc08.src/shc08.cc | 54 ++ sim/ucsim/hc08.src/simhc08.cc | 45 ++ sim/ucsim/hc08.src/simhc08cl.h | 45 ++ 15 files changed, 2768 insertions(+) create mode 100644 sim/ucsim/hc08.src/(c).1 create mode 100644 sim/ucsim/hc08.src/Makefile.in create mode 100644 sim/ucsim/hc08.src/clean.mk create mode 100644 sim/ucsim/hc08.src/conf.mk create mode 100644 sim/ucsim/hc08.src/glob.cc create mode 100644 sim/ucsim/hc08.src/glob.h create mode 100644 sim/ucsim/hc08.src/hc08.cc create mode 100644 sim/ucsim/hc08.src/hc08cl.h create mode 100644 sim/ucsim/hc08.src/hc08mac.h create mode 100644 sim/ucsim/hc08.src/inst.cc create mode 100644 sim/ucsim/hc08.src/instcl.h create mode 100644 sim/ucsim/hc08.src/regshc08.h create mode 100644 sim/ucsim/hc08.src/shc08.cc create mode 100644 sim/ucsim/hc08.src/simhc08.cc create mode 100644 sim/ucsim/hc08.src/simhc08cl.h diff --git a/sim/ucsim/hc08.src/(c).1 b/sim/ucsim/hc08.src/(c).1 new file mode 100644 index 00000000..d673f9fd --- /dev/null +++ b/sim/ucsim/hc08.src/(c).1 @@ -0,0 +1,25 @@ +/* + * Simulator of microcontrollers (@@F@@) + * + * Copyright (C) @@S@@,@@Y@@ Drotos Daniel, Talker Bt. + * + * To contact author send email to drdani@mazsola.iit.uni-miskolc.hu + * + */ + +/* This file is part of microcontroller simulator: ucsim. + +UCSIM is free software; you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation; either version 2 of the License, or +(at your option) any later version. + +UCSIM is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU General Public License for more details. + +You should have received a copy of the GNU General Public License +along with UCSIM; see the file COPYING. If not, write to the Free +Software Foundation, 59 Temple Place - Suite 330, Boston, MA +02111-1307, USA. */ diff --git a/sim/ucsim/hc08.src/Makefile.in b/sim/ucsim/hc08.src/Makefile.in new file mode 100644 index 00000000..3759862a --- /dev/null +++ b/sim/ucsim/hc08.src/Makefile.in @@ -0,0 +1,144 @@ +# +# uCsim hc08.src/Makefile +# +# (c) Drotos Daniel, Talker Bt. 1997 +# + +STARTYEAR = 1997 + +SHELL = /bin/sh +CXX = @CXX@ +CPP = @CPP@ +CXXCPP = @CXXCPP@ +RANLIB = @RANLIB@ +INSTALL = @INSTALL@ + +PRJDIR = .. + +DEFS = $(subs -DHAVE_CONFIG_H,,@DEFS@) +CPPFLAGS = @CPPFLAGS@ -I. -I$(PRJDIR) \ + -I$(PRJDIR)/cmd.src -I$(PRJDIR)/sim.src -I$(PRJDIR)/gui.src +CFLAGS = @CFLAGS@ -Wall +CXXFLAGS = @CXXFLAGS@ -Wall +M_OR_MM = @M_OR_MM@ +PICOPT = @PICOPT@ +SHAREDLIB = @SHAREDLIB@ + +EXEEXT = @EXEEXT@ + +LIBS = @LIBS@ -L$(PRJDIR) -lutil -lsim -lutil -lcmd -lguiucsim +DL = @DL@ +dl_ok = @dl_ok@ + +prefix = @prefix@ +exec_prefix = @exec_prefix@ +bindir = @bindir@ +libdir = @libdir@ +datadir = @datadir@ +includedir = @includedir@ +mandir = @mandir@ +man1dir = $(mandir)/man1 +man2dir = $(mandir)/man2 +infodir = @infodir@ +srcdir = @srcdir@ + +OBJECTS_SHARED = glob.o \ + inst.o \ + simhc08.o hc08.o +OBJECTS_EXE = shc08.o +OBJECTS = $(OBJECTS_SHARED) $(OBJECTS_EXE) + +HC08ASM = + +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 hc08.src tests + +tests: $(TEST_OBJ) + + +# Compiling and installing everything and runing test +# --------------------------------------------------- +install: all installdirs + $(INSTALL) -s shc08$(EXEEXT) $(bindir) + + +# Deleting all the installed files +# -------------------------------- +uninstall: + rm -f $(bindir)/shc08$(EXEEXT) + + +# Performing self-test +# -------------------- +check: test + +test: + + +# Performing installation test +# ---------------------------- +installcheck: + + +# Creating installation directories +# --------------------------------- +installdirs: + test -d $(bindir) || $(INSTALL) -d $(bindir) + + +# Creating dependencies +# --------------------- +dep: Makefile.dep + +Makefile.dep: *.cc *.h + $(CXXCPP) $(CPPFLAGS) $(M_OR_MM) *.cc >Makefile.dep + +include Makefile.dep +include clean.mk + +# My rules +# -------- +.SUFFIXES: .asm .hex + +hc08.src: shc08$(EXEEXT) shared_lib + +shc08$(EXEEXT): $(OBJECTS) $(PRJDIR)/*.a + $(CXX) $(CXXFLAGS) -o $@ $(OBJECTS) $(LIBS) + +ifeq ($(dlso_ok),yes) +shared_lib: $(PRJDIR)/shc08.so +else +shared_lib: + @$(PRJDIR)/mkecho $(PRJDIR) "No hc08 shared lib made." + @$(PRJDIR)/mkecho $(PRJDIR) "(SHAREDLIB="$(SHAREDLIB)",dl_ok="$(dl_ok)",enable_dlso="$(enable_dlso)")" +endif + +$(PRJDIR)/shc08.so: $(OBJECTS_SHARED) + $(CXX) -shared $(OBJECTS_SHARED) -o $(PRJDIR)/shc08.so + +otherlibs: + cd $(PRJDIR)/cmd.src && $(MAKE) all + cd $(PRJDIR)/sim.src && $(MAKE) all + +.cc.o: + $(CXX) $(CXXFLAGS) $(CPPFLAGS) $(TARGET_ARCH) -c $< -o $@ + +.asm.hex: + $(HC08ASM) -l $< -o $@ -e $<.lst + + +# Remaking configuration +# ---------------------- +checkconf: + @if [ -f $(PRJDIR)/devel ]; then\ + $(MAKE) -f conf.mk srcdir="$(srcdir)" PRJDIR="$(PRJDIR)" freshconf;\ + fi + +# End of hc08.src/Makefile.in diff --git a/sim/ucsim/hc08.src/clean.mk b/sim/ucsim/hc08.src/clean.mk new file mode 100644 index 00000000..f5708793 --- /dev/null +++ b/sim/ucsim/hc08.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 shc08$(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 hc08.src/clean.mk diff --git a/sim/ucsim/hc08.src/conf.mk b/sim/ucsim/hc08.src/conf.mk new file mode 100644 index 00000000..9ab5ebc6 --- /dev/null +++ b/sim/ucsim/hc08.src/conf.mk @@ -0,0 +1,10 @@ +# +# Makefile targets to remake configuration +# + +freshconf: Makefile + +Makefile: $(srcdir)/Makefile.in $(PRJDIR)/configure.in + cd $(PRJDIR) && $(SHELL) ./config.status + +# End of hc08.src/conf.mk diff --git a/sim/ucsim/hc08.src/glob.cc b/sim/ucsim/hc08.src/glob.cc new file mode 100644 index 00000000..7ed501c6 --- /dev/null +++ b/sim/ucsim/hc08.src/glob.cc @@ -0,0 +1,380 @@ +/* + * 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 + +#include "stypes.h" + + +/* +%d - direct addressing +%x - extended addressing +%p - pc relative addressing +%b - unsigned byte immediate addressing +%w - unsigned word immediate addressing +%s - signed byte immediate +%1 - unsigned byte index offset +%2 - unsigned word index offset +*/ + +/* uint code, mask; char branch; uchar length; char *mnemonic; */ +struct dis_entry disass_hc08[]= { + { 0x0000, 0x00ff, 'R', 3, "brset #0,%d,%p" }, + { 0x0001, 0x00ff, 'R', 3, "brclr #0,%d,%p" }, + { 0x0002, 0x00ff, 'R', 3, "brset #1,%d,%p" }, + { 0x0003, 0x00ff, 'R', 3, "brclr #1,%d,%p" }, + { 0x0004, 0x00ff, 'R', 3, "brset #2,%d,%p" }, + { 0x0005, 0x00ff, 'R', 3, "brclr #2,%d,%p" }, + { 0x0006, 0x00ff, 'R', 3, "brset #3,%d,%p" }, + { 0x0007, 0x00ff, 'R', 3, "brclr #3,%d,%p" }, + { 0x0008, 0x00ff, 'R', 3, "brset #4,%d,%p" }, + { 0x0009, 0x00ff, 'R', 3, "brclr #4,%d,%p" }, + { 0x000a, 0x00ff, 'R', 3, "brset #5,%d,%p" }, + { 0x000b, 0x00ff, 'R', 3, "brclr #5,%d,%p" }, + { 0x000c, 0x00ff, 'R', 3, "brset #6,%d,%p" }, + { 0x000d, 0x00ff, 'R', 3, "brclr #6,%d,%p" }, + { 0x000e, 0x00ff, 'R', 3, "brset #7,%d,%p" }, + { 0x000f, 0x00ff, 'R', 3, "brclr #7,%d,%p" }, + + { 0x0010, 0x00ff, ' ', 2, "bset #0,%d" }, + { 0x0011, 0x00ff, ' ', 2, "bclr #0,%d" }, + { 0x0012, 0x00ff, ' ', 2, "bset #1,%d" }, + { 0x0013, 0x00ff, ' ', 2, "bclr #1,%d" }, + { 0x0014, 0x00ff, ' ', 2, "bset #2,%d" }, + { 0x0015, 0x00ff, ' ', 2, "bclr #2,%d" }, + { 0x0016, 0x00ff, ' ', 2, "bset #3,%d" }, + { 0x0017, 0x00ff, ' ', 2, "bclr #3,%d" }, + { 0x0018, 0x00ff, ' ', 2, "bset #4,%d" }, + { 0x0019, 0x00ff, ' ', 2, "bclr #4,%d" }, + { 0x001a, 0x00ff, ' ', 2, "bset #5,%d" }, + { 0x001b, 0x00ff, ' ', 2, "bclr #5,%d" }, + { 0x001c, 0x00ff, ' ', 2, "bset #6,%d" }, + { 0x001d, 0x00ff, ' ', 2, "bclr #6,%d" }, + { 0x001e, 0x00ff, ' ', 2, "bset #7,%d" }, + { 0x001f, 0x00ff, ' ', 2, "bclr #7,%d" }, + + { 0x0020, 0x00ff, 'R', 2, "bra %p" }, + { 0x0021, 0x00ff, 'R', 2, "brn %p" }, + { 0x0022, 0x00ff, 'R', 2, "bhi %p" }, + { 0x0023, 0x00ff, 'R', 2, "bls %p" }, + { 0x0024, 0x00ff, 'R', 2, "bcc %p" }, + { 0x0025, 0x00ff, 'R', 2, "bcs %p" }, + { 0x0026, 0x00ff, 'R', 2, "bne %p" }, + { 0x0027, 0x00ff, 'R', 2, "beq %p" }, + { 0x0028, 0x00ff, 'R', 2, "bhcc %p" }, + { 0x0029, 0x00ff, 'R', 2, "bhcs %p" }, + { 0x002a, 0x00ff, 'R', 2, "bpl %p" }, + { 0x002b, 0x00ff, 'R', 2, "bmi %p" }, + { 0x002c, 0x00ff, 'R', 2, "bmc %p" }, + { 0x002d, 0x00ff, 'R', 2, "bms %p" }, + { 0x002e, 0x00ff, 'R', 2, "bil %p" }, + { 0x002f, 0x00ff, 'R', 2, "bih %p" }, + + { 0x0030, 0x00ff, ' ', 2, "neg %d" }, + { 0x0031, 0x00ff, 'R', 3, "cbeq %d,%p" }, + { 0x0033, 0x00ff, ' ', 2, "com %d" }, + { 0x0034, 0x00ff, ' ', 2, "lsr %d" }, + { 0x0035, 0x00ff, ' ', 2, "sthx %d" }, + { 0x0036, 0x00ff, ' ', 2, "ror %d" }, + { 0x0037, 0x00ff, ' ', 2, "asr %d" }, + { 0x0038, 0x00ff, ' ', 2, "lsl %d" }, + { 0x0039, 0x00ff, ' ', 2, "rol %d" }, + { 0x003a, 0x00ff, ' ', 2, "dec %d" }, + { 0x003b, 0x00ff, 'R', 3, "dbnz %d,%d" }, + { 0x003c, 0x00ff, ' ', 2, "inc %d" }, + { 0x003d, 0x00ff, ' ', 2, "tst %d" }, + { 0x003f, 0x00ff, ' ', 2, "clr %d" }, + + { 0x0040, 0x00ff, ' ', 1, "nega" }, + { 0x0041, 0x00ff, 'R', 3, "cbeqa %b,%p" }, + { 0x0042, 0x00ff, ' ', 1, "mul" }, + { 0x0043, 0x00ff, ' ', 1, "coma" }, + { 0x0044, 0x00ff, ' ', 1, "lsra" }, + { 0x0045, 0x00ff, ' ', 3, "ldhx %w" }, + { 0x0046, 0x00ff, ' ', 1, "rora" }, + { 0x0047, 0x00ff, ' ', 1, "asra" }, + { 0x0048, 0x00ff, ' ', 1, "lsla" }, + { 0x0049, 0x00ff, ' ', 1, "rola" }, + { 0x004a, 0x00ff, ' ', 1, "deca" }, + { 0x004b, 0x00ff, 'R', 2, "dbnza %p" }, + { 0x004c, 0x00ff, ' ', 1, "inca" }, + { 0x004d, 0x00ff, ' ', 1, "tsta" }, + { 0x004e, 0x00ff, ' ', 3, "mov %d,%d" }, + { 0x004f, 0x00ff, ' ', 1, "clra" }, + + { 0x0050, 0x00ff, ' ', 1, "negx" }, + { 0x0051, 0x00ff, 'R', 3, "cbeqx %b,%p" }, + { 0x0052, 0x00ff, ' ', 1, "div" }, + { 0x0053, 0x00ff, ' ', 1, "comx" }, + { 0x0054, 0x00ff, ' ', 1, "lsrx" }, + { 0x0055, 0x00ff, ' ', 2, "ldhx %d" }, + { 0x0056, 0x00ff, ' ', 1, "rorx" }, + { 0x0057, 0x00ff, ' ', 1, "asrx" }, + { 0x0058, 0x00ff, ' ', 1, "lslx" }, + { 0x0059, 0x00ff, ' ', 1, "rolx" }, + { 0x005a, 0x00ff, ' ', 1, "decx" }, + { 0x005b, 0x00ff, 'R', 2, "dbnzx %p" }, + { 0x005c, 0x00ff, ' ', 1, "incx" }, + { 0x005d, 0x00ff, ' ', 1, "tstx" }, + { 0x005e, 0x00ff, ' ', 3, "mov %d,x+" }, + { 0x005f, 0x00ff, ' ', 1, "clrx" }, + + { 0x0060, 0x00ff, ' ', 2, "neg %1,x" }, + { 0x0061, 0x00ff, 'R', 3, "cbeq %1,x+,%p" }, + { 0x0062, 0x00ff, ' ', 1, "nsa" }, + { 0x0063, 0x00ff, ' ', 2, "com %1,x" }, + { 0x0064, 0x00ff, ' ', 2, "lsr %1,x" }, + { 0x0065, 0x00ff, ' ', 3, "cphx %w" }, + { 0x0066, 0x00ff, ' ', 2, "ror %1,x" }, + { 0x0067, 0x00ff, ' ', 2, "asr %1,x" }, + { 0x0068, 0x00ff, ' ', 2, "lsl %1,x" }, + { 0x0069, 0x00ff, ' ', 2, "rol %1,x" }, + { 0x006a, 0x00ff, ' ', 2, "dec %1,x" }, + { 0x006b, 0x00ff, 'R', 2, "dbnz %1,x,%p" }, + { 0x006c, 0x00ff, ' ', 2, "inc %1,x" }, + { 0x006d, 0x00ff, ' ', 2, "tst %1,x" }, + { 0x006e, 0x00ff, ' ', 3, "mov %b,%d" }, + { 0x006f, 0x00ff, ' ', 2, "clr %1,x" }, + +/* + { 0x0070, 0x00ff, ' ', 2, "neg %b,sp" }, + { 0x0071, 0x00ff, 'R', 3, "cbeq %b,sp,%d" }, + { 0x0073, 0x00ff, ' ', 2, "com %b,sp" }, + { 0x0074, 0x00ff, ' ', 2, "lsr %b,sp" }, + { 0x0076, 0x00ff, ' ', 2, "ror %b,sp" }, + { 0x0077, 0x00ff, ' ', 2, "asr %b,sp" }, + { 0x0078, 0x00ff, ' ', 2, "lsl %b,sp" }, + { 0x0079, 0x00ff, ' ', 2, "rol %b,sp" }, + { 0x007a, 0x00ff, ' ', 2, "dec %b,sp" }, + { 0x007b, 0x00ff, 'R', 2, "dbnz %b,sp,%d" }, + { 0x007c, 0x00ff, ' ', 2, "inc %b,sp" }, + { 0x007d, 0x00ff, ' ', 2, "tst %b,sp" }, + { 0x007f, 0x00ff, ' ', 2, "clr %b,sp" }, +*/ + + { 0x0070, 0x00ff, ' ', 1, "neg ,x" }, + { 0x0071, 0x00ff, 'R', 2, "cbeq ,x+,%p" }, + { 0x0072, 0x00ff, ' ', 1, "daa" }, + { 0x0073, 0x00ff, ' ', 1, "com ,x" }, + { 0x0074, 0x00ff, ' ', 1, "lsr ,x" }, + { 0x0075, 0x00ff, ' ', 2, "cphx %d" }, + { 0x0076, 0x00ff, ' ', 1, "ror ,x" }, + { 0x0077, 0x00ff, ' ', 1, "asr ,x" }, + { 0x0078, 0x00ff, ' ', 1, "lsl ,x" }, + { 0x0079, 0x00ff, ' ', 1, "rol ,x" }, + { 0x007a, 0x00ff, ' ', 1, "dec ,x" }, + { 0x007b, 0x00ff, 'R', 2, "dbnz ,x,%p" }, + { 0x007c, 0x00ff, ' ', 1, "inc ,x" }, + { 0x007d, 0x00ff, ' ', 1, "tst ,x" }, + { 0x007e, 0x00ff, ' ', 2, "mov ,x+,%d" }, + { 0x007f, 0x00ff, ' ', 1, "clr ,x" }, + + { 0x0080, 0x00ff, ' ', 1, "rti" }, + { 0x0081, 0x00ff, ' ', 1, "rts" }, + { 0x0083, 0x00ff, ' ', 1, "swi" }, + { 0x0084, 0x00ff, ' ', 1, "tap" }, + { 0x0085, 0x00ff, ' ', 1, "tpa" }, + { 0x0086, 0x00ff, ' ', 1, "pula" }, + { 0x0087, 0x00ff, ' ', 1, "psha" }, + { 0x0088, 0x00ff, ' ', 1, "pulx" }, + { 0x0089, 0x00ff, ' ', 1, "pshx" }, + { 0x008a, 0x00ff, ' ', 1, "pulh" }, + { 0x008b, 0x00ff, ' ', 1, "pshh" }, + { 0x008c, 0x00ff, ' ', 1, "clrh" }, + { 0x008e, 0x00ff, ' ', 1, "stop" }, + { 0x008f, 0x00ff, ' ', 1, "wait" }, + + { 0x0090, 0x00ff, 'R', 2, "bge %p" }, + { 0x0091, 0x00ff, 'R', 2, "blt %p" }, + { 0x0092, 0x00ff, 'R', 2, "bgt %p" }, + { 0x0093, 0x00ff, 'R', 2, "ble %p" }, + { 0x0094, 0x00ff, ' ', 1, "txs" }, + { 0x0095, 0x00ff, ' ', 1, "tsx" }, + { 0x0097, 0x00ff, ' ', 1, "tax" }, + { 0x0098, 0x00ff, ' ', 1, "clc" }, + { 0x0099, 0x00ff, ' ', 1, "sec" }, + { 0x009a, 0x00ff, ' ', 1, "cli" }, + { 0x009b, 0x00ff, ' ', 1, "sei" }, + { 0x009c, 0x00ff, ' ', 1, "rsp" }, + { 0x009d, 0x00ff, ' ', 1, "nop" }, + { 0x009f, 0x00ff, ' ', 1, "txa" }, + + { 0x00a0, 0x00ff, ' ', 2, "sub %b" }, + { 0x00a1, 0x00ff, ' ', 2, "cmp %b" }, + { 0x00a2, 0x00ff, ' ', 2, "sbc %b" }, + { 0x00a3, 0x00ff, ' ', 2, "cpx %b" }, + { 0x00a4, 0x00ff, ' ', 2, "and %b" }, + { 0x00a5, 0x00ff, ' ', 2, "bit %b" }, + { 0x00a6, 0x00ff, ' ', 2, "lda %b" }, + { 0x00a7, 0x00ff, ' ', 2, "ais %s" }, + { 0x00a8, 0x00ff, ' ', 2, "eor %b" }, + { 0x00a9, 0x00ff, ' ', 2, "adc %b" }, + { 0x00aa, 0x00ff, ' ', 2, "ora %b" }, + { 0x00ab, 0x00ff, ' ', 2, "add %b" }, + { 0x00ad, 0x00ff, 'R', 2, "bsr %d" }, + { 0x00ae, 0x00ff, ' ', 2, "ldx %b" }, + { 0x00af, 0x00ff, ' ', 2, "aix %s" }, + + { 0x00b0, 0x00ff, ' ', 2, "sub %d" }, + { 0x00b1, 0x00ff, ' ', 2, "cmp %d" }, + { 0x00b2, 0x00ff, ' ', 2, "sbc %d" }, + { 0x00b3, 0x00ff, ' ', 2, "cpx %d" }, + { 0x00b4, 0x00ff, ' ', 2, "and %d" }, + { 0x00b5, 0x00ff, ' ', 2, "bit %d" }, + { 0x00b6, 0x00ff, ' ', 2, "lda %d" }, + { 0x00b7, 0x00ff, ' ', 2, "sta %d" }, + { 0x00b8, 0x00ff, ' ', 2, "eor %d" }, + { 0x00b9, 0x00ff, ' ', 2, "adc %d" }, + { 0x00ba, 0x00ff, ' ', 2, "ora %d" }, + { 0x00bb, 0x00ff, ' ', 2, "add %d" }, + { 0x00bc, 0x00ff, 'A', 2, "jmp %d" }, + { 0x00bd, 0x00ff, 'A', 2, "jsr %d" }, + { 0x00be, 0x00ff, ' ', 2, "ldx %d" }, + { 0x00bf, 0x00ff, ' ', 2, "stx %d" }, + + { 0x00c0, 0x00ff, ' ', 3, "sub %x" }, + { 0x00c1, 0x00ff, ' ', 3, "cmp %x" }, + { 0x00c2, 0x00ff, ' ', 3, "sbc %x" }, + { 0x00c3, 0x00ff, ' ', 3, "cpx %x" }, + { 0x00c4, 0x00ff, ' ', 3, "and %x" }, + { 0x00c5, 0x00ff, ' ', 3, "bit %x" }, + { 0x00c6, 0x00ff, ' ', 3, "lda %x" }, + { 0x00c7, 0x00ff, ' ', 3, "sta %x" }, + { 0x00c8, 0x00ff, ' ', 3, "eor %x" }, + { 0x00c9, 0x00ff, ' ', 3, "adc %x" }, + { 0x00ca, 0x00ff, ' ', 3, "ora %x" }, + { 0x00cb, 0x00ff, ' ', 3, "add %x" }, + { 0x00cc, 0x00ff, 'A', 3, "jmp %x" }, + { 0x00cd, 0x00ff, 'A', 3, "jsr %x" }, + { 0x00ce, 0x00ff, ' ', 3, "ldx %x" }, + { 0x00cf, 0x00ff, ' ', 3, "stx %x" }, + + { 0x00d0, 0x00ff, ' ', 3, "sub %2,x" }, + { 0x00d1, 0x00ff, ' ', 3, "cmp %2,x" }, + { 0x00d2, 0x00ff, ' ', 3, "sbc %2,x" }, + { 0x00d3, 0x00ff, ' ', 3, "cpx %2,x" }, + { 0x00d4, 0x00ff, ' ', 3, "and %2,x" }, + { 0x00d5, 0x00ff, ' ', 3, "bit %2,x" }, + { 0x00d6, 0x00ff, ' ', 3, "lda %2,x" }, + { 0x00d7, 0x00ff, ' ', 3, "sta %2,x" }, + { 0x00d8, 0x00ff, ' ', 3, "eor %2,x" }, + { 0x00d9, 0x00ff, ' ', 3, "adc %2,x" }, + { 0x00da, 0x00ff, ' ', 3, "ora %2,x" }, + { 0x00db, 0x00ff, ' ', 3, "add %2,x" }, + { 0x00dc, 0x00ff, ' ', 3, "jmp %2,x" }, + { 0x00dd, 0x00ff, ' ', 3, "jsr %2,x" }, + { 0x00de, 0x00ff, ' ', 3, "ldx %2,x" }, + { 0x00df, 0x00ff, ' ', 3, "stx %2,x" }, + + { 0x00e0, 0x00ff, ' ', 2, "sub %1,x" }, + { 0x00e1, 0x00ff, ' ', 2, "cmp %1,x" }, + { 0x00e2, 0x00ff, ' ', 2, "sbc %1,x" }, + { 0x00e3, 0x00ff, ' ', 2, "cpx %1,x" }, + { 0x00e4, 0x00ff, ' ', 2, "and %1,x" }, + { 0x00e5, 0x00ff, ' ', 2, "bit %1,x" }, + { 0x00e6, 0x00ff, ' ', 2, "lda %1,x" }, + { 0x00e7, 0x00ff, ' ', 2, "sta %1,x" }, + { 0x00e8, 0x00ff, ' ', 2, "eor %1,x" }, + { 0x00e9, 0x00ff, ' ', 2, "adc %1,x" }, + { 0x00ea, 0x00ff, ' ', 2, "ora %1,x" }, + { 0x00eb, 0x00ff, ' ', 2, "add %1,x" }, + { 0x00ec, 0x00ff, ' ', 2, "jmp %1,x" }, + { 0x00ed, 0x00ff, ' ', 2, "jsr %1,x" }, + { 0x00ee, 0x00ff, ' ', 2, "ldx %1,x" }, + { 0x00ef, 0x00ff, ' ', 2, "stx %1,x" }, + + { 0x00f0, 0x00ff, ' ', 1, "sub ,x" }, + { 0x00f1, 0x00ff, ' ', 1, "cmp ,x" }, + { 0x00f2, 0x00ff, ' ', 1, "sbc ,x" }, + { 0x00f3, 0x00ff, ' ', 1, "cpx ,x" }, + { 0x00f4, 0x00ff, ' ', 1, "and ,x" }, + { 0x00f5, 0x00ff, ' ', 1, "bit ,x" }, + { 0x00f6, 0x00ff, ' ', 1, "lda ,x" }, + { 0x00f7, 0x00ff, ' ', 1, "sta ,x" }, + { 0x00f8, 0x00ff, ' ', 1, "eor ,x" }, + { 0x00f9, 0x00ff, ' ', 1, "adc ,x" }, + { 0x00fa, 0x00ff, ' ', 1, "ora ,x" }, + { 0x00fb, 0x00ff, ' ', 1, "add ,x" }, + { 0x00fc, 0x00ff, ' ', 1, "jmp ,x" }, + { 0x00fd, 0x00ff, ' ', 1, "jsr ,x" }, + { 0x00fe, 0x00ff, ' ', 1, "ldx ,x" }, + { 0x00ff, 0x00ff, ' ', 1, "stx ,x" }, + + { 0, 0, 0, 0, NULL } +}; + + +struct dis_entry disass_hc08_9e[]= { + { 0x0060, 0x00ff, ' ', 2, "neg %1,sp" }, + { 0x0061, 0x00ff, 'R', 3, "cbeq %1,sp,%p" }, + { 0x0063, 0x00ff, ' ', 2, "com %1,sp" }, + { 0x0064, 0x00ff, ' ', 2, "lsr %1,sp" }, + { 0x0066, 0x00ff, ' ', 2, "ror %1,sp" }, + { 0x0067, 0x00ff, ' ', 2, "asr %1,sp" }, + { 0x0068, 0x00ff, ' ', 2, "lsl %1,sp" }, + { 0x0069, 0x00ff, ' ', 2, "rol %1,sp" }, + { 0x006a, 0x00ff, ' ', 2, "dec %1,sp" }, + { 0x006b, 0x00ff, 'R', 2, "dbnz %1,sp,%p" }, + { 0x006c, 0x00ff, ' ', 2, "inc %1,sp" }, + { 0x006d, 0x00ff, ' ', 2, "tst %1,sp" }, + { 0x006f, 0x00ff, ' ', 2, "clr %1,sp" }, + + { 0x00d0, 0x00ff, ' ', 3, "sub %2,sp" }, + { 0x00d1, 0x00ff, ' ', 3, "cmp %2,sp" }, + { 0x00d2, 0x00ff, ' ', 3, "sbc %2,sp" }, + { 0x00d3, 0x00ff, ' ', 3, "cpx %2,sp" }, + { 0x00d4, 0x00ff, ' ', 3, "and %2,sp" }, + { 0x00d5, 0x00ff, ' ', 3, "bit %2,sp" }, + { 0x00d6, 0x00ff, ' ', 3, "lda %2,sp" }, + { 0x00d7, 0x00ff, ' ', 3, "sta %2,sp" }, + { 0x00d8, 0x00ff, ' ', 3, "eor %2,sp" }, + { 0x00d9, 0x00ff, ' ', 3, "adc %2,sp" }, + { 0x00da, 0x00ff, ' ', 3, "ora %2,sp" }, + { 0x00db, 0x00ff, ' ', 3, "add %2,sp" }, + { 0x00de, 0x00ff, ' ', 3, "ldx %2,sp" }, + { 0x00df, 0x00ff, ' ', 3, "stx %2,sp" }, + + { 0x00e0, 0x00ff, ' ', 2, "sub %1,sp" }, + { 0x00e1, 0x00ff, ' ', 2, "cmp %1,sp" }, + { 0x00e2, 0x00ff, ' ', 2, "sbc %1,sp" }, + { 0x00e3, 0x00ff, ' ', 2, "cpx %1,sp" }, + { 0x00e4, 0x00ff, ' ', 2, "and %1,sp" }, + { 0x00e5, 0x00ff, ' ', 2, "bit %1,sp" }, + { 0x00e6, 0x00ff, ' ', 2, "lda %1,sp" }, + { 0x00e7, 0x00ff, ' ', 2, "sta %1,sp" }, + { 0x00e8, 0x00ff, ' ', 2, "eor %1,sp" }, + { 0x00e9, 0x00ff, ' ', 2, "adc %1,sp" }, + { 0x00ea, 0x00ff, ' ', 2, "ora %1,sp" }, + { 0x00eb, 0x00ff, ' ', 2, "add %1,sp" }, + { 0x00ee, 0x00ff, ' ', 2, "ldx %1,sp" }, + { 0x00ef, 0x00ff, ' ', 2, "stx %1,sp" }, + + { 0, 0, 0, 0, NULL } +}; + + +/* glob.cc */ diff --git a/sim/ucsim/hc08.src/glob.h b/sim/ucsim/hc08.src/glob.h new file mode 100644 index 00000000..eda7f1f1 --- /dev/null +++ b/sim/ucsim/hc08.src/glob.h @@ -0,0 +1,41 @@ +/* + * 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_hc08[]; + +extern struct dis_entry disass_hc08_9e[]; + + +#endif + +/* End of hc08.src/glob.h */ diff --git a/sim/ucsim/hc08.src/hc08.cc b/sim/ucsim/hc08.src/hc08.cc new file mode 100644 index 00000000..06af92c9 --- /dev/null +++ b/sim/ucsim/hc08.src/hc08.cc @@ -0,0 +1,582 @@ +/* + * Simulator of microcontrollers (hc08.cc) + * + * some hc08 code base from Karl Bongers karl@turbobit.com + * + * 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 /* for va_list */ +#include +#include +#include +#include "i_string.h" + +// prj +#include "pobjcl.h" + +// sim +#include "simcl.h" + +// local +#include "hc08cl.h" +#include "glob.h" +#include "regshc08.h" +#include "hc08mac.h" + +#define uint32 t_addr +#define uint8 unsigned char +#define int8 char + +const bool TRUE = 1; +const bool FALSE = 0; + +/*******************************************************************/ + + +/* + * Base type of HC08 controllers + */ + +cl_hc08::cl_hc08(class cl_sim *asim): + cl_uc(asim) +{ + type= CPU_HC08; +} + +int +cl_hc08::init(void) +{ + cl_uc::init(); /* Memories now exist */ + + xtal = 8000000; + + rom= mem(MEM_ROM); +// ram= mem(MEM_XRAM); + ram= rom; + + // zero out ram(this is assumed in regression tests) + for (int i=0x80; i<0x8000; i++) { + ram->set((t_addr) i, 0); + } + + return(0); +} + + +void +cl_hc08::reset(void) +{ + cl_uc::reset(); + + regs.SP = 0xff; + regs.A = 0; + regs.X = 0; + regs.H = 0; + regs.P = 0x60; + regs.VECTOR = 1; + +} + + +char * +cl_hc08::id_string(void) +{ + return("unspecified HC08"); +} + + +/* + * Making elements of the controller + */ + +t_addr +cl_hc08::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_hc08::mk_hw_elements(void) +{ + //class cl_base *o; + /* t_uc::mk_hw() does nothing */ +} + + +/* + * Help command interpreter + */ + +struct dis_entry * +cl_hc08::dis_tbl(void) +{ + return(disass_hc08); +} + +/*struct name_entry * +cl_hc08::sfr_tbl(void) +{ + return(0); +}*/ + +/*struct name_entry * +cl_hc08::bit_tbl(void) +{ + //FIXME + return(0); +}*/ + +int +cl_hc08::inst_length(t_addr addr) +{ + int len = 0; + char *s; + + s = get_disasm_info(addr, &len, NULL, NULL); + + return len; +} + +int +cl_hc08::inst_branch(t_addr addr) +{ + int b; + char *s; + + s = get_disasm_info(addr, NULL, &b, NULL); + + return b; +} + +int +cl_hc08::longest_inst(void) +{ + return 4; +} + + +char * +cl_hc08::get_disasm_info(t_addr addr, + int *ret_len, + int *ret_branch, + int *immed_offset) +{ + char *b = NULL; + uint code; + int len = 0; + int immed_n = 0; + int i; + int start_addr = addr; + struct dis_entry *dis_e; + + code= get_mem(MEM_ROM, addr++); + dis_e = NULL; + + switch(code) { + case 0x9e: /* ESC code to sp relative op-codes */ + code= get_mem(MEM_ROM, addr++); + i= 0; + while ((code & disass_hc08_9e[i].mask) != disass_hc08_9e[i].code && + disass_hc08_9e[i].mnemonic) + i++; + dis_e = &disass_hc08_9e[i]; + b= disass_hc08_9e[i].mnemonic; + if (b != NULL) + len += (disass_hc08_9e[i].length + 1); + break; + + default: + i= 0; + while ((code & disass_hc08[i].mask) != disass_hc08[i].code && + disass_hc08[i].mnemonic) + i++; + dis_e = &disass_hc08[i]; + b= disass_hc08[i].mnemonic; + if (b != NULL) + len += (disass_hc08[i].length); + break; + } + + 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 (len == 0) + len = 1; + + if (ret_len) + *ret_len = len; + + return b; +} + +char * +cl_hc08::disass(t_addr addr, char *sep) +{ + char work[256], temp[20]; + char *buf, *p, *b, *t; + int len = 0; + int immed_offset = 0; + + p= work; + + b = get_disasm_info(addr, &len, NULL, &immed_offset); + + if (b == NULL) { + buf= (char*)malloc(30); + strcpy(buf, "UNKNOWN/INVALID"); + return(buf); + } + + while (*b) + { + if (*b == '%') + { + b++; + switch (*(b++)) + { + case 's': // s signed byte immediate + sprintf(temp, "#%d", (char)get_mem(MEM_ROM, addr+immed_offset)); + ++immed_offset; + break; + case 'w': // w word immediate operand + sprintf(temp, "#0x%04x", + (uint)((get_mem(MEM_ROM, addr+immed_offset)<<8) | + (get_mem(MEM_ROM, addr+immed_offset+1))) ); + ++immed_offset; + ++immed_offset; + break; + case 'b': // b byte immediate operand + sprintf(temp, "#0x%02x", (uint)get_mem(MEM_ROM, addr+immed_offset)); + ++immed_offset; + break; + case 'x': // x extended addressing + sprintf(temp, "0x%04x", + (uint)((get_mem(MEM_ROM, addr+immed_offset)<<8) | + (get_mem(MEM_ROM, addr+immed_offset+1))) ); + ++immed_offset; + ++immed_offset; + break; + case 'd': // d direct addressing + sprintf(temp, "*0x%02x", (uint)get_mem(MEM_ROM, addr+immed_offset)); + ++immed_offset; + break; + case '2': // 2 word index offset + sprintf(temp, "0x%04x", + (uint)((get_mem(MEM_ROM, addr+immed_offset)<<8) | + (get_mem(MEM_ROM, addr+immed_offset+1))) ); + ++immed_offset; + ++immed_offset; + break; + case '1': // b byte index offset + sprintf(temp, "0x%02x", (uint)get_mem(MEM_ROM, addr+immed_offset)); + ++immed_offset; + break; + case 'p': // b byte index offset + sprintf(temp, "0x%04x", + addr+immed_offset+1 + +(char)get_mem(MEM_ROM, addr+immed_offset)); + ++immed_offset; + 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, b= buf; *p != ' '; p++, b++) + *b= *p; + p++; + *b= '\0'; + if (sep == NULL) + { + while (strlen(buf) < 6) + strcat(buf, " "); + } + else + strcat(buf, sep); + strcat(buf, p); + return(buf); +} + + +void +cl_hc08::print_regs(class cl_console *con) +{ + con->dd_printf("V--HINZC Flags= 0x%02x %3d %c ", + regs.P, regs.P, isprint(regs.P)?regs.P:'.'); + con->dd_printf("A= 0x%02x %3d %c\n", + regs.A, regs.A, isprint(regs.A)?regs.A:'.'); + con->dd_printf("%c--%c%c%c%c%c ", + (regs.P&BIT_V)?'1':'0', + (regs.P&BIT_H)?'1':'0', + (regs.P&BIT_I)?'1':'0', + (regs.P&BIT_N)?'1':'0', + (regs.P&BIT_Z)?'1':'0', + (regs.P&BIT_C)?'1':'0'); + con->dd_printf(" H= 0x%02x %3d %c ", + regs.H, regs.H, isprint(regs.H)?regs.H:'.'); + con->dd_printf("X= 0x%02x %3d %c\n", + regs.X, regs.X, isprint(regs.X)?regs.X:'.'); + con->dd_printf("SP= 0x%04x [SP+1]= %02x %3d %c\n", + regs.SP, ram->get(regs.SP+1), ram->get(regs.SP+1), + isprint(ram->get(regs.SP+1))?ram->get(regs.SP+1):'.'); + + print_disass(PC, con); +} + +/* + * Execution + */ + +int +cl_hc08::exec_inst(void) +{ + t_mem code; + + if (regs.VECTOR) { + PC = get2(0xfffe); + regs.VECTOR = 0; + return(resGO); + } + + if (fetch(&code)) + return(resBREAKPOINT); + tick(1); + switch ((code >> 4) & 0xf) { + case 0x0: return(inst_bittestsetclear(code, FALSE)); + case 0x1: return(inst_bitsetclear(code, FALSE)); + case 0x2: return(inst_condbranch(code, FALSE)); + case 0x3: + case 0x4: + case 0x5: + case 0x6: + case 0x7: + switch (code & 0xf) { + case 0x0: return(inst_neg(code, FALSE)); + case 0x1: return(inst_cbeq(code, FALSE)); + case 0x2: + switch (code) { + case 0x42: return(inst_mul(code, FALSE)); + case 0x52: return(inst_div(code, FALSE)); + case 0x62: return(inst_nsa(code, FALSE)); + case 0x72: return(inst_daa(code, FALSE)); + default: return(resHALT); + } + case 0x3: return(inst_com(code, FALSE)); + case 0x4: return(inst_lsr(code, FALSE)); + case 0x5: + switch (code) { + case 0x35: return(inst_sthx(code, FALSE)); + case 0x45: + case 0x55: return(inst_ldhx(code, FALSE)); + case 0x65: + case 0x75: return(inst_cphx(code, FALSE)); + default: return(resHALT); + } + case 0x6: return(inst_ror(code, FALSE)); + case 0x7: return(inst_asr(code, FALSE)); + case 0x8: return(inst_lsl(code, FALSE)); + case 0x9: return(inst_rol(code, FALSE)); + case 0xa: return(inst_dec(code, FALSE)); + case 0xb: return(inst_dbnz(code, FALSE)); + case 0xc: return(inst_inc(code, FALSE)); + case 0xd: return(inst_tst(code, FALSE)); + case 0xe: + switch (code) { + case 0x4e: + case 0x5e: + case 0x6e: + case 0x7e: return(inst_mov(code, FALSE)); + default: return(resHALT); + } + case 0xf: return(inst_clr(code, FALSE)); + default: return(resHALT); + } + case 0x8: + switch (code & 0xf) { + case 0x0: return(inst_rti(code, FALSE)); + case 0x1: return(inst_rts(code, FALSE)); + case 0x3: return(inst_swi(code, FALSE)); + case 0x4: + case 0x5: return(inst_transfer(code, FALSE)); + case 0x6: + case 0x7: + case 0x8: + case 0x9: + case 0xa: + case 0xb: return(inst_pushpull(code, FALSE)); + case 0xc: return(inst_clrh(code, FALSE)); + case 0xe: return(inst_stop(code, FALSE)); + case 0xf: return(inst_wait(code, FALSE)); + default: return(resHALT); + } + case 0x9: + switch (code & 0xf) { + case 0x0: + case 0x1: + case 0x2: + case 0x3: return(inst_condbranch(code, FALSE)); + case 0x4: + case 0x5: + case 0x7: + case 0xf: return(inst_transfer(code, FALSE)); + case 0x8: + case 0x9: + case 0xa: + case 0xb: return(inst_setclearflags(code, FALSE)); + case 0xc: return(inst_rsp(code, FALSE)); + case 0xd: return(inst_nop(code, FALSE)); + case 0xe: + code = fetch(); + switch ((code >> 4) & 0xf) { + case 0x6: + switch (code & 0xf) { + case 0x0: return(inst_neg(code, TRUE)); + case 0x1: return(inst_cbeq(code, TRUE)); + case 0x3: return(inst_com(code, TRUE)); + case 0x4: return(inst_lsr(code, TRUE)); + case 0x6: return(inst_ror(code, TRUE)); + case 0x7: return(inst_asr(code, TRUE)); + case 0x8: return(inst_lsl(code, TRUE)); + case 0x9: return(inst_rol(code, TRUE)); + case 0xa: return(inst_dec(code, TRUE)); + case 0xb: return(inst_dbnz(code, TRUE)); + case 0xc: return(inst_inc(code, TRUE)); + case 0xd: return(inst_tst(code, TRUE)); + case 0xf: return(inst_clr(code, TRUE)); + default: return(resHALT); + } + case 0xd: + case 0xe: + switch (code & 0xf) { + case 0x0: return(inst_sub(code, TRUE)); + case 0x1: return(inst_cmp(code, TRUE)); + case 0x2: return(inst_sbc(code, TRUE)); + case 0x3: return(inst_cpx(code, TRUE)); + case 0x4: return(inst_and(code, TRUE)); + case 0x5: return(inst_bit(code, TRUE)); + case 0x6: return(inst_lda(code, TRUE)); + case 0x7: return(inst_sta(code, TRUE)); + case 0x8: return(inst_eor(code, TRUE)); + case 0x9: return(inst_adc(code, TRUE)); + case 0xa: return(inst_ora(code, TRUE)); + case 0xb: return(inst_add(code, TRUE)); + case 0xc: return(resHALT); + case 0xd: putchar(regs.A); fflush(stdout); return(resGO); + case 0xe: return(inst_ldx(code, TRUE)); + case 0xf: return(inst_stx(code, TRUE)); + default: return(resHALT); + } + default: return(resHALT); + } + + } + case 0xa: + case 0xb: + case 0xc: + case 0xd: + case 0xe: + case 0xf: + switch (code & 0xf) { + case 0x0: return(inst_sub(code, FALSE)); + case 0x1: return(inst_cmp(code, FALSE)); + case 0x2: return(inst_sbc(code, FALSE)); + case 0x3: return(inst_cpx(code, FALSE)); + case 0x4: return(inst_and(code, FALSE)); + case 0x5: return(inst_bit(code, FALSE)); + case 0x6: return(inst_lda(code, FALSE)); + case 0x7: + if (code==0xa7) + return(inst_ais(code, FALSE)); + else + return(inst_sta(code, FALSE)); + case 0x8: return(inst_eor(code, FALSE)); + case 0x9: return(inst_adc(code, FALSE)); + case 0xa: return(inst_ora(code, FALSE)); + case 0xb: return(inst_add(code, FALSE)); + case 0xc: + if (code==0xac) + return(resHALT); + else + return(inst_jmp(code, FALSE)); + case 0xd: + if (code==0xad) + return(inst_bsr(code, FALSE)); + else + return(inst_jsr(code, FALSE)); + case 0xe: return(inst_ldx(code, FALSE)); + case 0xf: + if (code==0xaf) + return(inst_aix(code, FALSE)); + else + return(inst_stx(code, FALSE)); + default: return(resHALT); + } + default: return(resHALT); + } + + if (PC) + PC--; + else + PC= get_mem_size(MEM_ROM)-1; + + sim->stop(resINV_INST); + return(resINV_INST); +} + + +/* End of hc08.src/hc08.cc */ diff --git a/sim/ucsim/hc08.src/hc08cl.h b/sim/ucsim/hc08.src/hc08cl.h new file mode 100644 index 00000000..eae0bb23 --- /dev/null +++ b/sim/ucsim/hc08.src/hc08cl.h @@ -0,0 +1,75 @@ +/* + * Simulator of microcontrollers (hc08cl.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 HC08CL_HEADER +#define HC08CL_HEADER + +#include "uccl.h" + +#include "regshc08.h" + + +/* + * Base type of Z80 microcontrollers + */ + +class cl_hc08: public cl_uc +{ +public: + cl_mem *ram; + cl_mem *rom; + struct t_regs regs; +public: + cl_hc08(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_hw_elements(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, char *sep); + virtual void print_regs(class cl_console *con); + + virtual int exec_inst(void); + + virtual char * get_disasm_info(t_addr addr, + int *ret_len, + int *ret_branch, + int *immed_offset); + + virtual void reset(void); +#include "instcl.h" +}; + + +#endif + +/* End of hc08.src/hc08cl.h */ diff --git a/sim/ucsim/hc08.src/hc08mac.h b/sim/ucsim/hc08.src/hc08mac.h new file mode 100644 index 00000000..0b1df1c7 --- /dev/null +++ b/sim/ucsim/hc08.src/hc08mac.h @@ -0,0 +1,46 @@ +/* + * Simulator of microcontrollers (z80mac.h) + * + * some z80 code base from Karl Bongers karl@turbobit.com + * + * Copyright (C) 1999,99 Drotos Daniel, Talker Bt. + * + * To contact author send email to drdani@mazsola.iit.uni-miskolc.hu + * + */ + +// shift positions +#define BITPOS_C 0 // 1 +#define BITPOS_Z 1 // 2H +#define BITPOS_N 2 // 4H +#define BITPOS_I 3 // 8H +#define BITPOS_H 4 // 10H +#define BITPUS_V 7 // 80H + +#define store2(addr, val) { ram->set((t_addr) (addr), (val >> 8) & 0xff); \ + ram->set((t_addr) (addr+1), val & 0xff); } +#define store1(addr, val) ram->set((t_addr) (addr), val) +#define get1(addr) ram->get((t_addr) (addr)) +#define get2(addr) ((ram->get((t_addr) (addr)) << 8) | ram->get((t_addr) (addr+1)) ) +#define fetch2() ((fetch() << 8) | fetch() ) +#define fetch1() fetch() +#define push2(val) {store2(regs.SP-1,(val)); regs.SP-=2; } +#define push1(val) {store1(regs.SP,(val)); regs.SP-=1; } +#define pop2(var) {var=get2(regs.SP+1); regs.SP+=2;} +#define pop1(var) {var=get1(regs.SP+1); regs.SP+=1;} +#define add_u16_disp(_w, _d) (( (unsigned short)(_w) + (char)(_d) ) & 0xffff) + + +#define FLAG_SET(f) {regs.P |= f;} +#define FLAG_CLEAR(f) {regs.P &= ~(f);} +#define FLAG_ASSIGN(f,c) {regs.P = (c) ? regs.P | (f) : regs.P & ~(f);} +#define FLAG_NZ(f) { \ + regs.P = (regs.P & ~(BIT_N|BIT_Z)) \ + | ((f) ? 0 : BIT_Z) \ + | (((f) & 0x80) ? BIT_N : 0) \ + ; } +#define EA_IMM(c) ((((c) >> 4) & 0xf)==0xa) +#define OPERAND(code,prefix) (EA_IMM(code) ? fetch() : get1(fetchea(code,prefix))) + + + diff --git a/sim/ucsim/hc08.src/inst.cc b/sim/ucsim/hc08.src/inst.cc new file mode 100644 index 00000000..6c491a14 --- /dev/null +++ b/sim/ucsim/hc08.src/inst.cc @@ -0,0 +1,1154 @@ +/* + * Simulator of microcontrollers (inst.cc) + * + * hc08 code base from Erik Petrich epetrich@users.sourceforge.net + * + * 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 + +// local +#include "hc08cl.h" +#include "regshc08.h" +#include "hc08mac.h" + + + +void +cl_hc08::incx(void) +{ + int hx = (regs.H << 8) | (regs.X); + hx++; + regs.H = (hx >> 8) & 0xff; + regs.X = hx & 0xff; +} + +int +cl_hc08::fetchea(t_mem code, bool prefix) +{ + switch ((code >> 4) & 0x0f) { + case 0x0: + case 0x1: + case 0x3: + case 0xb: + return fetch(); // Direct + case 0x7: + case 0xf: + return (regs.H << 8) | regs.X; // IX + case 0x6: + case 0xe: + if (!prefix) + return ((unsigned char)fetch())+((regs.H << 8) | regs.X); // IX1 + else + return ((unsigned char)fetch())+regs.SP; // SP1 + case 0xd: + if (!prefix) + return fetch2()+((regs.H << 8) | regs.X); // IX2 + else + return fetch2()+regs.SP; // SP2 + case 0xc: + return fetch2(); + default: + return(resHALT); + } +} + + +int +cl_hc08::inst_nop(t_mem code, bool prefix) +{ + return(resGO); +} + + +int +cl_hc08::inst_transfer(t_mem code, bool prefix) +{ + int hx; + + switch (code) { + case 0x84: // TAP + regs.P = regs.A | 0x60; + break; + case 0x85: // TPA + regs.A = regs.P | 0x60; + break; + case 0x97: // TAX + regs.X = regs.A; + break; + case 0x9f: // TXA + regs.A = regs.X; + break; + case 0x94: // TXS + hx = (regs.H << 8) | regs.X; + regs.SP = (hx - 1) & 0xffff; + break; + case 0x95: // TSX + hx = regs.SP +1; + regs.H = (hx >> 8) & 0xff; + regs.X = hx & 0xff; + break; + default: + return(resHALT); + } + return(resGO); +} + + +int +cl_hc08::inst_setclearflags(t_mem code, bool prefix) +{ + switch (code) { + case 0x98: + regs.P &= ~BIT_C; + break; + case 0x99: + regs.P |= BIT_C; + break; + case 0x9a: + regs.P &= ~BIT_I; + break; + case 0x9b: + regs.P |= BIT_I; + break; + default: + return(resHALT); + } + return(resGO); +} + + +int +cl_hc08::inst_rsp(t_mem code, bool prefix) +{ + regs.SP = 0x00ff; + return(resGO); +} + + +int +cl_hc08::inst_nsa(t_mem code, bool prefix) +{ + regs.A = ((regs.A & 0xf0)>>4) | ((regs.A & 0x0f)<<4); + return(resGO); +} + + + +int +cl_hc08::inst_lda(t_mem code, bool prefix) +{ + regs.A = OPERAND(code, prefix); + FLAG_CLEAR(BIT_V); + FLAG_NZ(regs.A); + return(resGO); +} + +int +cl_hc08::inst_ldx(t_mem code, bool prefix) +{ + regs.X = OPERAND(code, prefix); + FLAG_CLEAR(BIT_V); + FLAG_NZ(regs.X); + return(resGO); +} + +int +cl_hc08::inst_sta(t_mem code, bool prefix) +{ + int ea = fetchea(code, prefix); + + //fprintf (stdout, "ea = 0x%04x\n", ea); + + FLAG_CLEAR(BIT_V); + FLAG_NZ(regs.A); + store1(ea, regs.A); + return(resGO); +} + +int +cl_hc08::inst_stx(t_mem code, bool prefix) +{ + int ea = fetchea(code, prefix); + + FLAG_CLEAR(BIT_V); + FLAG_NZ(regs.X); + store1(ea, regs.X); + return(resGO); +} + +int +cl_hc08::inst_add(t_mem code, bool prefix) +{ + int result; + uchar operand; + + operand = OPERAND(code, prefix); + result = (regs.A + operand) & 0xff; + FLAG_NZ (result); + FLAG_ASSIGN (BIT_V, 0x80 & ((regs.A & operand & ~result) + | (~regs.A & ~operand & result))); + FLAG_ASSIGN (BIT_H, 0x10 & ((regs.A & operand) + | (operand & ~result) + | (~result & regs.A))); + FLAG_ASSIGN (BIT_C, 0x80 & ((regs.A & operand) + | (operand & ~result) + | (~result & regs.A))); + regs.A = result; + return(resGO); +} + +int +cl_hc08::inst_adc(t_mem code, bool prefix) +{ + int result; + uchar operand; + + operand = OPERAND(code, prefix); + result = (regs.A + operand + ((regs.P & BIT_C)!=0)) & 0xff; + FLAG_NZ (result); + FLAG_ASSIGN (BIT_V, 0x80 & ((regs.A & operand & ~result) + | (~regs.A & ~operand & result))); + FLAG_ASSIGN (BIT_H, 0x10 & ((regs.A & operand) + | (operand & ~result) + | (~result & regs.A))); + FLAG_ASSIGN (BIT_C, 0x80 & ((regs.A & operand) + | (operand & ~result) + | (~result & regs.A))); + regs.A = result; + return(resGO); +} + +int +cl_hc08::inst_sub(t_mem code, bool prefix) +{ + int result; + uchar operand; + + operand = OPERAND(code, prefix); + result = (regs.A - operand) & 0xff; + FLAG_NZ (result); + FLAG_ASSIGN (BIT_V, 0x80 & ((regs.A & ~operand & ~result) + | (~regs.A & operand & result))); + FLAG_ASSIGN (BIT_C, 0x80 & ((~regs.A & operand) + | (operand & result) + | (result & ~regs.A))); + regs.A = result; + return(resGO); +} + +int +cl_hc08::inst_sbc(t_mem code, bool prefix) +{ + int result; + uchar operand; + + operand = OPERAND(code, prefix); + result = (regs.A - operand - ((regs.P & BIT_C)!=0) ) & 0xff; + FLAG_NZ (result); + FLAG_ASSIGN (BIT_V, 0x80 & ((regs.A & ~operand & ~result) + | (~regs.A & operand & result))); + FLAG_ASSIGN (BIT_C, 0x80 & ((~regs.A & operand) + | (operand & result) + | (result & ~regs.A))); + regs.A = result; + return(resGO); +} + +int +cl_hc08::inst_cmp(t_mem code, bool prefix) +{ + int result; + uchar operand; + + operand = OPERAND(code, prefix); + result = (regs.A - operand) & 0xff; + FLAG_NZ (result); + FLAG_ASSIGN (BIT_V, 0x80 & ((regs.A & ~operand & ~result) + | (~regs.A & operand & result))); + FLAG_ASSIGN (BIT_C, 0x80 & ((~regs.A & operand) + | (operand & result) + | (result & ~regs.A))); + return(resGO); +} + +int +cl_hc08::inst_cpx(t_mem code, bool prefix) +{ + int result; + uchar operand; + + operand = OPERAND(code, prefix); + result = (regs.X - operand) & 0xff; + FLAG_NZ (result); + FLAG_ASSIGN (BIT_V, 0x80 & ((regs.X & ~operand & ~result) + | (~regs.X & operand & result))); + FLAG_ASSIGN (BIT_C, 0x80 & ((~regs.X & operand) + | (operand & result) + | (result & ~regs.X))); + return(resGO); +} + +int +cl_hc08::inst_jmp(t_mem code, bool prefix) +{ + PC = fetchea(code, prefix); + + return(resGO); +} + +int +cl_hc08::inst_jsr(t_mem code, bool prefix) +{ + int newPC = fetchea(code, prefix); + + push2(PC); + PC = newPC; + + return(resGO); +} + +int +cl_hc08::inst_bsr(t_mem code, bool prefix) +{ + signed char ofs = fetch(); + + push2(PC); + PC += ofs; + + return(resGO); +} + +int +cl_hc08::inst_ais(t_mem code, bool prefix) +{ + regs.SP = regs.SP + (signed char)fetch(); + return(resGO); +} + +int +cl_hc08::inst_aix(t_mem code, bool prefix) +{ + regs.X = regs.X + (signed char)fetch(); + return(resGO); +} + +int +cl_hc08::inst_and(t_mem code, bool prefix) +{ + regs.A = regs.A & OPERAND(code, prefix); + FLAG_CLEAR(BIT_V); + FLAG_NZ(regs.A); + return(resGO); +} + +int +cl_hc08::inst_bit(t_mem code, bool prefix) +{ + uchar operand = regs.A & OPERAND(code, prefix); + FLAG_CLEAR(BIT_V); + FLAG_NZ(operand); + return(resGO); +} + +int +cl_hc08::inst_ora(t_mem code, bool prefix) +{ + regs.A = regs.A | OPERAND(code, prefix); + FLAG_CLEAR(BIT_V); + FLAG_NZ(regs.A); + return(resGO); +} + +int +cl_hc08::inst_eor(t_mem code, bool prefix) +{ + regs.A = regs.A ^ OPERAND(code, prefix); + FLAG_CLEAR(BIT_V); + FLAG_NZ(regs.A); + return(resGO); +} + +int +cl_hc08::inst_asr(t_mem code, bool prefix) +{ + int ea = 0xffff; + uchar operand; + + if ((code & 0xf0) == 0x40) + operand = regs.A; + else if ((code & 0xf0) == 0x50) + operand = regs.X; + else { + ea = fetchea(code,prefix); + operand = get1(ea); + } + + FLAG_ASSIGN (BIT_C, operand & 1); + operand = (operand >> 1) | (operand & 0x80); + FLAG_NZ (operand); + FLAG_ASSIGN (BIT_V, ((regs.P & BIT_C)!=0) ^ ((regs.P & BIT_N)!=0)); + + if ((code & 0xf0) == 0x40) + regs.A = operand; + else if ((code & 0xf0) == 0x50) + regs.X = operand; + else { + store1(ea, operand); + } + + return(resGO); +} + + +int +cl_hc08::inst_lsr(t_mem code, bool prefix) +{ + int ea = 0xffff; + uchar operand; + + if ((code & 0xf0) == 0x40) + operand = regs.A; + else if ((code & 0xf0) == 0x50) + operand = regs.X; + else { + ea = fetchea(code,prefix); + operand = get1(ea); + } + + FLAG_ASSIGN (BIT_C, operand & 1); + operand = (operand >> 1) & 0x7f; + FLAG_NZ (operand); + FLAG_ASSIGN (BIT_V, ((regs.P & BIT_C)!=0) ^ ((regs.P & BIT_N)!=0)); + + if ((code & 0xf0) == 0x40) + regs.A = operand; + else if ((code & 0xf0) == 0x50) + regs.X = operand; + else { + store1(ea, operand); + } + return(resGO); +} + + +int +cl_hc08::inst_lsl(t_mem code, bool prefix) +{ + int ea = 0xffff; + uchar operand; + + if ((code & 0xf0) == 0x40) + operand = regs.A; + else if ((code & 0xf0) == 0x50) + operand = regs.X; + else { + ea = fetchea(code,prefix); + operand = get1(ea); + } + + FLAG_ASSIGN (BIT_C, operand & 0x80); + operand = (operand << 1); + FLAG_NZ (operand); + FLAG_ASSIGN (BIT_V, ((regs.P & BIT_C)!=0) ^ ((regs.P & BIT_N)!=0)); + + if ((code & 0xf0) == 0x40) + regs.A = operand; + else if ((code & 0xf0) == 0x50) + regs.X = operand; + else { + store1(ea, operand); + } + return(resGO); +} + + +int +cl_hc08::inst_rol(t_mem code, bool prefix) +{ + uchar c = (regs.P & BIT_C)!=0; + int ea = 0xffff; + uchar operand; + + if ((code & 0xf0) == 0x40) + operand = regs.A; + else if ((code & 0xf0) == 0x50) + operand = regs.X; + else { + ea = fetchea(code,prefix); + operand = get1(ea); + } + + FLAG_ASSIGN (BIT_C, operand & 0x80); + operand = (operand << 1) | c; + FLAG_NZ (operand); + FLAG_ASSIGN (BIT_V, ((regs.P & BIT_C)!=0) ^ ((regs.P & BIT_N)!=0)); + + if ((code & 0xf0) == 0x40) + regs.A = operand; + else if ((code & 0xf0) == 0x50) + regs.X = operand; + else { + store1(ea, operand); + } + return(resGO); +} + + +int +cl_hc08::inst_ror(t_mem code, bool prefix) +{ + uchar c = (regs.P & BIT_C)!=0; + int ea = 0xffff; + uchar operand; + + if ((code & 0xf0) == 0x40) + operand = regs.A; + else if ((code & 0xf0) == 0x50) + operand = regs.X; + else { + ea = fetchea(code,prefix); + operand = get1(ea); + } + + FLAG_ASSIGN (BIT_C, operand & 1); + operand = (operand >> 1) | (c << 7); + FLAG_NZ (operand); + FLAG_ASSIGN (BIT_V, ((regs.P & BIT_C)!=0) ^ ((regs.P & BIT_N)!=0)); + + if ((code & 0xf0) == 0x40) + regs.A = operand; + else if ((code & 0xf0) == 0x50) + regs.X = operand; + else { + store1(ea, operand); + } + return(resGO); +} + + +int +cl_hc08::inst_inc(t_mem code, bool prefix) +{ + int ea = 0xffff; + uchar operand; + + if ((code & 0xf0) == 0x40) + operand = regs.A; + else if ((code & 0xf0) == 0x50) + operand = regs.X; + else { + ea = fetchea(code,prefix); + operand = get1(ea); + } + + operand++; + FLAG_NZ (operand); + FLAG_ASSIGN (BIT_V, operand == 0x80); + + if ((code & 0xf0) == 0x40) + regs.A = operand; + else if ((code & 0xf0) == 0x50) + regs.X = operand; + else { + store1(ea, operand); + } + return(resGO); +} + + +int +cl_hc08::inst_dec(t_mem code, bool prefix) +{ + int ea = 0xffff; + uchar operand; + + if ((code & 0xf0) == 0x40) + operand = regs.A; + else if ((code & 0xf0) == 0x50) + operand = regs.X; + else { + ea = fetchea(code,prefix); + operand = get1(ea); + } + + operand--; + FLAG_NZ (operand); + FLAG_ASSIGN (BIT_V, operand == 0x7f); + + if ((code & 0xf0) == 0x40) + regs.A = operand; + else if ((code & 0xf0) == 0x50) + regs.X = operand; + else { + store1(ea, operand); + } + return(resGO); +} + +int +cl_hc08::inst_dbnz(t_mem code, bool prefix) +{ + int ea = 0xffff; + uchar operand; + signed char ofs; + + if ((code & 0xf0) == 0x40) + operand = regs.A; + else if ((code & 0xf0) == 0x50) + operand = regs.X; + else { + ea = fetchea(code,prefix); + operand = get1(ea); + } + + operand--; + FLAG_NZ (operand); + FLAG_ASSIGN (BIT_V, operand == 0x7f); + + if ((code & 0xf0) == 0x40) + regs.A = operand; + else if ((code & 0xf0) == 0x50) + regs.X = operand; + else { + store1(ea, operand); + } + + ofs = fetch(); + if (operand) + PC += ofs; + + return(resGO); +} + + +int +cl_hc08::inst_tst(t_mem code, bool prefix) +{ + int ea = 0xffff; + uchar operand; + + if ((code & 0xf0) == 0x40) + operand = regs.A; + else if ((code & 0xf0) == 0x50) + operand = regs.X; + else { + ea = fetchea(code,prefix); + operand = get1(ea); + } + + FLAG_NZ (operand); + FLAG_CLEAR (BIT_V); + + return(resGO); +} + + +int +cl_hc08::inst_clr(t_mem code, bool prefix) +{ + int ea = 0xffff; + uchar operand; + + operand = 0; + FLAG_CLEAR (BIT_V); + FLAG_CLEAR (BIT_N); + FLAG_SET (BIT_Z); + + if ((code & 0xf0) == 0x40) + regs.A = operand; + else if ((code & 0xf0) == 0x50) + regs.X = operand; + else { + store1(ea, operand); + } + return(resGO); +} + + +int +cl_hc08::inst_clrh(t_mem code, bool prefix) +{ + FLAG_CLEAR (BIT_V); + FLAG_CLEAR (BIT_N); + FLAG_SET (BIT_Z); + regs.H = 0; + return(resGO); +} + + +int +cl_hc08::inst_com(t_mem code, bool prefix) +{ + int ea = 0xffff; + uchar operand; + + if ((code & 0xf0) == 0x40) + operand = regs.A; + else if ((code & 0xf0) == 0x50) + operand = regs.X; + else { + ea = fetchea(code,prefix); + operand = get1(ea); + } + + operand = ~operand; + FLAG_SET (BIT_C); + FLAG_NZ (operand); + FLAG_CLEAR (BIT_V); + + if ((code & 0xf0) == 0x40) + regs.A = operand; + else if ((code & 0xf0) == 0x50) + regs.X = operand; + else { + store1(ea, operand); + } + return(resGO); +} + + +int +cl_hc08::inst_neg(t_mem code, bool prefix) +{ + int ea = 0xffff; + uchar operand; + + if ((code & 0xf0) == 0x40) + operand = regs.A; + else if ((code & 0xf0) == 0x50) + operand = regs.X; + else { + ea = fetchea(code,prefix); + operand = get1(ea); + } + + FLAG_ASSIGN (BIT_V, operand==0x80); + FLAG_ASSIGN (BIT_C, operand!=0x00); + operand = -operand; + FLAG_NZ (operand); + + if ((code & 0xf0) == 0x40) + regs.A = operand; + else if ((code & 0xf0) == 0x50) + regs.X = operand; + else { + store1(ea, operand); + } + return(resGO); +} + + + +int +cl_hc08::inst_pushpull(t_mem code, bool prefix) +{ + switch (code) { + case 0x86: + pop1(regs.A); + break; + case 0x87: + push1(regs.A); + break; + case 0x88: + pop1(regs.X); + break; + case 0x89: + push1(regs.X); + break; + case 0x8a: + pop1(regs.H); + break; + case 0x8b: + push1(regs.H); + break; + default: + return(resHALT); + } + return(resGO); +} + + + + +int +cl_hc08::inst_stop(t_mem code, bool prefix) +{ + FLAG_CLEAR (BIT_I); + return(resGO); +} + + +int +cl_hc08::inst_wait(t_mem code, bool prefix) +{ + FLAG_CLEAR (BIT_I); + return(resGO); +} + + +int +cl_hc08::inst_daa(t_mem code, bool prefix) +{ + uchar lsn, msn; + + lsn = regs.A & 0xf; + msn = (regs.A >> 4) & 0xf; + if (regs.P & BIT_H) { + lsn += 16; + msn = (msn-1) & 0xf; + } + if (regs.P & BIT_C) + msn += 16; + + FLAG_CLEAR (BIT_C); + while (lsn>9) { + lsn -= 10; + msn++; + } + if (msn>9) { + msn = msn % 10; + FLAG_SET (BIT_C); + } + + return(resGO); +} + +int +cl_hc08::inst_mul(t_mem code, bool prefix) +{ + int result = regs.A * regs.X; + regs.A = result & 0xff; + regs.X = (result >> 8) & 0xff; + FLAG_CLEAR (BIT_C); + FLAG_CLEAR (BIT_H); + return(resGO); +} + +int +cl_hc08::inst_div(t_mem code, bool prefix) +{ + int dividend = (regs.H << 8) | regs.A; + int quotient; + + if (regs.X) { + quotient = dividend / regs.X; + if (quotient<=0xff) { + regs.A = quotient; + regs.H = dividend % regs.X; + FLAG_CLEAR (BIT_C); + FLAG_ASSIGN (BIT_Z, quotient==0); + } + else + FLAG_SET (BIT_C); // overflow + } else + FLAG_SET (BIT_C); // division by zero + + return(resGO); +} + + +int +cl_hc08::inst_condbranch(t_mem code, bool prefix) +{ + bool taken; + signed char ofs; + + if ((code & 0xf0)==0x20) { + switch ((code>>1) & 7) { + case 0: // BRA + taken = 1; + break; + case 1: // BHI + taken = (regs.P & BIT_C) || !(regs.P & BIT_Z); + break; + case 2: // BCC + taken = !(regs.P & BIT_C); + break; + case 3: // BNE + taken = !(regs.P & BIT_Z); + break; + case 4: // BHCC + taken = !(regs.P & BIT_H); + break; + case 5: // BPL + taken = !(regs.P & BIT_N); + break; + case 6: // BMC + taken = !(regs.P & BIT_I); + break; + case 7: // BIL + taken = 0; // TODO: should read simulated IRQ# pin + default: + return(resHALT); + } + } + else if ((code & 0xf0)==0x90) { + switch ((code>>1) & 7) { + case 0: // BGE + taken = !(((regs.P & BIT_N)!=0) ^ ((regs.P & BIT_V)!=0)); + break; + case 1: // BLT + taken = (!(((regs.P & BIT_N)!=0) ^ ((regs.P & BIT_V)!=0))) + || (regs.P & BIT_Z); + break; + default: + return(resHALT); + } + } + else + return(resHALT); + + if (code & 1) + taken = ! taken; + + ofs = fetch(); + if (taken) + PC += ofs; + + return(resGO); +} + +int +cl_hc08::inst_bitsetclear(t_mem code, bool prefix) +{ + uchar bit = (code >> 1) & 7; + int ea = fetchea(code, prefix); + uchar operand = get1(ea); + + if (code & 1) + operand &= ~(1 << bit); + else + operand |= (1 << bit); + store1(ea, operand); + return(resGO); +} + +int +cl_hc08::inst_bittestsetclear(t_mem code, bool prefix) +{ + uchar bit = (code >> 1) & 7; + int ea = fetchea(code, prefix); + uchar operand = get1(ea); + signed char ofs; + bool taken; + + if (code & 1) + taken = operand & (1 << bit); + else + taken = !(operand & (1 << bit)); + + ofs = fetch(); + if (taken) + PC += ofs; + + FLAG_ASSIGN (BIT_C, operand & (1 << bit)); + return(resGO); +} + +int +cl_hc08::inst_cbeq(t_mem code, bool prefix) +{ + int ea; + uchar operand1, operand2; + signed char ofs; + + if ((code & 0xf0) == 0x40) { + operand1 = regs.A; + operand2 = fetch(); + } + else if ((code & 0xf0) == 0x50) { + operand1 = regs.X; + operand2 = fetch(); + } + else { + ea = fetchea(code,prefix); + operand1 = get1(ea); + operand2 = regs.A; + } + + ofs = fetch(); + if (operand1==operand2) + PC += ofs; + + if (code==0x71) + incx(); + + return(resGO); +} + +int +cl_hc08::inst_rti(t_mem code, bool prefix) +{ + pop1(regs.P); + regs.P |= 0x60; + pop1(regs.A); + pop1(regs.X); + pop2(PC); + + return(resGO); +} + +int +cl_hc08::inst_rts(t_mem code, bool prefix) +{ + pop2(PC); + + return(resGO); +} + + +int +cl_hc08::inst_mov(t_mem code, bool prefix) +{ + int ea; + uchar operand; + bool aix; + + switch (code) { + case 0x4e: + operand = get1(fetch()); + ea = fetch(); + aix = 0; + break; + case 0x5e: + operand = get1(fetch()); + ea = regs.X; + aix = 1; + break; + case 0x6e: + operand = fetch(); + ea = fetch(); + aix = 0; + break; + case 0x7e: + operand = get1(regs.X); + ea = fetch(); + aix = 1; + break; + default: + return(resHALT); + } + + store1(ea, operand); + if (aix) + incx(); + + FLAG_NZ(operand); + FLAG_CLEAR(BIT_V); + + return(resGO); +} + + +int +cl_hc08::inst_sthx(t_mem code, bool prefix) +{ + int ea = fetch1(); + + store1(ea, regs.H); + store1((ea+1) & 0xffff, regs.X); + + FLAG_CLEAR(BIT_V); + FLAG_ASSIGN(BIT_N, regs.X & 0x80); + FLAG_ASSIGN(BIT_Z, !regs.X && !regs.A); + return(resGO); +} + +int +cl_hc08::inst_ldhx(t_mem code, bool prefix) +{ + int ea; + + if (code == 0x45) { + regs.H = fetch(); + regs.X = fetch(); + } + else if (code == 0x55) { + ea = fetch(); + regs.H = get1(ea); + regs.X = get1(ea+1); + } + else + return(resHALT); + + FLAG_CLEAR(BIT_V); + FLAG_ASSIGN(BIT_N, regs.X & 0x80); + FLAG_ASSIGN(BIT_Z, !regs.X && !regs.A); + return(resGO); +} + + +int +cl_hc08::inst_cphx(t_mem code, bool prefix) +{ + int ea; + int hx; + int operand; + int result; + + if (code == 0x65) { + operand = fetch2(); + } + else if (code == 0x75) { + ea = fetch(); + operand = (get1(ea) << 8) | get1(ea+1); + } + else + return(resHALT); + + hx = (regs.H << 8) | regs.X; + + result = (hx-operand) & 0xffff; + + FLAG_ASSIGN (BIT_V, 0x8000 & ((hx & ~operand & ~result) + | (~hx & operand & result))); + FLAG_ASSIGN (BIT_C, 0x8000 & ((~hx & operand) + | (operand & result) + | (result & ~hx))); + FLAG_ASSIGN(BIT_N, result & 0x8000); + FLAG_ASSIGN(BIT_Z, !result); + + return(resGO); +} + +int +cl_hc08::inst_swi(t_mem code, bool prefix) +{ + push2(PC); + push1(regs.X); + push1(regs.A); + push1(regs.P); + FLAG_CLEAR(BIT_I); + + PC = get2(0xfffc); + + return(resGO); +} + + +/* End of hc08.src/inst.cc */ diff --git a/sim/ucsim/hc08.src/instcl.h b/sim/ucsim/hc08.src/instcl.h new file mode 100644 index 00000000..22b9bd55 --- /dev/null +++ b/sim/ucsim/hc08.src/instcl.h @@ -0,0 +1,61 @@ +/* hc08.src/instcl.h */ + + virtual void incx(void); + virtual int fetchea(t_mem code, bool prefix); + virtual int inst_nop(t_mem code, bool prefix); + virtual int inst_transfer(t_mem code, bool prefix); + virtual int inst_setclearflags(t_mem code, bool prefix); + virtual int inst_rsp(t_mem code, bool prefix); + virtual int inst_nsa(t_mem code, bool prefix); + virtual int inst_lda(t_mem code, bool prefix); + virtual int inst_ldx(t_mem code, bool prefix); + virtual int inst_sta(t_mem code, bool prefix); + virtual int inst_stx(t_mem code, bool prefix); + virtual int inst_add(t_mem code, bool prefix); + virtual int inst_adc(t_mem code, bool prefix); + virtual int inst_sub(t_mem code, bool prefix); + virtual int inst_sbc(t_mem code, bool prefix); + virtual int inst_cmp(t_mem code, bool prefix); + virtual int inst_cpx(t_mem code, bool prefix); + virtual int inst_jmp(t_mem code, bool prefix); + virtual int inst_jsr(t_mem code, bool prefix); + virtual int inst_ais(t_mem code, bool prefix); + virtual int inst_aix(t_mem code, bool prefix); + virtual int inst_and(t_mem code, bool prefix); + virtual int inst_bit(t_mem code, bool prefix); + virtual int inst_ora(t_mem code, bool prefix); + virtual int inst_eor(t_mem code, bool prefix); + virtual int inst_asr(t_mem code, bool prefix); + virtual int inst_lsr(t_mem code, bool prefix); + virtual int inst_lsl(t_mem code, bool prefix); + virtual int inst_rol(t_mem code, bool prefix); + virtual int inst_ror(t_mem code, bool prefix); + virtual int inst_inc(t_mem code, bool prefix); + virtual int inst_dec(t_mem code, bool prefix); + virtual int inst_dbnz(t_mem code, bool prefix); + virtual int inst_tst(t_mem code, bool prefix); + virtual int inst_clr(t_mem code, bool prefix); + virtual int inst_clrh(t_mem code, bool prefix); + virtual int inst_com(t_mem code, bool prefix); + virtual int inst_neg(t_mem code, bool prefix); + virtual int inst_pushpull(t_mem code, bool prefix); + virtual int inst_stop(t_mem code, bool prefix); + virtual int inst_wait(t_mem code, bool prefix); + virtual int inst_daa(t_mem code, bool prefix); + virtual int inst_mul(t_mem code, bool prefix); + virtual int inst_div(t_mem code, bool prefix); + virtual int inst_condbranch(t_mem code, bool prefix); + virtual int inst_bitsetclear(t_mem code, bool prefix); + virtual int inst_bittestsetclear(t_mem code, bool prefix); + virtual int inst_cbeq(t_mem code, bool prefix); + virtual int inst_rti(t_mem code, bool prefix); + virtual int inst_rts(t_mem code, bool prefix); + virtual int inst_mov(t_mem code, bool prefix); + virtual int inst_sthx(t_mem code, bool prefix); + virtual int inst_ldhx(t_mem code, bool prefix); + virtual int inst_cphx(t_mem code, bool prefix); + virtual int inst_swi(t_mem code, bool prefix); + virtual int inst_bsr(t_mem code, bool prefix); + + +/* End of hc08.src/instcl.h */ diff --git a/sim/ucsim/hc08.src/regshc08.h b/sim/ucsim/hc08.src/regshc08.h new file mode 100644 index 00000000..dd6b087e --- /dev/null +++ b/sim/ucsim/hc08.src/regshc08.h @@ -0,0 +1,80 @@ +/* + * Simulator of microcontrollers (regsz80.h) + * + * some z80 code base from Karl Bongers karl@turbobit.com + * + * 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 REGHC08_HEADER +#define REGHC08_HEADER + +#include "ddconfig.h" + + +struct t_regpair +{ +#ifdef WORDS_BIGENDIAN + TYPE_UBYTE h; + TYPE_UBYTE l; +#else + TYPE_UBYTE l; + TYPE_UBYTE h; +#endif +}; + +#define DEF_REGPAIR(BIGNAME,smallname) \ + union { \ + TYPE_UWORD BIGNAME; \ + struct t_regpair smallname; \ + } + +struct t_regs +{ + TYPE_UBYTE A; + TYPE_UBYTE P; + TYPE_UBYTE H; + TYPE_UBYTE X; + TYPE_UWORD SP; + TYPE_UBYTE VECTOR; +}; + +#define BIT_C 0x01 // carry status(out of bit 7) +#define BIT_Z 0x02 // zero status, 1=zero, 0=nonzero +#define BIT_N 0x04 // sign, 1=negative, 0=positive (or zero) +#define BIT_I 0x08 // interrupt mask, 1=disabled, 0=enabled +#define BIT_H 0x10 // half carry status(out of bit 3) +#define BIT_V 0x80 // signed overflow, 1=overflow +#define BIT_ALL (BIT_C |BIT_Z |BIT_N |BIT_I |BIT_H |BIT_V) // all bits + +#define BITPOS_C 0 // 1 +#define BITPOS_Z 1 // 2H +#define BITPOS_N 2 // 4H +#define BITPOS_I 3 // 8H +#define BITPOS_H 4 // 10H +#define BITPOS_V 7 // 80H + +#endif + +/* End of hc08.src/regshc08.h */ diff --git a/sim/ucsim/hc08.src/shc08.cc b/sim/ucsim/hc08.src/shc08.cc new file mode 100644 index 00000000..ffcd951f --- /dev/null +++ b/sim/ucsim/hc08.src/shc08.cc @@ -0,0 +1,54 @@ +/* + * Simulator of microcontrollers (shc08.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 "simhc08cl.h" + + +int +main(int argc, char *argv[]) +{ + class cl_sim *sim; + + application= new cl_app(); + application->init(argc, argv); + sim= new cl_simhc08(application); + sim->init(); + application->set_simulator(sim); + application->run(); + delete application; + return(0); +} + + +/* End of hc08.src/shc08.cc */ diff --git a/sim/ucsim/hc08.src/simhc08.cc b/sim/ucsim/hc08.src/simhc08.cc new file mode 100644 index 00000000..57de2bd4 --- /dev/null +++ b/sim/ucsim/hc08.src/simhc08.cc @@ -0,0 +1,45 @@ +/* + * Simulator of microcontrollers (simhc08.cc) + * + * Copyright (C) 1999,99 Drotos Daniel, Talker Bt. + * + * To contact author send email to drdani@mazsola.iit.uni-miskolc.hu + * + */ + +/* This file is part of microcontroller simulator: ucsim. + +UCSIM is free software; you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation; either version 2 of the License, or +(at your option) any later version. + +UCSIM is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU General Public License for more details. + +You should have received a copy of the GNU General Public License +along with UCSIM; see the file COPYING. If not, write to the Free +Software Foundation, 59 Temple Place - Suite 330, Boston, MA +02111-1307, USA. */ +/*@1@*/ + + +// local +#include "simhc08cl.h" +#include "hc08cl.h" + + +cl_simhc08::cl_simhc08(class cl_app *the_app): + cl_sim(the_app) +{} + +class cl_uc * +cl_simhc08::mk_controller(void) +{ + return(new cl_hc08(this)); +} + + +/* End of hc08.src/simhc08.cc */ diff --git a/sim/ucsim/hc08.src/simhc08cl.h b/sim/ucsim/hc08.src/simhc08cl.h new file mode 100644 index 00000000..19f83f8f --- /dev/null +++ b/sim/ucsim/hc08.src/simhc08cl.h @@ -0,0 +1,45 @@ +/* + * Simulator of microcontrollers (simhc08cl.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 SIMHC08CL_HEADER +#define SIMHC08CL_HEADER + +#include "simcl.h" + + +class cl_simhc08: public cl_sim +{ +public: + cl_simhc08(class cl_app *the_app); + + virtual class cl_uc *mk_controller(void); +}; + + +#endif + +/* End of hc08.src/simhc08cl.h */ -- 2.30.2