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