From 8c8f34ff4281a55d2f535335c02999246e9e12f2 Mon Sep 17 00:00:00 2001 From: bernhardheld Date: Mon, 28 Jan 2002 10:19:59 +0000 Subject: [PATCH] Merge branch ucsim-034-pre3 to main trunk; new version 0.4 git-svn-id: https://sdcc.svn.sourceforge.net/svnroot/sdcc/trunk/sdcc@1850 4a8a32a2-be11-0410-ad9d-d568d2c75423 --- sim/ucsim/.version | 2 +- sim/ucsim/Makefile | 22 +- sim/ucsim/README | 1 + sim/ucsim/avr.src/Makefile.in | 32 +- sim/ucsim/avr.src/arith_inst.cc | 46 +- sim/ucsim/avr.src/avr.cc | 29 +- sim/ucsim/avr.src/bit_inst.cc | 38 +- sim/ucsim/avr.src/inst.cc | 2 +- sim/ucsim/avr.src/jump_inst.cc | 2 +- sim/ucsim/avr.src/logic_inst.cc | 10 +- sim/ucsim/avr.src/move_inst.cc | 52 +- sim/ucsim/avr.src/port.cc | 8 +- sim/ucsim/avr.src/portcl.h | 2 +- sim/ucsim/clean.mk | 19 +- sim/ucsim/cmd.src/Makefile.in | 4 +- sim/ucsim/cmd.src/bp.cc | 8 +- sim/ucsim/cmd.src/cmdconf.cc | 3 +- sim/ucsim/cmd.src/cmdset.cc | 33 +- sim/ucsim/cmd.src/cmduc.cc | 4 +- sim/ucsim/cmd.src/cmdutil.cc | 7 +- sim/ucsim/cmd.src/cmdutil.h | 4 +- sim/ucsim/cmd.src/newcmd.cc | 21 +- sim/ucsim/cmd.src/newcmdcl.h | 10 +- sim/ucsim/cmd.src/set.cc | 44 +- sim/ucsim/cmd.src/setcl.h | 4 +- sim/ucsim/cmd.src/timer.cc | 5 +- sim/ucsim/conf | 41 +- sim/ucsim/conf.mk | 1 + sim/ucsim/config.guess | 580 ++++++++++ sim/ucsim/config.sub | 876 ++++++++++++++ sim/ucsim/configure | 423 ++++--- sim/ucsim/configure.in | 111 +- sim/ucsim/ddconfig_in.h | 2 + sim/ucsim/doc/Makefile.in | 2 + sim/ucsim/doc/cpu_types.html | 26 + sim/ucsim/doc/invoke.html | 11 +- sim/ucsim/error.cc | 49 + sim/ucsim/errorcl.h | 56 + sim/ucsim/globals.cc | 4 +- sim/ucsim/gui.src/Makefile.in | 27 +- sim/ucsim/gui.src/guicl.h | 2 +- sim/ucsim/gui.src/serio.src/Makefile.in | 2 + sim/ucsim/gui.src/serio.src/frontend.hh | 1 + sim/ucsim/gui.src/serio.src/main.cc | 2 +- sim/ucsim/main_in.mk | 21 +- sim/ucsim/packages.mk | 30 + sim/ucsim/packages_in.mk | 30 + sim/ucsim/pobj.cc | 43 +- sim/ucsim/pobjcl.h | 2 + sim/ucsim/s51.src/Makefile.in | 30 +- sim/ucsim/s51.src/arith.cc | 413 ++++--- sim/ucsim/s51.src/bit.cc | 102 +- sim/ucsim/s51.src/clean.mk | 2 +- sim/ucsim/s51.src/glob.cc | 3 +- sim/ucsim/s51.src/inc.cc | 54 +- sim/ucsim/s51.src/interrupt.cc | 87 +- sim/ucsim/s51.src/interruptcl.h | 18 +- sim/ucsim/s51.src/jmp.cc | 239 ++-- sim/ucsim/s51.src/logic.cc | 144 +-- sim/ucsim/s51.src/mov.cc | 247 ++-- sim/ucsim/s51.src/pca.cc | 329 ++++++ sim/ucsim/s51.src/pcacl.h | 75 ++ sim/ucsim/s51.src/port.cc | 116 +- sim/ucsim/s51.src/portcl.h | 13 +- sim/ucsim/s51.src/regs51.h | 5 +- sim/ucsim/s51.src/serial.cc | 391 ++++++- sim/ucsim/s51.src/serialcl.h | 43 +- sim/ucsim/s51.src/timer0.cc | 354 +++++- sim/ucsim/s51.src/timer0cl.h | 29 +- sim/ucsim/s51.src/timer1.cc | 47 +- sim/ucsim/s51.src/timer1cl.h | 9 +- sim/ucsim/s51.src/timer2.cc | 367 +++++- sim/ucsim/s51.src/timer2cl.h | 46 +- sim/ucsim/s51.src/types51.h | 59 + sim/ucsim/s51.src/uc390.cc | 459 +++----- sim/ucsim/s51.src/uc390cl.h | 18 +- sim/ucsim/s51.src/uc390hw.cc | 313 +++++ sim/ucsim/s51.src/uc390hwcl.h | 63 + sim/ucsim/s51.src/uc51.cc | 918 ++++----------- sim/ucsim/s51.src/uc51cl.h | 86 +- sim/ucsim/s51.src/uc51r.cc | 374 +----- sim/ucsim/s51.src/uc51rcl.h | 12 +- sim/ucsim/s51.src/uc52.cc | 114 +- sim/ucsim/s51.src/uc52cl.h | 13 +- sim/ucsim/s51.src/uc89c51r.cc | 176 ++- sim/ucsim/s51.src/uc89c51rcl.h | 23 +- sim/ucsim/s51.src/wdt.cc | 106 ++ sim/ucsim/s51.src/wdtcl.h | 65 ++ sim/ucsim/sim.src/Makefile.in | 16 +- sim/ucsim/sim.src/app.cc | 14 +- sim/ucsim/sim.src/appcl.h | 8 +- sim/ucsim/sim.src/arg.cc | 9 +- sim/ucsim/sim.src/argcl.h | 10 +- sim/ucsim/sim.src/brk.cc | 145 ++- sim/ucsim/sim.src/brkcl.h | 76 +- sim/ucsim/sim.src/hw.cc | 249 +++- sim/ucsim/sim.src/hwcl.h | 96 +- sim/ucsim/sim.src/itsrc.cc | 33 +- sim/ucsim/sim.src/itsrccl.h | 15 +- sim/ucsim/sim.src/mem.cc | 1182 +++++++++++++++---- sim/ucsim/sim.src/memcl.h | 272 ++++- sim/ucsim/sim.src/optioncl.h | 2 +- sim/ucsim/sim.src/sim.cc | 16 +- sim/ucsim/sim.src/simcl.h | 5 +- sim/ucsim/sim.src/stackcl.h | 2 +- sim/ucsim/sim.src/test_mem_speed.cc | 94 +- sim/ucsim/sim.src/uc.cc | 359 +++--- sim/ucsim/sim.src/uccl.h | 49 +- sim/ucsim/stypes.h | 73 +- sim/ucsim/xa.src/(c).1 | 25 + sim/ucsim/xa.src/Makefile.in | 120 ++ sim/ucsim/xa.src/clean.mk | 26 + sim/ucsim/xa.src/conf.mk | 10 + sim/ucsim/xa.src/glob.cc | 231 ++++ sim/ucsim/xa.src/glob.h | 160 +++ sim/ucsim/xa.src/inst.cc | 327 ++++++ sim/ucsim/xa.src/inst_gen.cc | 274 +++++ sim/ucsim/xa.src/instcl.h | 54 + sim/ucsim/xa.src/regsxa.h | 192 ++++ sim/ucsim/xa.src/simxa.cc | 45 + sim/ucsim/xa.src/simxacl.h | 45 + sim/ucsim/xa.src/sxa.cc | 52 + sim/ucsim/xa.src/xa.cc | 650 +++++++++++ sim/ucsim/xa.src/xacl.h | 87 ++ sim/ucsim/z80.src/Makefile.in | 36 +- sim/ucsim/z80.src/glob.cc | 1232 +++++++++++++++++++- sim/ucsim/z80.src/glob.h | 7 + sim/ucsim/z80.src/inst.cc | 1312 ++++++++++++++++++++- sim/ucsim/z80.src/inst_cb.cc | 704 ++++++++++++ sim/ucsim/z80.src/inst_dd.cc | 52 + sim/ucsim/z80.src/inst_ddcb.cc | 53 + sim/ucsim/z80.src/inst_ed.cc | 330 ++++++ sim/ucsim/z80.src/inst_fd.cc | 52 + sim/ucsim/z80.src/inst_fdcb.cc | 52 + sim/ucsim/z80.src/inst_xd.cc | 534 +++++++++ sim/ucsim/z80.src/inst_xxcb.cc | 694 +++++++++++ sim/ucsim/z80.src/instcl.h | 94 +- sim/ucsim/z80.src/regsz80.h | 36 +- sim/ucsim/z80.src/z80.cc | 456 ++++++-- sim/ucsim/z80.src/z80.txt | 1402 +++++++++++++++++++++++ sim/ucsim/z80.src/z80cl.h | 11 +- sim/ucsim/z80.src/z80mac.h | 266 +++++ 142 files changed, 17837 insertions(+), 3225 deletions(-) create mode 100755 sim/ucsim/config.guess create mode 100755 sim/ucsim/config.sub create mode 100644 sim/ucsim/error.cc create mode 100644 sim/ucsim/errorcl.h create mode 100644 sim/ucsim/packages.mk create mode 100644 sim/ucsim/packages_in.mk create mode 100644 sim/ucsim/s51.src/pca.cc create mode 100644 sim/ucsim/s51.src/pcacl.h create mode 100644 sim/ucsim/s51.src/types51.h create mode 100644 sim/ucsim/s51.src/uc390hw.cc create mode 100644 sim/ucsim/s51.src/uc390hwcl.h create mode 100644 sim/ucsim/s51.src/wdt.cc create mode 100644 sim/ucsim/s51.src/wdtcl.h create mode 100644 sim/ucsim/xa.src/(c).1 create mode 100644 sim/ucsim/xa.src/Makefile.in create mode 100644 sim/ucsim/xa.src/clean.mk create mode 100644 sim/ucsim/xa.src/conf.mk create mode 100644 sim/ucsim/xa.src/glob.cc create mode 100644 sim/ucsim/xa.src/glob.h create mode 100644 sim/ucsim/xa.src/inst.cc create mode 100644 sim/ucsim/xa.src/inst_gen.cc create mode 100644 sim/ucsim/xa.src/instcl.h create mode 100644 sim/ucsim/xa.src/regsxa.h create mode 100644 sim/ucsim/xa.src/simxa.cc create mode 100644 sim/ucsim/xa.src/simxacl.h create mode 100644 sim/ucsim/xa.src/sxa.cc create mode 100644 sim/ucsim/xa.src/xa.cc create mode 100644 sim/ucsim/xa.src/xacl.h create mode 100644 sim/ucsim/z80.src/inst_cb.cc create mode 100644 sim/ucsim/z80.src/inst_dd.cc create mode 100644 sim/ucsim/z80.src/inst_ddcb.cc create mode 100644 sim/ucsim/z80.src/inst_ed.cc create mode 100644 sim/ucsim/z80.src/inst_fd.cc create mode 100644 sim/ucsim/z80.src/inst_fdcb.cc create mode 100644 sim/ucsim/z80.src/inst_xd.cc create mode 100644 sim/ucsim/z80.src/inst_xxcb.cc create mode 100644 sim/ucsim/z80.src/z80.txt create mode 100644 sim/ucsim/z80.src/z80mac.h diff --git a/sim/ucsim/.version b/sim/ucsim/.version index d724e60d..bd73f470 100644 --- a/sim/ucsim/.version +++ b/sim/ucsim/.version @@ -1 +1 @@ -0.3.2-pre1 +0.4 diff --git a/sim/ucsim/Makefile b/sim/ucsim/Makefile index 9f737410..f33bed6e 100644 --- a/sim/ucsim/Makefile +++ b/sim/ucsim/Makefile @@ -9,7 +9,8 @@ STARTYEAR = 1997 SHELL = /bin/sh PRJDIR = . -PKGS = cmd.src sim.src gui.src s51.src avr.src z80.src doc +include packages.mk +#PKGS = cmd.src sim.src gui.src s51.src avr.src z80.src doc srcdir = . @@ -49,8 +50,7 @@ uninstall: # Deleting all files created by building the program # -------------------------------------------------- clean: - rm -f *core *[%~] *.[oa] *.so ucsim - rm -f .[a-z]*~ + $(MAKE) -f clean.mk clean @for pkg in $(PKGS); do\ $(MAKE) -C $$pkg -f clean.mk clean ;\ done @@ -59,8 +59,7 @@ clean: # Deleting all files created by configuring or building the program # ----------------------------------------------------------------- distclean: clean - rm -f config.cache config.log config.status - rm -f ddconfig.h main.mk *.dep + $(MAKE) -f clean.mk distclean @for pkg in $(PKGS); do\ $(MAKE) -C $$pkg -f clean.mk distclean ;\ done @@ -70,6 +69,7 @@ distclean: clean # Like clean but some files may still exist # ----------------------------------------- mostlyclean: clean + $(MAKE) -f clean.mk mostlyclean @for pkg in $(PKGS); do\ $(MAKE) -C $$pkg -f clean.mk mostlyclean ;\ done @@ -79,6 +79,7 @@ mostlyclean: clean # everything deleted by distclean plus files created by bison, stc. # ----------------------------------------------------------------------- realclean: distclean + $(MAKE) -f clean.mk realclean @for pkg in $(PKGS); do\ $(MAKE) -C $$pkg -f clean.mk realclean ;\ done @@ -97,6 +98,16 @@ dist: distclean # Performing self-test # -------------------- check: + $(MAKE) -f main.mk check + @for pkg in $(PKGS); do\ + $(MAKE) -C $$pkg check ;\ + done + +test: + $(MAKE) -f main.mk test + @for pkg in $(PKGS); do\ + $(MAKE) -C $$pkg test ;\ + done # Performing installation test @@ -173,6 +184,7 @@ echo_freshconf: @echo "FRESHCONF" checkconf: + @echo "CHECKCONF" @if [ -f devel ]; then $(MAKE) freshconf; fi # End of Makefile diff --git a/sim/ucsim/README b/sim/ucsim/README index 2f0994ef..87bd0d1a 100644 --- a/sim/ucsim/README +++ b/sim/ucsim/README @@ -108,6 +108,7 @@ Karl-Max Wagner Edmar Wienskoski Jr Alexandre Frey Kaido Karner +Karl Bongers Maintener of serialview: Timothy Hurman Maintener of other parts: Daniel Drotos diff --git a/sim/ucsim/avr.src/Makefile.in b/sim/ucsim/avr.src/Makefile.in index d24280a3..d08b8c71 100644 --- a/sim/ucsim/avr.src/Makefile.in +++ b/sim/ucsim/avr.src/Makefile.in @@ -21,8 +21,12 @@ CPPFLAGS = @CPPFLAGS@ -I. -I$(PRJDIR) \ CFLAGS = @CFLAGS@ -Wall CXXFLAGS = @CXXFLAGS@ -Wall M_OR_MM = @M_OR_MM@ +PICOPT = @PICOPT@ +SHAREDLIB = @SHAREDLIB@ LIBS = @LIBS@ -L$(PRJDIR) -lsim -lcmd -lutil -lguiucsim +DL = @DL@ +dl_ok = @dl_ok@ prefix = @prefix@ exec_prefix = @exec_prefix@ @@ -36,10 +40,15 @@ man2dir = $(mandir)/man2 infodir = @infodir@ srcdir = @srcdir@ -OBJECTS = savr.o glob.o \ +OBJECTS_SHARED = glob.o \ simavr.o avr.o port.o \ inst.o bit_inst.o jump_inst.o move_inst.o logic_inst.o \ arith_inst.o +OBJECTS_EXE = savr.o +OBJECTS = $(OBJECTS_SHARED) $(OBJECTS_EXE) + +enable_dlso = @enable_dlso@ +dlso_ok = @dlso_ok@ AVRASM = tavrasm TEST_OBJ = test_bit.hex test_dis.hex test_mov.hex test_jmp.hex \ @@ -50,8 +59,6 @@ TEST_OBJ = test_bit.hex test_dis.hex test_mov.hex test_jmp.hex \ # ------------------------------------------ all: checkconf otherlibs avr.src -tests: $(TEST_OBJ) - # Compiling and installing everything and runing test # --------------------------------------------------- @@ -67,7 +74,9 @@ uninstall: # Performing self-test # -------------------- -check: +check: $(TEST_OBJ) + +test: # Performing installation test @@ -99,10 +108,21 @@ include clean.mk # -------- .SUFFIXES: .asm .hex -avr.src: savr +avr.src: savr shared_lib savr: $(OBJECTS) $(PRJDIR)/*.a - $(CXX) $(CXXFLAGS) -o savr $(OBJECTS) $(LIBS) + $(CXX) $(CXXFLAGS) $(OBJECTS) $(LIBS) -o savr + +ifeq ($(dlso_ok),yes) +shared_lib: $(PRJDIR)/savr.so +else +shared_lib: + @echo "No AVR shared lib made." + @echo "(SHAREDLIB="$(SHAREDLIB)",dl_ok="$(dl_ok)",enable_dlso="$(enable_dlso)")" +endif + +$(PRJDIR)/savr.so: $(OBJECTS_SHARED) + $(CXX) -shared $(OBJECTS_SHARED) -o $(PRJDIR)/savr.so otherlibs: cd $(PRJDIR)/cmd.src && $(MAKE) all diff --git a/sim/ucsim/avr.src/arith_inst.cc b/sim/ucsim/avr.src/arith_inst.cc index 566797d0..86cc5b99 100644 --- a/sim/ucsim/avr.src/arith_inst.cc +++ b/sim/ucsim/avr.src/arith_inst.cc @@ -103,7 +103,7 @@ cl_avr::sbci_Rd_K(t_mem code) t_mem sreg= ram->get(SREG); (signed)result= (signed)D-(signed)K-(sreg&BIT_C)?1:0; res= result & 0xff; - ram->write(d, &res); + ram->write(d, res); sreg= sreg & ~(BIT_H|BIT_S|BIT_V|BIT_N|BIT_C); if (0x08 & (((~D)&K) | (K&res) | (res&(~D)))) @@ -153,7 +153,7 @@ cl_avr::subi_Rd_K(t_mem code) D|= ~0xff; (signed)result= (signed)D-(signed)K; res= result & 0xff; - ram->write(d, &res); + ram->write(d, res); t_mem sreg= ram->get(SREG) & ~(BIT_H|BIT_S|BIT_V|BIT_N|BIT_Z|BIT_C); if (0x08 & (((~D)&K) | (K&res) | (res&(~D)))) @@ -289,7 +289,7 @@ cl_avr::sbc_Rd_Rr(t_mem code) t_mem sreg= ram->get(SREG); (signed)result= (signed)D-(signed)R-(sreg&BIT_C)?1:0; res= result & 0xff; - ram->write(d, &res); + ram->write(d, res); sreg= sreg & ~(BIT_H|BIT_S|BIT_V|BIT_N|BIT_C); if (0x08 & (((~D)&R) | (R&res) | (res&(~D)))) @@ -335,7 +335,7 @@ cl_avr::add_Rd_Rr(t_mem code) D= ram->read(d); result= D+R; res= result & 0xff; - ram->write(d, &res); + ram->write(d, res); t_mem sreg= ram->get(SREG); if (!res) @@ -440,7 +440,7 @@ cl_avr::sub_Rd_Rr(t_mem code) D|= ~0xff; (signed)result= (signed)D-(signed)R; res= result & 0xff; - ram->write(d, &res); + ram->write(d, res); t_mem sreg= ram->get(SREG) & ~(BIT_H|BIT_S|BIT_V|BIT_N|BIT_Z|BIT_C); if (0x08 & (((~D)&R) | (R&res) | (res&(~D)))) @@ -487,7 +487,7 @@ cl_avr::adc_Rd_Rr(t_mem code) t_mem sreg= ram->get(SREG); result= D+R+((sreg&BIT_C)?1:0); res= result & 0xff; - ram->write(d, &res); + ram->write(d, res); if (!res) sreg|= BIT_Z; @@ -536,7 +536,7 @@ cl_avr::com_Rd(t_mem code) D= ram->read(d); result= ~D; res= result & 0xff; - ram->write(d, &res); + ram->write(d, res); t_mem sreg= ram->get(SREG); if (!res) @@ -572,7 +572,7 @@ cl_avr::neg_Rd(t_mem code) D= ram->read(d); result= (~D)+1; res= result & 0xff; - ram->write(d, &res); + ram->write(d, res); t_mem sreg= ram->get(SREG); if (res & (~d) & 0x08) @@ -621,7 +621,7 @@ cl_avr::inc_Rd(t_mem code) d= (code&0x1f0)>>4; t_mem data= ram->read(d)+1; - ram->write(d, &data); + ram->write(d, data); t_mem sreg= ram->get(SREG); data= data&0xff; @@ -679,7 +679,7 @@ cl_avr::asr_Rd(t_mem code) if (result & 0x40) result|= 0x80; res= result & 0xff; - ram->write(d, &res); + ram->write(d, res); if (res & 0x80) { sreg|= BIT_N; @@ -694,7 +694,7 @@ cl_avr::asr_Rd(t_mem code) sreg|= BIT_S; if (!res) sreg|= BIT_Z; - ram->write(SREG, &sreg); + ram->write(SREG, sreg); return(resGO); } @@ -719,10 +719,10 @@ cl_avr::lsr_Rd(t_mem code) sreg|= (BIT_C|BIT_V|BIT_S); result= D >> 1; res= result & 0xff; - ram->write(d, &res); + ram->write(d, res); if (!res) sreg|= BIT_Z; - ram->write(SREG, &sreg); + ram->write(SREG, sreg); return(resGO); } @@ -753,7 +753,7 @@ cl_avr::ror_Rd(t_mem code) } result= (D >> 1) | oldc?0x80:0; res= result & 0xff; - ram->write(d, &res); + ram->write(d, res); if (res & 0x80) { sreg|= BIT_N; @@ -768,7 +768,7 @@ cl_avr::ror_Rd(t_mem code) sreg|= BIT_S; if (!res) sreg|= BIT_Z; - ram->write(SREG, &sreg); + ram->write(SREG, sreg); return(resGO); } @@ -790,7 +790,7 @@ cl_avr::dec_Rd(t_mem code) D= ram->read(d); result= D-1; res= result & 0xff; - ram->write(d, &res); + ram->write(d, res); t_mem sreg= ram->get(SREG); if (!res) @@ -842,12 +842,12 @@ cl_avr::mul_Rd_Rr(t_mem code) result= R*D; resl= result & 0xff; resh= (result>>8) & 0xff; - ram->write(0, &resl); - ram->write(1, &resh); + ram->write(0, resl); + ram->write(1, resh); t_mem sreg= ram->read(SREG) & ~BIT_C; if (resh & 0x80) sreg|= BIT_C; - ram->write(SREG, &sreg); + ram->write(SREG, sreg); tick(1); return(resGO); } @@ -872,8 +872,8 @@ cl_avr::adiw_Rdl_K(t_mem code) result= D+K; res= result & 0xffff; t_mem resl= result&0xff, resh= (result>>8)&0xff; - ram->write(dl+1, &resh); - ram->write(dl, &resl); + ram->write(dl+1, resh); + ram->write(dl, resl); t_mem sreg= ram->get(SREG); if (!res) @@ -925,8 +925,8 @@ cl_avr::sbiw_Rdl_K(t_mem code) (signed)result= (signed)D-(signed)K; res= result & 0xffff; t_mem resl= res&0xff, resh= (res>>8)&0xff; - ram->write(dl+1, &resh); - ram->write(dl, &resl); + ram->write(dl+1, resh); + ram->write(dl, resl); t_mem sreg= ram->get(SREG) & ~(BIT_S|BIT_V|BIT_N|BIT_Z|BIT_C); int n= 0, v= 0; diff --git a/sim/ucsim/avr.src/avr.cc b/sim/ucsim/avr.src/avr.cc index 74ac188a..2fda8bee 100644 --- a/sim/ucsim/avr.src/avr.cc +++ b/sim/ucsim/avr.src/avr.cc @@ -226,8 +226,8 @@ cl_avr::disass(t_addr addr, char *sep) int k= code&0xfff; if (code&0x800) k|= -4096; - sprintf(temp, "0x%06lx", - (k+1+(signed int)addr) % rom->size); + sprintf(temp, "0x%06"_A_"x", + t_addr((k+1+(signed int)addr) % rom->size)); break; } default: @@ -288,8 +288,7 @@ cl_avr::print_regs(class cl_console *con) (sreg&BIT_N)?'1':'0', (sreg&BIT_Z)?'1':'0', (sreg&BIT_C)?'1':'0'); - con->dd_printf("SP = 0x%06x\n", - ram->get(SPH)*256+ram->get(SPL)); + con->dd_printf("SP = 0x%06x\n", ram->get(SPH)*256+ram->get(SPL)); x= ram->get(XH)*256 + ram->get(XL); data= ram->get(x); @@ -561,12 +560,12 @@ cl_avr::push_data(t_mem data) spl= ram->read(SPL); sph= ram->read(SPH); sp= 0xffff & (256*sph + spl); - ram->write(sp, &data); + data= ram->write(sp, data); sp= 0xffff & (sp-1); spl= sp & 0xff; sph= (sp>>8) & 0xff; - ram->write(SPL, &spl); - ram->write(SPH, &sph); + ram->write(SPL, spl); + ram->write(SPH, sph); return(resGO); } @@ -581,14 +580,14 @@ cl_avr::push_addr(t_addr addr) sp= 0xffff & (256*sph + spl); al= addr & 0xff; ah= (addr>>8) & 0xff; - ram->write(sp, &ah); + ram->write(sp, ah); sp= 0xffff & (sp-1); - ram->write(sp, &al); + ram->write(sp, al); sp= 0xffff & (sp-1); spl= sp & 0xff; sph= (sp>>8) & 0xff; - ram->write(SPL, &spl); - ram->write(SPH, &sph); + ram->write(SPL, spl); + ram->write(SPH, sph); return(resGO); } @@ -605,8 +604,8 @@ cl_avr::pop_data(t_mem *data) *data= ram->read(sp); spl= sp & 0xff; sph= (sp>>8) & 0xff; - ram->write(SPL, &spl); - ram->write(SPH, &sph); + ram->write(SPL, spl); + ram->write(SPH, sph); return(resGO); } @@ -627,8 +626,8 @@ cl_avr::pop_addr(t_addr *addr) *addr= ah*256 + al; spl= sp & 0xff; sph= (sp>>8) & 0xff; - ram->write(SPL, &spl); - ram->write(SPH, &sph); + ram->write(SPL, spl); + ram->write(SPH, sph); return(resGO); } diff --git a/sim/ucsim/avr.src/bit_inst.cc b/sim/ucsim/avr.src/bit_inst.cc index 1753e9d0..06998379 100644 --- a/sim/ucsim/avr.src/bit_inst.cc +++ b/sim/ucsim/avr.src/bit_inst.cc @@ -41,7 +41,7 @@ int cl_avr::sec(t_mem code) { t_mem d= BIT_C | ram->read(SREG); - ram->write(SREG, &d); + ram->write(SREG, d); return(resGO); } @@ -57,7 +57,7 @@ int cl_avr::sen(t_mem code) { t_mem d= BIT_N | ram->read(SREG); - ram->write(SREG, &d); + ram->write(SREG, d); return(resGO); } @@ -73,7 +73,7 @@ int cl_avr::sez(t_mem code) { t_mem d= BIT_Z | ram->read(SREG); - ram->write(SREG, &d); + ram->write(SREG, d); return(resGO); } @@ -89,7 +89,7 @@ int cl_avr::sei(t_mem code) { t_mem d= BIT_I | ram->read(SREG); - ram->write(SREG, &d); + ram->write(SREG, d); return(resGO); } @@ -105,7 +105,7 @@ int cl_avr::ses(t_mem code) { t_mem d= BIT_S | ram->read(SREG); - ram->write(SREG, &d); + ram->write(SREG, d); return(resGO); } @@ -121,7 +121,7 @@ int cl_avr::sev(t_mem code) { t_mem d= BIT_V | ram->read(SREG); - ram->write(SREG, &d); + ram->write(SREG, d); return(resGO); } @@ -137,7 +137,7 @@ int cl_avr::set(t_mem code) { t_mem d= BIT_T | ram->read(SREG); - ram->write(SREG, &d); + ram->write(SREG, d); return(resGO); } @@ -153,7 +153,7 @@ int cl_avr::seh(t_mem code) { t_mem d= BIT_H | ram->read(SREG); - ram->write(SREG, &d); + ram->write(SREG, d); return(resGO); } @@ -169,7 +169,7 @@ int cl_avr::clc(t_mem code) { t_mem d= ~BIT_C & ram->read(SREG); - ram->write(SREG, &d); + ram->write(SREG, d); return(resGO); } @@ -185,7 +185,7 @@ int cl_avr::cln(t_mem code) { t_mem d= ~BIT_N & ram->read(SREG); - ram->write(SREG, &d); + ram->write(SREG, d); return(resGO); } @@ -201,7 +201,7 @@ int cl_avr::clz(t_mem code) { t_mem d= ~BIT_Z & ram->read(SREG); - ram->write(SREG, &d); + ram->write(SREG, d); return(resGO); } @@ -217,7 +217,7 @@ int cl_avr::cli(t_mem code) { t_mem d= ~BIT_I & ram->read(SREG); - ram->write(SREG, &d); + ram->write(SREG, d); return(resGO); } @@ -233,7 +233,7 @@ int cl_avr::cls(t_mem code) { t_mem d= ~BIT_S & ram->read(SREG); - ram->write(SREG, &d); + ram->write(SREG, d); return(resGO); } @@ -249,7 +249,7 @@ int cl_avr::clv(t_mem code) { t_mem d= ~BIT_V & ram->read(SREG); - ram->write(SREG, &d); + ram->write(SREG, d); return(resGO); } @@ -265,7 +265,7 @@ int cl_avr::clt(t_mem code) { t_mem d= ~BIT_T & ram->read(SREG); - ram->write(SREG, &d); + ram->write(SREG, d); return(resGO); } @@ -281,7 +281,7 @@ int cl_avr::clh(t_mem code) { t_mem d= ~BIT_H & ram->read(SREG); - ram->write(SREG, &d); + ram->write(SREG, d); return(resGO); } @@ -302,7 +302,7 @@ cl_avr::cbi_A_b(t_mem code) addr= ((code&0xf8)>>3)+0x20; mask= 1 << (code&7); d= ~mask & ram->read(addr); - ram->write(addr, &d); + ram->write(addr, d); tick(1); return(resGO); } @@ -323,7 +323,7 @@ cl_avr::sbi_A_b(t_mem code) addr= ((code&0xf8)>>3)+0x20; mask= 1 << (code&7); t_mem d= mask | ram->read(addr); - ram->write(addr, &d); + ram->write(addr, d); tick(1); return(resGO); } @@ -350,7 +350,7 @@ cl_avr::bld_Rd_b(t_mem code) data= ram->read(d) | mask; else data= ram->read(d) & ~mask; - ram->write(d, &data); + ram->write(d, data); return(resGO); } diff --git a/sim/ucsim/avr.src/inst.cc b/sim/ucsim/avr.src/inst.cc index 3e9382c9..5818294f 100644 --- a/sim/ucsim/avr.src/inst.cc +++ b/sim/ucsim/avr.src/inst.cc @@ -88,7 +88,7 @@ cl_avr::ser_Rd(t_mem code) { t_addr d= (code&0xf0)>>4; t_mem data= 0xff; - ram->write(d, &data); + ram->write(d, data); return(resGO); } diff --git a/sim/ucsim/avr.src/jump_inst.cc b/sim/ucsim/avr.src/jump_inst.cc index 706b6935..49c9769b 100644 --- a/sim/ucsim/avr.src/jump_inst.cc +++ b/sim/ucsim/avr.src/jump_inst.cc @@ -121,7 +121,7 @@ cl_avr::reti(t_mem code) PC= a % rom->size; t_mem sreg= ram->read(SREG); sreg|= BIT_I; - ram->write(SREG, &sreg); + ram->write(SREG, sreg); tick(3); return(resGO); } diff --git a/sim/ucsim/avr.src/logic_inst.cc b/sim/ucsim/avr.src/logic_inst.cc index fadc9808..3a2c935b 100644 --- a/sim/ucsim/avr.src/logic_inst.cc +++ b/sim/ucsim/avr.src/logic_inst.cc @@ -45,7 +45,7 @@ cl_avr::ori_Rd_K(t_mem code) d= (code&0xf0)>>4; K= ((code&0xf00)>>4)|(code&0xf); data= K | ram->read(d); - ram->write(d+16, &data); + ram->write(d+16, data); set_zn0s(data); return(resGO); } @@ -67,7 +67,7 @@ cl_avr::andi_Rd_K(t_mem code) d= (code&0xf0)>>4; K= ((code&0xf00)>>4)|(code&0xf); data= K & ram->read(d); - ram->write(d+16, &data); + ram->write(d+16, data); set_zn0s(data); return(resGO); } @@ -89,7 +89,7 @@ cl_avr::and_Rd_Rr(t_mem code) d= (code&0x1f0)>>4; r= ((code&0x200)>>5)|(code&0xf); data= ram->read(d) & ram->read(r); - ram->write(d, &data); + ram->write(d, data); set_zn0s(data); return(resGO); } @@ -111,7 +111,7 @@ cl_avr::eor_Rd_Rr(t_mem code) d= (code&0x1f0)>>4; r= ((code&0x200)>>5)|(code&0xf); data= ram->read(d) ^ ram->read(r); - ram->write(d, &data); + ram->write(d, data); set_zn0s(data); return(resGO); } @@ -133,7 +133,7 @@ cl_avr::or_Rd_Rr(t_mem code) d= (code&0x1f0)>>4; r= ((code&0x200)>>5)|(code&0xf); data= ram->read(d) | ram->read(r); - ram->write(d, &data); + ram->write(d, data); set_zn0s(data); return(resGO); } diff --git a/sim/ucsim/avr.src/move_inst.cc b/sim/ucsim/avr.src/move_inst.cc index 7ad3a005..42c7590f 100644 --- a/sim/ucsim/avr.src/move_inst.cc +++ b/sim/ucsim/avr.src/move_inst.cc @@ -89,7 +89,7 @@ cl_avr::ldi_Rd_K(t_mem code) d= (code&0xf0)>>4; K= ((code&0xf00)>>4)|(code&0xf); - ram->write(d+16, &K); + ram->write(d+16, K); return(resGO); } @@ -118,7 +118,7 @@ cl_avr::ldd_Rd_Z_q(t_mem code) q= ((code&0x2000)>>8)|((code&0xc00)>>7)|(code&0x7); z= ram->get(ZH)*256 + ram->get(ZL); t_mem data= ram->read(z+q); - ram->write(d, &data); + ram->write(d, data); tick(1); return(resGO); } @@ -141,7 +141,7 @@ cl_avr::ldd_Rd_Y_q(t_mem code) q= ((code&0x2000)>>8)|((code&0xc00)>>7)|(code&0x7); y= ram->get(YH)*256 + ram->get(YL); t_mem data= ram->read(y+q); - ram->write(d, &data); + ram->write(d, data); tick(1); return(resGO); } @@ -164,7 +164,7 @@ cl_avr::std_Z_q_Rr(t_mem code) q= ((code&0x2000)>>8)|((code&0xc00)>>7)|(code&0x7); z= ram->get(ZH)*256 + ram->get(ZL); t_mem data= ram->read(r); - ram->write(z+q, &data); + ram->write(z+q, data); tick(1); return(resGO); } @@ -187,7 +187,7 @@ cl_avr::std_Y_q_Rr(t_mem code) q= ((code&0x2000)>>8)|((code&0xc00)>>7)|(code&0x7); y= ram->get(YH)*256 + ram->get(YL); t_mem data= ram->read(r); - ram->write(y+q, &data); + ram->write(y+q, data); tick(1); return(resGO); } @@ -209,7 +209,7 @@ cl_avr::lds_Rd_k(t_mem code) d= (code&0x1f0)>>4; k= fetch(); t_mem data= ram->read(k); - ram->write(d, &data); + ram->write(d, data); tick(2); return(resGO); } @@ -230,7 +230,7 @@ cl_avr::ld_Rd_Z$(t_mem code) d= (code&0x1f0)>>4; z= ram->get(ZH)*256 + ram->get(ZL); t_mem data= ram->read(z); - ram->write(d, &data); + ram->write(d, data); ram->set(ZL, data= (ram->get(ZL)+1)&0xff); if (!data) ram->set(ZH, (ram->get(ZH)+1)&0xff); @@ -258,7 +258,7 @@ cl_avr::ld_Rd_$Z(t_mem code) ram->set(ZH, (ram->get(ZH)-1)&0xff); z= ram->get(ZH)*256 + z; data= ram->read(z); - ram->write(d, &data); + ram->write(d, data); tick(1); return(resGO); } @@ -307,7 +307,7 @@ cl_avr::ld_Rd_Y$(t_mem code) d= (code&0x1f0)>>4; y= ram->get(YH)*256 + ram->get(YL); t_mem data= ram->read(y); - ram->write(d, &data); + ram->write(d, data); ram->set(YL, data= (ram->get(YL)+1)&0xff); if (!data) ram->set(YH, (ram->get(YH)+1)&0xff); @@ -335,7 +335,7 @@ cl_avr::ld_Rd_$Y(t_mem code) ram->set(YH, (ram->get(YH)-1)&0xff); y= ram->get(YH)*256 + y; data= ram->read(y); - ram->write(d, &data); + ram->write(d, data); tick(1); return(resGO); } @@ -356,7 +356,7 @@ cl_avr::ld_Rd_X(t_mem code) d= (code&0x1f0)>>4; x= ram->get(XH)*256 + ram->get(XL); t_mem data= ram->read(x); - ram->write(d, &data); + ram->write(d, data); tick(1); return(resGO); } @@ -377,7 +377,7 @@ cl_avr::ld_Rd_X$(t_mem code) d= (code&0x1f0)>>4; x= ram->get(XH)*256 + ram->get(XL); t_mem data= ram->read(x); - ram->write(d, &data); + ram->write(d, data); ram->set(XL, data= (ram->get(XL)+1)&0xff); if (!data) ram->set(XH, (ram->get(XH)+1)&0xff); @@ -405,7 +405,7 @@ cl_avr::ld_Rd_$X(t_mem code) ram->set(XH, (ram->get(XH)-1)&0xff); x= ram->get(XH)*256 + x; data= ram->read(x); - ram->write(d, &data); + ram->write(d, data); tick(1); return(resGO); } @@ -426,7 +426,7 @@ cl_avr::pop_Rd(t_mem code) d= (code&0x1f0)>>4; pop_data(&D); - ram->write(d, &D); + ram->write(d, D); tick(1); return(resGO); @@ -449,7 +449,7 @@ cl_avr::sts_k_Rr(t_mem code) r= (code&0x1f0)>>4; k= fetch(); t_mem data= ram->read(r); - ram->write(k, &data); + ram->write(k, data); tick(2); return(resGO); } @@ -470,7 +470,7 @@ cl_avr::st_Z$_Rr(t_mem code) r= (code&0x1f0)>>4; z= ram->get(ZH)*256 + ram->get(ZL); t_mem data= ram->read(r); - ram->write(z, &data); + ram->write(z, data); ram->set(ZL, data= (ram->get(ZL)+1)&0xff); if (!data) ram->set(ZH, (ram->get(ZH)+1)&0xff); @@ -498,7 +498,7 @@ cl_avr::st_$Z_Rr(t_mem code) ram->set(ZH, (ram->get(ZH)-1)&0xff); z= ram->get(ZH)*256 + z; data= ram->read(r); - ram->write(z, &data); + ram->write(z, data); tick(1); return(resGO); } @@ -519,7 +519,7 @@ cl_avr::st_Y$_Rr(t_mem code) r= (code&0x1f0)>>4; y= ram->get(YH)*256 + ram->get(YL); t_mem data= ram->read(r); - ram->write(y, &data); + ram->write(y, data); ram->set(YL, data= (ram->get(YL)+1)&0xff); if (!data) ram->set(YH, (ram->get(YH)+1)&0xff); @@ -547,7 +547,7 @@ cl_avr::st_$Y_Rr(t_mem code) ram->set(YH, (ram->get(YH)-1)&0xff); y= ram->get(YH)*256 + y; data= ram->read(r); - ram->write(y, &data); + ram->write(y, data); tick(1); return(resGO); } @@ -569,7 +569,7 @@ cl_avr::st_X_Rr(t_mem code) r= (code&0x1f0)>>4; x= ram->get(XH)*256 + ram->get(XL); t_mem data= ram->read(r); - ram->write(x, &data); + ram->write(x, data); tick(1); return(resGO); } @@ -590,7 +590,7 @@ cl_avr::st_X$_Rr(t_mem code) r= (code&0x1f0)>>4; x= ram->get(XH)*256 + ram->get(XL); t_mem data= ram->read(r); - ram->write(x, &data); + ram->write(x, data); ram->set(XL, data= (ram->get(XL)+1)&0xff); if (!data) ram->set(XH, (ram->get(XH)+1)&0xff); @@ -618,7 +618,7 @@ cl_avr::st_$X_Rr(t_mem code) ram->set(XH, (ram->get(XH)-1)&0xff); x= ram->get(XH)*256 + x; data= ram->read(r); - ram->write(x, &data); + ram->write(x, data); tick(1); return(resGO); } @@ -663,7 +663,7 @@ cl_avr::swap_Rd(t_mem code) data= ram->read(d); temp= (data>>4)&0xf; data= (data<<4)|temp; - ram->write(d, &data); + ram->write(d, data); return(resGO); } @@ -684,7 +684,7 @@ cl_avr::in_Rd_A(t_mem code) P= ((code&0x600)>>5)|(code&0xf); d= (code&0x1f0)>>4; data= ram->read(P+0x20); - ram->write(d, &data); + ram->write(d, data); return(resGO); } @@ -705,7 +705,7 @@ cl_avr::out_A_Rr(t_mem code) P= ((code&0x600)>>5)|(code&0xf); r= (code&0x1f0)>>4; data= ram->read(r); - ram->write(P+0x20, &data); + ram->write(P+0x20, data); return(resGO); } @@ -725,7 +725,7 @@ cl_avr::mov_Rd_Rr(t_mem code) d= (code&0x1f0)>>4; r= ((code&0x200)>>5)|(code&0xf); t_mem data= ram->read(r); - ram->write(d, &data); + ram->write(d, data); return(resGO); } diff --git a/sim/ucsim/avr.src/port.cc b/sim/ucsim/avr.src/port.cc index ca7be64b..0cb2638f 100644 --- a/sim/ucsim/avr.src/port.cc +++ b/sim/ucsim/avr.src/port.cc @@ -34,11 +34,11 @@ Software Foundation, 59 Temple Place - Suite 330, Boston, MA cl_port::cl_port(class cl_uc *auc): cl_hw(auc, HW_PORT, 0, "port") { - uc->register_hw_read(MEM_SFR, 2, this); - uc->register_hw_read(MEM_SFR, 4, this); + //uc->register_hw_read(MEM_SFR, 2, this); + //uc->register_hw_read(MEM_SFR, 4, this); } -ulong +/*ulong cl_port::read(class cl_mem *mem, long addr) { switch (addr) @@ -49,7 +49,7 @@ cl_port::read(class cl_mem *mem, long addr) return(44); } return(cl_hw::read(mem, addr)); -} +}*/ /* End of avr.src/port.cc */ diff --git a/sim/ucsim/avr.src/portcl.h b/sim/ucsim/avr.src/portcl.h index fc189c74..781a98be 100644 --- a/sim/ucsim/avr.src/portcl.h +++ b/sim/ucsim/avr.src/portcl.h @@ -36,7 +36,7 @@ class cl_port: public cl_hw public: cl_port(class cl_uc *auc); - virtual ulong read(class cl_mem *mem, long addr); + //virtual ulong read(class cl_mem *mem, long addr); }; diff --git a/sim/ucsim/clean.mk b/sim/ucsim/clean.mk index 6446fb20..93eefab0 100644 --- a/sim/ucsim/clean.mk +++ b/sim/ucsim/clean.mk @@ -1,22 +1,23 @@ -# PENDING: Delegate up to the Makefile - # Deleting all files created by building the program # -------------------------------------------------- clean: - make clean + rm -f *core *[%~] *.[oa] *.so ucsim + rm -f .[a-z]*~ + # Deleting all files created by configuring or building the program # ----------------------------------------------------------------- -distclean: - make distclean +distclean: clean + rm -f config.cache config.log config.status + rm -f ddconfig.h main.mk *.dep + # Like clean but some files may still exist # ----------------------------------------- -mostlyclean: - make mostlyclean +mostlyclean: clean + # Deleting everything that can reconstructed by this Makefile. It deletes # everything deleted by distclean plus files created by bison, etc. # ----------------------------------------------------------------------- -realclean: - make realclean \ No newline at end of file +realclean: distclean diff --git a/sim/ucsim/cmd.src/Makefile.in b/sim/ucsim/cmd.src/Makefile.in index 3edbab35..020c6160 100644 --- a/sim/ucsim/cmd.src/Makefile.in +++ b/sim/ucsim/cmd.src/Makefile.in @@ -60,6 +60,8 @@ uninstall: # -------------------- check: +test: + # Performing installation test # ---------------------------- @@ -91,7 +93,7 @@ include clean.mk cmdlib: $(PRJDIR)/libcmd.a $(PRJDIR)/libcmd.a: $(OBJECTS) - $(AR) -rcu $*.a $(OBJECTS) + ar -rcu $*.a $(OBJECTS) $(RANLIB) $*.a .cc.o: diff --git a/sim/ucsim/cmd.src/bp.cc b/sim/ucsim/cmd.src/bp.cc index c951642b..7a130240 100644 --- a/sim/ucsim/cmd.src/bp.cc +++ b/sim/ucsim/cmd.src/bp.cc @@ -102,7 +102,8 @@ cl_break_cmd::do_fetch(class cl_uc *uc, con->dd_printf("Breakpoint at 0x%06x is already set.\n", addr); else { - class cl_brk *b= new cl_fetch_brk(uc->make_new_brknr(), + class cl_brk *b= new cl_fetch_brk(uc->mem(MEM_ROM), + uc->make_new_brknr(), addr, perm, hit); b->init(); uc->fbrk->add_bp(b); @@ -190,7 +191,10 @@ COMMAND_DO_WORK_UC(cl_delete_cmd) { long num; if (param->get_ivalue(&num)) - uc->rm_brk(num); + { + if (!uc->rm_brk(num)) + con->dd_printf("Error\n"); + } } } return(DD_FALSE); diff --git a/sim/ucsim/cmd.src/cmdconf.cc b/sim/ucsim/cmd.src/cmdconf.cc index 92aae0c2..1d4d79e5 100644 --- a/sim/ucsim/cmd.src/cmdconf.cc +++ b/sim/ucsim/cmd.src/cmdconf.cc @@ -50,7 +50,8 @@ COMMAND_DO_WORK_UC(cl_conf_cmd) con->dd_printf("ucsim version %s\n", VERSIONSTR); con->dd_printf("Type of microcontroller: %s\n", uc->id_string()); - con->dd_printf("Controller has %d hardware element(s).\n", uc->hws->count); + con->dd_printf("Controller has %d hardware element(s).\n", + uc->hws->count); for (i= 0; i < uc->hws->count; i++) { class cl_hw *hw= (class cl_hw *)(uc->hws->at(i)); diff --git a/sim/ucsim/cmd.src/cmdset.cc b/sim/ucsim/cmd.src/cmdset.cc index d77702f9..5d145c56 100644 --- a/sim/ucsim/cmd.src/cmdset.cc +++ b/sim/ucsim/cmd.src/cmdset.cc @@ -86,15 +86,17 @@ COMMAND_DO_WORK_SIM(cl_run_cmd) } else { - b= new cl_fetch_brk(sim->uc->make_new_brknr(), end, + b= new cl_fetch_brk(sim->uc->mem(MEM_ROM), + sim->uc->make_new_brknr(), end, brkDYNAMIC, 1); sim->uc->fbrk->add_bp(b); } } } con->dd_printf("Simulation started, PC=0x%06x\n", sim->uc->PC); - if (sim->uc->fbrk_at(start)) + if (sim->uc->fbrk_at(sim->uc->PC)) sim->uc->do_inst(1); + sim->start(con); return(DD_FALSE); } @@ -126,7 +128,9 @@ COMMAND_DO_WORK_SIM(cl_stop_cmd) // class cl_cmdline *cmdline, class cl_console *con) COMMAND_DO_WORK_UC(cl_step_cmd) { + printf("step %x\n",uc->PC); uc->do_inst(1); + printf("step done %x\n",uc->PC); uc->print_regs(con); return(0); } @@ -144,8 +148,11 @@ COMMAND_DO_WORK_SIM(cl_next_cmd) { class cl_brk *b; t_addr next; - struct dis_entry *de; + int branch; + int inst_len; +#if 0 + struct dis_entry *de; t_mem code= sim->uc->get_mem(MEM_ROM, sim->uc->PC); int i= 0; de= &(sim->uc->dis_tbl()[i]); @@ -155,16 +162,28 @@ COMMAND_DO_WORK_SIM(cl_next_cmd) i++; de= &(sim->uc->dis_tbl()[i]); } - if ((de->branch == 'a') || - (de->branch == 'l')) +#endif + + branch = sim->uc->inst_branch(sim->uc->PC); + inst_len = sim->uc->inst_length(sim->uc->PC); + + if ((branch == 'a') || (branch == 'l')) { - next= sim->uc->PC + de->length; + next= sim->uc->PC + inst_len; if (!sim->uc->fbrk_at(next)) { - b= new cl_fetch_brk(sim->uc->make_new_brknr(), + b= new cl_fetch_brk(sim->uc->mem(MEM_ROM), + sim->uc->make_new_brknr(), next, brkDYNAMIC, 1); + + b->init(); +// sim->uc->fbrk->add_bp(b); + sim->uc->fbrk->add(b); + b->activate(); } + if (sim->uc->fbrk_at(sim->uc->PC)) + sim->uc->do_inst(1); sim->start(con); //sim->uc->do_inst(-1); } diff --git a/sim/ucsim/cmd.src/cmduc.cc b/sim/ucsim/cmd.src/cmduc.cc index 5c4bf67a..3623bd7a 100644 --- a/sim/ucsim/cmd.src/cmduc.cc +++ b/sim/ucsim/cmd.src/cmduc.cc @@ -340,7 +340,7 @@ COMMAND_DO_WORK_UC(cl_dc_cmd) for (; start <= end; - start+= uc->inst_length(rom->get(start))) + start+= uc->inst_length(start)) uc->print_disass(start, con); last= start; return(DD_FALSE); @@ -455,7 +455,7 @@ COMMAND_DO_WORK_UC(cl_fill_cmd) { t_mem d; d= what; - mem->write(i, &d); + mem->write(i, d); } } else diff --git a/sim/ucsim/cmd.src/cmdutil.cc b/sim/ucsim/cmd.src/cmdutil.cc index c56bbe4c..50a90e3e 100644 --- a/sim/ucsim/cmd.src/cmdutil.cc +++ b/sim/ucsim/cmd.src/cmdutil.cc @@ -130,7 +130,7 @@ get_name_entry(struct name_entry tabl[], char *name, class cl_uc *uc) * Interpreting a bitname */ -bool +/*bool interpret_bitname(char *name, class cl_uc *uc, uchar **cell, uchar *celladdr, uchar *bitaddr, uchar *bitmask, @@ -189,7 +189,8 @@ interpret_bitname(char *name, class cl_uc *uc, *celladdr= (*bitaddr >> 3) + 0x20; } // *bitaddr, *celladdr now OK - *cell= uc->get_bit/*FIXME*/(*bitaddr); + *cell= uc->get_bit//FIXME + (*bitaddr); *bitmask= BIT_MASK(*bitaddr); // making symbolic name if (!symname) @@ -221,7 +222,7 @@ interpret_bitname(char *name, class cl_uc *uc, strcat(sym, bitnumstr); *symname= sym; return(DD_TRUE); -} +}*/ /* diff --git a/sim/ucsim/cmd.src/cmdutil.h b/sim/ucsim/cmd.src/cmdutil.h index 679e6967..0e630d9d 100644 --- a/sim/ucsim/cmd.src/cmdutil.h +++ b/sim/ucsim/cmd.src/cmdutil.h @@ -38,10 +38,10 @@ extern int make_server_socket(unsigned short int port); extern struct name_entry *get_name_entry(struct name_entry tabl[], char *name, class cl_uc *uc); -extern bool interpret_bitname(char *name, class cl_uc *uc, +/*extern bool interpret_bitname(char *name, class cl_uc *uc, uchar **cell, uchar *celladdr, uchar *bitaddr, uchar *bitmask, - char **symname); + char **symname);*/ extern char *proc_escape(char *string, int *len); diff --git a/sim/ucsim/cmd.src/newcmd.cc b/sim/ucsim/cmd.src/newcmd.cc index 580af58d..57c45cac 100644 --- a/sim/ucsim/cmd.src/newcmd.cc +++ b/sim/ucsim/cmd.src/newcmd.cc @@ -638,7 +638,7 @@ int cl_cmd::do_work(class cl_cmdline *cmdline, class cl_console *con) { con->dd_printf("Command \"%s\" does nothing.\n", - (char*)(names->at(0))); + (char*)(names->at(0))); return(0); } @@ -647,7 +647,7 @@ cl_cmd::do_work(class cl_app *app, class cl_cmdline *cmdline, class cl_console *con) { con->dd_printf("Command \"%s\" does nothing on application.\n", - (char*)(names->at(0))); + (char*)(names->at(0))); return(0); } @@ -656,7 +656,7 @@ cl_cmd::do_work(class cl_sim *sim, class cl_cmdline *cmdline, class cl_console *con) { con->dd_printf("Command \"%s\" does nothing on simulator.\n", - (char*)(names->at(0))); + (char*)(names->at(0))); return(0); } @@ -665,7 +665,7 @@ cl_cmd::do_work(class cl_uc *uc, class cl_cmdline *cmdline, class cl_console *con) { con->dd_printf("Command \"%s\" does nothing on microcontroller.\n", - (char*)(names->at(0))); + (char*)(names->at(0))); return(0); } @@ -1349,12 +1349,19 @@ cl_commander::dd_printf(char *format, ...) { va_list ap; int ret= 0; + FILE *f; - if (actual_console && - actual_console->out) + if (actual_console) + f= actual_console->out; + else if (frozen_console) + f= frozen_console->out; + else + f= 0; + if (/*actual_console && + actual_console->out*/f) { va_start(ap, format); - ret= cmd_do_print(actual_console->out, format, ap); + ret= cmd_do_print(f/*actual_console->out*/, format, ap); va_end(ap); } return(ret); diff --git a/sim/ucsim/cmd.src/newcmdcl.h b/sim/ucsim/cmd.src/newcmdcl.h index 96cd43d5..9b6bba0e 100644 --- a/sim/ucsim/cmd.src/newcmdcl.h +++ b/sim/ucsim/cmd.src/newcmdcl.h @@ -32,7 +32,7 @@ Software Foundation, 59 Temple Place - Suite 330, Boston, MA #include "ddconfig.h" #include -#include // to define fd_set +#include #if FD_HEADER_OK # include HEADER_FD #endif @@ -121,7 +121,7 @@ public: int can_rep, char *short_hlp, char *long_hlp); - ~cl_cmd(void); + virtual ~cl_cmd(void); virtual void add_name(char *name); virtual int name_match(char *aname, int strict); @@ -270,7 +270,7 @@ public: char *short_hlp, char *long_hlp, class cl_cmdset *acommands); - ~cl_super_cmd(void); + virtual ~cl_super_cmd(void); virtual int work(class cl_app *app, class cl_cmdline *cmdline, class cl_console *con); @@ -299,7 +299,7 @@ public: #ifdef SOCKET_AVAIL cl_console(int portnumber, class cl_app *the_app); #endif - ~cl_console(void); + virtual ~cl_console(void); virtual int init(void); virtual void welcome(void); @@ -350,7 +350,7 @@ public: public: cl_commander(class cl_app *the_app, class cl_cmdset *acmdset/*, class cl_sim *asim*/); - ~cl_commander(void); + virtual ~cl_commander(void); virtual int init(void); virtual class cl_console *mk_console(char *fin, char *fout); diff --git a/sim/ucsim/cmd.src/set.cc b/sim/ucsim/cmd.src/set.cc index 48888480..b7e48ae4 100644 --- a/sim/ucsim/cmd.src/set.cc +++ b/sim/ucsim/cmd.src/set.cc @@ -68,9 +68,10 @@ COMMAND_DO_WORK_UC(cl_set_mem_cmd) int i; t_addr addr; for (i= 0, addr= start; - i < len && addr < mem->size; + i < len && addr <= mem->size; i++, addr++) - mem->write(addr, &(array[i])); + mem->set(addr, array[i]); + uc->check_errors(); mem->dump(start, start+len-1, 8, con); } } @@ -117,38 +118,43 @@ COMMAND_DO_WORK_UC(cl_set_bit_cmd) /* - * Command: set port + * Command: set hw *---------------------------------------------------------------------------- */ -//int -//cl_set_port_cmd::do_work(class cl_sim *sim, -// class cl_cmdline *cmdline, class cl_console *con) -COMMAND_DO_WORK_UC(cl_set_port_cmd) +COMMAND_DO_WORK_UC(cl_set_hw_cmd) { - class cl_hw *hw; - long l= 0, pn= -1; - class cl_cmd_arg *params[4]= { cmdline->param(0), + class cl_hw *hw= 0; + class cl_cmd_arg *params[1]= { cmdline->param(0)/*, cmdline->param(1), cmdline->param(2), - cmdline->param(3) }; + cmdline->param(3)*/ }; - if (cmdline->syntax_match(uc, HW NUMBER)) { + if (/*cmdline->syntax_match(uc, HW)*/params[0]->as_hw(uc)) { hw= params[0]->value.hw; - pn= hw->id; - l= params[1]->value.number; + //pn= hw->id; + //l= params[1]->value.number; } - else if (cmdline->syntax_match(uc, NUMBER NUMBER)) { + /*else if (cmdline->syntax_match(uc, NUMBER NUMBER)) { pn= params[0]->value.number; l= params[1]->value.number; - } + hw= uc->get_hw(HW_PORT, pn, 0); + }*/ else con->dd_printf("%s\n", short_help?short_help:"Error: wrong syntax\n"); - if (pn < 0 || + /*if (pn < 0 || pn > 3) con->dd_printf("Error: wrong port\n"); - else - uc->port_pins[pn]= l; + else*/ + { + if (hw) + { + cmdline->shift(); + hw->set_cmd(cmdline, con); + } + else + con->dd_printf("Error: no hw\n"); + } return(DD_FALSE);; } diff --git a/sim/ucsim/cmd.src/setcl.h b/sim/ucsim/cmd.src/setcl.h index 7ffc58fc..7524778a 100644 --- a/sim/ucsim/cmd.src/setcl.h +++ b/sim/ucsim/cmd.src/setcl.h @@ -37,8 +37,8 @@ COMMAND_ON(uc,cl_set_mem_cmd); // SET BIT COMMAND_ON(uc,cl_set_bit_cmd); -// SET PORT -COMMAND_ON(uc,cl_set_port_cmd); +// SET HW +COMMAND_ON(uc,cl_set_hw_cmd); // SET OPTION COMMAND_ON(uc,cl_set_option_cmd); diff --git a/sim/ucsim/cmd.src/timer.cc b/sim/ucsim/cmd.src/timer.cc index 17abb4c8..021b0822 100644 --- a/sim/ucsim/cmd.src/timer.cc +++ b/sim/ucsim/cmd.src/timer.cc @@ -81,7 +81,7 @@ COMMAND_DO_WORK_UC(cl_timer_cmd) return(val(uc, cmdline, con)); else con->dd_printf("Undefined timer command: \"%s\". Try \"help timer\"\n", - s); + s); } return(0); } @@ -114,8 +114,7 @@ cl_timer_cmd::add(class cl_uc *uc, if (!name && what < 1) { - con->dd_printf("Error: " - "Timer id must be greater then zero or a string\n"); + con->dd_printf("Error: Timer id must be greater then zero or a string\n"); return(DD_FALSE); } if (ticker) diff --git a/sim/ucsim/conf b/sim/ucsim/conf index 724ad86d..c3e4fcf4 100755 --- a/sim/ucsim/conf +++ b/sim/ucsim/conf @@ -1 +1,40 @@ -./configure --prefix=${HOME}/local "$@" +#!/bin/bash + +TARGET=linux + +if [ "$#" -ge 1 ]; then + case "$1" in + [lL]*) TARGET=linux;shift;; + [mM]*) TARGET=mingw;shift;; + *) echo "Unknown target \"${1}\"" >&2; exit 1;; + esac +fi + +if [ -f devel ]; then + export CXXFLAGS="" +fi + +case $TARGET in + linux) + ./configure --prefix=${HOME}/local \ + --enable-ucsim \ + --enable-dlso \ + --enable-serio \ + --enable-z80 \ + --enable-xa \ + "$@" + ;; + mingw) + export CC=/usr/local/cross-tools/mingw32/bin/gcc + export CXX=/usr/local/cross-tools/mingw32/bin/g++ + ./configure --prefix=${HOME}/local \ + --disable-ucsim \ + --disable-dlso \ + --disable-serio \ + --enable-z80 \ + --enable-xa \ + "$@" + ;; +esac + +# End of conf diff --git a/sim/ucsim/conf.mk b/sim/ucsim/conf.mk index 8ef8dcf9..3520f3c8 100644 --- a/sim/ucsim/conf.mk +++ b/sim/ucsim/conf.mk @@ -10,5 +10,6 @@ main.mk: $(srcdir)/main_in.mk config.status ddconfig.h: ddconfig_in.h config.status @echo "Re-making ddconfig.h" $(SHELL) ./config.status + touch ddconfig.h # End of conf.mk diff --git a/sim/ucsim/config.guess b/sim/ucsim/config.guess new file mode 100755 index 00000000..6a378489 --- /dev/null +++ b/sim/ucsim/config.guess @@ -0,0 +1,580 @@ +#!/bin/sh +#set -x +# Attempt to guess a canonical system name. +# Copyright (C) 1992, 1993, 1994, 1995 Free Software Foundation, Inc. +# +# This file 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. +# +# This program 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 this program; if not, write to the Free Software +# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. +# +# As a special exception to the GNU General Public License, if you +# distribute this file as part of a program that contains a +# configuration script generated by Autoconf, you may include it under +# the same distribution terms that you use for the rest of that program. + +# Written by Per Bothner . +# The master version of this file is at the FSF in /home/gd/gnu/lib. +# +# This script attempts to guess a canonical system name similar to +# config.sub. If it succeeds, it prints the system name on stdout, and +# exits with 0. Otherwise, it exits with 1. +# +# The plan is that this can be called by configure scripts if you +# don't specify an explicit system type (host/target name). +# +# Only a few systems have been added to this list; please add others +# (but try to keep the structure clean). +# + +# This is needed to find uname on a Pyramid OSx when run in the BSD universe. +# (ghazi@noc.rutgers.edu 8/24/94.) +if (test -f /.attbin/uname) >/dev/null 2>&1 ; then + PATH=$PATH:/.attbin ; export PATH +fi + +UNAME_MACHINE=`(uname -m) 2>/dev/null|sed 's/ *$//'` || UNAME_MACHINE=unknown +UNAME_RELEASE=`(uname -r) 2>/dev/null|sed 's/ *$//'` || UNAME_RELEASE=unknown +UNAME_SYSTEM=`(uname -s) 2>/dev/null|sed 's/ *$//'` || UNAME_SYSTEM=unknown +UNAME_VERSION=`(uname -v) 2>/dev/null|sed 's/ *$//'` || UNAME_VERSION=unknown + +trap 'rm -f dummy.c dummy.o dummy; exit 1' 1 2 15 + +# Note: order is significant - the case branches are not exclusive. + +case "${UNAME_MACHINE}:${UNAME_SYSTEM}:${UNAME_RELEASE}:${UNAME_VERSION}" in + *:QNX:*:*) + echo "i386-pc-qnx`echo ${UNAME_VERSION}|cut -c1-1`" + exit 0 ;; + alpha:OSF1:V*:*) + # After 1.2, OSF1 uses "V1.3" for uname -r. + echo alpha-dec-osf`echo ${UNAME_RELEASE} | sed -e 's/^V//'` + exit 0 ;; + alpha:OSF1:*:*) + # 1.2 uses "1.2" for uname -r. + echo alpha-dec-osf${UNAME_RELEASE} + exit 0 ;; + 21064:Windows_NT:50:3) + echo alpha-dec-winnt3.5 + exit 0 ;; + amiga:NetBSD:*:*) + echo m68k-cbm-netbsd${UNAME_RELEASE} + exit 0 ;; + arm:RISC*:1.[012]*:*|arm:riscix:1.[012]*:*) + echo arm-acorn-riscix${UNAME_RELEASE} + exit 0;; + Pyramid*:OSx*:*:*) + if test "`(/bin/universe) 2>/dev/null`" = att ; then + echo pyramid-pyramid-sysv3 + else + echo pyramid-pyramid-bsd + fi + exit 0 ;; + sun4*:SunOS:5.*:*) + echo sparc-sun-solaris2`echo ${UNAME_RELEASE}|sed -e 's/[^.]*//'` + exit 0 ;; + i86pc:SunOS:5.*:*) + echo i386-unknown-solaris2`echo ${UNAME_RELEASE}|sed -e 's/[^.]*//'` + exit 0 ;; + sun4*:SunOS:6*:*) + # According to config.sub, this is the proper way to canonicalize + # SunOS6. Hard to guess exactly what SunOS6 will be like, but + # it's likely to be more like Solaris than SunOS4. + echo sparc-sun-solaris3`echo ${UNAME_RELEASE}|sed -e 's/[^.]*//'` + exit 0 ;; + sun4*:SunOS:*:*) + case "`/usr/bin/arch -k`" in + Series*|S4*) + UNAME_RELEASE=`uname -v` + ;; + esac + # Japanese Language versions have a version number like `4.1.3-JL'. + echo sparc-sun-sunos`echo ${UNAME_RELEASE}|sed -e 's/-/_/'` + exit 0 ;; + sun3*:SunOS:*:*) + echo m68k-sun-sunos${UNAME_RELEASE} + exit 0 ;; + atari*:NetBSD:*:*) + echo m68k-atari-netbsd${UNAME_RELEASE} + exit 0 ;; + sun3*:NetBSD:*:*) + echo m68k-sun-netbsd${UNAME_RELEASE} + exit 0 ;; + mac68k:NetBSD:*:*) + echo m68k-apple-netbsd${UNAME_RELEASE} + exit 0 ;; + RISC*:ULTRIX:*:*) + echo mips-dec-ultrix${UNAME_RELEASE} + exit 0 ;; + VAX*:ULTRIX*:*:*) + echo vax-dec-ultrix${UNAME_RELEASE} + exit 0 ;; + mips:*:4*:UMIPS) + echo mips-mips-riscos4sysv + exit 0 ;; + mips:*:5*:RISCos) + echo mips-mips-riscos${UNAME_RELEASE} + exit 0 ;; + m88k:CX/UX:7*:*) + echo m88k-harris-cxux7 + exit 0 ;; + m88k:*:4*:R4*) + echo m88k-motorola-sysv4 + exit 0 ;; + m88k:*:3*:R3*) + echo m88k-motorola-sysv3 + exit 0 ;; + AViiON:dgux:*:*) + if [ ${TARGET_BINARY_INTERFACE}x = m88kdguxelfx \ + -o ${TARGET_BINARY_INTERFACE}x = x ] ; then + echo m88k-dg-dgux${UNAME_RELEASE} + else + echo m88k-dg-dguxbcs${UNAME_RELEASE} + fi + exit 0 ;; + M88*:DolphinOS:*:*) # DolphinOS (SVR3) + echo m88k-dolphin-sysv3 + exit 0 ;; + M88*:*:R3*:*) + # Delta 88k system running SVR3 + echo m88k-motorola-sysv3 + exit 0 ;; + XD88*:*:*:*) # Tektronix XD88 system running UTekV (SVR3) + echo m88k-tektronix-sysv3 + exit 0 ;; + Tek43[0-9][0-9]:UTek:*:*) # Tektronix 4300 system running UTek (BSD) + echo m68k-tektronix-bsd + exit 0 ;; + *:IRIX*:*:*) + echo mips-sgi-irix`echo ${UNAME_RELEASE}|sed -e 's/-/_/g'` + exit 0 ;; + ????????:AIX?:[12].1:2) # AIX 2.2.1 or AIX 2.1.1 is RT/PC AIX. + echo romp-ibm-aix # uname -m gives an 8 hex-code CPU id + exit 0 ;; # Note that: echo "'`uname -s`'" gives 'AIX ' + i[345]86:AIX:*:*) + echo i386-ibm-aix + exit 0 ;; + *:AIX:2:3) + if grep bos325 /usr/include/stdio.h >/dev/null 2>&1; then + sed 's/^ //' << EOF >dummy.c + #include + + main() + { + if (!__power_pc()) + exit(1); + puts("powerpc-ibm-aix3.2.5"); + exit(0); + } +EOF + ${CC-cc} dummy.c -o dummy && ./dummy && rm dummy.c dummy && exit 0 + rm -f dummy.c dummy + echo rs6000-ibm-aix3.2.5 + elif grep bos324 /usr/include/stdio.h >/dev/null 2>&1; then + echo rs6000-ibm-aix3.2.4 + else + echo rs6000-ibm-aix3.2 + fi + exit 0 ;; + *:AIX:*:4) + if /usr/sbin/lsattr -EHl proc0 | grep POWER >/dev/null 2>&1; then + IBM_ARCH=rs6000 + else + IBM_ARCH=powerpc + fi + if [ -x /usr/bin/oslevel ] ; then + IBM_REV=`/usr/bin/oslevel` + else + IBM_REV=4.${UNAME_RELEASE} + fi + echo ${IBM_ARCH}-ibm-aix${IBM_REV} + exit 0 ;; + *:AIX:*:*) + echo rs6000-ibm-aix + exit 0 ;; + ibmrt:4.4BSD:*|romp-ibm:BSD:*) + echo romp-ibm-bsd4.4 + exit 0 ;; + ibmrt:*BSD:*|romp-ibm:BSD:*) # covers RT/PC NetBSD and + echo romp-ibm-bsd${UNAME_RELEASE} # 4.3 with uname added to + exit 0 ;; # report: romp-ibm BSD 4.3 + *:BOSX:*:*) + echo rs6000-bull-bosx + exit 0 ;; + DPX/2?00:B.O.S.:*:*) + echo m68k-bull-sysv3 + exit 0 ;; + 9000/[34]??:4.3bsd:1.*:*) + echo m68k-hp-bsd + exit 0 ;; + hp300:4.4BSD:*:* | 9000/[34]??:4.3bsd:2.*:*) + echo m68k-hp-bsd4.4 + exit 0 ;; + 9000/[3478]??:HP-UX:*:*) + case "${UNAME_MACHINE}" in + 9000/31? ) HP_ARCH=m68000 ;; + 9000/[34]?? ) HP_ARCH=m68k ;; + 9000/7?? | 9000/8?[79] ) HP_ARCH=hppa1.1 ;; + 9000/8?? ) HP_ARCH=hppa1.0 ;; + esac + HPUX_REV=`echo ${UNAME_RELEASE}|sed -e 's/[^.]*.[0B]*//'` + echo ${HP_ARCH}-hp-hpux${HPUX_REV} + exit 0 ;; + 3050*:HI-UX:*:*) + sed 's/^ //' << EOF >dummy.c + #include + int + main () + { + long cpu = sysconf (_SC_CPU_VERSION); + /* The order matters, because CPU_IS_HP_MC68K erroneously returns + true for CPU_PA_RISC1_0. CPU_IS_PA_RISC returns correct + results, however. */ + if (CPU_IS_PA_RISC (cpu)) + { + switch (cpu) + { + case CPU_PA_RISC1_0: puts ("hppa1.0-hitachi-hiuxwe2"); break; + case CPU_PA_RISC1_1: puts ("hppa1.1-hitachi-hiuxwe2"); break; + case CPU_PA_RISC2_0: puts ("hppa2.0-hitachi-hiuxwe2"); break; + default: puts ("hppa-hitachi-hiuxwe2"); break; + } + } + else if (CPU_IS_HP_MC68K (cpu)) + puts ("m68k-hitachi-hiuxwe2"); + else puts ("unknown-hitachi-hiuxwe2"); + exit (0); + } +EOF + ${CC-cc} dummy.c -o dummy && ./dummy && rm dummy.c dummy && exit 0 + rm -f dummy.c dummy + echo unknown-hitachi-hiuxwe2 + exit 0 ;; + 9000/7??:4.3bsd:*:* | 9000/8?[79]:4.3bsd:*:* ) + echo hppa1.1-hp-bsd + exit 0 ;; + 9000/8??:4.3bsd:*:*) + echo hppa1.0-hp-bsd + exit 0 ;; + hp7??:OSF1:*:* | hp8?[79]:OSF1:*:* ) + echo hppa1.1-hp-osf + exit 0 ;; + hp8??:OSF1:*:*) + echo hppa1.0-hp-osf + exit 0 ;; + parisc*:Lites*:*:*) + echo hppa1.1-hp-lites + exit 0 ;; + C1*:ConvexOS:*:* | convex:ConvexOS:C1*:*) + echo c1-convex-bsd + exit 0 ;; + C2*:ConvexOS:*:* | convex:ConvexOS:C2*:*) + if getsysinfo -f scalar_acc + then echo c32-convex-bsd + else echo c2-convex-bsd + fi + exit 0 ;; + C34*:ConvexOS:*:* | convex:ConvexOS:C34*:*) + echo c34-convex-bsd + exit 0 ;; + C38*:ConvexOS:*:* | convex:ConvexOS:C38*:*) + echo c38-convex-bsd + exit 0 ;; + C4*:ConvexOS:*:* | convex:ConvexOS:C4*:*) + echo c4-convex-bsd + exit 0 ;; + CRAY*X-MP:*:*:*) + echo xmp-cray-unicos + exit 0 ;; + CRAY*Y-MP:*:*:*) + echo ymp-cray-unicos${UNAME_RELEASE} + exit 0 ;; + CRAY*C90:*:*:*) + echo c90-cray-unicos${UNAME_RELEASE} + exit 0 ;; + CRAY-2:*:*:*) + echo cray2-cray-unicos + exit 0 ;; + hp3[0-9][05]:NetBSD:*:*) + echo m68k-hp-netbsd${UNAME_RELEASE} + exit 0 ;; + i[345]86:BSD/386:*:* | *:BSD/OS:*:*) + echo ${UNAME_MACHINE}-unknown-bsdi${UNAME_RELEASE} + exit 0 ;; + *:FreeBSD:*:*) + echo ${UNAME_MACHINE}-unknown-freebsd`echo ${UNAME_RELEASE}|sed -e 's/[-(].*//'` + exit 0 ;; + *:NetBSD:*:*) + echo ${UNAME_MACHINE}-unknown-netbsd`echo ${UNAME_RELEASE}|sed -e 's/[-_].*/\./'` + exit 0 ;; + *:GNU:*:*) + echo `echo ${UNAME_MACHINE}|sed -e 's,/.*$,,'`-unknown-gnu`echo ${UNAME_RELEASE}|sed -e 's,/.*$,,'` + exit 0 ;; + *:Linux:*:*) + # The BFD linker knows what the default object file format is, so + # first see if it will tell us. + ld_help_string=`ld --help 2>&1|grep "supported emulations:" 2>&1` + if echo $ld_help_string | grep >/dev/null 2>&1 "supported emulations: elf_i[345]86"; then + echo "${UNAME_MACHINE}-unknown-linux" ; exit 0 + elif echo $ld_help_string | grep >/dev/null 2>&1 "supported emulations: i[345]86linux"; then + echo "${UNAME_MACHINE}-unknown-linuxaout" ; exit 0 + elif echo $ld_help_string | grep >/dev/null 2>&1 "supported emulations: i[345]86coff"; then + echo "${UNAME_MACHINE}-unknown-linuxcoff" ; exit 0 + elif test "${UNAME_MACHINE}" = "alpha" ; then + echo alpha-unknown-linux ; exit 0 + else + # Either a pre-BFD a.out linker (linuxoldld) or one that does not give us + # useful --help. Gcc wants to distinguish between linuxoldld and linuxaout, + # and between different C library versions. + test ! -d /usr/lib/ldscripts/. \ + && test ! -d /usr/*-*-linux*/lib/ldscripts \ + && echo "${UNAME_MACHINE}-unknown-linuxoldld" && exit 0 + # Determine whether the default compiler is a.out or elf + cat >dummy.c < +main(argc, argv) +int argc; +char *argv[]; +{ +#ifdef __ELF__ +# ifdef __GLIBC__ +# if __GLIBC__ >= 2 + printf ("%s-unknown-linux\n", argv[1]); +# else + printf ("%s-unknown-linuxlibc1\n", argv[1]); +# endif +# else + printf ("%s-unknown-linuxlibc1\n", argv[1]); +# endif +#else + printf ("%s-unknown-linuxaout\n", argv[1]); +#endif + return 0; +} +EOF + ${CC-cc} dummy.c -o dummy 2>/dev/null && ./dummy "${UNAME_MACHINE}" && rm dummy.c dummy && exit 0 + rm -f dummy.c dummy + fi ;; +# ptx 4.0 does uname -s correctly, with DYNIX/ptx in there. earlier versions +# are messed up and put the nodename in both sysname and nodename. + i[345]86:DYNIX/ptx:4*:*) + echo i386-sequent-sysv4 + exit 0 ;; + i[345]86:*:4.*:* | i[345]86:SYSTEM_V:4.*:*) + if grep Novell /usr/include/link.h >/dev/null 2>/dev/null; then + echo ${UNAME_MACHINE}-univel-sysv${UNAME_RELEASE} + else + echo ${UNAME_MACHINE}-unknown-sysv${UNAME_RELEASE} + fi + exit 0 ;; + i[345]86:*:3.2:*) + if test -f /usr/options/cb.name; then + UNAME_REL=`sed -n 's/.*Version //p' /dev/null >/dev/null ; then + UNAME_REL=`(/bin/uname -X|egrep Release|sed -e 's/.*= //')` + (/bin/uname -X|egrep i80486 >/dev/null) && UNAME_MACHINE=i486 + echo ${UNAME_MACHINE}-unknown-sco$UNAME_REL + else + echo ${UNAME_MACHINE}-unknown-sysv32 + fi + exit 0 ;; + Intel:Mach:3*:*) + echo i386-unknown-mach3 + exit 0 ;; + paragon:*:*:*) + echo i860-intel-osf1 + exit 0 ;; + i860:*:4.*:*) # i860-SVR4 + if grep Stardent /usr/include/sys/uadmin.h >/dev/null 2>&1 ; then + echo i860-stardent-sysv${UNAME_RELEASE} # Stardent Vistra i860-SVR4 + else # Add other i860-SVR4 vendors below as they are discovered. + echo i860-unknown-sysv${UNAME_RELEASE} # Unknown i860-SVR4 + fi + exit 0 ;; + mini*:CTIX:SYS*5:*) + # "miniframe" + echo m68010-convergent-sysv + exit 0 ;; + M680[234]0:*:R3V[567]*:*) + test -r /sysV68 && echo 'm68k-motorola-sysv' && exit 0 ;; + 3[345]??:*:4.0:3.0 | 3[345]??,*:*:4.0:3.0) + uname -p 2>/dev/null | grep 86 >/dev/null \ + && echo i486-ncr-sysv4.3 && exit 0 ;; + 3[345]??:*:4.0:* | 3[345]??,*:*:4.0:*) + uname -p 2>/dev/null | grep 86 >/dev/null \ + && echo i486-ncr-sysv4 && exit 0 ;; + m680[234]0:LynxOS:2.[23]*:*) + echo m68k-lynx-lynxos${UNAME_RELEASE} + exit 0 ;; + mc68030:UNIX_System_V:4.*:*) + echo m68k-atari-sysv4 + exit 0 ;; + i[345]86:LynxOS:2.[23]*:*) + echo i386-lynx-lynxos${UNAME_RELEASE} + exit 0 ;; + TSUNAMI:LynxOS:2.[23]*:*) + echo sparc-lynx-lynxos${UNAME_RELEASE} + exit 0 ;; + rs6000:LynxOS:2.[23]*:*) + echo rs6000-lynx-lynxos${UNAME_RELEASE} + exit 0 ;; + RM*:SINIX-*:*:*) + echo mips-sni-sysv4 + exit 0 ;; + *:SINIX-*:*:*) + if uname -p 2>/dev/null >/dev/null ; then + UNAME_MACHINE=`(uname -p) 2>/dev/null` + echo ${UNAME_MACHINE}-sni-sysv4 + else + echo ns32k-sni-sysv + fi + exit 0 ;; +esac + +#echo '(No uname command or uname output not recognized.)' 1>&2 +#echo "${UNAME_MACHINE}:${UNAME_SYSTEM}:${UNAME_RELEASE}:${UNAME_VERSION}" 1>&2 + +cat >dummy.c < +# include +#endif +main () +{ +#if defined (sony) +#if defined (MIPSEB) + /* BFD wants "bsd" instead of "newsos". Perhaps BFD should be changed, + I don't know.... */ + printf ("mips-sony-bsd\n"); exit (0); +#else +#include + printf ("m68k-sony-newsos%s\n", +#ifdef NEWSOS4 + "4" +#else + "" +#endif + ); exit (0); +#endif +#endif + +#if defined (__arm) && defined (__acorn) && defined (__unix) + printf ("arm-acorn-riscix"); exit (0); +#endif + +#if defined (hp300) && !defined (hpux) + printf ("m68k-hp-bsd\n"); exit (0); +#endif + +#if defined (NeXT) +#if !defined (__ARCHITECTURE__) +#define __ARCHITECTURE__ "m68k" +#endif + int version; + version=`(hostinfo | sed -n 's/.*NeXT Mach \([0-9]*\).*/\1/p') 2>/dev/null`; + printf ("%s-next-nextstep%s\n", __ARCHITECTURE__, version==2 ? "2" : "3"); + exit (0); +#endif + +#if defined (MULTIMAX) || defined (n16) +#if defined (UMAXV) + printf ("ns32k-encore-sysv\n"); exit (0); +#else +#if defined (CMU) + printf ("ns32k-encore-mach\n"); exit (0); +#else + printf ("ns32k-encore-bsd\n"); exit (0); +#endif +#endif +#endif + +#if defined (__386BSD__) + printf ("i386-unknown-bsd\n"); exit (0); +#endif + +#if defined (sequent) +#if defined (i386) + printf ("i386-sequent-dynix\n"); exit (0); +#endif +#if defined (ns32000) + printf ("ns32k-sequent-dynix\n"); exit (0); +#endif +#endif + +#if defined (_SEQUENT_) + struct utsname un; + + uname(&un); + + if (strncmp(un.version, "V2", 2) == 0) { + printf ("i386-sequent-ptx2\n"); exit (0); + } + if (strncmp(un.version, "V1", 2) == 0) { /* XXX is V1 correct? */ + printf ("i386-sequent-ptx1\n"); exit (0); + } + printf ("i386-sequent-ptx\n"); exit (0); + +#endif + +#if defined (vax) +#if !defined (ultrix) + printf ("vax-dec-bsd\n"); exit (0); +#else + printf ("vax-dec-ultrix\n"); exit (0); +#endif +#endif + +#if defined (alliant) && defined (i860) + printf ("i860-alliant-bsd\n"); exit (0); +#endif + + exit (1); +} +EOF + +${CC-cc} dummy.c -o dummy 2>/dev/null && ./dummy && rm dummy.c dummy && exit 0 +rm -f dummy.c dummy + +# Apollos put the system type in the environment. + +test -d /usr/apollo && { echo ${ISP}-apollo-${SYSTYPE}; exit 0; } + +# Convex versions that predate uname can use getsysinfo(1) + +if [ -x /usr/convex/getsysinfo ] +then + case `getsysinfo -f cpu_type` in + c1*) + echo c1-convex-bsd + exit 0 ;; + c2*) + if getsysinfo -f scalar_acc + then echo c32-convex-bsd + else echo c2-convex-bsd + fi + exit 0 ;; + c34*) + echo c34-convex-bsd + exit 0 ;; + c38*) + echo c38-convex-bsd + exit 0 ;; + c4*) + echo c4-convex-bsd + exit 0 ;; + esac +fi + +#echo '(Unable to guess system type)' 1>&2 +echo UNKNOWN +exit 1 diff --git a/sim/ucsim/config.sub b/sim/ucsim/config.sub new file mode 100755 index 00000000..acce8093 --- /dev/null +++ b/sim/ucsim/config.sub @@ -0,0 +1,876 @@ +#!/bin/sh +# Configuration validation subroutine script, version 1.1. +# Copyright (C) 1991, 1992, 1993, 1994, 1995 Free Software Foundation, Inc. +# This file is (in principle) common to ALL GNU software. +# The presence of a machine in this file suggests that SOME GNU software +# can handle that machine. It does not imply ALL GNU software can. +# +# This file 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. +# +# This program 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 this program; if not, write to the Free Software +# Foundation, Inc., 59 Temple Place - Suite 330, +# Boston, MA 02111-1307, USA. + +# As a special exception to the GNU General Public License, if you +# distribute this file as part of a program that contains a +# configuration script generated by Autoconf, you may include it under +# the same distribution terms that you use for the rest of that program. + +# Configuration subroutine to validate and canonicalize a configuration type. +# Supply the specified configuration type as an argument. +# If it is invalid, we print an error message on stderr and exit with code 1. +# Otherwise, we print the canonical config type on stdout and succeed. + +# This file is supposed to be the same for all GNU packages +# and recognize all the CPU types, system types and aliases +# that are meaningful with *any* GNU software. +# Each package is responsible for reporting which valid configurations +# it does not support. The user should be able to distinguish +# a failure to support a valid configuration from a meaningless +# configuration. + +# The goal of this file is to map all the various variations of a given +# machine specification into a single specification in the form: +# CPU_TYPE-MANUFACTURER-OPERATING_SYSTEM +# It is wrong to echo any other type of specification. + +if [ x$1 = x ] +then + echo Configuration name missing. 1>&2 + echo "Usage: $0 CPU-MFR-OPSYS" 1>&2 + echo "or $0 ALIAS" 1>&2 + echo where ALIAS is a recognized configuration type. 1>&2 + exit 1 +fi + +# First pass through any local machine types. +case $1 in + *local*) + echo $1 + exit 0 + ;; + *) + ;; +esac + +# Separate what the user gave into CPU-COMPANY and OS (if any). +basic_machine=`echo $1 | sed 's/-[^-]*$//'` +if [ $basic_machine != $1 ] +then os=`echo $1 | sed 's/.*-/-/'` +else os=; fi + +### Let's recognize common machines as not being operating systems so +### that things like config.sub decstation-3100 work. We also +### recognize some manufacturers as not being operating systems, so we +### can provide default operating systems below. +case $os in + -sun*os*) + # Prevent following clause from handling this invalid input. + ;; + -dec* | -mips* | -sequent* | -encore* | -pc532* | -sgi* | -sony* | \ + -att* | -7300* | -3300* | -delta* | -motorola* | -sun[234]* | \ + -unicom* | -ibm* | -next | -hp | -isi* | -apollo | -altos* | \ + -convergent* | -ncr* | -news | -32* | -3600* | -3100* | -hitachi* |\ + -c[123]* | -convex* | -sun | -crds | -omron* | -dg | -ultra | -tti* | \ + -harris | -dolphin | -highlevel | -gould | -cbm | -ns | -masscomp ) + os= + basic_machine=$1 + ;; + -hiux*) + os=-hiuxwe2 + ;; + -sco4) + os=-sco3.2v4 + basic_machine=`echo $1 | sed -e 's/86-.*/86-unknown/'` + ;; + -sco3.2.[4-9]*) + os=`echo $os | sed -e 's/sco3.2./sco3.2v/'` + basic_machine=`echo $1 | sed -e 's/86-.*/86-unknown/'` + ;; + -sco3.2v[4-9]*) + # Don't forget version if it is 3.2v4 or newer. + basic_machine=`echo $1 | sed -e 's/86-.*/86-unknown/'` + ;; + -sco*) + os=-sco3.2v2 + basic_machine=`echo $1 | sed -e 's/86-.*/86-unknown/'` + ;; + -isc) + os=-isc2.2 + basic_machine=`echo $1 | sed -e 's/86-.*/86-unknown/'` + ;; + -clix*) + basic_machine=clipper-intergraph + ;; + -isc*) + basic_machine=`echo $1 | sed -e 's/86-.*/86-unknown/'` + ;; + -lynx*) + os=-lynxos + ;; + -ptx*) + basic_machine=`echo $1 | sed -e 's/86-.*/86-sequent/'` + ;; + -windowsnt*) + os=`echo $os | sed -e 's/windowsnt/winnt/'` + ;; + -qnx4) + os=-qnx4 + ;; + -qnx2) + os=-qnx2 + ;; +esac + +# Decode aliases for certain CPU-COMPANY combinations. +case $basic_machine in + # Recognize the basic CPU types without company name. + # Some are omitted here because they have special meanings below. + tahoe | i[345]86 | i860 | m68k | m68000 | m88k | ns32k | arm \ + | arme[lb] | pyramid \ + | tron | a29k | 580 | i960 | h8300 | hppa1.0 | hppa1.1 \ + | alpha | we32k | ns16k | clipper | sparclite | i370 | sh \ + | powerpc | powerpcle | sparc64 | 1750a | dsp16xx | mips64 | mipsel \ + | pdp11 | mips64el | mips64orion | mips64orionel \ + | sparc) + basic_machine=$basic_machine-unknown + ;; + # Object if more than one company name word. + *-*-*) + echo Invalid configuration \`$1\': machine \`$basic_machine\' not recognized 1>&2 + exit 1 + ;; + # Recognize the basic CPU types with company name. + vax-* | tahoe-* | i[345]86-* | i860-* | m68k-* | m68000-* | m88k-* \ + | sparc-* | ns32k-* | fx80-* | arm-* | c[123]* \ + | mips-* | pyramid-* | tron-* | a29k-* | romp-* | rs6000-* | power-* \ + | none-* | 580-* | cray2-* | h8300-* | i960-* | xmp-* | ymp-* \ + | hppa1.0-* | hppa1.1-* | alpha-* | we32k-* | cydra-* | ns16k-* \ + | pn-* | np1-* | xps100-* | clipper-* | orion-* | sparclite-* \ + | pdp11-* | sh-* | powerpc-* | powerpcle-* | sparc64-* | mips64-* | mipsel-* \ + | mips64el-* | mips64orion-* | mips64orionel-*) + ;; + # Recognize the various machine names and aliases which stand + # for a CPU type and a company and sometimes even an OS. + 3b1 | 7300 | 7300-att | att-7300 | pc7300 | safari | unixpc) + basic_machine=m68000-att + ;; + 3b*) + basic_machine=we32k-att + ;; + alliant | fx80) + basic_machine=fx80-alliant + ;; + altos | altos3068) + basic_machine=m68k-altos + ;; + am29k) + basic_machine=a29k-none + os=-bsd + ;; + amdahl) + basic_machine=580-amdahl + os=-sysv + ;; + amiga | amiga-*) + basic_machine=m68k-cbm + ;; + amigados) + basic_machine=m68k-cbm + os=-amigados + ;; + amigaunix | amix) + basic_machine=m68k-cbm + os=-sysv4 + ;; + apollo68) + basic_machine=m68k-apollo + os=-sysv + ;; + balance) + basic_machine=ns32k-sequent + os=-dynix + ;; + convex-c1) + basic_machine=c1-convex + os=-bsd + ;; + convex-c2) + basic_machine=c2-convex + os=-bsd + ;; + convex-c32) + basic_machine=c32-convex + os=-bsd + ;; + convex-c34) + basic_machine=c34-convex + os=-bsd + ;; + convex-c38) + basic_machine=c38-convex + os=-bsd + ;; + cray | ymp) + basic_machine=ymp-cray + os=-unicos + ;; + cray2) + basic_machine=cray2-cray + os=-unicos + ;; + crds | unos) + basic_machine=m68k-crds + ;; + da30 | da30-*) + basic_machine=m68k-da30 + ;; + decstation | decstation-3100 | pmax | pmax-* | pmin | dec3100 | decstatn) + basic_machine=mips-dec + ;; + delta | 3300 | motorola-3300 | motorola-delta \ + | 3300-motorola | delta-motorola) + basic_machine=m68k-motorola + ;; + delta88) + basic_machine=m88k-motorola + os=-sysv3 + ;; + dpx20 | dpx20-*) + basic_machine=rs6000-bull + os=-bosx + ;; + dpx2* | dpx2*-bull) + basic_machine=m68k-bull + os=-sysv3 + ;; + ebmon29k) + basic_machine=a29k-amd + os=-ebmon + ;; + elxsi) + basic_machine=elxsi-elxsi + os=-bsd + ;; + encore | umax | mmax) + basic_machine=ns32k-encore + ;; + fx2800) + basic_machine=i860-alliant + ;; + genix) + basic_machine=ns32k-ns + ;; + gmicro) + basic_machine=tron-gmicro + os=-sysv + ;; + h3050r* | hiux*) + basic_machine=hppa1.1-hitachi + os=-hiuxwe2 + ;; + h8300hms) + basic_machine=h8300-hitachi + os=-hms + ;; + harris) + basic_machine=m88k-harris + os=-sysv3 + ;; + hp300-*) + basic_machine=m68k-hp + ;; + hp300bsd) + basic_machine=m68k-hp + os=-bsd + ;; + hp300hpux) + basic_machine=m68k-hp + os=-hpux + ;; + hp9k2[0-9][0-9] | hp9k31[0-9]) + basic_machine=m68000-hp + ;; + hp9k3[2-9][0-9]) + basic_machine=m68k-hp + ;; + hp9k7[0-9][0-9] | hp7[0-9][0-9] | hp9k8[0-9]7 | hp8[0-9]7) + basic_machine=hppa1.1-hp + ;; + hp9k8[0-9][0-9] | hp8[0-9][0-9]) + basic_machine=hppa1.0-hp + ;; + i370-ibm* | ibm*) + basic_machine=i370-ibm + os=-mvs + ;; +# I'm not sure what "Sysv32" means. Should this be sysv3.2? + i[345]86v32) + basic_machine=`echo $1 | sed -e 's/86.*/86-unknown/'` + os=-sysv32 + ;; + i[345]86v4*) + basic_machine=`echo $1 | sed -e 's/86.*/86-unknown/'` + os=-sysv4 + ;; + i[345]86v) + basic_machine=`echo $1 | sed -e 's/86.*/86-unknown/'` + os=-sysv + ;; + i[345]86sol2) + basic_machine=`echo $1 | sed -e 's/86.*/86-unknown/'` + os=-solaris2 + ;; + iris | iris4d) + basic_machine=mips-sgi + case $os in + -irix*) + ;; + *) + os=-irix4 + ;; + esac + ;; + isi68 | isi) + basic_machine=m68k-isi + os=-sysv + ;; + m88k-omron*) + basic_machine=m88k-omron + ;; + magnum | m3230) + basic_machine=mips-mips + os=-sysv + ;; + merlin) + basic_machine=ns32k-utek + os=-sysv + ;; + miniframe) + basic_machine=m68000-convergent + ;; + mips3*-*) + basic_machine=`echo $basic_machine | sed -e 's/mips3/mips64/'` + ;; + mips3*) + basic_machine=`echo $basic_machine | sed -e 's/mips3/mips64/'`-unknown + ;; + ncr3000) + basic_machine=i486-ncr + os=-sysv4 + ;; + news | news700 | news800 | news900) + basic_machine=m68k-sony + os=-newsos + ;; + news1000) + basic_machine=m68030-sony + os=-newsos + ;; + news-3600 | risc-news) + basic_machine=mips-sony + os=-newsos + ;; + next | m*-next ) + basic_machine=m68k-next + case $os in + -nextstep* ) + ;; + -ns2*) + os=-nextstep2 + ;; + *) + os=-nextstep3 + ;; + esac + ;; + nh3000) + basic_machine=m68k-harris + os=-cxux + ;; + nh[45]000) + basic_machine=m88k-harris + os=-cxux + ;; + nindy960) + basic_machine=i960-intel + os=-nindy + ;; + np1) + basic_machine=np1-gould + ;; + pa-hitachi) + basic_machine=hppa1.1-hitachi + os=-hiuxwe2 + ;; + paragon) + basic_machine=i860-intel + os=-osf + ;; + pbd) + basic_machine=sparc-tti + ;; + pbb) + basic_machine=m68k-tti + ;; + pc532 | pc532-*) + basic_machine=ns32k-pc532 + ;; + pentium | p5 | p6) + # We don't have specific support for the Intel Pentium (p6) followon yet, so just call it a Pentium + basic_machine=i586-intel + ;; + pentium-* | p5-* | p6-*) + # We don't have specific support for the Intel Pentium (p6) followon yet, so just call it a Pentium + basic_machine=i586-`echo $basic_machine | sed 's/^[^-]*-//'` + ;; + k5) + # We don't have specific support for AMD's K5 yet, so just call it a Pentium + basic_machine=i586-amd + ;; + nexen) + # We don't have specific support for Nexgen yet, so just call it a Pentium + basic_machine=i586-nexgen + ;; + pn) + basic_machine=pn-gould + ;; + power) basic_machine=rs6000-ibm + ;; + ppc) basic_machine=powerpc-unknown + ;; + ppc-*) basic_machine=powerpc-`echo $basic_machine | sed 's/^[^-]*-//'` + ;; + ppcle | powerpclittle | ppc-le | powerpc-little) + basic_machine=powerpcle-unknown + ;; + ppcle-* | powerpclittle-*) + basic_machine=powerpcle-`echo $basic_machine | sed 's/^[^-]*-//'` + ;; + ps2) + basic_machine=i386-ibm + ;; + rm[46]00) + basic_machine=mips-siemens + ;; + rtpc | rtpc-*) + basic_machine=romp-ibm + ;; + sequent) + basic_machine=i386-sequent + ;; + sh) + basic_machine=sh-hitachi + os=-hms + ;; + sps7) + basic_machine=m68k-bull + os=-sysv2 + ;; + spur) + basic_machine=spur-unknown + ;; + sun2) + basic_machine=m68000-sun + ;; + sun2os3) + basic_machine=m68000-sun + os=-sunos3 + ;; + sun2os4) + basic_machine=m68000-sun + os=-sunos4 + ;; + sun3os3) + basic_machine=m68k-sun + os=-sunos3 + ;; + sun3os4) + basic_machine=m68k-sun + os=-sunos4 + ;; + sun4os3) + basic_machine=sparc-sun + os=-sunos3 + ;; + sun4os4) + basic_machine=sparc-sun + os=-sunos4 + ;; + sun4sol2) + basic_machine=sparc-sun + os=-solaris2 + ;; + sun3 | sun3-*) + basic_machine=m68k-sun + ;; + sun4) + basic_machine=sparc-sun + ;; + sun386 | sun386i | roadrunner) + basic_machine=i386-sun + ;; + symmetry) + basic_machine=i386-sequent + os=-dynix + ;; + tower | tower-32) + basic_machine=m68k-ncr + ;; + udi29k) + basic_machine=a29k-amd + os=-udi + ;; + ultra3) + basic_machine=a29k-nyu + os=-sym1 + ;; + vaxv) + basic_machine=vax-dec + os=-sysv + ;; + vms) + basic_machine=vax-dec + os=-vms + ;; + vxworks960) + basic_machine=i960-wrs + os=-vxworks + ;; + vxworks68) + basic_machine=m68k-wrs + os=-vxworks + ;; + vxworks29k) + basic_machine=a29k-wrs + os=-vxworks + ;; + xmp) + basic_machine=xmp-cray + os=-unicos + ;; + xps | xps100) + basic_machine=xps100-honeywell + ;; + none) + basic_machine=none-none + os=-none + ;; + +# Here we handle the default manufacturer of certain CPU types. It is in +# some cases the only manufacturer, in others, it is the most popular. + mips) + basic_machine=mips-mips + ;; + romp) + basic_machine=romp-ibm + ;; + rs6000) + basic_machine=rs6000-ibm + ;; + vax) + basic_machine=vax-dec + ;; + pdp11) + basic_machine=pdp11-dec + ;; + we32k) + basic_machine=we32k-att + ;; + sparc) + basic_machine=sparc-sun + ;; + cydra) + basic_machine=cydra-cydrome + ;; + orion) + basic_machine=orion-highlevel + ;; + orion105) + basic_machine=clipper-highlevel + ;; + *) + echo Invalid configuration \`$1\': machine \`$basic_machine\' not recognized 1>&2 + exit 1 + ;; +esac + +# Here we canonicalize certain aliases for manufacturers. +case $basic_machine in + *-digital*) + basic_machine=`echo $basic_machine | sed 's/digital.*/dec/'` + ;; + *-commodore*) + basic_machine=`echo $basic_machine | sed 's/commodore.*/cbm/'` + ;; + *) + ;; +esac + +# Decode manufacturer-specific aliases for certain operating systems. + +if [ x"$os" != x"" ] +then +case $os in + # -solaris* is a basic system type, with this one exception. + -solaris1 | -solaris1.*) + os=`echo $os | sed -e 's|solaris1|sunos4|'` + ;; + -solaris) + os=-solaris2 + ;; + -unixware* | svr4*) + os=-sysv4 + ;; + -gnu/linux*) + os=`echo $os | sed -e 's|gnu/linux|linux|'` + ;; + # First accept the basic system types. + # The portable systems comes first. + # Each alternative MUST END IN A *, to match a version number. + # -sysv* is not here because it comes later, after sysvr4. + -gnu* | -bsd* | -mach* | -minix* | -genix* | -ultrix* | -irix* \ + | -vms* | -sco* | -esix* | -isc* | -aix* | -sunos | -sunos[345]* \ + | -hpux* | -unos* | -osf* | -luna* | -dgux* | -solaris* | -sym* \ + | -amigados* | -msdos* | -newsos* | -unicos* | -aos* \ + | -nindy* | -vxworks* | -ebmon* | -hms* | -mvs* | -clix* \ + | -riscos* | -linux* | -uniplus* | -iris* | -rtu* | -xenix* \ + | -hiux* | -386bsd* | -netbsd* | -freebsd* | -riscix* \ + | -lynxos* | -bosx* | -nextstep* | -cxux* | -aout* | -elf* \ + | -ptx* | -coff* | -ecoff* | -winnt* | -domain* | -vsta* \ + | -udi* | -eabi* | -lites* ) + # Remember, each alternative MUST END IN *, to match a version number. + ;; + -sunos5*) + os=`echo $os | sed -e 's|sunos5|solaris2|'` + ;; + -sunos6*) + os=`echo $os | sed -e 's|sunos6|solaris3|'` + ;; + -osfrose*) + os=-osfrose + ;; + -osf*) + os=-osf + ;; + -utek*) + os=-bsd + ;; + -dynix*) + os=-bsd + ;; + -acis*) + os=-aos + ;; + -ctix* | -uts*) + os=-sysv + ;; + # Preserve the version number of sinix5. + -sinix5.*) + os=`echo $os | sed -e 's|sinix|sysv|'` + ;; + -sinix*) + os=-sysv4 + ;; + -triton*) + os=-sysv3 + ;; + -oss*) + os=-sysv3 + ;; + -svr4) + os=-sysv4 + ;; + -svr3) + os=-sysv3 + ;; + -sysvr4) + os=-sysv4 + ;; + # This must come after -sysvr4. + -sysv*) + ;; + -xenix) + os=-xenix + ;; + -qnx*) + #os=-qnx + ;; + -none) + ;; + *) + # Get rid of the `-' at the beginning of $os. + os=`echo $os | sed 's/[^-]*-//'` + echo Invalid configuration \`$1\': system \`$os\' not recognized 1>&2 + exit 1 + ;; +esac +else + +# Here we handle the default operating systems that come with various machines. +# The value should be what the vendor currently ships out the door with their +# machine or put another way, the most popular os provided with the machine. + +# Note that if you're going to try to match "-MANUFACTURER" here (say, +# "-sun"), then you have to tell the case statement up towards the top +# that MANUFACTURER isn't an operating system. Otherwise, code above +# will signal an error saying that MANUFACTURER isn't an operating +# system, and we'll never get to this point. + +case $basic_machine in + *-acorn) + os=-riscix1.2 + ;; + arm*-semi) + os=-aout + ;; + pdp11-*) + os=-none + ;; + *-dec | vax-*) + os=-ultrix4.2 + ;; + m68*-apollo) + os=-domain + ;; + i386-sun) + os=-sunos4.0.2 + ;; + m68000-sun) + os=-sunos3 + # This also exists in the configure program, but was not the + # default. + # os=-sunos4 + ;; + *-tti) # must be before sparc entry or we get the wrong os. + os=-sysv3 + ;; + sparc-* | *-sun) + os=-sunos4.1.1 + ;; + *-ibm) + os=-aix + ;; + *-hp) + os=-hpux + ;; + *-hitachi) + os=-hiux + ;; + i860-* | *-att | *-ncr | *-altos | *-motorola | *-convergent) + os=-sysv + ;; + *-cbm) + os=-amigados + ;; + *-dg) + os=-dgux + ;; + *-dolphin) + os=-sysv3 + ;; + m68k-ccur) + os=-rtu + ;; + m88k-omron*) + os=-luna + ;; + *-sequent) + os=-ptx + ;; + *-crds) + os=-unos + ;; + *-ns) + os=-genix + ;; + i370-*) + os=-mvs + ;; + *-next) + os=-nextstep3 + ;; + *-gould) + os=-sysv + ;; + *-highlevel) + os=-bsd + ;; + *-encore) + os=-bsd + ;; + *-sgi) + os=-irix + ;; + *-siemens) + os=-sysv4 + ;; + *-masscomp) + os=-rtu + ;; + *) + os=-none + ;; +esac +fi + +# Here we handle the case where we know the os, and the CPU type, but not the +# manufacturer. We pick the logical manufacturer. +vendor=unknown +case $basic_machine in + *-unknown) + case $os in + -riscix*) + vendor=acorn + ;; + -sunos*) + vendor=sun + ;; + -lynxos*) + vendor=lynx + ;; + -aix*) + vendor=ibm + ;; + -hpux*) + vendor=hp + ;; + -hiux*) + vendor=hitachi + ;; + -unos*) + vendor=crds + ;; + -dgux*) + vendor=dg + ;; + -luna*) + vendor=omron + ;; + -genix*) + vendor=ns + ;; + -mvs*) + vendor=ibm + ;; + -ptx*) + vendor=sequent + ;; + -vxworks*) + vendor=wrs + ;; + esac + basic_machine=`echo $basic_machine | sed "s/unknown/$vendor/"` + ;; +esac + +echo $basic_machine$os diff --git a/sim/ucsim/configure b/sim/ucsim/configure index dad0de58..0ffb4c1e 100755 --- a/sim/ucsim/configure +++ b/sim/ucsim/configure @@ -11,6 +11,20 @@ ac_help= ac_default_prefix=/usr/local # Any additions from configure.in: +ac_help="$ac_help + --enable-ucsim compile ucsim frontend" +ac_help="$ac_help + --enable-dlso compile dynamically loadable shared libraries" +ac_help="$ac_help + --disable-51 do not compile simulator for MCS51" +ac_help="$ac_help + --disable-avr do not compile simulator for AVR" +ac_help="$ac_help + --enable-z80 compile simulator for Z80" +ac_help="$ac_help + --enable-xa compile simulator for XA" +ac_help="$ac_help + --enable-serio compile serio GUI tool (needs curses)" # Initialize some variables set by options. # The variables have the same names as the options, with @@ -528,7 +542,7 @@ do # Extract the first word of "$ac_prog", so it can be a program name with args. set dummy $ac_prog; ac_word=$2 echo $ac_n "checking for $ac_word""... $ac_c" 1>&6 -echo "configure:532: checking for $ac_word" >&5 +echo "configure:546: checking for $ac_word" >&5 if eval "test \"`echo '$''{'ac_cv_prog_AWK'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else @@ -559,7 +573,7 @@ done echo $ac_n "checking version of the package""... $ac_c" 1>&6 -echo "configure:563: checking version of the package" >&5 +echo "configure:577: checking version of the package" >&5 if test -f .version; then VERSION=`cat .version` echo "$ac_t""$VERSION" 1>&6 @@ -591,6 +605,86 @@ cat >> confdefs.h <&6 -echo "configure:603: checking for $ac_word" >&5 +echo "configure:697: checking for $ac_word" >&5 if eval "test \"`echo '$''{'ac_cv_prog_CXX'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else @@ -631,7 +725,7 @@ test -n "$CXX" || CXX="gcc" echo $ac_n "checking whether the C++ compiler ($CXX $CXXFLAGS $LDFLAGS) works""... $ac_c" 1>&6 -echo "configure:635: checking whether the C++ compiler ($CXX $CXXFLAGS $LDFLAGS) works" >&5 +echo "configure:729: checking whether the C++ compiler ($CXX $CXXFLAGS $LDFLAGS) works" >&5 ac_ext=C # CXXFLAGS is not in ac_cpp because -g, -O, etc. are not valid cpp options. @@ -642,12 +736,12 @@ cross_compiling=$ac_cv_prog_cxx_cross cat > conftest.$ac_ext << EOF -#line 646 "configure" +#line 740 "configure" #include "confdefs.h" int main(){return(0);} EOF -if { (eval echo configure:651: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then +if { (eval echo configure:745: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then ac_cv_prog_cxx_works=yes # If we can't run a trivial program, we are probably using a cross compiler. if (./conftest; exit) 2>/dev/null; then @@ -673,12 +767,12 @@ if test $ac_cv_prog_cxx_works = no; then { echo "configure: error: installation or configuration problem: C++ compiler cannot create executables." 1>&2; exit 1; } fi echo $ac_n "checking whether the C++ compiler ($CXX $CXXFLAGS $LDFLAGS) is a cross-compiler""... $ac_c" 1>&6 -echo "configure:677: checking whether the C++ compiler ($CXX $CXXFLAGS $LDFLAGS) is a cross-compiler" >&5 +echo "configure:771: checking whether the C++ compiler ($CXX $CXXFLAGS $LDFLAGS) is a cross-compiler" >&5 echo "$ac_t""$ac_cv_prog_cxx_cross" 1>&6 cross_compiling=$ac_cv_prog_cxx_cross echo $ac_n "checking whether we are using GNU C++""... $ac_c" 1>&6 -echo "configure:682: checking whether we are using GNU C++" >&5 +echo "configure:776: checking whether we are using GNU C++" >&5 if eval "test \"`echo '$''{'ac_cv_prog_gxx'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else @@ -687,7 +781,7 @@ else yes; #endif EOF -if { ac_try='${CXX-g++} -E conftest.C'; { (eval echo configure:691: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; }; } | egrep yes >/dev/null 2>&1; then +if { ac_try='${CXX-g++} -E conftest.C'; { (eval echo configure:785: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; }; } | egrep yes >/dev/null 2>&1; then ac_cv_prog_gxx=yes else ac_cv_prog_gxx=no @@ -706,7 +800,7 @@ ac_test_CXXFLAGS="${CXXFLAGS+set}" ac_save_CXXFLAGS="$CXXFLAGS" CXXFLAGS= echo $ac_n "checking whether ${CXX-g++} accepts -g""... $ac_c" 1>&6 -echo "configure:710: checking whether ${CXX-g++} accepts -g" >&5 +echo "configure:804: checking whether ${CXX-g++} accepts -g" >&5 if eval "test \"`echo '$''{'ac_cv_prog_cxx_g'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else @@ -738,7 +832,7 @@ else fi echo $ac_n "checking how to run the C++ preprocessor""... $ac_c" 1>&6 -echo "configure:742: checking how to run the C++ preprocessor" >&5 +echo "configure:836: checking how to run the C++ preprocessor" >&5 if test -z "$CXXCPP"; then if eval "test \"`echo '$''{'ac_cv_prog_CXXCPP'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 @@ -751,12 +845,12 @@ ac_link='${CXX-g++} -o conftest${ac_exeext} $CXXFLAGS $CPPFLAGS $LDFLAGS conftes cross_compiling=$ac_cv_prog_cxx_cross CXXCPP="${CXX-g++} -E" cat > conftest.$ac_ext < EOF ac_try="$ac_cpp conftest.$ac_ext >/dev/null 2>conftest.out" -{ (eval echo configure:760: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; } +{ (eval echo configure:854: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; } ac_err=`grep -v '^ *+' conftest.out | grep -v "^conftest.${ac_ext}\$"` if test -z "$ac_err"; then : @@ -811,7 +905,7 @@ ac_configure=$ac_aux_dir/configure # This should be Cygnus configure. # SVR4 /usr/ucb/install, which tries to use the nonexistent group "staff" # ./install, which can be erroneously created by make from ./install.sh. echo $ac_n "checking for a BSD compatible install""... $ac_c" 1>&6 -echo "configure:815: checking for a BSD compatible install" >&5 +echo "configure:909: checking for a BSD compatible install" >&5 if test -z "$INSTALL"; then if eval "test \"`echo '$''{'ac_cv_path_install'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 @@ -866,7 +960,7 @@ test -z "$INSTALL_DATA" && INSTALL_DATA='${INSTALL} -m 644' # Extract the first word of "ranlib", so it can be a program name with args. set dummy ranlib; ac_word=$2 echo $ac_n "checking for $ac_word""... $ac_c" 1>&6 -echo "configure:870: checking for $ac_word" >&5 +echo "configure:964: checking for $ac_word" >&5 if eval "test \"`echo '$''{'ac_cv_prog_RANLIB'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else @@ -904,7 +998,7 @@ cross_compiling=$ac_cv_prog_cxx_cross # Extract the first word of "strip", so it can be a program name with args. set dummy strip; ac_word=$2 echo $ac_n "checking for $ac_word""... $ac_c" 1>&6 -echo "configure:908: checking for $ac_word" >&5 +echo "configure:1002: checking for $ac_word" >&5 if eval "test \"`echo '$''{'ac_cv_prog_STRIP'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else @@ -940,12 +1034,12 @@ if test -d /stuff/include; then fi echo $ac_n "checking for ANSI C header files""... $ac_c" 1>&6 -echo "configure:944: checking for ANSI C header files" >&5 +echo "configure:1038: checking for ANSI C header files" >&5 if eval "test \"`echo '$''{'ac_cv_header_stdc'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else cat > conftest.$ac_ext < #include @@ -953,7 +1047,7 @@ else #include EOF ac_try="$ac_cpp conftest.$ac_ext >/dev/null 2>conftest.out" -{ (eval echo configure:957: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; } +{ (eval echo configure:1051: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; } ac_err=`grep -v '^ *+' conftest.out | grep -v "^conftest.${ac_ext}\$"` if test -z "$ac_err"; then rm -rf conftest* @@ -970,7 +1064,7 @@ rm -f conftest* if test $ac_cv_header_stdc = yes; then # SunOS 4.x string.h does not declare mem*, contrary to ANSI. cat > conftest.$ac_ext < EOF @@ -988,7 +1082,7 @@ fi if test $ac_cv_header_stdc = yes; then # ISC 2.0.2 stdlib.h does not declare free, contrary to ANSI. cat > conftest.$ac_ext < EOF @@ -1009,7 +1103,7 @@ if test "$cross_compiling" = yes; then : else cat > conftest.$ac_ext <&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext} && (./conftest; exit) 2>/dev/null +if { (eval echo configure:1121: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext} && (./conftest; exit) 2>/dev/null then : else @@ -1050,17 +1144,17 @@ for ac_hdr in getopt.h do ac_safe=`echo "$ac_hdr" | sed 'y%./+-%__p_%'` echo $ac_n "checking for $ac_hdr""... $ac_c" 1>&6 -echo "configure:1054: checking for $ac_hdr" >&5 +echo "configure:1148: checking for $ac_hdr" >&5 if eval "test \"`echo '$''{'ac_cv_header_$ac_safe'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else cat > conftest.$ac_ext < EOF ac_try="$ac_cpp conftest.$ac_ext >/dev/null 2>conftest.out" -{ (eval echo configure:1064: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; } +{ (eval echo configure:1158: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; } ac_err=`grep -v '^ *+' conftest.out | grep -v "^conftest.${ac_ext}\$"` if test -z "$ac_err"; then rm -rf conftest* @@ -1090,17 +1184,17 @@ for ac_hdr in unistd.h do ac_safe=`echo "$ac_hdr" | sed 'y%./+-%__p_%'` echo $ac_n "checking for $ac_hdr""... $ac_c" 1>&6 -echo "configure:1094: checking for $ac_hdr" >&5 +echo "configure:1188: checking for $ac_hdr" >&5 if eval "test \"`echo '$''{'ac_cv_header_$ac_safe'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else cat > conftest.$ac_ext < EOF ac_try="$ac_cpp conftest.$ac_ext >/dev/null 2>conftest.out" -{ (eval echo configure:1104: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; } +{ (eval echo configure:1198: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; } ac_err=`grep -v '^ *+' conftest.out | grep -v "^conftest.${ac_ext}\$"` if test -z "$ac_err"; then rm -rf conftest* @@ -1128,17 +1222,17 @@ done ac_safe=`echo "sys/socket.h" | sed 'y%./+-%__p_%'` echo $ac_n "checking for sys/socket.h""... $ac_c" 1>&6 -echo "configure:1132: checking for sys/socket.h" >&5 +echo "configure:1226: checking for sys/socket.h" >&5 if eval "test \"`echo '$''{'ac_cv_header_$ac_safe'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else cat > conftest.$ac_ext < EOF ac_try="$ac_cpp conftest.$ac_ext >/dev/null 2>conftest.out" -{ (eval echo configure:1142: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; } +{ (eval echo configure:1236: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; } ac_err=`grep -v '^ *+' conftest.out | grep -v "^conftest.${ac_ext}\$"` if test -z "$ac_err"; then rm -rf conftest* @@ -1163,7 +1257,7 @@ EOF EOF cat > conftest.$ac_ext < EOF @@ -1190,17 +1284,17 @@ fi ac_safe=`echo "dlfcn.h" | sed 'y%./+-%__p_%'` echo $ac_n "checking for dlfcn.h""... $ac_c" 1>&6 -echo "configure:1194: checking for dlfcn.h" >&5 +echo "configure:1288: checking for dlfcn.h" >&5 if eval "test \"`echo '$''{'ac_cv_header_$ac_safe'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else cat > conftest.$ac_ext < EOF ac_try="$ac_cpp conftest.$ac_ext >/dev/null 2>conftest.out" -{ (eval echo configure:1204: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; } +{ (eval echo configure:1298: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; } ac_err=`grep -v '^ *+' conftest.out | grep -v "^conftest.${ac_ext}\$"` if test -z "$ac_err"; then rm -rf conftest* @@ -1226,12 +1320,12 @@ for ac_hdr in dirent.h sys/ndir.h sys/dir.h ndir.h do ac_safe=`echo "$ac_hdr" | sed 'y%./+-%__p_%'` echo $ac_n "checking for $ac_hdr that defines DIR""... $ac_c" 1>&6 -echo "configure:1230: checking for $ac_hdr that defines DIR" >&5 +echo "configure:1324: checking for $ac_hdr that defines DIR" >&5 if eval "test \"`echo '$''{'ac_cv_header_dirent_$ac_safe'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else cat > conftest.$ac_ext < #include <$ac_hdr> @@ -1239,7 +1333,7 @@ int main() { DIR *dirp = 0; ; return 0; } EOF -if { (eval echo configure:1243: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then +if { (eval echo configure:1337: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then rm -rf conftest* eval "ac_cv_header_dirent_$ac_safe=yes" else @@ -1264,7 +1358,7 @@ done # Two versions of opendir et al. are in -ldir and -lx on SCO Xenix. if test $ac_header_dirent = dirent.h; then echo $ac_n "checking for opendir in -ldir""... $ac_c" 1>&6 -echo "configure:1268: checking for opendir in -ldir" >&5 +echo "configure:1362: checking for opendir in -ldir" >&5 ac_lib_var=`echo dir'_'opendir | sed 'y%./+-%__p_%'` if eval "test \"`echo '$''{'ac_cv_lib_$ac_lib_var'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 @@ -1272,7 +1366,7 @@ else ac_save_LIBS="$LIBS" LIBS="-ldir $LIBS" cat > conftest.$ac_ext <&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then +if { (eval echo configure:1384: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then rm -rf conftest* eval "ac_cv_lib_$ac_lib_var=yes" else @@ -1308,7 +1402,7 @@ fi else echo $ac_n "checking for opendir in -lx""... $ac_c" 1>&6 -echo "configure:1312: checking for opendir in -lx" >&5 +echo "configure:1406: checking for opendir in -lx" >&5 ac_lib_var=`echo x'_'opendir | sed 'y%./+-%__p_%'` if eval "test \"`echo '$''{'ac_cv_lib_$ac_lib_var'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 @@ -1316,7 +1410,7 @@ else ac_save_LIBS="$LIBS" LIBS="-lx $LIBS" cat > conftest.$ac_ext <&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then +if { (eval echo configure:1428: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then rm -rf conftest* eval "ac_cv_lib_$ac_lib_var=yes" else @@ -1356,13 +1450,13 @@ fi # This must be after CXXCPP echo $ac_n "checking which header file defines FD_ macros""... $ac_c" 1>&6 -echo "configure:1360: checking which header file defines FD_ macros" >&5 +echo "configure:1454: checking which header file defines FD_ macros" >&5 if eval "test \"`echo '$''{'ucsim_cv_fd'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else ucsim_cv_fd="unknown" cat > conftest.$ac_ext < @@ -1378,7 +1472,7 @@ fi rm -f conftest* cat > conftest.$ac_ext < @@ -1394,7 +1488,7 @@ fi rm -f conftest* cat > conftest.$ac_ext < @@ -1472,7 +1566,7 @@ EOF # Checking for functions/libs # =========================================================================== echo $ac_n "checking for socket in -lsocket""... $ac_c" 1>&6 -echo "configure:1476: checking for socket in -lsocket" >&5 +echo "configure:1570: checking for socket in -lsocket" >&5 ac_lib_var=`echo socket'_'socket | sed 'y%./+-%__p_%'` if eval "test \"`echo '$''{'ac_cv_lib_$ac_lib_var'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 @@ -1480,7 +1574,7 @@ else ac_save_LIBS="$LIBS" LIBS="-lsocket $LIBS" cat > conftest.$ac_ext <&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then +if { (eval echo configure:1592: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then rm -rf conftest* eval "ac_cv_lib_$ac_lib_var=yes" else @@ -1522,7 +1616,7 @@ else fi echo $ac_n "checking for xdr_short in -lnsl""... $ac_c" 1>&6 -echo "configure:1526: checking for xdr_short in -lnsl" >&5 +echo "configure:1620: checking for xdr_short in -lnsl" >&5 ac_lib_var=`echo nsl'_'xdr_short | sed 'y%./+-%__p_%'` if eval "test \"`echo '$''{'ac_cv_lib_$ac_lib_var'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 @@ -1530,7 +1624,7 @@ else ac_save_LIBS="$LIBS" LIBS="-lnsl $LIBS" cat > conftest.$ac_ext <&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then +if { (eval echo configure:1642: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then rm -rf conftest* eval "ac_cv_lib_$ac_lib_var=yes" else @@ -1572,7 +1666,7 @@ else fi echo $ac_n "checking for dlopen in -ldl""... $ac_c" 1>&6 -echo "configure:1576: checking for dlopen in -ldl" >&5 +echo "configure:1670: checking for dlopen in -ldl" >&5 ac_lib_var=`echo dl'_'dlopen | sed 'y%./+-%__p_%'` if eval "test \"`echo '$''{'ac_cv_lib_$ac_lib_var'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 @@ -1580,7 +1674,7 @@ else ac_save_LIBS="$LIBS" LIBS="-ldl $LIBS" cat > conftest.$ac_ext <&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then +if { (eval echo configure:1692: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then rm -rf conftest* eval "ac_cv_lib_$ac_lib_var=yes" else @@ -1620,7 +1714,7 @@ fi echo $ac_n "checking for panel_above in -lpanel""... $ac_c" 1>&6 -echo "configure:1624: checking for panel_above in -lpanel" >&5 +echo "configure:1718: checking for panel_above in -lpanel" >&5 ac_lib_var=`echo panel'_'panel_above | sed 'y%./+-%__p_%'` if eval "test \"`echo '$''{'ac_cv_lib_$ac_lib_var'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 @@ -1628,7 +1722,7 @@ else ac_save_LIBS="$LIBS" LIBS="-lpanel -lcurses $LIBS" cat > conftest.$ac_ext <&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then +if { (eval echo configure:1740: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then rm -rf conftest* eval "ac_cv_lib_$ac_lib_var=yes" else @@ -1665,7 +1759,7 @@ else echo "$ac_t""no" 1>&6 panel_ok="no" echo $ac_n "checking for nl in -lcurses""... $ac_c" 1>&6 -echo "configure:1669: checking for nl in -lcurses" >&5 +echo "configure:1763: checking for nl in -lcurses" >&5 ac_lib_var=`echo curses'_'nl | sed 'y%./+-%__p_%'` if eval "test \"`echo '$''{'ac_cv_lib_$ac_lib_var'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 @@ -1673,7 +1767,7 @@ else ac_save_LIBS="$LIBS" LIBS="-lcurses $LIBS" cat > conftest.$ac_ext <&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then +if { (eval echo configure:1785: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then rm -rf conftest* eval "ac_cv_lib_$ac_lib_var=yes" else @@ -1718,12 +1812,12 @@ fi echo $ac_n "checking for vprintf""... $ac_c" 1>&6 -echo "configure:1722: checking for vprintf" >&5 +echo "configure:1816: checking for vprintf" >&5 if eval "test \"`echo '$''{'ac_cv_func_vprintf'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else cat > conftest.$ac_ext <&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then +if { (eval echo configure:1847: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then rm -rf conftest* eval "ac_cv_func_vprintf=yes" else @@ -1773,12 +1867,12 @@ fi if test "$ac_cv_func_vprintf" != yes; then echo $ac_n "checking for _doprnt""... $ac_c" 1>&6 -echo "configure:1777: checking for _doprnt" >&5 +echo "configure:1871: checking for _doprnt" >&5 if eval "test \"`echo '$''{'ac_cv_func__doprnt'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else cat > conftest.$ac_ext <&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then +if { (eval echo configure:1902: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then rm -rf conftest* eval "ac_cv_func__doprnt=yes" else @@ -1831,12 +1925,12 @@ fi for ac_func in vsnprintf vasprintf do echo $ac_n "checking for $ac_func""... $ac_c" 1>&6 -echo "configure:1835: checking for $ac_func" >&5 +echo "configure:1929: checking for $ac_func" >&5 if eval "test \"`echo '$''{'ac_cv_func_$ac_func'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else cat > conftest.$ac_ext <&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then +if { (eval echo configure:1960: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then rm -rf conftest* eval "ac_cv_func_$ac_func=yes" else @@ -1889,12 +1983,12 @@ done for ac_func in strlen strcpy strcat strstr strcmp strerror strtok strdup do echo $ac_n "checking for $ac_func""... $ac_c" 1>&6 -echo "configure:1893: checking for $ac_func" >&5 +echo "configure:1987: checking for $ac_func" >&5 if eval "test \"`echo '$''{'ac_cv_func_$ac_func'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else cat > conftest.$ac_ext <&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then +if { (eval echo configure:2018: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then rm -rf conftest* eval "ac_cv_func_$ac_func=yes" else @@ -1947,12 +2041,12 @@ done for ac_func in strchr memcpy do echo $ac_n "checking for $ac_func""... $ac_c" 1>&6 -echo "configure:1951: checking for $ac_func" >&5 +echo "configure:2045: checking for $ac_func" >&5 if eval "test \"`echo '$''{'ac_cv_func_$ac_func'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else cat > conftest.$ac_ext <&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then +if { (eval echo configure:2076: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then rm -rf conftest* eval "ac_cv_func_$ac_func=yes" else @@ -2005,12 +2099,12 @@ done for ac_func in fgets do echo $ac_n "checking for $ac_func""... $ac_c" 1>&6 -echo "configure:2009: checking for $ac_func" >&5 +echo "configure:2103: checking for $ac_func" >&5 if eval "test \"`echo '$''{'ac_cv_func_$ac_func'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else cat > conftest.$ac_ext <&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then +if { (eval echo configure:2134: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then rm -rf conftest* eval "ac_cv_func_$ac_func=yes" else @@ -2063,12 +2157,12 @@ done for ac_func in yylex do echo $ac_n "checking for $ac_func""... $ac_c" 1>&6 -echo "configure:2067: checking for $ac_func" >&5 +echo "configure:2161: checking for $ac_func" >&5 if eval "test \"`echo '$''{'ac_cv_func_$ac_func'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else cat > conftest.$ac_ext <&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then +if { (eval echo configure:2192: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then rm -rf conftest* eval "ac_cv_func_$ac_func=yes" else @@ -2120,7 +2214,7 @@ done echo $ac_n "checking whether scanf knows %a""... $ac_c" 1>&6 -echo "configure:2124: checking whether scanf knows %a" >&5 +echo "configure:2218: checking whether scanf knows %a" >&5 if eval "test \"`echo '$''{'ucsim_cv_scanf_a'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else @@ -2129,7 +2223,7 @@ if test "$cross_compiling" = yes; then ucsim_cv_scanf_a="unknown" else cat > conftest.$ac_ext <&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext} && (./conftest; exit) 2>/dev/null +if { (eval echo configure:2250: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext} && (./conftest; exit) 2>/dev/null then ucsim_cv_scanf_a="yes" else @@ -2176,7 +2270,7 @@ EOF fi echo $ac_n "checking whether getcwd is GNUish""... $ac_c" 1>&6 -echo "configure:2180: checking whether getcwd is GNUish" >&5 +echo "configure:2274: checking whether getcwd is GNUish" >&5 if eval "test \"`echo '$''{'ucsim_cv_getcwd'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else @@ -2184,7 +2278,7 @@ else ucsim_cv_getcwd="unknown" else cat > conftest.$ac_ext <&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext} && (./conftest; exit) 2>/dev/null +if { (eval echo configure:2296: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext} && (./conftest; exit) 2>/dev/null then ucsim_cv_getcwd="yes" else @@ -2225,7 +2319,7 @@ fi #' echo $ac_n "checking for type of length pointer parameter of accept""... $ac_c" 1>&6 -echo "configure:2229: checking for type of length pointer parameter of accept" >&5 +echo "configure:2323: checking for type of length pointer parameter of accept" >&5 if eval "test \"`echo '$''{'ucsim_cv_accept_length_type'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else @@ -2234,7 +2328,7 @@ else for ac_val in int size_t socklen_t; do CPPFLAGS="$ac_save_CPPFLAGS -DACCEPT_SOCKLEN_T=$ac_val" cat > conftest.$ac_ext < #include @@ -2242,7 +2336,7 @@ int main() { struct sockaddr a; $ac_val len; accept (0, &a, &len); ; return 0; } EOF -if { (eval echo configure:2246: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then +if { (eval echo configure:2340: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then rm -rf conftest* ucsim_cv_accept_length_type=$ac_val; break else @@ -2255,8 +2349,7 @@ rm -f conftest* fi echo "$ac_t""$ucsim_cv_accept_length_type" 1>&6 - - if test $ucsim_cv_accept_length_type != no; then + if test "$ucsim_cv_accept_length_type" != no; then cat >> confdefs.h <&6 -echo "configure:2293: checking whether byte ordering is bigendian" >&5 +if test "$cross_compiling" == "no" +then + echo $ac_n "checking whether byte ordering is bigendian""... $ac_c" 1>&6 +echo "configure:2389: checking whether byte ordering is bigendian" >&5 if eval "test \"`echo '$''{'ac_cv_c_bigendian'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else ac_cv_c_bigendian=unknown # See if sys/param.h defines the BYTE_ORDER macro. cat > conftest.$ac_ext < #include @@ -2307,11 +2403,11 @@ int main() { #endif ; return 0; } EOF -if { (eval echo configure:2311: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then +if { (eval echo configure:2407: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then rm -rf conftest* # It does; now see whether it defined to BIG_ENDIAN or not. cat > conftest.$ac_ext < #include @@ -2322,7 +2418,7 @@ int main() { #endif ; return 0; } EOF -if { (eval echo configure:2326: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then +if { (eval echo configure:2422: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then rm -rf conftest* ac_cv_c_bigendian=yes else @@ -2342,7 +2438,7 @@ if test "$cross_compiling" = yes; then { echo "configure: error: can not run test program while cross compiling" 1>&2; exit 1; } else cat > conftest.$ac_ext <&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext} && (./conftest; exit) 2>/dev/null +if { (eval echo configure:2458: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext} && (./conftest; exit) 2>/dev/null then ac_cv_c_bigendian=no else @@ -2381,8 +2477,18 @@ EOF fi +else +#echo "CROSS ENDIAN" + if $CXX -v 2>&1|grep "mingw" >/dev/null 2>&1; then + ac_cv_c_bigendian=no + else + : # FIXME + fi +#echo "CROSS ENDIAN DONE" +fi + echo $ac_n "checking whether preprocessor accepts -MM or -M""... $ac_c" 1>&6 -echo "configure:2386: checking whether preprocessor accepts -MM or -M" >&5 +echo "configure:2492: checking whether preprocessor accepts -MM or -M" >&5 if eval "test \"`echo '$''{'ucsim_cv_MM'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else @@ -2405,7 +2511,7 @@ M_OR_MM=$ucsim_cv_MM echo $ac_n "checking whether $CXX accepts -ggdb""... $ac_c" 1>&6 -echo "configure:2409: checking whether $CXX accepts -ggdb" >&5 +echo "configure:2515: checking whether $CXX accepts -ggdb" >&5 if eval "test \"`echo '$''{'ucsim_cv_CXXggdb'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else @@ -2426,7 +2532,7 @@ echo "$ac_t""$ucsim_cv_CXXggdb" 1>&6 if test "$ucsim_cv_CXXggdb" = "yes"; then if test "$CXXFLAGS"x = x ;then - CXXFLAGS="-ggdb -O" + CXXFLAGS="-ggdb" else CXXFLAGS="$CXXFLAGS -ggdb" fi @@ -2434,7 +2540,7 @@ fi echo $ac_n "checking whether $CXX accepts -pipe""... $ac_c" 1>&6 -echo "configure:2438: checking whether $CXX accepts -pipe" >&5 +echo "configure:2544: checking whether $CXX accepts -pipe" >&5 if eval "test \"`echo '$''{'ucsim_cv_CXXpipe'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else @@ -2461,7 +2567,7 @@ PICOPT="" SHAREDLIB="no" echo $ac_n "checking whether $CXX accepts -fPIC""... $ac_c" 1>&6 -echo "configure:2465: checking whether $CXX accepts -fPIC" >&5 +echo "configure:2571: checking whether $CXX accepts -fPIC" >&5 if eval "test \"`echo '$''{'ucsim_cv_CXXfPIC'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else @@ -2485,7 +2591,7 @@ if test "$ucsim_cv_CXXfPIC" = "yes"; then else echo $ac_n "checking whether $CXX accepts -fpic""... $ac_c" 1>&6 -echo "configure:2489: checking whether $CXX accepts -fpic" >&5 +echo "configure:2595: checking whether $CXX accepts -fpic" >&5 if eval "test \"`echo '$''{'ucsim_cv_CXXfpic'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else @@ -2514,6 +2620,7 @@ fi # If this is Cygwin neither use Position Independant Code # nor build .so # Quick + dirty by Bernhard +# FIXME if $CXX -v 2>&1 | grep -i cygwin 1>&5 2>&5; then PICOPT="" SHAREDLIB="no" @@ -2521,18 +2628,22 @@ fi +dlso_ok="no" +if test $SHAREDLIB = "yes" -a $dl_ok = "yes" -a $enable_dlso = "yes"; then + dlso_ok="yes" +fi + # Checks for typedefs, structures, and compiler characteristics. # =========================================================================== - echo $ac_n "checking return type of signal handlers""... $ac_c" 1>&6 -echo "configure:2531: checking return type of signal handlers" >&5 +echo "configure:2642: checking return type of signal handlers" >&5 if eval "test \"`echo '$''{'ac_cv_type_signal'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else cat > conftest.$ac_ext < #include @@ -2549,7 +2660,7 @@ int main() { int i; ; return 0; } EOF -if { (eval echo configure:2553: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then +if { (eval echo configure:2664: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then rm -rf conftest* ac_cv_type_signal=void else @@ -2567,8 +2678,9 @@ cat >> confdefs.h <&6 -echo "configure:2572: checking size of char" >&5 +echo "configure:2684: checking size of char" >&5 if eval "test \"`echo '$''{'ac_cv_sizeof_char'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else @@ -2576,7 +2688,7 @@ else { echo "configure: error: can not run test program while cross compiling" 1>&2; exit 1; } else cat > conftest.$ac_ext <&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext} && (./conftest; exit) 2>/dev/null +if { (eval echo configure:2707: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext} && (./conftest; exit) 2>/dev/null then ac_cv_sizeof_char=`cat conftestval` else @@ -2611,7 +2723,7 @@ EOF echo $ac_n "checking size of short""... $ac_c" 1>&6 -echo "configure:2615: checking size of short" >&5 +echo "configure:2727: checking size of short" >&5 if eval "test \"`echo '$''{'ac_cv_sizeof_short'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else @@ -2619,7 +2731,7 @@ else { echo "configure: error: can not run test program while cross compiling" 1>&2; exit 1; } else cat > conftest.$ac_ext <&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext} && (./conftest; exit) 2>/dev/null +if { (eval echo configure:2750: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext} && (./conftest; exit) 2>/dev/null then ac_cv_sizeof_short=`cat conftestval` else @@ -2654,7 +2766,7 @@ EOF echo $ac_n "checking size of int""... $ac_c" 1>&6 -echo "configure:2658: checking size of int" >&5 +echo "configure:2770: checking size of int" >&5 if eval "test \"`echo '$''{'ac_cv_sizeof_int'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else @@ -2662,7 +2774,7 @@ else { echo "configure: error: can not run test program while cross compiling" 1>&2; exit 1; } else cat > conftest.$ac_ext <&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext} && (./conftest; exit) 2>/dev/null +if { (eval echo configure:2793: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext} && (./conftest; exit) 2>/dev/null then ac_cv_sizeof_int=`cat conftestval` else @@ -2697,7 +2809,7 @@ EOF echo $ac_n "checking size of long""... $ac_c" 1>&6 -echo "configure:2701: checking size of long" >&5 +echo "configure:2813: checking size of long" >&5 if eval "test \"`echo '$''{'ac_cv_sizeof_long'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else @@ -2705,7 +2817,7 @@ else { echo "configure: error: can not run test program while cross compiling" 1>&2; exit 1; } else cat > conftest.$ac_ext <&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext} && (./conftest; exit) 2>/dev/null +if { (eval echo configure:2836: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext} && (./conftest; exit) 2>/dev/null then ac_cv_sizeof_long=`cat conftestval` else @@ -2740,7 +2852,7 @@ EOF echo $ac_n "checking size of long long""... $ac_c" 1>&6 -echo "configure:2744: checking size of long long" >&5 +echo "configure:2856: checking size of long long" >&5 if eval "test \"`echo '$''{'ac_cv_sizeof_long_long'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else @@ -2748,7 +2860,7 @@ else { echo "configure: error: can not run test program while cross compiling" 1>&2; exit 1; } else cat > conftest.$ac_ext <&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext} && (./conftest; exit) 2>/dev/null +if { (eval echo configure:2879: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext} && (./conftest; exit) 2>/dev/null then ac_cv_sizeof_long_long=`cat conftestval` else @@ -2782,6 +2894,18 @@ cat >> confdefs.h <&1|grep "mingw" >/dev/null 2>&1; then + ac_cv_sizeof_char=1 + ac_cv_sizeof_short=2 + ac_cv_sizeof_int=4 + ac_cv_sizeof_long=4 + ac_cv_sizeof_long_long=4 + else + : # FIXME + fi +#echo +fi type_name() { @@ -2809,15 +2933,15 @@ type_name() } echo $ac_n "checking type name for byte""... $ac_c" 1>&6 -echo "configure:2813: checking type name for byte" >&5 +echo "configure:2937: checking type name for byte" >&5 TYPE_BYTE=`type_name 1` echo "$ac_t""$TYPE_BYTE" 1>&6 echo $ac_n "checking type name for word""... $ac_c" 1>&6 -echo "configure:2817: checking type name for word" >&5 +echo "configure:2941: checking type name for word" >&5 TYPE_WORD=`type_name 2` echo "$ac_t""$TYPE_WORD" 1>&6 echo $ac_n "checking type name for dword""... $ac_c" 1>&6 -echo "configure:2821: checking type name for dword" >&5 +echo "configure:2945: checking type name for dword" >&5 TYPE_DWORD=`type_name 4` echo "$ac_t""$TYPE_DWORD" 1>&6 cat >> confdefs.h <> confdefs.h </dev/null; then + A="h" +elif echo $TYPE_DWORD|grep long >/dev/null; then + A="l" +else + A="" +fi + +if echo $TYPE_WORD|grep short >/dev/null; then M="h" +elif echo $TYPE_WORD|grep long >/dev/null; then M="l" +else M="" +fi + +cat >> confdefs.h <> confdefs.h <> $CONFIG_STATUS <&1|grep "mingw" >/dev/null 2>&1; then + ac_cv_c_bigendian=no + else + : # FIXME + fi +#echo "CROSS ENDIAN DONE" +fi + AC_CACHE_CHECK(whether preprocessor accepts -MM or -M,ucsim_cv_MM, echo "#include " >_test_.c echo "" >>_test_.c @@ -260,7 +324,7 @@ AC_SUBST(M_OR_MM) DD_COPT(CXX, ggdb) if test "$ucsim_cv_CXXggdb" = "yes"; then if test "$CXXFLAGS"x = x ;then - CXXFLAGS="-ggdb -O" + CXXFLAGS="-ggdb" else CXXFLAGS="$CXXFLAGS -ggdb" fi @@ -288,6 +352,7 @@ fi # If this is Cygwin neither use Position Independant Code # nor build .so # Quick + dirty by Bernhard +# FIXME if $CXX -v 2>&1 | grep -i cygwin 1>&5 2>&5; then PICOPT="" SHAREDLIB="no" @@ -295,17 +360,34 @@ fi AC_SUBST(SHAREDLIB) AC_SUBST(PICOPT) +dlso_ok="no" +if test $SHAREDLIB = "yes" -a $dl_ok = "yes" -a $enable_dlso = "yes"; then + dlso_ok="yes" +fi +AC_SUBST(dlso_ok) # Checks for typedefs, structures, and compiler characteristics. # =========================================================================== - AC_TYPE_SIGNAL +if test "$cross_compiling" = "no"; then AC_CHECK_SIZEOF(char) AC_CHECK_SIZEOF(short) AC_CHECK_SIZEOF(int) AC_CHECK_SIZEOF(long) AC_CHECK_SIZEOF(long long) +else + if $CXX -v 2>&1|grep "mingw" >/dev/null 2>&1; then + ac_cv_sizeof_char=1 + ac_cv_sizeof_short=2 + ac_cv_sizeof_int=4 + ac_cv_sizeof_long=4 + ac_cv_sizeof_long_long=4 + else + : # FIXME + fi +#echo +fi type_name() { @@ -345,15 +427,34 @@ AC_DEFINE_UNQUOTED(TYPE_BYTE, $TYPE_BYTE) AC_DEFINE_UNQUOTED(TYPE_WORD, $TYPE_WORD) AC_DEFINE_UNQUOTED(TYPE_DWORD, $TYPE_DWORD) +if echo $TYPE_DWORD|grep short >/dev/null; then + A="h" +elif echo $TYPE_DWORD|grep long >/dev/null; then + A="l" +else + A="" +fi + +if echo $TYPE_WORD|grep short >/dev/null; then M="h" +elif echo $TYPE_WORD|grep long >/dev/null; then M="l" +else M="" +fi + +AC_DEFINE_UNQUOTED(_A_, "${A}") +AC_DEFINE_UNQUOTED(_M_, "${M}") + + # Generating output files # =========================================================================== AC_OUTPUT(main.mk:main_in.mk +packages.mk:packages_in.mk sim.src/Makefile cmd.src/Makefile s51.src/Makefile avr.src/Makefile z80.src/Makefile +xa.src/Makefile gui.src/Makefile gui.src/serio.src/Makefile doc/Makefile diff --git a/sim/ucsim/ddconfig_in.h b/sim/ucsim/ddconfig_in.h index 6fdc7f9c..6a13aa0d 100644 --- a/sim/ucsim/ddconfig_in.h +++ b/sim/ucsim/ddconfig_in.h @@ -90,6 +90,8 @@ Software Foundation, 59 Temple Place - Suite 330, Boston, MA #define TYPE_UWORD unsigned TYPE_WORD #define TYPE_UDWORD unsigned TYPE_DWORD #undef WORDS_BIGENDIAN +#undef _M_ +#undef _A_ #undef VERSIONSTR #undef VERSIONHI diff --git a/sim/ucsim/doc/Makefile.in b/sim/ucsim/doc/Makefile.in index 37486cb5..028902b2 100644 --- a/sim/ucsim/doc/Makefile.in +++ b/sim/ucsim/doc/Makefile.in @@ -50,6 +50,8 @@ uninstall: # -------------------- check: +test: + # Performing installation test # ---------------------------- diff --git a/sim/ucsim/doc/cpu_types.html b/sim/ucsim/doc/cpu_types.html index d546f37f..5c8820b7 100644 --- a/sim/ucsim/doc/cpu_types.html +++ b/sim/ucsim/doc/cpu_types.html @@ -14,6 +14,8 @@ family:
8052/8032 +
DS390 +
8051R
89C51R @@ -110,6 +112,30 @@ microcontrollers and additionaly: +

DS390

+ +You can select this type of microcontroller using DS390 as +parameter for -t option (this is a CMOS type). + +It includes same features as 8052 and adds: + +
  • 24 bit flat mode + +
  • support for dual DPTR register + +
  • 128k external RAM + +
  • 128k ROM + +
  • 4k internal SRAM usable + +
  • 10 bit stack mode + +
  • "timed access" of SFRs + +
+ +

8051R

You can select this type of microcontroller using one of the following diff --git a/sim/ucsim/doc/invoke.html b/sim/ucsim/doc/invoke.html index 5a206732..024b138e 100644 --- a/sim/ucsim/doc/invoke.html +++ b/sim/ucsim/doc/invoke.html @@ -30,10 +30,13 @@ them in specified order into the ROM of the simulated system.
Type of CPU. Recognized types are: 51, 8051, 8751, C51, 80C51, 87C51, 31, 8031, C31, 80C31, 52, 8052, 8752, C52, 80C52, 87C52, 32, 8032, C32, 80C32, 51R, 51RA, 51RB, 51RC, C51R, C51RA, C51RB, C51RC, -89C51R, 251, C251, DS390, DS390F. Note that recongition of a CPU type as option does -not mean that the simulator can simulate that kind of CPU. Default -type is C51. DS390 supports Dallas DS80C390 dual-dptr operations, -DS390F supports minimal flat24 mode code and dual-dptr operations. +89C51R, 251, C251, DS390, DS390F. Note that recognition of a CPU type +as option does not mean that the simulator can simulate that kind of +CPU. Default type is C51. +
DS390 supports Dallas DS80C390 24 bit flat mode, dual-dptr operations, etc. +DS390F is the same as DS390, but it starts already in 24 bit flat mode +(ACON = 0xFA instead of 0xF8). DS390F is needed to run programs compiled +with sdcc -mds390.
See how to select CPU type. diff --git a/sim/ucsim/error.cc b/sim/ucsim/error.cc new file mode 100644 index 00000000..7f3fa5d6 --- /dev/null +++ b/sim/ucsim/error.cc @@ -0,0 +1,49 @@ +/* + * Simulator of microcontrollers (error.cc) + * + * Copyright (C) 2001,01 Drotos Daniel, Talker Bt. + * + * To contact author send email to drdani@mazsola.iit.uni-miskolc.hu + * + */ + +/* This file is part of microcontroller simulator: ucsim. + +UCSIM is free software; you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation; either version 2 of the License, or +(at your option) any later version. + +UCSIM is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU General Public License for more details. + +You should have received a copy of the GNU General Public License +along with UCSIM; see the file COPYING. If not, write to the Free +Software Foundation, 59 Temple Place - Suite 330, Boston, MA +02111-1307, USA. */ +/*@1@*/ + +// prj (local) +#include "errorcl.h" + +// cmd.src +#include "newcmdcl.h" + + +cl_error::cl_error(void): + cl_base() +{} + +cl_error::~cl_error(void) +{} + +void +cl_error::print(class cl_commander *c) +{ + c->dd_printf("Error\n"); +} + + +/* End of sim.src/error.cc */ diff --git a/sim/ucsim/errorcl.h b/sim/ucsim/errorcl.h new file mode 100644 index 00000000..99f83e81 --- /dev/null +++ b/sim/ucsim/errorcl.h @@ -0,0 +1,56 @@ +/* + * Simulator of microcontrollers (errorcl.h) + * + * Copyright (C) 2001,01 Drotos Daniel, Talker Bt. + * + * To contact author send email to drdani@mazsola.iit.uni-miskolc.hu + * + */ + +/* This file is part of microcontroller simulator: ucsim. + +UCSIM is free software; you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation; either version 2 of the License, or +(at your option) any later version. + +UCSIM is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU General Public License for more details. + +You should have received a copy of the GNU General Public License +along with UCSIM; see the file COPYING. If not, write to the Free +Software Foundation, 59 Temple Place - Suite 330, Boston, MA +02111-1307, USA. */ +/*@1@*/ + +#ifndef ERRORCL_HEADER +#define ERRORCL_HEADER + +// prj +#include "pobjcl.h" +#include "stypes.h" + +// cmd.src +//#include "newcmdcl.h" + + +class cl_commander; //forward + +class cl_error: public cl_base +{ +public: + bool inst; // Occured during instruction execution + t_addr PC; // Address of the instruction +public: + cl_error(void); + virtual ~cl_error(void); + + virtual void print(class cl_commander *c); +}; + + +#endif + +/* End of sim.src/errorcl.h */ diff --git a/sim/ucsim/globals.cc b/sim/ucsim/globals.cc index 516d059f..a9f04a5b 100644 --- a/sim/ucsim/globals.cc +++ b/sim/ucsim/globals.cc @@ -45,6 +45,7 @@ struct id_element mem_ids[]= { { MEM_IRAM , "IRAM " }, { MEM_SFR , "SFR " }, { MEM_IXRAM, "IXRAM" }, + { MEM_DUMMY, "DUMMY" }, { 0, 0 } }; @@ -54,6 +55,7 @@ struct id_element mem_classes[]= { { MEM_IRAM , "iram" }, { MEM_SFR , "sfr" }, { MEM_IXRAM, "ixram" }, + { MEM_DUMMY, "dummy" }, { 0, 0 } }; @@ -65,7 +67,7 @@ struct id_element cpu_states[]= { }; -char *warranty= +char *warranty= " NO WARRANTY 11. BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY diff --git a/sim/ucsim/gui.src/Makefile.in b/sim/ucsim/gui.src/Makefile.in index be24aca2..e8944911 100644 --- a/sim/ucsim/gui.src/Makefile.in +++ b/sim/ucsim/gui.src/Makefile.in @@ -36,8 +36,14 @@ man2dir = $(mandir)/man2 infodir = @infodir@ srcdir = @srcdir@ +enable_serio = @enable_serio@ PKGS = -CURSES_PKGS = serio.src +ifeq ($(enable_serio),yes) +SERIO_PKG = serio.src +else +SERIO_PKG = +endif +CURSES_PKGS = $(SERIO.PKG) # Common code OBJECTS = rec.o @@ -60,8 +66,8 @@ all: gui.src gui.src: checkconf gui_api ifeq ($(curses_ok),yes) - @for pkg in $(CURSES_PKGS); do\ - $(MAKE) -C $$pkg $$pkg ;\ + @for pkg in dummy $(CURSES_PKGS); do\ + if test -d $$pkg; then $(MAKE) -C $$pkg $$pkg; else : ; fi ;\ done endif # @for pkg in $(PKGS); do\ @@ -93,12 +99,19 @@ uninstall_gui_api: # Performing self-test # -------------------- -check: check_gui_api +check: check_local @for pkg in $(PKGS); do\ cd $$pkg && $(MAKE) check ; cd ..;\ done -check_gui_api: +check_local: + +test: test_local + @for pkg in $(PKGS); do\ + cd $$pkg && $(MAKE) test ; cd ..;\ + done + +test_local: # Performing installation test @@ -135,13 +148,13 @@ include clean.mk ucsim_lib: $(PRJDIR)/libguiucsim.a $(PRJDIR)/libguiucsim.a: $(OBJECTS) $(UCSIM_OBJECTS) - $(AR) -rcu $*.a $(OBJECTS) $(UCSIM_OBJECTS) + ar -rcu $*.a $(OBJECTS) $(UCSIM_OBJECTS) $(RANLIB) $*.a tool_lib: $(PRJDIR)/libguitool.a $(PRJDIR)/libguitool.a: $(OBJECTS) $(TOOL_OBJECTS) - $(AR) -rcu $*.a $(OBJECTS) $(TOOL_OBJECTS) + ar -rcu $*.a $(OBJECTS) $(TOOL_OBJECTS) $(RANLIB) $*.a .cc.o: diff --git a/sim/ucsim/gui.src/guicl.h b/sim/ucsim/gui.src/guicl.h index 6d7f99ff..3fd37029 100644 --- a/sim/ucsim/gui.src/guicl.h +++ b/sim/ucsim/gui.src/guicl.h @@ -47,7 +47,7 @@ public: class cl_list *ifs; public: cl_gui(class cl_sim *asim); - ~cl_gui(void); + virtual ~cl_gui(void); virtual class cl_gui_if *if_by_obj(class cl_guiobj *o); }; diff --git a/sim/ucsim/gui.src/serio.src/Makefile.in b/sim/ucsim/gui.src/serio.src/Makefile.in index 26a49006..7f4b6b74 100644 --- a/sim/ucsim/gui.src/serio.src/Makefile.in +++ b/sim/ucsim/gui.src/serio.src/Makefile.in @@ -61,6 +61,8 @@ uninstall: # -------------------- check: +test: + # Performing installation test # ---------------------------- diff --git a/sim/ucsim/gui.src/serio.src/frontend.hh b/sim/ucsim/gui.src/serio.src/frontend.hh index fb4ae33c..aa13b9c9 100644 --- a/sim/ucsim/gui.src/serio.src/frontend.hh +++ b/sim/ucsim/gui.src/serio.src/frontend.hh @@ -4,6 +4,7 @@ ******************************************************************************/ #include #include +/*#include */ #include "config.h" struct COORDS_S diff --git a/sim/ucsim/gui.src/serio.src/main.cc b/sim/ucsim/gui.src/serio.src/main.cc index e39cce7f..5ce36122 100644 --- a/sim/ucsim/gui.src/serio.src/main.cc +++ b/sim/ucsim/gui.src/serio.src/main.cc @@ -11,7 +11,7 @@ #include #include #include -#include +#include // FIXME #include "fileio.hh" #include "frontend.hh" #include "posix_signal.hh" diff --git a/sim/ucsim/main_in.mk b/sim/ucsim/main_in.mk index a7bfd636..7d47fb85 100644 --- a/sim/ucsim/main_in.mk +++ b/sim/ucsim/main_in.mk @@ -15,10 +15,13 @@ INSTALL = @INSTALL@ PRJDIR = . SIMDIR = sim.src +CMDDIR = cmd.src +GUIDIR = gui.src DEFS = $(subs -DHAVE_CONFIG_H,,@DEFS@) # FIXME: -Imcs51 must be removed!!! -CPPFLAGS = @CPPFLAGS@ -I$(PRJDIR) -I$(PRJDIR)/$(SIMDIR) +CPPFLAGS = @CPPFLAGS@ -I$(PRJDIR) -I$(PRJDIR)/$(SIMDIR) \ + -I$(CMDDIR) -I$(GUIDIR) CFLAGS = @CFLAGS@ -I$(PRJDIR) -Wall CXXFLAGS = @CXXFLAGS@ -I$(PRJDIR) -Wall M_OR_MM = @M_OR_MM@ @@ -26,7 +29,6 @@ M_OR_MM = @M_OR_MM@ LIB_LIST = sim cmd sim util UCSIM_LIBS = $(patsubst %,-l%,$(LIB_LIST)) UCSIM_LIB_FILES = $(patsubst %,lib%.a,$(LIB_LIST)) -LIBS = @LIBS@ prefix = @prefix@ exec_prefix = @exec_prefix@ @@ -40,12 +42,14 @@ man2dir = $(mandir)/man2 infodir = @infodir@ srcdir = @srcdir@ -OBJECTS = pobj.o globals.o utils.o +OBJECTS = pobj.o globals.o utils.o error.o SOURCES = $(patsubst %.o,%.cc,$(OBJECTS)) UCSIM_OBJECTS = ucsim.o UCSIM_SOURCES = $(patsubst %.o,%.cc,$(UCSIM_OBJECTS)) ALL_SOURCES = $(SOURCES) $(UCSIM_SOURCES) +enable_ucsim = @enable_ucsim@ + # Compiling entire program or any subproject # ------------------------------------------ @@ -73,6 +77,7 @@ uninstall: # -------------------- check: +test: # Performing installation test # ---------------------------- @@ -101,13 +106,19 @@ include clean.mk # My rules # -------- libutil.a: $(OBJECTS) - $(AR) -rcu $*.a $(OBJECTS) + ar -rcu $*.a $(OBJECTS) $(RANLIB) $*.a + +ifeq ($(enable_ucsim),yes) ucsim_app: libs ucsim +else +ucsim_app: +endif ucsim: $(UCSIM_OBJECTS) $(UCSIM_LIB_FILES) - $(CXX) $(CXXFLAGS) -o $@ $< -L$(PRJDIR) $(UCSIM_LIBS) $(LIBS) + echo $(UCSIM_LIB_FILES) + $(CXX) $(CXXFLAGS) -o $@ $< -L$(PRJDIR) $(UCSIM_LIBS) .cc.o: $(CXX) $(CXXFLAGS) $(CPPFLAGS) $(TARGET_ARCH) -c $< -o $@ diff --git a/sim/ucsim/packages.mk b/sim/ucsim/packages.mk new file mode 100644 index 00000000..06285d6f --- /dev/null +++ b/sim/ucsim/packages.mk @@ -0,0 +1,30 @@ +enable_51 = yes +enable_avr = yes +enable_z80 = yes +enable_xa = yes + +ifeq ($(enable_51),yes) +S51 = s51.src +else +S51 = +endif + +ifeq ($(enable_avr),yes) +SAVR = avr.src +else +SAVR = +endif + +ifeq ($(enable_z80),yes) +SZ80 = z80.src +else +SZ80 = +endif + +ifeq ($(enable_xa),yes) +XA = xa.src +else +XA = +endif + +PKGS = cmd.src sim.src gui.src $(S51) $(SAVR) $(SZ80) $(XA) doc diff --git a/sim/ucsim/packages_in.mk b/sim/ucsim/packages_in.mk new file mode 100644 index 00000000..6a3675d3 --- /dev/null +++ b/sim/ucsim/packages_in.mk @@ -0,0 +1,30 @@ +enable_51 = @enable_51@ +enable_avr = @enable_avr@ +enable_z80 = @enable_z80@ +enable_xa = @enable_xa@ + +ifeq ($(enable_51),yes) +S51 = s51.src +else +S51 = +endif + +ifeq ($(enable_avr),yes) +SAVR = avr.src +else +SAVR = +endif + +ifeq ($(enable_z80),yes) +SZ80 = z80.src +else +SZ80 = +endif + +ifeq ($(enable_xa),yes) +XA = xa.src +else +XA = +endif + +PKGS = cmd.src sim.src gui.src $(S51) $(SAVR) $(SZ80) $(XA) doc diff --git a/sim/ucsim/pobj.cc b/sim/ucsim/pobj.cc index 57405baa..d2e164c1 100644 --- a/sim/ucsim/pobj.cc +++ b/sim/ucsim/pobj.cc @@ -86,7 +86,8 @@ cl_list::cl_list(t_index alimit, t_index adelta): cl_list::~cl_list(void) { - delete Items; + //delete Items; + free(Items); } @@ -135,7 +136,10 @@ cl_list::disconn_at(t_index index) void cl_list::disconn(void *item) { - disconn_at(index_of(item)); + t_index i; + + if (index_of(item, &i)) + disconn_at(i); } @@ -163,6 +167,19 @@ cl_list::free_at(t_index index) free_item(Item); } +void +cl_list::free_all(void) +{ + t_index i; + + if (count) + { + for (i= count-1; i; i--) + free_at(i); + free_at(0); + } +} + /* * Inserting a new item to the exact position @@ -296,6 +313,19 @@ cl_list::index_of(void *item) return(0); /* Needed by Sun! */ } +bool +cl_list::index_of(void *item, t_index *idx) +{ + for (t_index i= 0; i < count; i++) + if (item == Items[i]) + { + if (idx) + *idx= i; + return(DD_TRUE); + } + return(DD_FALSE); +} + /* * Inserting a new item to the collection. @@ -376,13 +406,14 @@ cl_list::set_limit(t_index alimit) AItems= 0; else { - AItems = new void *[alimit]; - //i= ALimit*(sizeof(void *)); - //AItems= (void **)malloc(i); + //AItems = new void *[alimit]; + int i= alimit*(sizeof(void *)); + AItems= (void **)malloc(i); if (count) memcpy(AItems, Items, count*sizeof(void *)); } - delete Items; + //delete Items; + free(Items); Items= AItems; Limit= alimit; } diff --git a/sim/ucsim/pobjcl.h b/sim/ucsim/pobjcl.h index 501c53d5..b105450d 100644 --- a/sim/ucsim/pobjcl.h +++ b/sim/ucsim/pobjcl.h @@ -72,6 +72,7 @@ public: void *at(t_index index); virtual t_index index_of(void *item); + virtual bool index_of(void *item, t_index *idx); int get_count(void); virtual void *pop(void); virtual void *top(void); @@ -80,6 +81,7 @@ public: virtual void set_limit(t_index alimit); void free_at(t_index index); + void free_all(void); void disconn_at(t_index index); void disconn(void *item); void disconn_all(void); diff --git a/sim/ucsim/s51.src/Makefile.in b/sim/ucsim/s51.src/Makefile.in index 2588ff2d..10be85e8 100644 --- a/sim/ucsim/s51.src/Makefile.in +++ b/sim/ucsim/s51.src/Makefile.in @@ -31,7 +31,6 @@ SDCPPFLAGS = LIBS = @LIBS@ -L$(PRJDIR) -lsim -lcmd -lguiucsim -lutil DL = @DL@ - dl_ok = @dl_ok@ prefix = @prefix@ @@ -49,26 +48,26 @@ srcdir = @srcdir@ OBJECTS_SHARED = glob.o sim51.o \ inc.o jmp.o mov.o logic.o arith.o bit.o \ timer0.o timer1.o timer2.o serial.o port.o interrupt.o \ - uc51.o uc52.o uc51r.o uc89c51r.o uc251.o uc390.o + wdt.o pca.o \ + uc51.o uc52.o uc51r.o uc89c51r.o uc251.o \ + uc390.o uc390hw.o OBJECTS_EXE = s51.o OBJECTS = $(OBJECTS_SHARED) $(OBJECTS_EXE) +enable_dlso = @enable_dlso@ +dlso_ok = @dlso_ok@ + # Compiling entire program or any subproject # ------------------------------------------ all: checkconf otherlibs s51.src -tests: test_ser.ihx - -test_ser.ihx: test_ser.rel - $(SDCC) $(SDCFLAGS) $< - # Compiling and installing everything and runing test # --------------------------------------------------- install: all installdirs - if test -f s51.exe; then $(INSTALL) s51.exe $(bindir); $(STRIP) $(bindir)/s51.exe; fi - if test -f s51; then $(INSTALL) s51 $(bindir); $(STRIP) $(bindir)/s51; fi + if test -f s51.exe; then $(INSTALL) -s s51.exe $(bindir); $(STRIP) $(bindir)/s51.exe; fi + if test -f s51; then $(INSTALL) -s s51 $(bindir); $(STRIP) $(bindir)/s51; fi # Deleting all the installed files @@ -79,8 +78,12 @@ uninstall: # Performing self-test # -------------------- -check: +check: test + +test: test_ser.ihx +test_ser.ihx: test_ser.rel + $(SDCC) $(SDCFLAGS) $< # Performing installation test # ---------------------------- @@ -114,13 +117,14 @@ include clean.mk s51.src: s51 shared_lib s51: $(OBJECTS) $(PRJDIR)/*.a - $(CXX) $(CXXFLAGS) -o s51 $(OBJECTS) $(LIBS) + $(CXX) $(CXXFLAGS) $(OBJECTS) $(LIBS) -o s51 -ifeq ($(SHAREDLIB),yes) +ifeq ($(dlso_ok),yes) shared_lib: $(PRJDIR)/s51.so else shared_lib: - @echo "No shared lib made." + @echo "No 51 shared lib made." + @echo "(SHAREDLIB="$(SHAREDLIB)",dl_ok="$(dl_ok)",enable_dlso="$(enable_dlso)")" endif $(PRJDIR)/s51.so: $(OBJECTS_SHARED) diff --git a/sim/ucsim/s51.src/arith.cc b/sim/ucsim/s51.src/arith.cc index d1949152..6fe2033b 100644 --- a/sim/ucsim/s51.src/arith.cc +++ b/sim/ucsim/s51.src/arith.cc @@ -32,6 +32,7 @@ Software Foundation, 59 Temple Place - Suite 330, Boston, MA // local #include "uc51cl.h" #include "regs51.h" +#include "types51.h" /* @@ -43,13 +44,13 @@ Software Foundation, 59 Temple Place - Suite 330, Boston, MA int t_uc51::inst_rr(uchar code) { - uchar acc; + uchar ac; - acc= sfr->read(event_at.ws= event_at.rs= ACC); - if (acc & 0x01) - sfr->set(ACC, (acc >> 1) | 0x80); + ac= acc->read(); + if (ac & 0x01) + acc->write((ac >> 1) | 0x80); else - sfr->set(ACC, acc >> 1); + acc->write(ac >> 1); return(resGO); } @@ -64,15 +65,14 @@ int t_uc51::inst_rrc(uchar code) { bool cy; - uchar acc; + uchar ac; cy= SFR_GET_C; - SET_C((acc= sfr->read(ACC)) & 0x01); - event_at.ws= event_at.rs= ACC; - acc>>= 1; + SFR_SET_C((ac= acc->read()) & 0x01); + ac>>= 1; if (cy) - acc|= 0x80; - sfr->set(ACC, acc); + ac|= 0x80; + sfr->write(ACC, ac); return(resGO); } @@ -86,13 +86,13 @@ t_uc51::inst_rrc(uchar code) int t_uc51::inst_rl(uchar code) { - uchar acc; + uchar ac; - acc= sfr->read(event_at.ws= event_at.rs= ACC); - if (acc & 0x80) - sfr->set(ACC, (acc << 1 ) | 0x01); + ac= acc->read(); + if (ac & 0x80) + acc->write((ac << 1 ) | 0x01); else - sfr->set(ACC, acc << 1); + acc->write(ac << 1); return(resGO); } @@ -106,19 +106,18 @@ t_uc51::inst_rl(uchar code) int t_uc51::inst_add_a_$data(uchar code) { - uchar data, acc; + uchar data, ac; bool newC, newA, c6; data= fetch(); - acc = sfr->get(ACC); - newC= (((uint)acc+(uint)(data)) > 255)?0x80:0; - newA= ((acc&0x0f)+(data&0x0f)) & 0xf0; - c6 = ((acc&0x7f)+(data&0x7f)) & 0x80; - event_at.ws= ACC; - sfr->set(ACC, acc+data); - SET_C(newC); - SET_BIT(newC ^ c6, PSW, bmOV); - SET_BIT(newA, PSW, bmAC); + ac = acc->read(); + newC= (((uint)ac+(uint)(data)) > 255)?0x80:0; + newA= ((ac&0x0f)+(data&0x0f)) & 0xf0; + c6 = ((ac&0x7f)+(data&0x7f)) & 0x80; + acc->write(ac+data); + SFR_SET_C(newC); + SFR_SET_BIT(newC ^ c6, PSW, bmOV); + SFR_SET_BIT(newA, PSW, bmAC); return(resGO); } @@ -132,19 +131,21 @@ t_uc51::inst_add_a_$data(uchar code) int t_uc51::inst_add_a_addr(uchar code) { - uchar data, acc; + uchar data, ac; bool newC, newA, c6; - - data= read(get_direct(fetch(), &event_at.ri, &event_at.rs)); - acc = sfr->get(ACC); - newC= (((uint)acc+(uint)(data)) > 255)?0x80:0; - newA= ((acc&0x0f)+(data&0x0f)) & 0xf0; - c6 = ((acc&0x7f)+(data&0x7f)) & 0x80; - event_at.ws= ACC; - sfr->set(ACC, acc+data); - SET_C(newC); - SET_BIT(newC ^ c6, PSW, bmOV); - SET_BIT(newA, PSW, bmAC); + class cl_cell *cell; + t_addr a; + + cell= get_direct(a= fetch()); + data= cell->read(); + ac = acc->get(); + newC= (((uint)ac+(uint)(data)) > 255)?0x80:0; + newA= ((ac&0x0f)+(data&0x0f)) & 0xf0; + c6 = ((ac&0x7f)+(data&0x7f)) & 0x80; + acc->write(ac+data); + SFR_SET_C(newC); + SFR_SET_BIT(newC ^ c6, PSW, bmOV); + SFR_SET_BIT(newA, PSW, bmAC); return(resGO); } @@ -158,22 +159,21 @@ t_uc51::inst_add_a_addr(uchar code) int t_uc51::inst_add_a_$ri(uchar code) { - uchar data, *addr, acc; + uchar data, ac; bool newC, newA, c6; - int res; - - addr= get_indirect(event_at.ri= *(get_reg(code & 0x01)), &res); - acc = sfr->get(ACC); - data= *addr; - newC= (((uint)acc+(uint)data) > 255)?0x80:0; - newA= ((acc&0x0f)+(data&0x0f)) & 0xf0; - c6 = ((acc&0x7f)+(data&0x7f)) & 0x80; - event_at.ws= ACC; - sfr->set(ACC, acc+data); - SET_C(newC); - SET_BIT(newC ^ c6, PSW, bmOV); - SET_BIT(newA, PSW, bmAC); - return(res); + class cl_cell *cell; + + cell= iram->get_cell(get_reg(code & 0x01)->read()); + ac = acc->get(); + data= cell->read(); + newC= (((uint)ac+(uint)data) > 255)?0x80:0; + newA= ((ac&0x0f)+(data&0x0f)) & 0xf0; + c6 = ((ac&0x7f)+(data&0x7f)) & 0x80; + acc->write(ac+data); + SFR_SET_C(newC); + SFR_SET_BIT(newC ^ c6, PSW, bmOV); + SFR_SET_BIT(newA, PSW, bmAC); + return(resGO); } @@ -186,19 +186,18 @@ t_uc51::inst_add_a_$ri(uchar code) int t_uc51::inst_add_a_rn(uchar code) { - uchar data, acc; + uchar data, ac; bool newC, newA, c6; - data= *(get_reg(code & 0x07, &event_at.ri)); - acc = sfr->get(ACC); - newC= (((uint)acc+(uint)data) > 255)?0x80:0; - newA= ((acc&0x0f)+(data&0x0f)) & 0xf0; - c6 = ((acc&0x7f)+(data&0x7f)) & 0x80; - event_at.ws= ACC; - sfr->set(ACC, acc+data); - SET_C(newC); - SET_BIT(newC ^ c6, PSW, bmOV); - SET_BIT(newA, PSW, bmAC); + data= get_reg(code & 0x07)->read(); + ac = acc->get(); + newC= (((uint)ac+(uint)data) > 255)?0x80:0; + newA= ((ac&0x0f)+(data&0x0f)) & 0xf0; + c6 = ((ac&0x7f)+(data&0x7f)) & 0x80; + acc->write(ac+data); + SFR_SET_C(newC); + SFR_SET_BIT(newC ^ c6, PSW, bmOV); + SFR_SET_BIT(newA, PSW, bmAC); return(resGO); } @@ -213,14 +212,14 @@ int t_uc51::inst_rlc(uchar code) { bool cy; - uchar acc; + uchar ac; cy= SFR_GET_C; - SET_C((acc= sfr->get(event_at.rs= ACC)) & 0x80); - acc<<= 1; + SFR_SET_C((ac= acc->get()) & 0x80); + ac<<= 1; if (cy) - acc|= 0x01; - sfr->set(event_at.ws= ACC, acc); + ac|= 0x01; + acc->write(ac); return(resGO); } @@ -234,18 +233,18 @@ t_uc51::inst_rlc(uchar code) int t_uc51::inst_addc_a_$data(uchar code) { - uchar data, acc; + uchar data, ac; bool orgC, newC, newA, c6; data= fetch(); - acc = sfr->get(ACC); - newC= (((uint)acc+(uint)data+((orgC= SFR_GET_C)?1:0)) > 255)?0x80:0; - newA= ((acc&0x0f)+(data&0x0f)+(orgC?1:0)) & 0xf0; - c6 = ((acc&0x7f)+(data&0x7f)+(orgC?1:0)) & 0x80; - sfr->set(event_at.ws= ACC, acc + data + (orgC?1:0)); - SET_C(newC); - SET_BIT(newC ^ c6, PSW, bmOV); - SET_BIT(newA, PSW, bmAC); + ac = acc->get(); + newC= (((uint)ac+(uint)data+((orgC= SFR_GET_C)?1:0)) > 255)?0x80:0; + newA= ((ac&0x0f)+(data&0x0f)+(orgC?1:0)) & 0xf0; + c6 = ((ac&0x7f)+(data&0x7f)+(orgC?1:0)) & 0x80; + acc->write(ac + data + (orgC?1:0)); + SFR_SET_C(newC); + SFR_SET_BIT(newC ^ c6, PSW, bmOV); + SFR_SET_BIT(newA, PSW, bmAC); return(resGO); } @@ -259,18 +258,21 @@ t_uc51::inst_addc_a_$data(uchar code) int t_uc51::inst_addc_a_addr(uchar code) { - uchar data, acc; + uchar data, ac; bool orgC, newC, newA, c6; - - data= read(get_direct(fetch(), &event_at.ri, &event_at.rs)); - acc = sfr->get(ACC); - newC= (((uint)acc+(uint)data+((orgC= SFR_GET_C)?1:0)) > 255)?0x80:0; - newA= ((acc&0x0f)+(data&0x0f)+(orgC?1:0)) & 0xf0; - c6 = ((acc&0x7f)+(data&0x7f)+(orgC?1:0)) & 0x80; - sfr->set(event_at.ws= ACC, acc + data + (orgC?1:0)); - SET_C(newC); - SET_BIT(newC ^ c6, PSW, bmOV); - SET_BIT(newA, PSW, bmAC); + class cl_cell *cell; + t_addr a; + + cell= get_direct(a= fetch()); + data= cell->read(); + ac = acc->get(); + newC= (((uint)ac+(uint)data+((orgC= SFR_GET_C)?1:0)) > 255)?0x80:0; + newA= ((ac&0x0f)+(data&0x0f)+(orgC?1:0)) & 0xf0; + c6 = ((ac&0x7f)+(data&0x7f)+(orgC?1:0)) & 0x80; + acc->write(ac + data + (orgC?1:0)); + SFR_SET_C(newC); + SFR_SET_BIT(newC ^ c6, PSW, bmOV); + SFR_SET_BIT(newA, PSW, bmAC); return(resGO); } @@ -284,21 +286,21 @@ t_uc51::inst_addc_a_addr(uchar code) int t_uc51::inst_addc_a_$ri(uchar code) { - uchar data, *addr, acc; + uchar data, ac; bool orgC, newC, newA, c6; - int res; - - addr= get_indirect(event_at.ri= *(get_reg(code & 0x01)), &res); - acc = sfr->get(ACC); - data= *addr; - newC= (((uint)acc+(uint)data+((orgC= SFR_GET_C)?1:0)) > 255)?0x80:0; - newA= ((acc&0x0f)+(data&0x0f)+(orgC?1:0)) & 0xf0; - c6 = ((acc&0x7f)+(data&0x7f)+(orgC?1:0)) & 0x80; - sfr->set(event_at.ws= ACC, acc + data + (orgC?1:0)); - SET_C(newC); - SET_BIT(newC ^ c6, PSW, bmOV); - SET_BIT(newA, PSW, bmAC); - return(res); + class cl_cell *cell; + + cell= iram->get_cell(get_reg(code & 0x01)->read()); + ac = acc->get(); + data= cell->read(); + newC= (((uint)ac+(uint)data+((orgC= SFR_GET_C)?1:0)) > 255)?0x80:0; + newA= ((ac&0x0f)+(data&0x0f)+(orgC?1:0)) & 0xf0; + c6 = ((ac&0x7f)+(data&0x7f)+(orgC?1:0)) & 0x80; + acc->write(ac + data + (orgC?1:0)); + SFR_SET_C(newC); + SFR_SET_BIT(newC ^ c6, PSW, bmOV); + SFR_SET_BIT(newA, PSW, bmAC); + return(resGO); } @@ -311,18 +313,18 @@ t_uc51::inst_addc_a_$ri(uchar code) int t_uc51::inst_addc_a_rn(uchar code) { - uchar data, acc; + uchar data, ac; bool orgC, newC, newA, c6; - data= *(get_reg(code & 0x07, &event_at.ri)); - acc = sfr->get(ACC); - newC= (((uint)acc+(uint)data+((orgC= SFR_GET_C)?1:0)) > 255)?0x80:0; - newA= ((acc&0x0f)+(data&0x0f)+(orgC?1:0)) & 0xf0; - c6 = ((acc&0x7f)+(data&0x7f)+(orgC?1:0)) & 0x80; - sfr->set(event_at.ws= ACC, acc + data + (orgC?1:0)); - SET_C(newC); - SET_BIT(newC ^ c6, PSW, bmOV); - SET_BIT(newA, PSW, bmAC); + data= get_reg(code & 0x07)->read(); + ac = acc->get(); + newC= (((uint)ac+(uint)data+((orgC= SFR_GET_C)?1:0)) > 255)?0x80:0; + newA= ((ac&0x0f)+(data&0x0f)+(orgC?1:0)) & 0xf0; + c6 = ((ac&0x7f)+(data&0x7f)+(orgC?1:0)) & 0x80; + acc->write(ac + data + (orgC?1:0)); + SFR_SET_C(newC); + SFR_SET_BIT(newC ^ c6, PSW, bmOV); + SFR_SET_BIT(newA, PSW, bmAC); return(resGO); } @@ -336,20 +338,20 @@ t_uc51::inst_addc_a_rn(uchar code) int t_uc51::inst_div_ab(uchar code) { - uchar temp, psw, b, acc; + uchar temp, pw, b, ac; - psw= sfr->get(PSW); - psw&= ~bmCY; - if (!(b= sfr->get(event_at.rs= B))) - psw|= bmOV; + pw= psw->get(); + pw&= ~bmCY; + if (!(b= sfr->get(B))) + pw|= bmOV; else { - psw&= ~bmOV; - temp= (acc= sfr->get(ACC)) / b; - sfr->set(B, acc % b); - sfr->set(event_at.ws= ACC, temp); + pw&= ~bmOV; + temp= (ac= acc->get()) / b; + sfr->write(B, ac % b); + acc->write(temp); } - sfr->set(PSW, psw); + psw->write(pw); tick(3); return(resGO); } @@ -364,22 +366,21 @@ t_uc51::inst_div_ab(uchar code) int t_uc51::inst_subb_a_$data(uchar code) { - uchar data, acc, result, psw, c; + uchar data, ac, result, pw, c; data= fetch(); - acc = sfr->get(ACC); - result= acc-data; - psw= sfr->get(PSW); - if ((c= (psw & bmCY)?1:0)) + ac = acc->get(); + result= ac-data; + pw= psw->get(); + if ((c= (pw & bmCY)?1:0)) result--; - sfr->set(event_at.ws= ACC, result); - sfr->set(PSW, - (psw & ~(bmCY|bmOV|bmAC)) | - (((unsigned int)acc < (unsigned int)(data+c))?bmCY:0) | - (((acc<0x80 && data>0x7f && result>0x7f) || - (acc>0x7f && data<0x80 && result<0x80))?bmOV:0) | - (((acc&0x0f) < ((data+c)&0x0f) || - (c && ((data&0x0f)==0x0f)))?bmAC:0)); + acc->write(result); + psw->write((pw & ~(bmCY|bmOV|bmAC)) | + (((unsigned int)ac < (unsigned int)(data+c))?bmCY:0) | + (((ac<0x80 && data>0x7f && result>0x7f) || + (ac>0x7f && data<0x80 && result<0x80))?bmOV:0) | + (((ac&0x0f) < ((data+c)&0x0f) || + (c && ((data&0x0f)==0x0f)))?bmAC:0)); return(resGO); } @@ -393,22 +394,22 @@ t_uc51::inst_subb_a_$data(uchar code) int t_uc51::inst_subb_a_addr(uchar code) { - uchar *addr, data, acc, result, psw,c ; - - addr= get_direct(fetch(), &event_at.ri, &event_at.rs); - acc = sfr->get(ACC); - data= read(addr); - result= acc-data; - psw= sfr->get(PSW); - if ((c= (psw & bmCY)?1:0)) + uchar data, ac, result, pw, c; + class cl_cell *cell; + + cell= get_direct(fetch()); + ac = acc->get(); + data= cell->read(); + result= ac-data; + pw= psw->get(); + if ((c= (pw & bmCY)?1:0)) result--; - sfr->set(event_at.ws= ACC, result); - sfr->set(PSW, - (psw & ~(bmCY|bmOV|bmAC)) | - (((unsigned int)acc < (unsigned int)(data+c))?bmCY:0) | - (((acc<0x80 && data>0x7f && result>0x7f) || - (acc>0x7f && data<0x80 && result<0x80))?bmOV:0) | - (((acc&0x0f) < ((data+c)&0x0f) || + acc->write(result); + psw->set((pw & ~(bmCY|bmOV|bmAC)) | + (((unsigned int)ac < (unsigned int)(data+c))?bmCY:0) | + (((ac<0x80 && data>0x7f && result>0x7f) || + (ac>0x7f && data<0x80 && result<0x80))?bmOV:0) | + (((ac&0x0f) < ((data+c)&0x0f) || (c && ((data&0x0f)==0x0f)))?bmAC:0)); return(resGO); } @@ -423,24 +424,24 @@ t_uc51::inst_subb_a_addr(uchar code) int t_uc51::inst_subb_a_$ri(uchar code) { - uchar data, acc, result, psw, c; - int res; - - data= *(get_indirect(event_at.ri= *(get_reg(code & 0x01)), &res)); - acc = sfr->get(ACC); - result= acc-data; - psw= sfr->get(PSW); - if ((c= (psw & bmCY)?1:0)) + uchar data, ac, result, pw, c; + class cl_cell *cell; + + cell= iram->get_cell(get_reg(code & 0x01)->read()); + data= cell->read(); + ac = acc->get(); + result= ac-data; + pw= psw->get(); + if ((c= (pw & bmCY)?1:0)) result--; - sfr->set(event_at.ws= ACC, result); - sfr->set(PSW, - (psw & ~(bmCY|bmOV|bmAC)) | - (((unsigned int)acc < (unsigned int)(data+c))?bmCY:0) | - (((acc<0x80 && data>0x7f && result>0x7f) || - (acc>0x7f && data<0x80 && result<0x80))?bmOV:0) | - (((acc&0x0f) < ((data+c)&0x0f) || - (c && ((data&0x0f)==0x0f)))?bmAC:0)); - return(res); + acc->write(result); + psw->write((pw & ~(bmCY|bmOV|bmAC)) | + (((unsigned int)ac < (unsigned int)(data+c))?bmCY:0) | + (((ac<0x80 && data>0x7f && result>0x7f) || + (ac>0x7f && data<0x80 && result<0x80))?bmOV:0) | + (((ac&0x0f) < ((data+c)&0x0f) || + (c && ((data&0x0f)==0x0f)))?bmAC:0)); + return(resGO); } @@ -453,22 +454,21 @@ t_uc51::inst_subb_a_$ri(uchar code) int t_uc51::inst_subb_a_rn(uchar code) { - uchar data, acc, result, psw, c; + uchar data, ac, result, pw, c; - data= *(get_reg(code & 0x07, &event_at.ri)); - acc = sfr->get(ACC); - result= acc-data; - psw= sfr->get(PSW); - if ((c= (psw & bmCY)?1:0)) + data= get_reg(code & 0x07)->read(); + ac = acc->get(); + result= ac-data; + pw= psw->get(); + if ((c= (pw & bmCY)?1:0)) result--; - sfr->set(event_at.ws= ACC, result); - sfr->set(PSW, - (psw & ~(bmCY|bmOV|bmAC)) | - (((unsigned int)acc < (unsigned int)(data+c))?bmCY:0) | - (((acc<0x80 && data>0x7f && result>0x7f) || - (acc>0x7f && data<0x80 && result<0x80))?bmOV:0) | - (((acc&0x0f) < ((data+c)&0x0f) || - (c && ((data&0x0f)==0x0f)))?bmAC:0)); + acc->write(result); + psw->write((pw & ~(bmCY|bmOV|bmAC)) | + (((unsigned int)ac < (unsigned int)(data+c))?bmCY:0) | + (((ac<0x80 && data>0x7f && result>0x7f) || + (ac>0x7f && data<0x80 && result<0x80))?bmOV:0) | + (((ac&0x0f) < ((data+c)&0x0f) || + (c && ((data&0x0f)==0x0f)))?bmAC:0)); return(resGO); } @@ -482,15 +482,15 @@ t_uc51::inst_subb_a_rn(uchar code) int t_uc51::inst_mul_ab(uchar code) { - uint temp, psw, acc, b; - - psw= sfr->get(PSW); - psw&= ~bmCY; - temp= (acc= sfr->get(ACC)) * (b= sfr->get(B)); - sfr->set(event_at.ws= ACC, temp & 0xff); - sfr->set(event_at.rs= B, (temp >> 8) & 0xff); - SET_BIT(sfr->get(B), PSW, bmOV); - SET_BIT(0, PSW, bmCY); + uint temp, pw, ac, b, x; + + pw= psw->get(); + pw&= ~bmCY; + temp= (ac= acc->read()) * (b= sfr->get(B)); + acc->write(temp & 0xff); + x= sfr->write(B, (temp >> 8) & 0xff); + SFR_SET_BIT(x/*sfr->get(B)*/, PSW, bmOV); + SFR_SET_BIT(0, PSW, bmCY); tick(3); return(resGO); } @@ -505,27 +505,26 @@ t_uc51::inst_mul_ab(uchar code) int t_uc51::inst_da_a(uchar code) { - uchar acc, psw; + uchar ac, pw; - acc= sfr->get(ACC); - psw= sfr->get(PSW); - event_at.ws= ACC; - if ((acc & 0x0f) > 9 || - (psw & bmAC)) + ac= acc->get(); + pw= psw->get(); + if ((ac & 0x0f) > 9 || + (pw & bmAC)) { - if (((uint)acc+(uint)0x06) > 255) - psw|= bmCY; - acc+= 0x06; + if (((uint)ac+(uint)0x06) > 255) + pw|= bmCY; + ac+= 0x06; } - if ((acc & 0xf0) > 0x90 || - (psw & bmCY)) + if ((ac & 0xf0) > 0x90 || + (pw & bmCY)) { - if (((uint)acc+(uint)0x60) > 255) - psw|= bmCY; - acc+= 0x60; + if (((uint)ac+(uint)0x60) > 255) + pw|= bmCY; + ac+= 0x60; } - sfr->set(ACC, acc); - sfr->set(PSW, psw); + acc->write(ac); + psw->write(pw); return(resGO); } diff --git a/sim/ucsim/s51.src/bit.cc b/sim/ucsim/s51.src/bit.cc index 4d7e44cb..64b5222f 100644 --- a/sim/ucsim/s51.src/bit.cc +++ b/sim/ucsim/s51.src/bit.cc @@ -30,6 +30,7 @@ Software Foundation, 59 Temple Place - Suite 330, Boston, MA // local #include "uc51cl.h" #include "regs51.h" +#include "types51.h" /* @@ -41,12 +42,14 @@ Software Foundation, 59 Temple Place - Suite 330, Boston, MA int t_uc51::inst_orl_c_bit(uchar code) { - uchar *addr, bitaddr; - - addr= get_bit(bitaddr= fetch(), &event_at.ri, &event_at.rs); - SET_C(GET_C || - (read(addr) & BIT_MASK(bitaddr))); - event_at.ws= PSW; + uchar bitaddr; + + t_addr a; + t_mem m; + class cl_mem *mem; + mem= bit2mem(bitaddr= fetch(), &a, &m); + SFR_SET_C(SFR_GET_C || + (mem->read(a) & m)); tick(1); return(resGO); } @@ -61,12 +64,13 @@ t_uc51::inst_orl_c_bit(uchar code) int t_uc51::inst_anl_c_bit(uchar code) { - uchar *addr, bitaddr; + t_mem m; + t_addr a; + class cl_mem *mem; - addr= get_bit(bitaddr= fetch(), &event_at.ri, &event_at.rs); - SET_C(GET_C && - (read(addr) & BIT_MASK(bitaddr))); - event_at.ws= PSW; + mem= bit2mem(fetch(), &a, &m); + SFR_SET_C(SFR_GET_C && + (mem->read(a) & m)); tick(1); return(resGO); } @@ -81,15 +85,16 @@ t_uc51::inst_anl_c_bit(uchar code) int t_uc51::inst_mov_bit_c(uchar code) { - uchar *addr, bitaddr; - - addr= get_bit(bitaddr= fetch(), &event_at.wi, &event_at.ws); - if (GET_C) - (*addr)|= BIT_MASK(bitaddr); + t_addr a; + t_mem m, d; + class cl_mem *mem; + + mem= bit2mem(fetch(), &a, &m); + d= mem->read(a, HW_PORT); + if (SFR_GET_C) + mem->write(a, d|m); else - (*addr)&= ~BIT_MASK(bitaddr); - event_at.rs= PSW; - proc_write(addr); + mem->write(a, d&~m); tick(1); return(resGO); } @@ -104,11 +109,12 @@ t_uc51::inst_mov_bit_c(uchar code) int t_uc51::inst_mov_c_bit(uchar code) { - uchar *addr, bitaddr; + t_addr a; + t_mem m; + class cl_mem *mem; - addr= get_bit(bitaddr= fetch(), &event_at.ri, &event_at.rs); - SET_C(read(addr) & BIT_MASK(bitaddr)); - event_at.ws= PSW; + mem= bit2mem(fetch(), &a, &m); + SFR_SET_C(mem->read(a) & m); return(resGO); } @@ -122,12 +128,13 @@ t_uc51::inst_mov_c_bit(uchar code) int t_uc51::inst_anl_c_$bit(uchar code) { - uchar *addr, bitaddr; + t_mem m; + t_addr a; + class cl_mem *mem; - addr= get_bit(bitaddr= fetch(), &event_at.ri, &event_at.rs); - SET_C(GET_C && - !(read(addr) & BIT_MASK(bitaddr))); - event_at.ws= PSW; + mem= bit2mem(fetch(), &a, &m); + SFR_SET_C(SFR_GET_C && + !(mem->read(a) & m)); tick(1); return(resGO); } @@ -142,11 +149,13 @@ t_uc51::inst_anl_c_$bit(uchar code) int t_uc51::inst_cpl_bit(uchar code) { - uchar *addr, bitaddr; + t_addr a; + t_mem m, d; + class cl_mem *mem; - addr= get_bit(bitaddr= fetch(), &event_at.wi, &event_at.ws); - (*addr)^= BIT_MASK(bitaddr); - proc_write(addr); + mem= bit2mem(fetch(), &a, &m); + d= mem->read(a, HW_PORT); + mem->write(a, d^m); return(resGO); } @@ -160,8 +169,7 @@ t_uc51::inst_cpl_bit(uchar code) int t_uc51::inst_cpl_c(uchar code) { - sfr->set(PSW, sfr->get(PSW) ^ bmCY); - event_at.ws= PSW; + psw->write(psw->read() ^ bmCY); return(resGO); } @@ -175,11 +183,13 @@ t_uc51::inst_cpl_c(uchar code) int t_uc51::inst_clr_bit(uchar code) { - uchar *addr, bitaddr; + t_addr a; + t_mem m; + class cl_mem *mem; - addr= get_bit(bitaddr= fetch(), &event_at.wi, &event_at.ws); - (*addr)&= ~BIT_MASK(bitaddr); - proc_write(addr); + mem= bit2mem(fetch(), &a, &m); + t_mem d= mem->read(a, HW_PORT); + mem->write(a, d&~m); return(resGO); } @@ -193,8 +203,7 @@ t_uc51::inst_clr_bit(uchar code) int t_uc51::inst_clr_c(uchar code) { - sfr->set(PSW, sfr->get(PSW) & ~bmCY); - event_at.ws= PSW; + psw->write(psw->read() & ~bmCY); return(resGO); } @@ -208,11 +217,13 @@ t_uc51::inst_clr_c(uchar code) int t_uc51::inst_setb_bit(uchar code) { - uchar *addr, bitaddr; + t_addr a; + t_mem m, d; + class cl_mem *mem; - addr= get_bit(bitaddr= fetch(), &event_at.wi, &event_at.ws); - (*addr)|= BIT_MASK(bitaddr); - proc_write(addr); + mem= bit2mem(fetch(), &a, &m); + d= mem->read(a, HW_PORT); + mem->write(a, d|m); return(resGO); } @@ -226,8 +237,7 @@ t_uc51::inst_setb_bit(uchar code) int t_uc51::inst_setb_c(uchar code) { - sfr->set(PSW, sfr->get(PSW) | bmCY); - event_at.ws= PSW; + psw->write(psw->read() | bmCY); return(resGO); } diff --git a/sim/ucsim/s51.src/clean.mk b/sim/ucsim/s51.src/clean.mk index a4a2d391..b12c6104 100644 --- a/sim/ucsim/s51.src/clean.mk +++ b/sim/ucsim/s51.src/clean.mk @@ -4,7 +4,7 @@ # -------------------------------------------------- clean: rm -f *core *[%~] *.[oa] - rm -f test_*.??* '(null).cdb' + rm -f test_*.??* '(null).cdb' *.lnk *.ihx rm -f .[a-z]*~ rm -f s51 diff --git a/sim/ucsim/s51.src/glob.cc b/sim/ucsim/s51.src/glob.cc index 381f3a07..65e9c0ce 100644 --- a/sim/ucsim/s51.src/glob.cc +++ b/sim/ucsim/s51.src/glob.cc @@ -634,8 +634,9 @@ struct cpu_entry cpus_51[]= {"251" , CPU_251, CPU_CMOS}, {"C251" , CPU_251, CPU_CMOS}, + {"DS390" , CPU_DS390, CPU_CMOS}, - {"DS390F" , CPU_DS390F, CPU_CMOS}, + {"DS390F", CPU_DS390F, CPU_CMOS}, {NULL, 0, 0} }; diff --git a/sim/ucsim/s51.src/inc.cc b/sim/ucsim/s51.src/inc.cc index f3d67750..83e48ce9 100644 --- a/sim/ucsim/s51.src/inc.cc +++ b/sim/ucsim/s51.src/inc.cc @@ -41,7 +41,7 @@ Software Foundation, 59 Temple Place - Suite 330, Boston, MA int t_uc51::inst_inc_a(uchar code) { - sfr->set(event_at.ws= ACC, sfr->get(ACC)+1); + acc->wadd(1); return(resGO); } @@ -55,11 +55,10 @@ t_uc51::inst_inc_a(uchar code) int t_uc51::inst_inc_addr(uchar code) { - uchar *addr; + class cl_cell *cell= get_direct(fetch()); - addr= get_direct(fetch(), &event_at.wi, &event_at.ws); - (*addr)++; - proc_write(addr); + t_mem d= cell->read(HW_PORT); + cell->write(d+1); return(resGO); } @@ -73,13 +72,11 @@ t_uc51::inst_inc_addr(uchar code) int t_uc51::inst_inc_$ri(uchar code) { - uchar *addr; - int res; + class cl_cell *cell; - addr= get_indirect(event_at.wi= *(get_reg(code & 0x01)), &res); - (*addr)++; - proc_write(addr); - return(res); + cell= iram->get_cell(get_reg(code & 0x01)->read()); + cell->wadd(1); + return(resGO); } @@ -92,7 +89,9 @@ t_uc51::inst_inc_$ri(uchar code) int t_uc51::inst_inc_rn(uchar code) { - (*(get_reg(code & 0x07, &event_at.wi)))++; + class cl_cell *reg= get_reg(code & 0x07); + + reg->wadd(1); return(resGO); } @@ -106,7 +105,8 @@ t_uc51::inst_inc_rn(uchar code) int t_uc51::inst_dec_a(uchar code) { - sfr->set(event_at.ws= ACC, sfr->get(ACC)-1); + acc->wadd(-1); + return(resGO); } @@ -120,11 +120,11 @@ t_uc51::inst_dec_a(uchar code) int t_uc51::inst_dec_addr(uchar code) { - uchar *addr; + class cl_cell *cell; - addr= get_direct(fetch(), &event_at.wi, &event_at.ws); - (*addr)--; - proc_write(addr); + cell= get_direct(fetch()); + t_mem d= cell->read(HW_PORT); + cell->write(d-1); return(resGO); } @@ -138,13 +138,11 @@ t_uc51::inst_dec_addr(uchar code) int t_uc51::inst_dec_$ri(uchar code) { - uchar *addr; - int res; + class cl_cell *cell; - addr= get_indirect(event_at.wi= *(get_reg(code & 0x01)), &res); - (*addr)--; - proc_write(addr); - return(res); + cell= iram->get_cell(get_reg(code & 0x01)->read()); + cell->add(-1); + return(resGO); } @@ -157,7 +155,9 @@ t_uc51::inst_dec_$ri(uchar code) int t_uc51::inst_dec_rn(uchar code) { - (*(get_reg(code & 0x07, &event_at.wi)))--; + class cl_cell *reg= get_reg(code & 0x07); + + reg->wadd(-1); return(resGO); } @@ -173,9 +173,9 @@ t_uc51::inst_inc_dptr(uchar code) { uint dptr; - dptr= sfr->get(DPH)*256 + sfr->get(DPL) + 1; - sfr->set(event_at.ws= DPH, (dptr >> 8) & 0xff); - sfr->set(DPL, dptr & 0xff); + dptr= sfr->read(DPH)*256 + sfr->read(DPL) + 1; + sfr->write(DPH, (dptr >> 8) & 0xff); + sfr->write(DPL, dptr & 0xff); tick(1); return(resGO); } diff --git a/sim/ucsim/s51.src/interrupt.cc b/sim/ucsim/s51.src/interrupt.cc index 6cded082..5f9c8631 100644 --- a/sim/ucsim/s51.src/interrupt.cc +++ b/sim/ucsim/s51.src/interrupt.cc @@ -31,18 +31,101 @@ Software Foundation, 59 Temple Place - Suite 330, Boston, MA // local #include "interruptcl.h" #include "regs51.h" +//#include "uc51cl.h" +#include "types51.h" cl_interrupt::cl_interrupt(class cl_uc *auc): cl_hw(auc, HW_INTERRUPT, 0, "irq") -{} +{ + was_reti= DD_FALSE; +} -/*int +int cl_interrupt::init(void) { + class cl_mem *sfr; + + sfr= uc->mem(MEM_SFR); + if (sfr) + { + //sfr->register_hw(IE, this, 0); + register_cell(sfr, IE, 0, wtd_restore); + register_cell(sfr, TCON, &cell_tcon, wtd_restore_write); + bit_INT0= sfr->read(P3) & bm_INT0; + bit_INT1= sfr->read(P3) & bm_INT1; + } return(0); +} + +void +cl_interrupt::added_to_uc(void) +{ + uc->it_sources->add(new cl_it_src(bmEX0, TCON, bmIE0, 0x0003, true, + "external #0", 1)); + uc->it_sources->add(new cl_it_src(bmEX1, TCON, bmIE1, 0x0013, true, + "external #1", 3)); +} + +void +cl_interrupt::write(class cl_cell *cell, t_mem *val) +{ + if (cell == cell_tcon) + { + bit_IT0= *val & bmIT0; + bit_IT1= *val & bmIT1; + } + else + // IE register + was_reti= DD_TRUE; +} + +/*void +cl_interrupt::mem_cell_changed(class cl_mem *mem, t_addr addr) +{ }*/ +int +cl_interrupt::tick(int cycles) +{ + if (!bit_IT0 && !bit_INT0) + cell_tcon->set_bit1(bmIE0); + if (!bit_IT1 && !bit_INT1) + cell_tcon->set_bit1(bmIE1); + return(resGO); +} + +void +cl_interrupt::reset(void) +{ + was_reti= DD_FALSE; +} + +void +cl_interrupt::happen(class cl_hw *where, enum hw_event he, void *params) +{ + struct ev_port_changed *ep= (struct ev_port_changed *)params; + + if (where->cathegory == HW_PORT && + he == EV_PORT_CHANGED && + ep->id == 3) + { + t_mem p3n= ep->new_pins & ep->new_value; + t_mem p3o= ep->pins & ep->prev_value; + if (bit_IT0 && + !(p3n & bm_INT0) && + (p3o & bm_INT0)) + cell_tcon->set_bit1(bmIE0); + if (bit_IT1 && + !(p3n & bm_INT1) && + (p3o & bm_INT1)) + cell_tcon->set_bit1(bmIE1); + bit_INT0= p3n & bm_INT0; + bit_INT1= p3n & bm_INT1; + } +} + + void cl_interrupt::print_info(class cl_console *con) { diff --git a/sim/ucsim/s51.src/interruptcl.h b/sim/ucsim/s51.src/interruptcl.h index 04001797..b2076758 100644 --- a/sim/ucsim/s51.src/interruptcl.h +++ b/sim/ucsim/s51.src/interruptcl.h @@ -37,14 +37,24 @@ Software Foundation, 59 Temple Place - Suite 330, Boston, MA class cl_interrupt: public cl_hw { +public: + bool was_reti, bit_IT0, bit_IT1, bit_INT0, bit_INT1; + class cl_cell *cell_tcon; public: cl_interrupt(class cl_uc *auc); - //virtual int init(void); + virtual int init(void); + + virtual void added_to_uc(void); + + //virtual t_mem read(class cl_cell *cell); + virtual void write(class cl_cell *cell, t_mem *val); + + //virtual void mem_cell_changed(class cl_mem *mem, t_addr addr); - //virtual ulong read(class cl_mem *mem, long addr); - //virtual void write(class cl_mem *mem, long addr, ulong *val); + virtual int tick(int cycles); + virtual void reset(void); + virtual void happen(class cl_hw *where, enum hw_event he, void *params); - //virtual int tick(int cycles); virtual void print_info(class cl_console *con); }; diff --git a/sim/ucsim/s51.src/jmp.cc b/sim/ucsim/s51.src/jmp.cc index 89aa6d12..74d6a960 100644 --- a/sim/ucsim/s51.src/jmp.cc +++ b/sim/ucsim/s51.src/jmp.cc @@ -37,6 +37,8 @@ Software Foundation, 59 Temple Place - Suite 330, Boston, MA // local #include "uc51cl.h" #include "regs51.h" +#include "types51.h" +#include "interruptcl.h" /* @@ -67,16 +69,19 @@ t_uc51::inst_ajmp_addr(uchar code) int t_uc51::inst_jbc_bit_addr(uchar code) { - uchar bitaddr, *addr, jaddr; + uchar bitaddr, jaddr; bitaddr= fetch(); jaddr = fetch(); - addr = get_bit(bitaddr, &event_at.ri, &event_at.rs); - if (*addr & BIT_MASK(bitaddr)) - { - (*addr)&= ~BIT_MASK(bitaddr); - PC= (PC + (signed char)jaddr) & (EROM_SIZE - 1); - } + t_addr a; + t_mem m; + class cl_mem *mem; + if ((mem= bit2mem(bitaddr, &a, &m)) == 0) + return(resBITADDR); + t_mem d= mem->read(a, HW_PORT); + mem->write(a, d & ~m); + if (d & m) + PC= (PC + (signed char)jaddr) & (EROM_SIZE - 1); tick(1); return(resGO); } @@ -106,30 +111,24 @@ t_uc51::inst_ljmp(uchar code) int t_uc51::inst_acall_addr(uchar code) { - uchar h, l, *sp, *aof_SP; - int res; + uchar h, l; + class cl_cell *stck; + t_mem sp; h= (code >> 5) & 0x07; l= fetch(); - aof_SP= &((sfr->umem8)[SP]); - //MEM(MEM_SFR)[SP]++; - (*aof_SP)++; - proc_write_sp(*aof_SP); - sp= get_indirect(*aof_SP/*sfr->get(SP)*/, &res); - if (res != resGO) - res= resSTACK_OV; - (*sp)= PC & 0xff; // push low byte + sp= sfr->wadd(SP, 1); + //proc_write_sp(sp); + stck= iram->get_cell(sp); + stck->write(PC & 0xff); // push low byte tick(1); - //MEM(MEM_SFR)[SP]++; - (*aof_SP)++; - proc_write_sp(*aof_SP); - sp= get_indirect(*aof_SP/*sfr->get(SP)*/, &res); - if (res != resGO) - res= resSTACK_OV; - (*sp)= (PC >> 8) & 0xff; // push high byte + sp= sfr->wadd(SP, 1); + //proc_write_sp(sp); + stck= iram->get_cell(sp); + stck->write((PC >> 8) & 0xff); // push high byte PC= (PC & 0xf800) | (h*256 + l); - return(res); + return(resGO); } @@ -142,37 +141,31 @@ t_uc51::inst_acall_addr(uchar code) int t_uc51::inst_lcall(uchar code, uint addr) { - uchar h= 0, l= 0, *sp, *aof_SP; - int res; + uchar h= 0, l= 0; + t_mem sp; + class cl_cell *stck; if (!addr) { h= fetch(); l= fetch(); } - aof_SP= &((sfr->umem8)[SP]); - //MEM(MEM_SFR)[SP]++; - (*aof_SP)++; - proc_write_sp(*aof_SP); - sp= get_indirect(*aof_SP/*sfr->get(SP)*/, &res); - if (res != resGO) - res= resSTACK_OV; - (*sp)= PC & 0xff; // push low byte + sp= sfr->wadd(SP, 1); + //proc_write_sp(sp); + stck= iram->get_cell(sp); + stck->write(PC & 0xff); // push low byte if (!addr) tick(1); - //MEM(MEM_SFR)[SP]++; - (*aof_SP)++; - proc_write_sp(*aof_SP); - sp= get_indirect(*aof_SP/*sfr->get(SP)*/, &res); - if (res != resGO) - res= resSTACK_OV; - (*sp)= (PC >> 8) & 0xff; // push high byte + sp= sfr->wadd(SP, 1); + //proc_write_sp(sp); + stck= iram->get_cell(sp); + stck->write((PC >> 8) & 0xff); // push high byte if (addr) PC= addr; else PC= h*256 + l; - return(res); + return(resGO); } @@ -185,12 +178,16 @@ t_uc51::inst_lcall(uchar code, uint addr) int t_uc51::inst_jb_bit_addr(uchar code) { - uchar *addr, bitaddr, jaddr; + uchar bitaddr, jaddr; + t_addr a; + t_mem m; - addr= get_bit(bitaddr= fetch(), &event_at.ri, &event_at.rs); + class cl_mem *mem; + if ((mem= bit2mem(bitaddr= fetch(), &a, &m)) == 0) + return(resBITADDR); tick(1); jaddr= fetch(); - if (read(addr) & BIT_MASK(bitaddr)) + if (mem->read(a) & m) PC= (PC + (signed char)jaddr) & (EROM_SIZE-1); return(resGO); } @@ -205,28 +202,21 @@ t_uc51::inst_jb_bit_addr(uchar code) int t_uc51::inst_ret(uchar code) { - uchar h, l, *sp, *aof_SP; - int res; - - aof_SP= &((sfr->umem8)[SP]); - sp= get_indirect(*aof_SP/*sfr->get(SP)*/, &res); - if (res != resGO) - res= resSTACK_OV; - h= *sp; - //MEM(MEM_SFR)[SP]--; - (*aof_SP)--; - proc_write_sp(*aof_SP); + uchar h= 0, l= 0; + t_mem sp; + class cl_cell *stck; + + sp= sfr->read(SP); + stck= iram->get_cell(sp); + h= stck->read(); + sp= sfr->wadd(SP, -1); tick(1); - sp= get_indirect(*aof_SP/*sfr->get(SP)*/, &res); - if (res != resGO) - res= resSTACK_OV; - l= *sp; - //MEM(MEM_SFR)[SP]--; - (*aof_SP)--; - proc_write_sp(*aof_SP); + stck= iram->get_cell(sp); + l= stck->read(); + sp= sfr->wadd(SP, -1); PC= h*256 + l; - return(res); + return(resGO); } @@ -239,12 +229,16 @@ t_uc51::inst_ret(uchar code) int t_uc51::inst_jnb_bit_addr(uchar code) { - uchar *addr, bitaddr, jaddr; + uchar bitaddr, jaddr; + t_mem m; + t_addr a; + class cl_mem *mem; - addr= get_bit(bitaddr= fetch(), &event_at.ri, &event_at.rs); + if ((mem= bit2mem(bitaddr= fetch(), &a, &m)) == 0) + return(resBITADDR); tick(1); jaddr= fetch(); - if (!(read(addr) & BIT_MASK(bitaddr))) + if (!(mem->read(a) & m)) PC= (PC + (signed char)jaddr) & (get_mem_size(MEM_ROM)-1); return(resGO); } @@ -259,29 +253,22 @@ t_uc51::inst_jnb_bit_addr(uchar code) int t_uc51::inst_reti(uchar code) { - uchar h, l, *sp, *aof_SP; - int res; - - aof_SP= &((sfr->umem8)[SP]); - sp= get_indirect(*aof_SP/*sfr->get(SP)*/, &res); - if (res != resGO) - res= resSTACK_OV; - h= *sp; - //MEM(MEM_SFR)[SP]--; - (*aof_SP)--; - proc_write_sp(*aof_SP); + uchar h= 0, l= 0; + t_mem sp; + class cl_cell *stck; + + sp= sfr->read(SP); + stck= iram->get_cell(sp); + h= stck->read(); + sp= sfr->wadd(SP, -1); tick(1); - sp= get_indirect(*aof_SP/*sfr->get(SP)*/, &res); - if (res != resGO) - res= resSTACK_OV; - l= *sp; - //MEM(MEM_SFR)[SP]--; - (*aof_SP)--; - proc_write_sp(*aof_SP); + stck= iram->get_cell(sp); + l= stck->read(); + sp= sfr->wadd(SP, -1); PC= h*256 + l; - was_reti= DD_TRUE; + interrupt->was_reti= DD_TRUE; class it_level *il= (class it_level *)(it_levels->top()); if (il && il->level >= 0) @@ -289,7 +276,7 @@ t_uc51::inst_reti(uchar code) il= (class it_level *)(it_levels->pop()); delete il; } - return(res); + return(resGO); } @@ -306,9 +293,8 @@ t_uc51::inst_jc_addr(uchar code) jaddr= fetch(); tick(1); - if (GET_C) + if (SFR_GET_C) PC= (PC + (signed char)jaddr) & (EROM_SIZE-1); - event_at.rs= PSW; return(resGO); } @@ -326,9 +312,8 @@ t_uc51::inst_jnc_addr(uchar code) jaddr= fetch(); tick(1); - if (!GET_C) + if (!SFR_GET_C) PC= (PC + (signed char)jaddr) & (EROM_SIZE-1); - event_at.rs= ACC; return(resGO); } @@ -346,7 +331,7 @@ t_uc51::inst_jz_addr(uchar code) jaddr= fetch(); tick(1); - if (!sfr->get(ACC)) + if (!acc->read()) PC= (PC + (signed char)jaddr) & (EROM_SIZE-1); return(resGO); } @@ -365,7 +350,7 @@ t_uc51::inst_jnz_addr(uchar code) jaddr= fetch(); tick(1); - if (sfr->get(ACC)) + if (acc->read()) PC= (PC + (signed char)jaddr) & (EROM_SIZE-1); return(resGO); } @@ -380,8 +365,7 @@ t_uc51::inst_jnz_addr(uchar code) int t_uc51::inst_jmp_$a_dptr(uchar code) { - PC= (sfr->get(DPH)*256 + sfr->get(DPL) + - read_mem(MEM_SFR, ACC)) & + PC= (sfr->read(DPH)*256 + sfr->read(DPL) + acc->read()) & (EROM_SIZE - 1); tick(1); return(resGO); @@ -398,6 +382,7 @@ int t_uc51::inst_sjmp(uchar code) { signed char target= fetch(); + PC= (PC + target) & (EROM_SIZE -1); tick(1); return(resGO); @@ -413,13 +398,13 @@ t_uc51::inst_sjmp(uchar code) int t_uc51::inst_cjne_a_$data_addr(uchar code) { - uchar data, jaddr; + uchar data, jaddr, ac; data = fetch(); jaddr= fetch(); tick(1); - SET_C(sfr->get(ACC) < data); - if (read_mem(MEM_SFR, event_at.rs= ACC) != data) + SFR_SET_C((ac= acc->read()) < data); + if (ac != data) PC= (PC + (signed char)jaddr) & (EROM_SIZE - 1); return(resGO); } @@ -434,14 +419,16 @@ t_uc51::inst_cjne_a_$data_addr(uchar code) int t_uc51::inst_cjne_a_addr_addr(uchar code) { - uchar data, *addr, jaddr; + uchar data, jaddr; + t_addr a; + class cl_cell *cell; - addr = get_direct(fetch(), &event_at.ri, &event_at.rs); + cell= get_direct(a= fetch()); jaddr= fetch(); tick(1); - data= read(addr); - SET_C(sfr->get(ACC) < data); - if (sfr->get(event_at.rs= ACC) != data) + data= cell->read(); + SFR_SET_C(acc->get() < data); + if (acc->read() != data) PC= (PC + (signed char)jaddr) & (EROM_SIZE - 1); return(resGO); } @@ -456,17 +443,18 @@ t_uc51::inst_cjne_a_addr_addr(uchar code) int t_uc51::inst_cjne_$ri_$data_addr(uchar code) { - uchar *addr, data, jaddr; - int res; + uchar data, jaddr; + class cl_cell *cell; - addr = get_indirect(event_at.ri= *(get_reg(code & 0x01)), &res); + cell= iram->get_cell(get_reg(code & 0x01)->read()); data = fetch(); jaddr= fetch(); tick(1); - SET_C(*addr < data); - if (*addr != data) + t_mem d; + SFR_SET_C((d= cell->read()) < data); + if (d != data) PC= (PC + (signed char)jaddr) & (EROM_SIZE - 1); - return(res); + return(resGO); } @@ -479,14 +467,16 @@ t_uc51::inst_cjne_$ri_$data_addr(uchar code) int t_uc51::inst_cjne_rn_$data_addr(uchar code) { - uchar *reg, data, jaddr; + uchar data, jaddr; + class cl_cell *reg; - reg = get_reg(code & 0x07, &event_at.ri); + reg = get_reg(code & 0x07); data = fetch(); jaddr= fetch(); tick(1); - SET_C(*reg < data); - if (*reg != data) + t_mem r; + SFR_SET_C((r= reg->read()) < data); + if (r != data) PC= (PC + (signed char)jaddr) & (EROM_SIZE - 1); return(resGO); } @@ -501,12 +491,15 @@ t_uc51::inst_cjne_rn_$data_addr(uchar code) int t_uc51::inst_djnz_addr_addr(uchar code) { - uchar *addr, jaddr; - - addr = get_direct(fetch(), &event_at.wi, &event_at.ws); + uchar jaddr; + class cl_cell *cell; + + cell = get_direct(fetch()); jaddr= fetch(); tick(1); - if (--(*addr)) + t_mem d= cell->read(HW_PORT);//cell->wadd(-1); + d= cell->write(d-1); + if (d) PC= (PC + (signed char)jaddr) & (EROM_SIZE-1); return(resGO); } @@ -521,12 +514,14 @@ t_uc51::inst_djnz_addr_addr(uchar code) int t_uc51::inst_djnz_rn_addr(uchar code) { - uchar *reg, jaddr; - - reg = get_reg(code & 0x07, &event_at.wi); + uchar jaddr; + class cl_cell *reg; + + reg = get_reg(code & 0x07); jaddr= fetch(); tick(1); - if (--(*reg)) + t_mem r= reg->wadd(-1); + if (r) PC= (PC + (signed char)jaddr) & (EROM_SIZE-1); return(resGO); } diff --git a/sim/ucsim/s51.src/logic.cc b/sim/ucsim/s51.src/logic.cc index 32e936b9..b908912c 100644 --- a/sim/ucsim/s51.src/logic.cc +++ b/sim/ucsim/s51.src/logic.cc @@ -44,11 +44,10 @@ Software Foundation, 59 Temple Place - Suite 330, Boston, MA int t_uc51::inst_orl_addr_a(uchar code) { - uchar *addr; + class cl_cell *cell; - addr= get_direct(fetch(), &event_at.wi, &event_at.ws); - (*addr)|= sfr->get(event_at.rs= ACC); - proc_write(addr); + cell= get_direct(fetch()); + cell->write(cell->read(HW_PORT) | acc->read()); return(resGO); } @@ -62,13 +61,14 @@ t_uc51::inst_orl_addr_a(uchar code) int t_uc51::inst_orl_addr_$data(uchar code) { - uchar *addr; + class cl_cell *cell; + int res= resGO; - addr= get_direct(fetch(), &event_at.wi, &event_at.ws); - (*addr)|= fetch(); - proc_write(addr); + cell= get_direct(fetch()); + t_mem d= fetch(); + cell->write(cell->read(HW_PORT) | d); tick(1); - return(resGO); + return(res); } @@ -83,8 +83,8 @@ t_uc51::inst_orl_a_$data(uchar code) { uchar d; - d= sfr->get(event_at.ws= ACC); - sfr->set(ACC, d|= fetch()); + d= acc->read(); + acc->write(d|= fetch()); return(resGO); } @@ -98,11 +98,12 @@ t_uc51::inst_orl_a_$data(uchar code) int t_uc51::inst_orl_a_addr(uchar code) { - uchar *addr, d; + t_mem d; + class cl_cell *cell; - addr= get_direct(fetch(), &event_at.ri, &event_at.rs); - d= sfr->get(event_at.ws= ACC); - sfr->set(ACC, d|= read(addr)); + cell= get_direct(fetch()); + d= acc->read(); + acc->write(d|= cell->read()); return(resGO); } @@ -116,13 +117,13 @@ t_uc51::inst_orl_a_addr(uchar code) int t_uc51::inst_orl_a_$ri(uchar code) { - uchar *addr, d; - int res; + t_mem d; + class cl_cell *cell; - addr= get_indirect(event_at.ri= *(get_reg(code & 0x01)), &res); - d= sfr->get(event_at.ws= ACC); - sfr->set(ACC, d|= *addr); - return(res); + cell= iram->get_cell(get_reg(code & 0x01)->read()); + d= acc->read(); + acc->write(d|= cell->read()); + return(resGO); } @@ -135,10 +136,10 @@ t_uc51::inst_orl_a_$ri(uchar code) int t_uc51::inst_orl_a_rn(uchar code) { - uchar d; + t_mem d; - d= sfr->get(event_at.ws= ACC); - sfr->set(ACC, d|= *(get_reg(code & 0x07, &event_at.ri))); + d= acc->read(); + acc->write(d|= get_reg(code & 0x07)->read()); return(resGO); } @@ -152,11 +153,10 @@ t_uc51::inst_orl_a_rn(uchar code) int t_uc51::inst_anl_addr_a(uchar code) { - uchar *addr; - - addr= get_direct(fetch(), &event_at.wi, &event_at.ws); - (*addr)&= sfr->get(event_at.rs= ACC); - proc_write(addr); + class cl_cell *cell; + + cell= get_direct(fetch()); + cell->write(cell->read(HW_PORT) & acc->read()); return(resGO); } @@ -170,11 +170,12 @@ t_uc51::inst_anl_addr_a(uchar code) int t_uc51::inst_anl_addr_$data(uchar code) { - uchar *addr; + class cl_cell *cell; + t_mem d; - addr= get_direct(fetch(), &event_at.wi, &event_at.ws); - (*addr)&= fetch(); - proc_write(addr); + cell= get_direct(fetch()); + d= fetch(); + cell->write(cell->read(HW_PORT) & d); tick(1); return(resGO); } @@ -191,8 +192,8 @@ t_uc51::inst_anl_a_$data(uchar code) { uchar d; - d= sfr->get(event_at.ws= ACC); - sfr->set(ACC, d&= fetch()); + d= acc->read(); + acc->write(d & fetch()); return(resGO); } @@ -206,11 +207,12 @@ t_uc51::inst_anl_a_$data(uchar code) int t_uc51::inst_anl_a_addr(uchar code) { - uchar *addr, d; + t_mem d; + class cl_cell *cell; - addr= get_direct(fetch(), &event_at.ri, &event_at.rs); - d= sfr->get(event_at.ws= ACC); - sfr->set(ACC, d&= read(addr)); + cell= get_direct(fetch()); + d= acc->read(); + acc->write(d & cell->read()); return(resGO); } @@ -224,13 +226,13 @@ t_uc51::inst_anl_a_addr(uchar code) int t_uc51::inst_anl_a_$ri(uchar code) { - uchar *addr, d; - int res; + t_mem d; + class cl_cell *cell; - addr= get_indirect(event_at.ri= *(get_reg(code & 0x01)), &res); - d= sfr->get(event_at.ws= ACC); - sfr->set(ACC, d&= *addr); - return(res); + cell= iram->get_cell(get_reg(code & 0x01)->read()); + d= acc->read(); + acc->write(d & cell->read()); + return(resGO); } @@ -245,8 +247,8 @@ t_uc51::inst_anl_a_rn(uchar code) { uchar d; - d= sfr->get(event_at.ws= ACC); - sfr->set(ACC, d&= *(get_reg(code & 0x07, &event_at.ri))); + d= acc->read(); + acc->write(d & get_reg(code & 0x07)->read()); return(resGO); } @@ -260,11 +262,10 @@ t_uc51::inst_anl_a_rn(uchar code) int t_uc51::inst_xrl_addr_a(uchar code) { - uchar *addr; + class cl_cell *cell; - addr= get_direct(fetch(), &event_at.wi, &event_at.ws); - (*addr)^= sfr->get(event_at.rs= ACC); - proc_write(addr); + cell= get_direct(fetch()); + cell->write(cell->read(HW_PORT) ^ acc->read()); return(resGO); } @@ -278,11 +279,10 @@ t_uc51::inst_xrl_addr_a(uchar code) int t_uc51::inst_xrl_addr_$data(uchar code) { - uchar *addr; + class cl_cell *cell; - addr= get_direct(fetch(), &event_at.wi, &event_at.ws); - (*addr)^= fetch(); - proc_write(addr); + cell= get_direct(fetch()); + cell->write(cell->read(HW_PORT) ^ fetch()); tick(1); return(resGO); } @@ -299,8 +299,8 @@ t_uc51::inst_xrl_a_$data(uchar code) { uchar d; - d= sfr->get(event_at.ws= ACC); - sfr->set(ACC, d^= fetch()); + d= acc->read(); + acc->write(d ^ fetch()); return(resGO); } @@ -314,12 +314,12 @@ t_uc51::inst_xrl_a_$data(uchar code) int t_uc51::inst_xrl_a_addr(uchar code) { - uchar d; + t_mem d; + class cl_cell *cell; - d= sfr->get(event_at.ws= ACC); - sfr->set(ACC, d^= read(get_direct(fetch(), - &event_at.ri, - &event_at.ri))); + cell= get_direct(fetch()); + d= acc->read(); + acc->write(d ^ cell->read()); return(resGO); } @@ -333,13 +333,13 @@ t_uc51::inst_xrl_a_addr(uchar code) int t_uc51::inst_xrl_a_$ri(uchar code) { - uchar *addr, d; - int res; + t_mem d; + class cl_cell *cell; - addr= get_indirect(event_at.ri= *(get_reg(code & 0x01)), &res); - d= sfr->get(event_at.ws= ACC); - sfr->set(ACC, d^= *addr); - return(res); + cell= iram->get_cell(get_reg(code & 0x01)->read()); + d= acc->read(); + acc->write(d ^ cell->read()); + return(resGO); } @@ -352,10 +352,10 @@ t_uc51::inst_xrl_a_$ri(uchar code) int t_uc51::inst_xrl_a_rn(uchar code) { - uchar d; + t_mem d; - d= sfr->get(event_at.ws= ACC); - sfr->set(ACC, d^= *(get_reg(code & 0x07, &event_at.ri))); + d= acc->read(); + acc->write(d ^ get_reg(code & 0x07)->read()); return(resGO); } @@ -369,7 +369,7 @@ t_uc51::inst_xrl_a_rn(uchar code) int t_uc51::inst_cpl_a(uchar code) { - sfr->set(event_at.ws= ACC, ~(sfr->get(ACC))); + acc->write(~(acc->read())); return(resGO); } diff --git a/sim/ucsim/s51.src/mov.cc b/sim/ucsim/s51.src/mov.cc index 885b3324..a3240154 100644 --- a/sim/ucsim/s51.src/mov.cc +++ b/sim/ucsim/s51.src/mov.cc @@ -51,7 +51,7 @@ Software Foundation, 59 Temple Place - Suite 330, Boston, MA int t_uc51::inst_mov_a_$data(uchar code) { - sfr->set(event_at.ws= ACC, fetch()); + acc->write(fetch()); return(resGO); } @@ -65,11 +65,10 @@ t_uc51::inst_mov_a_$data(uchar code) int t_uc51::inst_mov_addr_$data(uchar code) { - uchar *addr; + class cl_cell *cell; - addr= get_direct(fetch(), &event_at.wi, &event_at.ws); - (*addr)= fetch(); - proc_write(addr); + cell= get_direct(fetch()); + cell->write(fetch()); tick(1); return(resGO); } @@ -84,13 +83,12 @@ t_uc51::inst_mov_addr_$data(uchar code) int t_uc51::inst_mov_$ri_$data(uchar code) { - uchar *addr; - int res; - - addr= get_indirect(event_at.wi= *(get_reg(code & 0x01)), &res); - (*addr)= fetch(); - proc_write(addr); - return(res); + class cl_cell *cell; + + cell= iram->get_cell(get_reg(code & 0x01)->read()); + t_mem d= fetch(); + cell->write(d); + return(resGO); } @@ -103,10 +101,10 @@ t_uc51::inst_mov_$ri_$data(uchar code) int t_uc51::inst_mov_rn_$data(uchar code) { - uchar *reg; + class cl_cell *reg; - reg= get_reg(code & 0x07, &event_at.wi); - (*reg)= fetch(); + reg= get_reg(code & 0x07); + reg->write(fetch()); return(resGO); } @@ -120,10 +118,7 @@ t_uc51::inst_mov_rn_$data(uchar code) int t_uc51::inst_movc_a_$a_pc(uchar code) { - //SFR[ACC]= EROM[event_at.rc= (PC + SFR[ACC]) & (EROM_SIZE - 1)]; - sfr->set(ACC, - mem(MEM_ROM)->get(event_at.rc= - (PC + sfr->get(ACC)))&(EROM_SIZE - 1)); + acc->write(mem(MEM_ROM)->read(PC + acc->read())); tick(1); return(resGO); } @@ -138,13 +133,12 @@ t_uc51::inst_movc_a_$a_pc(uchar code) int t_uc51::inst_mov_addr_addr(uchar code) { - uchar *d, *s; + class cl_cell *d, *s; /* SD reversed s & d here */ - s= get_direct(fetch(), &event_at.ri, &event_at.rs); - d= get_direct(fetch(), &event_at.wi, &event_at.ws); - (*d)= read(s); - proc_write(d); + s= get_direct(fetch()); + d= get_direct(fetch()); + d->write(s->read()); tick(1); return(resGO); } @@ -159,15 +153,13 @@ t_uc51::inst_mov_addr_addr(uchar code) int t_uc51::inst_mov_addr_$ri(uchar code) { - uchar *d, *s; - int res; + class cl_cell *d, *s; - d= get_direct(fetch(), &event_at.wi, &event_at.ws); - s= get_indirect(event_at.ri= *(get_reg(code & 0x01)), &res); - *d= *s; - proc_write(d); + d= get_direct(fetch()); + s= iram->get_cell(get_reg(code & 0x01)->read()); + d->write(s->read()); tick(1); - return(res); + return(resGO); } @@ -180,11 +172,10 @@ t_uc51::inst_mov_addr_$ri(uchar code) int t_uc51::inst_mov_addr_rn(uchar code) { - uchar *addr; + class cl_cell *cell; - addr= get_direct(fetch(), &event_at.wi, &event_at.ws); - (*addr)= *(get_reg(code & 0x07, &event_at.ri)); - proc_write(addr); + cell= get_direct(fetch()); + cell->write(get_reg(code & 0x07)->read()); tick(1); return(resGO); } @@ -199,8 +190,8 @@ t_uc51::inst_mov_addr_rn(uchar code) int t_uc51::inst_mov_dptr_$data(uchar code) { - sfr->set(event_at.ws= DPH, fetch()); - sfr->set(DPL, fetch()); + sfr->write(DPH, fetch()); + sfr->write(DPL, fetch()); tick(1); return(resGO); } @@ -215,10 +206,9 @@ t_uc51::inst_mov_dptr_$data(uchar code) int t_uc51::inst_movc_a_$a_dptr(uchar code) { - //SFR[ACC]= EROM[event_at.rc= (SFR[DPH]*256+SFR[DPL]+SFR[ACC])&(EROM_SIZE-1)]; - sfr->set(ACC, get_mem(MEM_ROM, event_at.rc= - (sfr->get(DPH)*256+sfr->get(DPL) + - sfr->get(ACC)) & (EROM_SIZE-1))); + acc->write(get_mem(MEM_ROM, + sfr->read(DPH)*256+sfr->read(DPL) + + acc->read())); tick(1); return(resGO); } @@ -233,14 +223,13 @@ t_uc51::inst_movc_a_$a_dptr(uchar code) int t_uc51::inst_mov_$ri_addr(uchar code) { - uchar *d, *s; - int res; + class cl_cell *d, *s; - d= get_indirect(event_at.wi= *(get_reg(code & 0x01)), &res); - s= get_direct(fetch(), &event_at.ri, &event_at.rs); - (*d)= read(s); + d= iram->get_cell(get_reg(code & 0x01)->read()); + s= get_direct(fetch()); + d->write(s->read()); tick(1); - return(res); + return(resGO); } @@ -253,11 +242,11 @@ t_uc51::inst_mov_$ri_addr(uchar code) int t_uc51::inst_mov_rn_addr(uchar code) { - uchar *reg, *addr; + class cl_cell *reg, *cell; - reg = get_reg(code & 0x07, &event_at.wi); - addr= get_direct(fetch(), &event_at.ri, &event_at.rs); - (*reg)= read(addr); + reg = get_reg(code & 0x07); + cell= get_direct(fetch()); + reg->write(cell->read()); tick(1); return(resGO); } @@ -272,17 +261,15 @@ t_uc51::inst_mov_rn_addr(uchar code) int t_uc51::inst_push(uchar code) { - uchar *addr, *sp; - int res; - - addr= get_direct(fetch(), &event_at.ri, &event_at.rs); - sfr->add(SP, 1); - sp= get_indirect(sfr->get(SP), &res); - if (res != resGO) - res= resSTACK_OV; - (*sp)= read(addr); + t_addr sp; + class cl_cell *stck, *cell; + + cell= get_direct(fetch()); + sp= sfr->wadd(SP, 1); + stck= iram->get_cell(sp); + stck->write(cell->read()); tick(1); - return(res); + return(resGO); } @@ -295,13 +282,13 @@ t_uc51::inst_push(uchar code) int t_uc51::inst_xch_a_addr(uchar code) { - uchar temp, *addr; + t_mem temp; + class cl_cell *cell; - addr= get_direct(fetch(), &event_at.ri, &event_at.rs); - temp= sfr->get(ACC); - sfr->set(event_at.ws= ACC, read(addr)); - (*addr)= temp; - proc_write(addr); + cell= get_direct(fetch()); + temp= acc->read(); + acc->write(cell->read()); + cell->write(temp); return(resGO); } @@ -315,14 +302,14 @@ t_uc51::inst_xch_a_addr(uchar code) int t_uc51::inst_xch_a_$ri(uchar code) { - uchar temp, *addr; - int res; - - addr= get_indirect(event_at.ri= *(get_reg(code & 0x01)), &res); - temp= sfr->get(ACC); - sfr->set(event_at.ws= ACC, *addr); - (*addr)= temp; - return(res); + t_mem temp; + class cl_cell *cell; + + cell= iram->get_cell(get_reg(code & 0x01)->read()); + temp= acc->read(); + acc->write(cell->read()); + cell->write(temp); + return(resGO); } @@ -335,12 +322,13 @@ t_uc51::inst_xch_a_$ri(uchar code) int t_uc51::inst_xch_a_rn(uchar code) { - uchar temp, *reg; + t_mem temp; + class cl_cell *reg; - reg = get_reg(code & 0x07, &event_at.ri); - temp= sfr->get(ACC); - sfr->set(event_at.wi= ACC, *reg); - (*reg)= temp; + reg = get_reg(code & 0x07); + temp= acc->read(); + acc->write(reg->read()); + reg->write(temp); return(resGO); } @@ -354,18 +342,15 @@ t_uc51::inst_xch_a_rn(uchar code) int t_uc51::inst_pop(uchar code) { - uchar *addr, *sp; - int res; - - addr= get_direct(fetch(), &event_at.wi, &event_at.ws); - sp= get_indirect(get_mem(MEM_SFR, SP), &res); - if (res != resGO) - res= resSTACK_OV; - sfr->add(SP, -1); - (*addr)= *sp; - proc_write(addr); + t_addr sp; + class cl_cell *cell, *stck; + + cell= get_direct(fetch()); + stck= iram->get_cell(sfr->get(SP)); + cell->write(stck->read()); + sp= sfr->wadd(SP, -1); tick(1); - return(res); + return(resGO); } @@ -378,14 +363,14 @@ t_uc51::inst_pop(uchar code) int t_uc51::inst_xchd_a_$ri(uchar code) { - uchar *addr, temp; - int res; - - addr= get_indirect(event_at.ri= *(get_reg(code & 0x01)), &res); - temp= *addr & 0x0f; - (*addr) = (*addr & 0xf0) | (sfr->get(ACC) & 0x0f); - sfr->set(event_at.ws= ACC, (sfr->get(ACC) & 0xf0) | temp); - return(res); + t_mem temp, d; + class cl_cell *cell; + + cell= iram->get_cell(get_reg(code & 0x01)->read()); + temp= (d= cell->read()) & 0x0f; + cell->write((d & 0xf0) | (acc->read() & 0x0f)); + acc->write((acc->get() & 0xf0) | temp); + return(resGO); } @@ -398,8 +383,8 @@ t_uc51::inst_xchd_a_$ri(uchar code) int t_uc51::inst_movx_a_$dptr(uchar code) { - sfr->set(event_at.ws= ACC, - get_mem(MEM_XRAM, event_at.rx=sfr->get(DPH)*256+sfr->get(DPL))); + acc->write(read_mem(MEM_XRAM, + sfr->read(DPH)*256 + sfr->read(DPL))); tick(1); return(resGO); } @@ -414,12 +399,10 @@ t_uc51::inst_movx_a_$dptr(uchar code) int t_uc51::inst_movx_a_$ri(uchar code) { - uchar *addr; + t_mem d; - addr= get_reg(code & 0x01); - sfr->set(event_at.ws= ACC, - read_mem(MEM_XRAM, - event_at.rx= (sfr->get(P2)&port_pins[2])*256+*addr)); + d= get_reg(code & 0x01)->read(); + acc->write(read_mem(MEM_XRAM, sfr->read(P2)*256 + d)); tick(1); return(resGO); } @@ -434,10 +417,10 @@ t_uc51::inst_movx_a_$ri(uchar code) int t_uc51::inst_mov_a_addr(uchar code) { - uchar *addr; + class cl_cell *cell; - addr= get_direct(fetch(), &event_at.ri, &event_at.rs); - sfr->set(event_at.ws= ACC, read(addr)); + cell= get_direct(fetch()); + acc->write(cell->read()); return(resGO); } @@ -451,12 +434,11 @@ t_uc51::inst_mov_a_addr(uchar code) int t_uc51::inst_mov_a_$ri(uchar code) { - uchar *addr; - int res; + class cl_cell *cell; - addr= get_indirect(event_at.ri= *(get_reg(code & 0x01)), &res); - sfr->set(event_at.ws= ACC, *addr); - return(res); + cell= iram->get_cell(get_reg(code & 0x01)->read()); + acc->write(cell->read()); + return(resGO); } @@ -469,7 +451,7 @@ t_uc51::inst_mov_a_$ri(uchar code) int t_uc51::inst_mov_a_rn(uchar code) { - sfr->set(event_at.ws= ACC, *(get_reg(code & 0x07, &event_at.ri))); + acc->write(get_reg(code & 0x07)->read()); return(resGO); } @@ -483,8 +465,7 @@ t_uc51::inst_mov_a_rn(uchar code) int t_uc51::inst_movx_$dptr_a(uchar code) { - set_mem(MEM_XRAM, event_at.wx= sfr->get(DPH)*256+sfr->get(DPL), - sfr->get(event_at.rs= ACC)); + write_mem(MEM_XRAM, sfr->read(DPH)*256 + sfr->read(DPL), acc->read()); tick(1); return(resGO); } @@ -499,12 +480,10 @@ t_uc51::inst_movx_$dptr_a(uchar code) int t_uc51::inst_movx_$ri_a(uchar code) { - uchar *addr; + t_mem d; - addr= get_reg(code & 0x01); - set_mem(MEM_XRAM, - event_at.wx= (sfr->get(P2) & port_pins[2])*256 + *addr, - sfr->get(ACC)); + d= get_reg(code & 0x01)->read(); + write_mem(MEM_XRAM, sfr->read(P2)*256 + d, acc->read()); tick(1); return(resGO); } @@ -519,11 +498,10 @@ t_uc51::inst_movx_$ri_a(uchar code) int t_uc51::inst_mov_addr_a(uchar code) { - uchar *addr; - - addr= get_direct(fetch(), &event_at.wi, &event_at.ws); - (*addr)= sfr->get(event_at.rs= ACC); - proc_write(addr); + class cl_cell *cell; + + cell= get_direct(fetch()); + cell->write(acc->read()); return(resGO); } @@ -537,12 +515,11 @@ t_uc51::inst_mov_addr_a(uchar code) int t_uc51::inst_mov_$ri_a(uchar code) { - uchar *addr; - int res; + class cl_cell *cell; - addr= get_indirect(event_at.wi= *(get_reg(code & 0x01)), &res); - (*addr)= sfr->get(event_at.rs= ACC); - return(res); + cell= iram->get_cell(get_reg(code & 0x01)->read()); + cell->write(acc->read()); + return(resGO); } @@ -555,10 +532,10 @@ t_uc51::inst_mov_$ri_a(uchar code) int t_uc51::inst_mov_rn_a(uchar code) { - uchar *reg; + class cl_cell *reg; - reg= get_reg(code &0x07, &event_at.wi); - (*reg)= sfr->get(event_at.rs= ACC); + reg= get_reg(code &0x07); + reg->write(acc->read()); return(resGO); } diff --git a/sim/ucsim/s51.src/pca.cc b/sim/ucsim/s51.src/pca.cc new file mode 100644 index 00000000..173893aa --- /dev/null +++ b/sim/ucsim/s51.src/pca.cc @@ -0,0 +1,329 @@ +/* + * Simulator of microcontrollers (pca.cc) + * + * Copyright (C) 1999,99 Drotos Daniel, Talker Bt. + * + * To contact author send email to drdani@mazsola.iit.uni-miskolc.hu + * + */ + +/* This file is part of microcontroller simulator: ucsim. + +UCSIM is free software; you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation; either version 2 of the License, or +(at your option) any later version. + +UCSIM is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU General Public License for more details. + +You should have received a copy of the GNU General Public License +along with UCSIM; see the file COPYING. If not, write to the Free +Software Foundation, 59 Temple Place - Suite 330, Boston, MA +02111-1307, USA. */ +/*@1@*/ + +#include + +// sim.src +#include "itsrccl.h" + +// local +#include "pcacl.h" +#include "regs51.h" +#include "types51.h" + + +cl_pca::cl_pca(class cl_uc *auc, int aid): + cl_hw(auc, HW_PCA, aid, "pca") +{ + t0_overflows= ECI_edge= 0; + int i; + for (i= 0; i < 5; cex_pos[i]= cex_neg[i]= DD_FALSE, i++) ; +} + +int +cl_pca::init(void) +{ + class cl_mem *sfr= uc->mem(MEM_SFR); + t_addr CCAPL[5]= {CCAPL[0], CCAPL[1], CCAPL[2], CCAPL[3], CCAPL[4]}; + t_addr CCAPH[5]= {CCAPH[0], CCAPH[1], CCAPH[2], CCAPH[3], CCAPH[4]}; + t_addr CCAPM[5]= {CCAPM[0], CCAPM[1], CCAPM[2], CCAPM[3], CCAPM[4]}; + int i; + + if (!sfr) + { + fprintf(stderr, "No SFR to register PCA[%d] into\n", id); + } + register_cell(sfr, CMOD, &cell_cmod, wtd_restore_write); + register_cell(sfr, CCON, &cell_ccon, wtd_restore_write); + for (i= 0; i < 5; i++) + { + use_cell(sfr, CCAPL[i], &cell_ccapl[i], wtd_restore); + use_cell(sfr, CCAPH[i], &cell_ccaph[i], wtd_restore); + register_cell(sfr, CCAPM[i], &cell_ccapm[i], wtd_restore_write); + } + use_cell(sfr, CL, &cell_cl, wtd_restore); + use_cell(sfr, CH, &cell_ch, wtd_restore); + return(0); +} + +void +cl_pca::added_to_uc(void) +{ + uc->it_sources->add_at(4, new cl_it_src(bmEC, CCON, bmCCF4, 0x0033, false, + "PCA module #4", 5)); + uc->it_sources->add_at(4, new cl_it_src(bmEC, CCON, bmCCF3, 0x0033, false, + "PCA module #3", 5)); + uc->it_sources->add_at(4, new cl_it_src(bmEC, CCON, bmCCF2, 0x0033, false, + "PCA module #2", 5)); + uc->it_sources->add_at(4, new cl_it_src(bmEC, CCON, bmCCF1, 0x0033, false, + "PCA module #1", 5)); + uc->it_sources->add_at(4, new cl_it_src(bmEC, CCON, bmCCF0, 0x0033, false, + "PCA module #0", 5)); + uc->it_sources->add_at(4, new cl_it_src(bmEC, CCON, bmCF, 0x0033, false, + "PCA counter", 5)); +} + +void +cl_pca::write(class cl_cell *cell, t_mem *val) +{ + //uchar bmCEX[5]= {bmCEX0, bmCEX1, bmCEX2, bmCEX3, bmCEX4}; + //uchar bmCCF[5]= {bmCCF0, bmCCF1, bmCCF2, bmCCF3, bmCCF4}; + + if (cell == cell_cmod) + { + bit_CIDL= *val & bmCIDL; + bit_WDTE= *val & bmWDTE; + bit_ECF = *val & bmECF; + t_mem o= clk_source; + if ((clk_source= *val & (bmCPS1|bmCPS0)) != o) + t0_overflows= ECI_edge= 0; + } + else if (cell == cell_ccon) + { + bit_CR= *val & bmCR; + } + else + { + int i; + for (i= 0; i < 5; i++) + { + if (cell == cell_ccapm[i]) + { + t_mem o= ccapm[i]; + ccapm[i]= *val & 0xff; + if (o != ccapm[i]) + cex_neg[i]= cex_pos[i]= DD_FALSE; + } + else + { + if (ccapm[i] & (bmMAT|bmTOG)) + { + if (cell == cell_ccapl[i]) + { + cell_ccapm[i]->set_bit0(bmECOM); + ccapm[i]= cell_ccapm[i]->get(); + } + else if (cell == cell_ccaph[i]) + { + cell_ccapm[i]->set_bit1(bmECOM); + ccapm[i]= cell_ccapm[i]->get(); + } + } + } + } + } +} + +/*void +cl_pca::mem_cell_changed(class cl_mem *mem, t_addr addr) +{ + class cl_mem *sfr= uc->mem(MEM_SFR); + + if (mem && sfr && mem == sfr) + { + if (addr == addr_ccapXl) + ccapXl= sfr->get_cell(addr_ccapXl); + else if (addr == addr_ccapXh) + ccapXh= sfr->get_cell(addr_ccapXh); + else if (addr == addr_ccapmX) + ccapmX= sfr->get_cell(addr_ccapmX); + } +}*/ + +int +cl_pca::tick(int cycles) +{ + int ret= resGO; + + if (!bit_CR) + return(resGO); + if (uc->state == stIDLE && + bit_CIDL) + return(resGO); + + switch (clk_source) + { + case 0: + do_pca_counter(cycles); + break; + case bmCPS0: + do_pca_counter(cycles*3); + break; + case bmCPS1: + do_pca_counter(t0_overflows); + t0_overflows= 0; + break; + case (bmCPS0|bmCPS1): + do_pca_counter(ECI_edge); + ECI_edge= 0; + break; + } + return(ret); +} + +void +cl_pca::do_pca_counter(int cycles) +{ + //class cl_mem *sfr= uc->mem(MEM_SFR); + + while (cycles--) + { + if (cell_cl->add(1) == 0) + { + int i; + for (i= 0; i < 5; i++) + if (ccapm[i] & bmPWM) + cell_ccapl[i]->set(cell_ccaph[i]->get()); + if (cell_ch->add(1) == 0) + { + // CH,CL overflow + cell_ccon->set_bit1(bmCF); + do_pca_module(0); + do_pca_module(1); + do_pca_module(2); + do_pca_module(3); + do_pca_module(4); + } + } + } +} + +void +cl_pca::do_pca_module(int nr) +{ + class cl_mem *sfr= uc->mem(MEM_SFR); + + uchar bmCEX[5]= {bmCEX0, bmCEX1, bmCEX2, bmCEX3, bmCEX4}; + uchar bmCCF[5]= {bmCCF0, bmCCF1, bmCCF2, bmCCF3, bmCCF4}; + //uint p1= sfr->get(P1); + + bool capture= DD_FALSE; + if ((ccapm[nr] & bmCAPP) && + cex_pos[nr]) + { + capture= DD_TRUE; + cex_pos[nr]= DD_FALSE; + } + if ((ccapm[nr] & bmCAPN) && + cex_neg[nr]) + { + capture= DD_TRUE; + cex_pos[nr]= DD_FALSE; + } + if (capture) + { + // Capture + cell_ccapl[nr]->set(cell_cl->get()); + cell_ccaph[nr]->set(cell_ch->get()); + cell_ccon->set_bit1(bmCCF[nr]); + } + + if (ccapm[nr] & bmECOM) + { + // Comparator enabled + if (cell_cl->get() == cell_ccapl[nr]->get() && + cell_ch->get() == cell_ccaph[nr]->get()) + { + // Match + if (nr == 4 && + (bit_WDTE)) + { + reset(); + return; + } + cell_ccon->set_bit1(bmCCF[nr]); + if (ccapm[nr] & bmTOG) + { + // Toggle + sfr->set(P1, sfr->get(P1) ^ bmCEX[nr]); + } + } + if (ccapm[nr] & bmPWM) + { + // PWM + /*if (cell_cl->get() == 0) + cell_ccapl[nr]->set(cell_ccaph[nr]->get());*/ + if (cell_cl->get() < cell_ccapl[nr]->get()) + //sfr->set(P1, sfr->get(P1) & ~(bmCEX[nr])); + sfr->set_bit1(P1, bmCEX[nr]); + else + sfr->set_bit1(P1, bmCEX[nr]); + } + } +} + +void +cl_pca::reset(void) +{ + t0_overflows= ECI_edge= 0; + int i; + for (i= 0; i < 5; cex_pos[i]= cex_neg[i]= DD_FALSE, i++) ; +} + +void +cl_pca::happen(class cl_hw *where, enum hw_event he, void *params) +{ + struct ev_port_changed *ep= (struct ev_port_changed *)params; + uchar bmCEX[5]= {bmCEX0, bmCEX1, bmCEX2, bmCEX3, bmCEX4}; + + if (where->cathegory == HW_PORT && + he == EV_PORT_CHANGED && + ep->id == 1) + { + t_mem p1n= ep->new_pins & ep->new_value; + t_mem p1o= ep->pins & ep->prev_value; + if (!(p1n & bmECI) && + (p1o & bmECI)) + ECI_edge++; + int i; + for (i= 0; i < 5; i++) + { + if (!(p1n & bmCEX[i]) && + (p1o & bmCEX[i])) + cex_neg[i]= DD_TRUE; + else if ((p1n & bmCEX[i]) && + !(p1o & bmCEX[i])) + cex_pos[i]= DD_TRUE; + } + } + else if (where->cathegory == HW_TIMER && + he == EV_OVERFLOW && + where->id == 0) + { + t0_overflows++; + } +} + + +void +cl_pca::print_info(class cl_console *con) +{ + con->dd_printf("%s[%d] FIXME\n", id_string, id); +} + + +/* End of s51.src/pca.cc */ diff --git a/sim/ucsim/s51.src/pcacl.h b/sim/ucsim/s51.src/pcacl.h new file mode 100644 index 00000000..c782118b --- /dev/null +++ b/sim/ucsim/s51.src/pcacl.h @@ -0,0 +1,75 @@ +/* + * Simulator of microcontrollers (pcacl.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 PORTCL_HEADER +#define PORTCL_HEADER + +// sim.src +//#include "stypes.h" +//#include "pobjcl.h" +#include "uccl.h" + +// local +//#include "newcmdcl.h" + + +class cl_pca: public cl_hw +{ +public: + class cl_cell *cell_cl, *cell_ch; + class cl_cell *cell_ccapl[5], *cell_ccaph[5], *cell_ccapm[5]; + t_mem ccapm[5]; + class cl_cell *cell_cmod, *cell_ccon; + long t0_overflows, ECI_edge; + t_mem clk_source; + bool bit_CIDL, bit_WDTE, bit_ECF, bit_CR; + bool cex_pos[5], cex_neg[5]; +public: + cl_pca(class cl_uc *auc, int aid); + virtual int init(void); + + virtual void added_to_uc(void); + + //virtual t_mem read(class cl_cell *cell); + virtual void write(class cl_cell *cell, t_mem *val); + + //virtual t_mem set_cmd(t_mem value); + //virtual void mem_cell_changed(class cl_mem *mem, t_addr addr); + + virtual int tick(int cycles); + virtual void do_pca_counter(int cycles); + virtual void do_pca_module(int nr); + virtual void reset(void); + virtual void happen(class cl_hw *where, enum hw_event he, void *params); + + virtual void print_info(class cl_console *con); +}; + + +#endif + +/* End of s51.src/pcacl.h */ diff --git a/sim/ucsim/s51.src/port.cc b/sim/ucsim/s51.src/port.cc index 96ebb530..37cf983c 100644 --- a/sim/ucsim/s51.src/port.cc +++ b/sim/ucsim/s51.src/port.cc @@ -29,47 +29,141 @@ Software Foundation, 59 Temple Place - Suite 330, Boston, MA #include "portcl.h" #include "regs51.h" +#include "types51.h" cl_port::cl_port(class cl_uc *auc, int aid): cl_hw(auc, HW_PORT, aid, "port") -{} +{ + port_pins= 0xff; +} int cl_port::init(void) { switch (id) { - case 0: sfr= P0; break; - case 1: sfr= P1; break; - case 2: sfr= P2; break; - case 3: sfr= P3; break; - case 4: sfr= P4; break; - case 5: sfr= P5; break; - default: sfr= P0; return(1); + case 0: addr_p= P0; break; + case 1: + { + addr_p= P1; + /*class cl_hw *hw; + if ((hw= uc->get_hw(HW_TIMER, 2, 0))) + hws_to_inform->add(hw);*/ + make_partner(HW_TIMER, 2); + make_partner(HW_PCA, 0); + break; + } + case 2: addr_p= P2; break; + case 3: + { + addr_p= P3; + //class cl_hw *hw; + /*if ((hw= uc->get_hw(HW_TIMER, 0, 0))) + hws_to_inform->add(hw); + if ((hw= uc->get_hw(HW_TIMER, 1, 0))) + hws_to_inform->add(hw); + if ((hw= uc->get_hw(HW_DUMMY, 0, 0))) + hws_to_inform->add(hw);*/ + make_partner(HW_TIMER, 0); + make_partner(HW_TIMER, 1); + make_partner(HW_INTERRUPT, 0); + make_partner(HW_DUMMY, 0); + break; + } + default: addr_p= P0; return(1); + } + class cl_mem *sfr= uc->mem(MEM_SFR); + if (!sfr) + { + fprintf(stderr, "No SFR to register port into\n"); } + //cell_p= sfr->register_hw(addr_p, this, (int*)0); + register_cell(sfr, addr_p, &cell_p, wtd_restore_write); + prev= cell_p->get(); return(0); } +t_mem +cl_port::read(class cl_cell *cell) +{ + //printf("port[%d] read\n",id); + return(cell->get() & port_pins); +} + +void +cl_port::write(class cl_cell *cell, t_mem *val) +{ + struct ev_port_changed ep; + + (*val)&= 0xff; // 8 bit port + ep.id= id; + ep.addr= addr_p; + ep.prev_value= cell_p->get(); + ep.new_value= *val; + ep.pins= ep.new_pins= port_pins; + if (ep.prev_value != ep.new_value) + inform_partners(EV_PORT_CHANGED, &ep); + prev= cell_p->get(); + //printf("port[%d] write 0x%x\n",id,val); +} + +void +cl_port::set_cmd(class cl_cmdline *cmdline, class cl_console *con) +{ + struct ev_port_changed ep; + class cl_cmd_arg *params[1]= { cmdline->param(0) }; + long value; + + if (cmdline->syntax_match(uc, NUMBER)) + { + value= params[0]->value.number & 0xff; + + ep.id= id; + ep.addr= addr_p; + ep.pins= port_pins; + port_pins= value; + ep.prev_value= cell_p->get(); + ep.new_value= cell_p->get(); + ep.new_pins= port_pins; + if (ep.pins != ep.new_pins) + inform_partners(EV_PORT_CHANGED, &ep); + } + else + { + con->dd_printf("Error: wrong systax\n"); + value= 0; + } +} + +/*void +cl_port::mem_cell_changed(class cl_mem *mem, t_addr addr) +{ + cl_hw::mem_cell_changed(mem, addr); + t_mem d= sfr->get(); + write(sfr, &d); +}*/ + void cl_port::print_info(class cl_console *con) { uchar data; con->dd_printf("%s[%d]\n", id_string, id); - data= uc->get_mem(MEM_SFR, sfr); + data= cell_p->get();//uc->get_mem(MEM_SFR, sfr); con->dd_printf("P%d ", id); con->print_bin(data, 8); con->dd_printf(" 0x%02x %3d %c (Value in SFR register)\n", data, data, isprint(data)?data:'.'); - data= uc->port_pins[id]; + data= /*uc->*/port_pins/*[id]*/; con->dd_printf("Pin%d ", id); con->print_bin(data, 8); con->dd_printf(" 0x%02x %3d %c (Output of outside circuits)\n", data, data, isprint(data)?data:'.'); - data= uc->port_pins[id] & uc->get_mem(MEM_SFR, sfr); + //data= /*uc->*/port_pins/*[id]*/ & sfr->get();//uc->get_mem(MEM_SFR, sfr); + data= cell_p->read(); con->dd_printf("Port%d ", id); con->print_bin(data, 8); con->dd_printf(" 0x%02x %3d %c (Value on the port pins)\n", diff --git a/sim/ucsim/s51.src/portcl.h b/sim/ucsim/s51.src/portcl.h index 87a6f7d5..b5a55ebe 100644 --- a/sim/ucsim/s51.src/portcl.h +++ b/sim/ucsim/s51.src/portcl.h @@ -38,14 +38,19 @@ Software Foundation, 59 Temple Place - Suite 330, Boston, MA class cl_port: public cl_hw { public: - int sfr; - + t_addr addr_p; + class cl_cell *cell_p; + t_mem port_pins; + t_mem prev; public: cl_port(class cl_uc *auc, int aid); virtual int init(void); - //virtual ulong read(class cl_mem *mem, long addr); - //virtual void write(class cl_mem *mem, long addr, ulong *val); + virtual t_mem read(class cl_cell *cell); + virtual void write(class cl_cell *cell, t_mem *val); + + virtual void set_cmd(class cl_cmdline *cmdline, class cl_console *con); + //virtual void mem_cell_changed(class cl_mem *mem, t_addr addr); //virtual int tick(int cycles); virtual void print_info(class cl_console *con); diff --git a/sim/ucsim/s51.src/regs51.h b/sim/ucsim/s51.src/regs51.h index ab07115c..60feafea 100644 --- a/sim/ucsim/s51.src/regs51.h +++ b/sim/ucsim/s51.src/regs51.h @@ -37,6 +37,9 @@ Software Foundation, 59 Temple Place - Suite 330, Boston, MA #define SP 0x81 /* Stack Pointer */ #define DPL 0x82 /* Data Pointer Low byte */ #define DPH 0x83 /* Data Pointer High byte */ +#define DPL1 0x84 /* 2nd Data Pointer Low byte */ +#define DPH1 0x85 /* 2nd Data Pointer High byte */ +#define DPS 0x86 /* DPS 1H=DPTR is DPL1/DPH1, 2H=AUTO DPTR INCR */ #define P0 0x80 /* Port #0 */ #define P1 0x90 /* Port #1 */ #define P2 0xa0 /* Port #2 */ @@ -95,8 +98,8 @@ Software Foundation, 59 Temple Place - Suite 330, Boston, MA #define MB 0xd4 /* MB register from math accelerator */ #define MC 0xd5 /* MC register from math accelerator */ #define CCON 0xd8 /* */ -#define WDCON 0xd8 /* */ #define CMOD 0xd9 /* */ +#define WDCON 0xd8 /* */ #define CCAPM0 0xda /* */ #define CCAPM1 0xdb /* */ #define CCAPM2 0xdc /* */ diff --git a/sim/ucsim/s51.src/serial.cc b/sim/ucsim/s51.src/serial.cc index a8e3985f..589ac5a7 100644 --- a/sim/ucsim/s51.src/serial.cc +++ b/sim/ucsim/s51.src/serial.cc @@ -25,20 +25,383 @@ Software Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ /*@1@*/ +#include "ddconfig.h" + +#include +#include +#include +#include +#include +#include +#include +#include +#include + +// local #include "serialcl.h" #include "regs51.h" +#include "uc51cl.h" cl_serial::cl_serial(class cl_uc *auc): cl_hw(auc, HW_UART, 0, "uart") {} -/*int +cl_serial::~cl_serial(void) +{ + if (serial_out) + { + if (isatty(fileno(serial_out))) + tcsetattr(fileno(serial_out), TCSANOW, &saved_attributes_out); + fclose(serial_out); + } + if (serial_in) + { + if (isatty(fileno(serial_in))) + tcsetattr(fileno(serial_in), TCSANOW, &saved_attributes_in); + fclose(serial_in); + } +} + +int cl_serial::init(void) { + class cl_mem *sfr; + int i; + struct termios tattr; + + sfr= uc->mem(MEM_SFR); + if (sfr) + { + //sbuf= sfr->register_hw(SBUF, this, 0); + //pcon= sfr->register_hw(PCON, this, 0); + //scon= sfr->register_hw(SCON, this, 0); + register_cell(sfr, SBUF, &sbuf, wtd_restore_write); + register_cell(sfr, PCON, &pcon, wtd_restore_write); + register_cell(sfr, SCON, &scon, wtd_restore_write); + } + + serial_in = (FILE*)uc->sim->app->args->get_parg(0, "Ser_in"); + serial_out= (FILE*)uc->sim->app->args->get_parg(0, "Ser_out"); + if (serial_in) + { + // making `serial' unbuffered + if (setvbuf(serial_in, NULL, _IONBF, 0)) + perror("Unbuffer serial input channel"); + // setting O_NONBLOCK + if ((i= fcntl(fileno(serial_in), F_GETFL, 0)) < 0) + perror("Get flags of serial input"); + i|= O_NONBLOCK; + if (fcntl(fileno(serial_in), F_SETFL, i) < 0) + perror("Set flags of serial input"); + // switching terminal to noncanonical mode + if (isatty(fileno(serial_in))) + { + tcgetattr(fileno(serial_in), &saved_attributes_in); + tcgetattr(fileno(serial_in), &tattr); + tattr.c_lflag&= ~(ICANON|ECHO); + tattr.c_cc[VMIN] = 1; + tattr.c_cc[VTIME]= 0; + tcsetattr(fileno(serial_in), TCSAFLUSH, &tattr); + } + else + fprintf(stderr, "Warning: serial input interface connected to a " + "non-terminal file.\n"); + } + if (serial_out) + { + // making `serial' unbuffered + if (setvbuf(serial_out, NULL, _IONBF, 0)) + perror("Unbuffer serial output channel"); + // setting O_NONBLOCK + if ((i= fcntl(fileno(serial_out), F_GETFL, 0)) < 0) + perror("Get flags of serial output"); + i|= O_NONBLOCK; + if (fcntl(fileno(serial_out), F_SETFL, i) < 0) + perror("Set flags of serial output"); + // switching terminal to noncanonical mode + if (isatty(fileno(serial_out))) + { + tcgetattr(fileno(serial_out), &saved_attributes_out); + tcgetattr(fileno(serial_out), &tattr); + tattr.c_lflag&= ~(ICANON|ECHO); + tattr.c_cc[VMIN] = 1; + tattr.c_cc[VTIME]= 0; + tcsetattr(fileno(serial_out), TCSAFLUSH, &tattr); + } + else + fprintf(stderr, "Warning: serial output interface connected to a " + "non-terminal file.\n"); + } + + class cl_hw *t2= uc->get_hw(HW_TIMER, 2, 0); + if ((there_is_t2= t2 != 0)) + { + t_mem d= sfr->get(T2CON); + t2_baud= d & (bmRCLK | bmTCLK); + } + else + t2_baud= DD_FALSE; + return(0); +} + +void +cl_serial::new_hw_added(class cl_hw *new_hw) +{ + if (new_hw->cathegory == HW_TIMER && + new_hw->id == 2) + { + there_is_t2= DD_TRUE; + t_mem d= uc->mem(MEM_SFR)->get(T2CON); + t2_baud= d & (bmRCLK | bmTCLK); + } +} + +void +cl_serial::added_to_uc(void) +{ + uc->it_sources->add(new cl_it_src(bmES , SCON, bmTI , 0x0023, false, + "serial transmit", 6)); + uc->it_sources->add(new cl_it_src(bmES , SCON, bmRI , 0x0023, false, + "serial receive", 6)); +} + +t_mem +cl_serial::read(class cl_cell *cell) +{ + if (cell == sbuf) + return(s_in); + else + return(cell->get()); +} + +void +cl_serial::write(class cl_cell *cell, t_mem *val) +{ + if (cell == sbuf) + { + s_out= *val; + s_sending= DD_TRUE; + s_tr_bit = 0; + s_tr_tick= 0; + s_tr_t1= 0; + } + if (cell == scon) + { + _mode= *val >> 6; + _bmREN= *val & bmREN; + _bits= 8; + switch (_mode) + { + case 0: + _bits= 8; + _divby= 12; + break; + case 1: + _bits= 10; + _divby= _bmSMOD?16:32; + break; + case 2: + _bits= 11; + _divby= _bmSMOD?16:32; + break; + case 3: + _bits= 11; + _divby= _bmSMOD?16:32; + break; + } + } + else if (cell == pcon) + { + _bmSMOD= *val & bmSMOD; + /*switch (_mode) + { + case 1: + _divby= _bmSMOD?16:32; + break; + case 2: + _divby= _bmSMOD?16:32; + break; + case 3: + _divby= _bmSMOD?16:32; + break; + }*/ + if (_mode) + _divby= _bmSMOD?16:32; + } +} + +/*void +cl_serial::mem_cell_changed(class cl_mem *mem, t_addr addr) +{ + class cl_mem *sfr= uc->mem(MEM_SFR); + t_mem d; + + d= sbuf->get(); + write(sbuf, &d); + d= pcon->get(); + write(pcon, &d); + d= scon->get(); + write(scon, &d); }*/ +int +cl_serial::serial_bit_cnt(void) +{ + //int divby= 12; + int *tr_src= 0, *rec_src= 0; + + switch (_mode) + { + case 0: + //divby = 12; + tr_src = &s_tr_tick; + rec_src= &s_rec_tick; + break; + case 1: + case 3: + //divby = (/*pcon->get()&bmSMOD*/_bmSMOD)?16:32; + tr_src = &s_tr_t1; + rec_src= &s_rec_t1; + break; + case 2: + //divby = (/*pcon->get()&bmSMOD*/_bmSMOD)?16:32; + tr_src = &s_tr_tick; + rec_src= &s_rec_tick; + break; + } + if (t2_baud) + _divby= 16; + if (s_sending) + { + while (*tr_src >= _divby) + { + (*tr_src)-= _divby; + s_tr_bit++; + //printf("serial bit sent %d\n",uc->ticks->ticks); + } + } + if (s_receiving) + { + while (*rec_src >= _divby) + { + (*rec_src)-= _divby; + s_rec_bit++; + } + } + return(0); +} + +int +cl_serial::tick(int cycles) +{ + char c; + + serial_bit_cnt(/*_mode*/); + if (s_sending && + (s_tr_bit >= _bits)) + { + s_sending= DD_FALSE; + scon->set_bit1(bmTI); + if (serial_out) + { + putc(s_out, serial_out); + fflush(serial_out); + } + s_tr_bit-= _bits; + //printf("serial out %d bit rems %d\n",s_tr_bit,uc->ticks->ticks); + } + if ((/*scn & bmREN*/_bmREN) && + serial_in && + !s_receiving) + { + fd_set set; static struct timeval timeout= {0,0}; + FD_ZERO(&set); + FD_SET(fileno(serial_in), &set); + int i= select(fileno(serial_in)+1, &set, NULL, NULL, &timeout); + if (i > 0 && + FD_ISSET(fileno(serial_in), &set)) + { + s_receiving= DD_TRUE; + s_rec_bit= 0; + s_rec_tick= /*uc51->*/s_rec_t1= 0; + } + } + if (s_receiving && + (s_rec_bit >= _bits)) + { + if (::read(fileno(serial_in), &c, 1) == 1) + { + s_in= c; + sbuf->set(s_in); + received(c); + } + s_receiving= DD_FALSE; + s_rec_bit-= _bits; + } + + int l; + s_tr_tick+= (l= cycles * uc->clock_per_cycle()); + s_rec_tick+= l; + return(0); +} + +void +cl_serial::received(int c) +{ + scon->set_bit1(bmRI); +} + +void +cl_serial::reset(void) +{ + s_tr_t1 = 0; + s_rec_t1 = 0; + s_tr_tick = 0; + s_rec_tick = 0; + s_in = 0; + s_out = 0; + s_sending = DD_FALSE; + s_receiving= DD_FALSE; + s_rec_bit = 0; + s_tr_bit = 0; +} + +void +cl_serial::happen(class cl_hw *where, enum hw_event he, void *params) +{ + if (where->cathegory == HW_TIMER) + { + if (where->id == 1) + { + //printf("serial: timer overflowed %ld\n", uc->ticks->ticks); + s_rec_t1++; + s_tr_t1++; + } + if (where->id == 2 /*&& there_is_t2*/) + { + switch (he) + { + case EV_T2_MODE_CHANGED: + { + if (!t2_baud) + s_rec_t1= s_tr_t1= 0; + t_mem *d= (t_mem *)params; + t2_baud= *d & (bmRCLK | bmTCLK); + break; + } + case EV_OVERFLOW: + //printf("T2 baud ov r%d t%d\n",s_rec_t1,s_tr_t1); + s_rec_t1++; + s_tr_t1++; + break; + default: break; + } + } + } +} + void cl_serial::print_info(class cl_console *con) { @@ -46,26 +409,34 @@ cl_serial::print_info(class cl_console *con) "8 bit UART timer clocked", "9 bit UART fixed clock", "9 bit UART timer clocked" }; - int scon= uc->get_mem(MEM_SFR, SCON); + int sc= scon->get(); con->dd_printf("%s[%d]", id_string, id); - int mode= (scon&(bmSM0|bmSM1))>>6; - con->dd_printf(" %s MultiProc=%s", modes[mode], - (mode&2)?((scon&bmSM2)?"ON":"OFF"):"none"); + int mode= (sc&(bmSM0|bmSM1))>>6; + con->dd_printf(" %s", modes[mode]); + if (mode == 1 || mode == 2) + con->dd_printf(" (timer%d)", (t2_baud)?2:1); + con->dd_printf(" MultiProc=%s", + (mode&2)?((sc&bmSM2)?"ON":"OFF"):"none"); con->dd_printf(" irq=%s", (uc->get_mem(MEM_SFR, IE)&bmES)?"en":"dis"); con->dd_printf(" prio=%d", uc->it_priority(bmPS)); con->dd_printf("\n"); con->dd_printf("Receiver"); - con->dd_printf(" %s", (scon&bmREN)?"ON":"OFF"); - con->dd_printf(" RB8=%c", (scon&bmRB8)?'1':'0'); - con->dd_printf(" irq=%c", (scon&bmRI)?'1':'0'); + con->dd_printf(" %s", (sc&bmREN)?"ON":"OFF"); + con->dd_printf(" RB8=%c", (sc&bmRB8)?'1':'0'); + con->dd_printf(" irq=%c", (sc&bmRI)?'1':'0'); con->dd_printf("\n"); con->dd_printf("Transmitter"); - con->dd_printf(" TB8=%c", (scon&bmTB8)?'1':'0'); - con->dd_printf(" irq=%c", (scon&bmTI)?'1':'0'); + con->dd_printf(" TB8=%c", (sc&bmTB8)?'1':'0'); + con->dd_printf(" irq=%c", (sc&bmTI)?'1':'0'); con->dd_printf("\n"); + /*con->dd_printf("s_rec_t1=%d s_rec_bit=%d s_rec_tick=%d\n", + s_rec_t1, s_rec_bit, s_rec_tick); + con->dd_printf("s_tr_t1=%d s_tr_bit=%d s_tr_tick=%d\n", + s_tr_t1, s_tr_bit, s_tr_tick); + con->dd_printf("divby=%d bits=%d\n", _divby, _bits);*/ } diff --git a/sim/ucsim/s51.src/serialcl.h b/sim/ucsim/s51.src/serialcl.h index a3db04cf..f4a375bd 100644 --- a/sim/ucsim/s51.src/serialcl.h +++ b/sim/ucsim/s51.src/serialcl.h @@ -32,19 +32,52 @@ Software Foundation, 59 Temple Place - Suite 330, Boston, MA #include "pobjcl.h" #include "uccl.h" -#include "newcmdcl.h" +//#include "newcmdcl.h" class cl_serial: public cl_hw { +protected: + bool there_is_t2, t2_baud; + class cl_cell *sbuf, *pcon, *scon; + struct termios saved_attributes_in; // Attributes of serial interface + struct termios saved_attributes_out; + FILE *serial_in; // Serial line input + FILE *serial_out; // Serial line output + uchar s_in; // Serial channel input reg + uchar s_out; // Serial channel output reg + bool s_sending; // Transmitter is working + bool s_receiving; // Receiver is working + int s_rec_bit; // Bit counter of receiver + int s_tr_bit; // Bit counter of transmitter + int s_rec_t1; // T1 overflows for receiving + int s_tr_t1; // T1 overflows for sending + int s_rec_tick; // Machine cycles for receiving + int s_tr_tick; // Machine cycles for sending + uchar _mode; + uchar _bmREN; + uchar _bmSMOD; + uchar _bits; + uchar _divby; public: cl_serial(class cl_uc *auc); - //virtual int init(void); + virtual ~cl_serial(void); + virtual int init(void); - //virtual ulong read(class cl_mem *mem, long addr); - //virtual void write(class cl_mem *mem, long addr, ulong *val); + virtual void new_hw_added(class cl_hw *new_hw); + virtual void added_to_uc(void); + virtual t_mem read(class cl_cell *cell); + virtual void write(class cl_cell *cell, t_mem *val); + + //virtual void mem_cell_changed(class cl_mem *mem, t_addr addr); + + virtual int serial_bit_cnt(void); + virtual void received(int c); + + virtual int tick(int cycles); + virtual void reset(void); + virtual void happen(class cl_hw *where, enum hw_event he, void *params); - //virtual int tick(int cycles); virtual void print_info(class cl_console *con); }; diff --git a/sim/ucsim/s51.src/timer0.cc b/sim/ucsim/s51.src/timer0.cc index 56f326cb..fddf0c82 100644 --- a/sim/ucsim/s51.src/timer0.cc +++ b/sim/ucsim/s51.src/timer0.cc @@ -27,39 +27,369 @@ Software Foundation, 59 Temple Place - Suite 330, Boston, MA #include "timer0cl.h" #include "regs51.h" +#include "types51.h" -cl_timer0::cl_timer0(class cl_uc *auc): - cl_hw(auc, HW_TIMER, 0, "timer0") -{} +cl_timer0::cl_timer0(class cl_uc *auc, int aid, char *aid_string): + cl_hw(auc, HW_TIMER, aid, aid_string) +{ + cell_tmod= cell_tcon= 0; + if (aid == 0) + { + mask_M0 = bmM00; + mask_M1 = bmM10; + mask_C_T = bmC_T0; + mask_GATE= bmGATE0; + mask_TR = bmTR0; + mask_INT = bm_INT0; + mask_TF = bmTF0; + mask_T = bmT0; + addr_tl = TL0; + addr_th = TH0; + } + else if (aid == 1) + { + mask_M0 = bmM01; + mask_M1 = bmM11; + mask_C_T = bmC_T1; + mask_GATE= bmGATE1; + mask_TR = bmTR1; + mask_INT = bm_INT1; + mask_TF = bmTF1; + mask_T = bmT1; + addr_tl = TL1; + addr_th = TH1; + } + else if (aid == 2) + { + addr_tl = TL2; + addr_th = TH2; + mask_T = bmT2; + mask_C_T = bmC_T2; + mask_TR = bmTR2; + mask_TF = bmTF2; + mask_M0= mask_M1= mask_GATE= mask_INT= 0; + } + else {} + make_partner(HW_PCA, 0); + make_partner(HW_PCA, 1); + make_partner(HW_PCA, 2); + make_partner(HW_PCA, 3); + make_partner(HW_PCA, 4); +} -/*int +int cl_timer0::init(void) { + class cl_mem *sfr= uc->mem(MEM_SFR); + + if (sfr) + { + //t_mem d; + if (id == 0 || id == 1) + { + //cell_tmod= sfr->register_hw(TMOD, this, 0); + register_cell(sfr, TMOD, &cell_tmod, wtd_restore_write); + //d= cell_tmod->get(); write(cell_tmod, &d); + //cell_tcon= sfr->register_hw(TCON, this, 0); + register_cell(sfr, TCON, &cell_tcon, wtd_restore_write); + //d= cell_tcon->get(); write(cell_tcon, &d); + INT= sfr->read(P3) & mask_INT; + } + else if (id == 2) + { + cell_tmod= 0; + //cell_tcon= sfr->register_hw(T2CON, this, 0); + register_cell(sfr, T2CON, &cell_tcon, wtd_restore_write); + //d= cell_tcon->get(); write(cell_tcon, &d); + } + //cell_tl= sfr->get_cell(addr_tl); + //cell_th= sfr->get_cell(addr_th); + use_cell(sfr, addr_tl, &cell_tl, wtd_restore); + use_cell(sfr, addr_th, &cell_th, wtd_restore); + } return(0); +} + +void +cl_timer0::added_to_uc(void) +{ + if (id == 0) + uc->it_sources->add(new cl_it_src(bmET0, TCON, bmTF0, 0x000b, true, + "timer #0", 2)); + else if (id == 1) + uc->it_sources->add(new cl_it_src(bmET1, TCON, bmTF1, 0x001b, true, + "timer #1", 4)); +} + +/*t_mem +cl_timer0::read(class cl_cell *cell) +{ + return(cell->get()); }*/ +void +cl_timer0::write(class cl_cell *cell, t_mem *val) +{ + if (cell == cell_tmod) + { + t_mem md= *val & (mask_M0|mask_M1); + if (md == mask_M0) + mode= 1; + else if (md == mask_M1) + mode= 2; + else if (md == (mask_M0|mask_M1)) + mode= 3; + else + mode= 0; + GATE= *val & mask_GATE; + C_T = *val & mask_C_T; + T_edge= 0; + } + else if (cell == cell_tcon) + { + TR= *val & mask_TR; + T_edge= 0; + } +} + +/*void +cl_timer0::mem_cell_changed(class cl_mem *mem, t_addr addr) +{ + //class cl_mem *sfr= uc->mem(MEM_SFR); + //t_mem d; + + cl_hw::mem_cell_changed(mem, addr); + + //d= cell_tmod->get(); + //write(cell_tmod, &d); + //d= cell_tcon->get(); + //write(cell_tcon, &d); + //if (addr == addr_tl) cell_tl= sfr->get_cell(addr_tl); + //if (addr == addr_th) cell_th= sfr->get_cell(addr_th); +}*/ + +int +cl_timer0::tick(int cycles) +{ + switch (mode) + { + case 0: do_mode0(cycles); break; + case 1: do_mode1(cycles); break; + case 2: do_mode2(cycles); break; + case 3: do_mode3(cycles); break; + } + return(resGO); +} + +int +cl_timer0::do_mode0(int cycles) +{ + if (!TR) + return(0); + + //t_mem p3= uc->mem(MEM_SFR)->get(P3); + if (GATE) + { + if ((/*p3 & mask_*/INT) == 0) + return(0); + } + + if (C_T) + { + /*cycles= 0; + if ((uc51->prev_p3 & mask_T) && + !(p3 & uc51->port_pins[3] & mask_T)) + cycles= 1;*/ + cycles= T_edge; + T_edge= 0; + } + while (cycles--) + { + // mod 0, TH= 8 bit t/c, TL= 5 bit precounter + t_mem tl= cell_tl->add(1); + if ((tl & 0x1f) == 0) + { + cell_tl->set(0); + if (!cell_th->add(1)) + { + cell_tcon->set_bit1(mask_TF); + overflow(); + } + } + } + + return(0); +} + +int +cl_timer0::do_mode1(int cycles) +{ + if (!TR) + return(0); + + //t_mem p3= uc->mem(MEM_SFR)->get(P3); + if (GATE) + { + if ((/*p3 & mask_*/INT) == 0) + return(0); + } + + if (C_T) + { + /*cycles= 0; + if ((uc51->prev_p3 & mask_T) && + !(p3 & uc51->port_pins[3] & mask_T)) + cycles= 1;*/ + cycles= T_edge; + T_edge= 0; + } + + while (cycles--) + { + // mod 1 TH+TL= 16 bit t/c + if (!cell_tl->add(1)) + { + if (!cell_th->add(1)) + { + cell_tcon->set_bit1(mask_TF); + overflow(); + } + } + } + + return(0); +} + +int +cl_timer0::do_mode2(int cycles) +{ + if (!TR) + return(0); + + //t_mem p3= uc->mem(MEM_SFR)->get(P3); + if (GATE) + { + if ((/*p3 & mask_*/INT) == 0) + return(0); + } + + if (C_T) + { + /*cycles= 0; + if ((uc51->prev_p3 & mask_T) && + !(p3 & uc51->port_pins[3] & mask_T)) + cycles= 1;*/ + cycles= T_edge; + T_edge= 0; + } + + //unsigned long startt= uc->ticks->ticks-(cycles*12);int i=0; + while (cycles--) + { + // mod 2 TL= 8 bit t/c auto reload from TH + if (!cell_tl->add(1)) + { + cell_tl->set(cell_th->get()); + cell_tcon->set_bit1(mask_TF); + //printf("timer%d overflow %d (%d) %d\n",id,uc->ticks->ticks,i,startt+(i*12)); + overflow(); + } + //i++; + } + return(0); +} + +int +cl_timer0::do_mode3(int cycles) +{ + int cyc= cycles; + //t_mem p3= uc->mem(MEM_SFR)->get(P3); + + if (!TR) + goto do_th; + + if (GATE) + { + if ((/*p3 & mask_*/INT) == 0) + goto do_th; + } + + if (C_T) + { + /*cycles= 0; + if ((uc51->prev_p3 & mask_T) && + !(p3 & uc51->port_pins[3] & mask_T)) + cycles= 1;*/ + cycles= T_edge; + T_edge= 0; + } + + while (cycles--) + { + if (!cell_tl->add(1)) + { + cell_tcon->set_bit1(mask_TF); + overflow(); + } + } + + do_th: + if ((cell_tcon->get() & bmTR1) != 0) + while (cyc--) + { + if (!cell_th->add(1)) + cell_tcon->set_bit1(bmTF1); + } + return(0); +} + +void +cl_timer0::overflow(void) +{ + inform_partners(EV_OVERFLOW, 0); +} + +void +cl_timer0::happen(class cl_hw *where, enum hw_event he, void *params) +{ + struct ev_port_changed *ep= (struct ev_port_changed *)params; + + if (where->cathegory == HW_PORT && + he == EV_PORT_CHANGED && + ep->id == 3) + { + t_mem p3n= ep->new_pins & ep->new_value; + t_mem p3o= ep->pins & ep->prev_value; + if ((p3n & mask_T) && + !(p3o & mask_T)) + T_edge++; + INT= p3n & mask_INT; + //printf("timer%d p%dchanged (%02x,%02x->%02x,%02x) INT=%d(%02x) edge=%d(%02x)\n",id,where->id,ep->prev_value,ep->pins,ep->new_value,ep->new_pins,INT,mask_INT,T_edge,mask_T); + } +} + void cl_timer0::print_info(class cl_console *con) { char *modes[]= { "13 bit", "16 bit", "8 bit autoreload", "2x8 bit" }; - int tmod= uc->get_mem(MEM_SFR, TMOD); + //t_mem tmod= cell_tmod->get(); int on; con->dd_printf("%s[%d] 0x%04x", id_string, id, - 256*uc->get_mem(MEM_SFR, TH0)+uc->get_mem(MEM_SFR, TL0)); - int mode= tmod & (bmM00|bmM10); + 256*cell_th->get()+cell_tl->get()); + //int mode= tmod & (bmM00|bmM10); con->dd_printf(" %s", modes[mode]); - con->dd_printf(" %s", (tmod&bmC_T0)?"counter":"timer"); - if (tmod&bmGATE0) + con->dd_printf(" %s", (/*tmod&bm*/C_T/*0*/)?"counter":"timer"); + if (/*tmod&bm*/GATE/*0*/) { con->dd_printf(" gated"); - on= uc->get_mem(MEM_SFR, P3) & uc->port_pins[3] & bm_INT0; + on= /*uc->get_mem(MEM_SFR, P3) & uc->port_pins[3] & mask_*/INT/*bm_INT0*/; } else - on= uc->get_mem(MEM_SFR, TCON) & bmTR0; + on= TR/*cell_tcon->get(TCON) & mask_TR*/; con->dd_printf(" %s", on?"ON":"OFF"); - con->dd_printf(" irq=%c", (uc->get_mem(MEM_SFR, TCON)&bmTF0)?'1':'0'); + con->dd_printf(" irq=%c", (cell_tcon->get()&mask_TF)?'1':'0'); con->dd_printf(" %s", (uc->get_mem(MEM_SFR, IE)&bmET0)?"en":"dis"); con->dd_printf(" prio=%d", uc->it_priority(bmPT0)); con->dd_printf("\n"); diff --git a/sim/ucsim/s51.src/timer0cl.h b/sim/ucsim/s51.src/timer0cl.h index 648f9239..950041fc 100644 --- a/sim/ucsim/s51.src/timer0cl.h +++ b/sim/ucsim/s51.src/timer0cl.h @@ -34,17 +34,36 @@ Software Foundation, 59 Temple Place - Suite 330, Boston, MA #include "newcmdcl.h" +#include "uc51cl.h" + class cl_timer0: public cl_hw { +protected: + class cl_cell *cell_tmod, *cell_tcon, *cell_tl, *cell_th; + t_mem mask_M0, mask_M1, mask_C_T, mask_GATE, mask_TR, mask_INT, + mask_T, mask_TF; + t_addr addr_tl, addr_th; + int mode, GATE, C_T, TR, INT, T_edge; public: - cl_timer0(class cl_uc *auc); - //virtual int init(void); + cl_timer0(class cl_uc *auc, int aid, char *aid_string); + virtual int init(void); + + virtual void added_to_uc(void); + + //virtual t_mem read(class cl_cell *cell); + virtual void write(class cl_cell *cell, t_mem *val); + + //virtual void mem_cell_changed(class cl_mem *mem, t_addr addr); - //virtual ulong read(class cl_mem *mem, long addr); - //virtual void write(class cl_mem *mem, long addr, ulong *val); + virtual int tick(int cycles); + virtual int do_mode0(int cycles); + virtual int do_mode1(int cycles); + virtual int do_mode2(int cycles); + virtual int do_mode3(int cycles); + virtual void overflow(void); + virtual void happen(class cl_hw *where, enum hw_event he, void *params); - //virtual int tick(int cycles); virtual void print_info(class cl_console *con); }; diff --git a/sim/ucsim/s51.src/timer1.cc b/sim/ucsim/s51.src/timer1.cc index e930b3e6..ccb0abd3 100644 --- a/sim/ucsim/s51.src/timer1.cc +++ b/sim/ucsim/s51.src/timer1.cc @@ -1,5 +1,5 @@ /* - * Simulator of microcontrollers (timer1.cc) + * Simulator of microcontrollers (s51.src/timer1.cc) * * Copyright (C) 1999,99 Drotos Daniel, Talker Bt. * @@ -29,9 +29,11 @@ Software Foundation, 59 Temple Place - Suite 330, Boston, MA #include "regs51.h" -cl_timer1::cl_timer1(class cl_uc *auc): - cl_hw(auc, HW_TIMER, 1, "timer1") -{} +cl_timer1::cl_timer1(class cl_uc *auc, int aid, char *aid_string): + cl_timer0(auc, aid, aid_string) +{ + make_partner(HW_UART, 0); +} /*int cl_timer1::init(void) @@ -39,31 +41,50 @@ cl_timer1::init(void) return(0); }*/ +/*void +cl_timer1::added(class cl_hw *new_hw) +{ + if (new_hw->cathegory == HW_UART) + hws_to_inform->add(new_hw); +}*/ + +int +cl_timer1::do_mode3(int cycles) +{ + return(0); +} + +/*void +cl_timer1::overflow(void) +{ + inform_partners(EV_OVERFLOW, 0); +}*/ + void cl_timer1::print_info(class cl_console *con) { char *modes[]= { "13 bit", "16 bit", "8 bit autoreload", "stop" }; - int tmod= uc->get_mem(MEM_SFR, TMOD); + //int tmod= cell_tmod->get(); int on; con->dd_printf("%s[%d] 0x%04x", id_string, id, - 256*uc->get_mem(MEM_SFR, TH1)+uc->get_mem(MEM_SFR, TL1)); - int mode= (tmod & (bmM11|bmM01)) >> 4; + 256*cell_th->get()+cell_tl->get()); + //int mode= (tmod & (bmM11|bmM01)) >> 4; con->dd_printf(" %s", modes[mode]); - con->dd_printf(" %s", (tmod&bmC_T1)?"counter":"timer"); - if (tmod&bmGATE1) + con->dd_printf(" %s", (/*tmod&bm*/C_T/*1*/)?"counter":"timer"); + if (/*tmod&bm*/GATE/*1*/) { con->dd_printf(" gated"); - on= uc->get_mem(MEM_SFR, P3) & uc->port_pins[3] & bm_INT0; + on= /*uc->get_mem(MEM_SFR, P3) & uc->port_pins[3] & mask_*/INT/*bm_INT1*/; } else - on= uc->get_mem(MEM_SFR, TCON) & bmTR1; + on= cell_tcon->get() & mask_TR/*bmTR1*/; con->dd_printf(" %s", on?"ON":"OFF"); - con->dd_printf(" irq=%c", (uc->get_mem(MEM_SFR, TCON)&bmTF1)?'1':'0'); + con->dd_printf(" irq=%c", (cell_tcon->get()&mask_TF)?'1':'0'); con->dd_printf(" %s", (uc->get_mem(MEM_SFR, IE)&bmET1)?"en":"dis"); con->dd_printf(" prio=%d", uc->it_priority(bmPT1)); con->dd_printf("\n"); } -/* End of timer1.cc */ +/* End of s51.src/timer1.cc */ diff --git a/sim/ucsim/s51.src/timer1cl.h b/sim/ucsim/s51.src/timer1cl.h index cd24a3b2..d696b45c 100644 --- a/sim/ucsim/s51.src/timer1cl.h +++ b/sim/ucsim/s51.src/timer1cl.h @@ -34,17 +34,22 @@ Software Foundation, 59 Temple Place - Suite 330, Boston, MA #include "newcmdcl.h" +#include "timer0cl.h" -class cl_timer1: public cl_hw +class cl_timer1: public cl_timer0 { public: - cl_timer1(class cl_uc *auc); + cl_timer1(class cl_uc *auc, int aid, char *aid_string); //virtual int init(void); + //virtual void new_hw_added(class cl_hw *new_hw); //virtual ulong read(class cl_mem *mem, long addr); //virtual void write(class cl_mem *mem, long addr, ulong *val); //virtual int tick(int cycles); + virtual int do_mode3(int cycles); + //virtual void overflow(void); + virtual void print_info(class cl_console *con); }; diff --git a/sim/ucsim/s51.src/timer2.cc b/sim/ucsim/s51.src/timer2.cc index 9c7f59dc..ea2ab95f 100644 --- a/sim/ucsim/s51.src/timer2.cc +++ b/sim/ucsim/s51.src/timer2.cc @@ -27,40 +27,379 @@ Software Foundation, 59 Temple Place - Suite 330, Boston, MA #include "timer2cl.h" #include "regs51.h" +#include "types51.h" -cl_timer2::cl_timer2(class cl_uc *auc): - cl_hw(auc, HW_TIMER, 2, "timer2") -{} +cl_timer2::cl_timer2(class cl_uc *auc, int aid, char *aid_string, + int afeatures): + cl_timer0(auc, /*2*/aid, /*"timer2"*/aid_string) +{ + features= afeatures; + exf2it= 0; + mask_RCLK= bmRCLK; + mask_TCLK= bmTCLK; + mask_CP_RL2= bmCP_RL2; + make_partner(HW_UART, 0); + if (features & (t2_down|t2_clock_out)) + register_cell(uc->mem(MEM_SFR), T2MOD, &cell_t2mod, wtd_restore_write); +} -/*int +int cl_timer2::init(void) { + cl_timer0::init(); + //cell_rcap2l= uc->mem(MEM_SFR)->get_cell(RCAP2L); + //cell_rcap2h= uc->mem(MEM_SFR)->get_cell(RCAP2H); + use_cell(uc->mem(MEM_SFR), RCAP2L, &cell_rcap2l, wtd_restore); + use_cell(uc->mem(MEM_SFR), RCAP2H, &cell_rcap2h, wtd_restore); + bit_t2ex= uc->read_mem(MEM_SFR, P1) & bmT2EX; return(0); +} + +void +cl_timer2::added_to_uc(void) +{ + uc->it_sources->add(new cl_it_src(bmET2, T2CON, bmTF2, 0x002b, false, + "timer #2 TF2", 7)); + exf2it= new cl_it_src(bmET2, T2CON, bmEXF2, 0x002b, false, + "timer #2 EXF2", 7); + uc->it_sources->add(exf2it); +} + +/*void +cl_timer2::mem_cell_changed(class cl_mem *mem, t_addr addr) +{ + class cl_mem *sfr= uc->mem(MEM_SFR); + class cl_cell *c= 0; + + if (mem && sfr && mem == sfr) + { + switch (addr) + { + case T2CON: + c= cell_tcon= sfr->get_cell(T2CON); + break; + } + if (c) + { + t_mem d= c->get(); + write(c, &d); + } + if (addr == addr_tl) + cell_tl= sfr->get_cell(addr_tl); + if (addr == addr_th) + cell_th= sfr->get_cell(addr_th); + cell_rcap2l= sfr->get_cell(RCAP2L); + cell_rcap2h= sfr->get_cell(RCAP2H); + } +}*/ + +/*void +cl_timer2::added(class cl_hw *new_hw) +{ + if (new_hw->cathegory == HW_UART) + hws_to_inform->add(new_hw); }*/ +void +cl_timer2::write(class cl_cell *cell, t_mem *val) +{ + int oldmode= mode; + bool oldtr= TR; + + if (exf2it) + exf2it->activate(); + if (cell == cell_tcon) + { + C_T = *val & mask_C_T; + TR = *val & mask_TR; + RCLK= *val & mask_RCLK; + TCLK= *val & mask_TCLK; + CP_RL2= *val & mask_CP_RL2; + EXEN2 = *val & bmEXEN2; + if (!(RCLK || TCLK) && + !CP_RL2) + mode= T2MODE_RELOAD; + else if (!(RCLK || TCLK) && + CP_RL2) + mode= T2MODE_CAPTURE; + else if (RCLK || TCLK) + mode= T2MODE_BAUDRATE; + else + mode= T2MODE_OFF; + if (mode != oldmode) + inform_partners(EV_T2_MODE_CHANGED, val); + } + else if (cell == cell_t2mod) + { + bit_dcen= (*val & bmDCEN) != 0; + bit_t2oe= (*val & bmT2OE) != 0; + if ((features & t2_down) && + bit_dcen && + mode == T2MODE_RELOAD) + { + mode= T2MODE_DOWN; + if (exf2it) + exf2it->deactivate(); + } + if ((features & t2_clock_out) && + bit_t2oe) + mode= T2MODE_CLKOUT; + } + if (mode != oldmode || + TR && !oldtr || + !TR && oldtr) + T_edge= t2ex_edge= 0; +} + +int +cl_timer2::tick(int cycles) +{ + switch (mode) + { + case T2MODE_BAUDRATE: + do_t2_baud(cycles); + break; + case T2MODE_CAPTURE: + do_t2_capture(cycles); + break; + case T2MODE_RELOAD: + do_t2_reload(cycles); + break; + case T2MODE_DOWN: + do_t2_down(cycles); + break; + case T2MODE_CLKOUT: + do_t2_clock_out(cycles); + break; + default: break; + } + + return(resGO); +} + +/* + * Baud rate generator mode of Timer #2 + */ + +int +cl_timer2::do_t2_baud(int cycles) +{ + if (EXEN2 && t2ex_edge) + { + cell_tcon->set_bit1(bmEXF2); + t2ex_edge= 0; + } + + if (!TR) + return(0); + + if (C_T) + (cycles= T_edge), T_edge= 0; + else + cycles*= 6; + + while (cycles--) + { + if (!cell_tl->add(1)) + if (!cell_th->add(1)) + { + cell_th->set(cell_rcap2h->get()); + cell_tl->set(cell_rcap2l->get()); + inform_partners(EV_OVERFLOW, 0); + } + } + return(resGO); +} + + +/* + * Capture function of Timer #2 + */ + +void +cl_timer2::do_t2_capture(int cycles) +{ + if (EXEN2 && t2ex_edge) + { + cell_tcon->set_bit1(bmEXF2); + cell_rcap2h->set(cell_th->get()); + cell_rcap2l->set(cell_tl->get()); + t2ex_edge= 0; + } + + if (!TR) + return; + + if (C_T) + (cycles= T_edge), T_edge= 0; + + if (!cell_tl->add(1)) + { + if (!cell_th->add(1)) + cell_tcon->set_bit1(bmTF2); + } +} + + +/* + * Auto Reload mode of Timer #2, counting UP + */ + +void +cl_timer2::do_t2_reload(int cycles) +{ + if (EXEN2 && t2ex_edge) + { + cell_tcon->set_bit1(bmEXF2); + cell_th->set(cell_rcap2h->get()); + cell_tl->set(cell_rcap2l->get()); + t2ex_edge= 0; + } + + if (!TR) + return; + + if (C_T) + (cycles= T_edge), T_edge= 0; + + if (!cell_tl->add(1)) + { + if (!cell_th->add(1)) + { + cell_tcon->set_bit1(mask_TF); + cell_th->set(cell_rcap2h->get()); + cell_tl->set(cell_rcap2l->get()); + } + } +} + +void +cl_timer2::do_t2_down(int cycles) +{ + bool toggle= DD_FALSE; + + if (!TR) + return; + + if (C_T) + (cycles= T_edge), T_edge= 0; + + if (bit_t2ex) + // UP + while (cycles--) + if (!cell_tl->add(1)) + { + if (!cell_th->add(1)) + { + cell_tcon->set_bit1(mask_TF); + cell_th->set(cell_rcap2h->get()); + cell_tl->set(cell_rcap2l->get()); + toggle= DD_TRUE; + } + } + else + // DOWN + while (cycles--) + { + t_mem l, h; + if ((l= cell_tl->add(-1)) == 0xff) + h= cell_th->add(-1); + else + h= cell_th->get(); + if ((TYPE_UWORD)(h*256+l) < + (TYPE_UWORD)(cell_rcap2h->get()*256+cell_rcap2l->get())) + { + cell_tcon->set_bit1(mask_TF); + cell_th->set(0xff); + cell_tl->set(0xff); + toggle= DD_TRUE; + } + } + if (toggle) + { + class cl_cell *p1= uc->mem(MEM_SFR)->get_cell(P1); + p1->set(p1->get() ^ bmEXF2); + } +} + +void +cl_timer2::do_t2_clock_out(int cycles) +{ + if (EXEN2 && t2ex_edge) + { + cell_tcon->set_bit1(bmEXF2); + t2ex_edge= 0; + } + + if (!TR) + return; + + if (C_T) + (cycles= T_edge), T_edge= 0; + else + cycles*= 6; + + while (cycles--) + { + if (!cell_tl->add(1)) + if (!cell_th->add(1)) + { + cell_th->set(cell_rcap2h->get()); + cell_tl->set(cell_rcap2l->get()); + inform_partners(EV_OVERFLOW, 0); + if (!C_T) + { + // toggle T2 on P1 + class cl_cell *p1= uc->mem(MEM_SFR)->get_cell(P1); + p1->set(p1->get() ^ bmT2); + } + } + } +} + +void +cl_timer2::happen(class cl_hw *where, enum hw_event he, void *params) +{ + struct ev_port_changed *ep= (struct ev_port_changed *)params; + + if (where->cathegory == HW_PORT && + he == EV_PORT_CHANGED && + ep->id == 1) + { + t_mem p1n= ep->new_pins & ep->new_value; + t_mem p1o= ep->pins & ep->prev_value; + if (!(p1n & mask_T) && + (p1o & mask_T)) + T_edge++; + if (!(p1n & bmT2EX) && + (p1o & bmT2EX)) + t2ex_edge++; + bit_t2ex= p1n & bmT2EX; + } +} + void cl_timer2::print_info(class cl_console *con) { - int t2con= uc->get_mem(MEM_SFR, T2CON); + int t2con= cell_tcon->get(); con->dd_printf("%s[%d] 0x%04x", id_string, id, - 256*uc->get_mem(MEM_SFR, TH2)+uc->get_mem(MEM_SFR, TL2)); - if (t2con & (bmRCLK|bmTCLK)) + 256*cell_th->get()+cell_tl->get()); + if (RCLK || TCLK) { con->dd_printf(" baud"); - if (t2con & bmRCLK) + if (RCLK) con->dd_printf(" RCLK"); - if (t2con & bmTCLK) + if (TCLK) con->dd_printf(" TCLK"); } else - con->dd_printf(" %s", (t2con&bmCP_RL2)?"capture":"reload"); + con->dd_printf(" %s", (CP_RL2)?"capture":"reload"); con->dd_printf(" 0x%04x", - 256*uc->get_mem(MEM_SFR, RCAP2H)+ - uc->get_mem(MEM_SFR, RCAP2L)); - con->dd_printf(" %s", (t2con&bmC_T2)?"counter":"timer"); - con->dd_printf(" %s", (t2con&bmTR2)?"ON":"OFF"); + 256*cell_rcap2h->get()+cell_rcap2l->get()); + con->dd_printf(" %s", (C_T)?"counter":"timer"); + con->dd_printf(" %s", (TR)?"ON":"OFF"); con->dd_printf(" irq=%c", (t2con&bmTF2)?'1':'0'); con->dd_printf(" %s", (uc->get_mem(MEM_SFR, IE)&bmET2)?"en":"dis"); con->dd_printf(" prio=%d", uc->it_priority(bmPT2)); diff --git a/sim/ucsim/s51.src/timer2cl.h b/sim/ucsim/s51.src/timer2cl.h index cf3f3b01..c5cb0cdb 100644 --- a/sim/ucsim/s51.src/timer2cl.h +++ b/sim/ucsim/s51.src/timer2cl.h @@ -34,17 +34,53 @@ Software Foundation, 59 Temple Place - Suite 330, Boston, MA #include "newcmdcl.h" +#include "timer0cl.h" -class cl_timer2: public cl_hw + +#define T2MODE_RELOAD 0 +#define T2MODE_CAPTURE 1 +#define T2MODE_BAUDRATE 2 +#define T2MODE_OFF 3 +#define T2MODE_DOWN 4 +#define T2MODE_CLKOUT 5 + +enum t2_features { + t2_default = 0x01, + t2_down = 0x02, + t2_clock_out = 0x04 +}; + + +class cl_timer2: public cl_timer0 { +protected: + int features; + class cl_it_src *exf2it; + t_mem mask_RCLK, mask_TCLK, mask_CP_RL2; + t_mem RCLK, TCLK, CP_RL2, EXEN2; + long t2ex_edge; + class cl_cell *cell_rcap2l, *cell_rcap2h, *cell_t2mod; + bool bit_dcen, bit_t2oe, bit_t2ex; public: - cl_timer2(class cl_uc *auc); - //virtual int init(void); + cl_timer2(class cl_uc *auc, int aid, char *aid_string, int afeautres); + virtual int init(void); + + virtual void added_to_uc(void); + //virtual void new_hw_added(class cl_hw *new_hw); //virtual ulong read(class cl_mem *mem, long addr); - //virtual void write(class cl_mem *mem, long addr, ulong *val); + virtual void write(class cl_cell *cell, t_mem *val); + + //virtual void mem_cell_changed(class cl_mem *mem, t_addr addr); - //virtual int tick(int cycles); + virtual int tick(int cycles); + virtual int do_t2_baud(int cycles); + virtual void do_t2_capture(int cycles); + virtual void do_t2_reload(int cycles); + virtual void do_t2_down(int cycles); + virtual void do_t2_clock_out(int cycles); + virtual void happen(class cl_hw *where, enum hw_event he, void *params); + virtual void print_info(class cl_console *con); }; diff --git a/sim/ucsim/s51.src/types51.h b/sim/ucsim/s51.src/types51.h new file mode 100644 index 00000000..964dacc6 --- /dev/null +++ b/sim/ucsim/s51.src/types51.h @@ -0,0 +1,59 @@ +/* + * Simulator of microcontrollers (types51.h) + * + * Copyright (C) 2002,02 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 TYPES51_HEADER +#define TYPES51_HEADER + +#include "ddconfig.h" + + +#define SET_BIT(newbit, reg, bitmask) \ +if (newbit) \ + (mem(MEM_SFR))->set_bit1((reg), (bitmask)); \ +else \ + (mem(MEM_SFR))->set_bit0((reg), (bitmask)); +#define SFR_SET_BIT(newbit, reg, bitmask) \ +if (newbit) \ + sfr->set_bit1((reg), (bitmask)); \ +else \ + sfr->set_bit0((reg), (bitmask)); +#define GET_C (get_mem(MEM_SFR, PSW) & bmCY) +#define SFR_GET_C (sfr->get(PSW) & bmCY) +#define SET_C(newC) SET_BIT((newC), PSW, bmCY) +#define SFR_SET_C(newC) SFR_SET_BIT((newC), PSW, bmCY) + + +/* Event parameters */ +struct ev_port_changed { + int id; + t_addr addr; + t_mem prev_value, new_value, pins, new_pins; +}; + +#endif + +/* End of s51.src/types51.h */ diff --git a/sim/ucsim/s51.src/uc390.cc b/sim/ucsim/s51.src/uc390.cc index fdf11ef8..1fc5e2cb 100644 --- a/sim/ucsim/s51.src/uc390.cc +++ b/sim/ucsim/s51.src/uc390.cc @@ -26,18 +26,15 @@ Software Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ /*@1@*/ - // Bernhard's ToDo list: // - implement math accelerator // - consider ACON bits -// - proc_write_sp (*aof_SP) / resSTACK_OV / event_at: insert this at the appropriate places // - buy some memory to run s51 with 2*4 Meg ROM/XRAM // strcpy (mem(MEM_ROM) ->addr_format, "0x%06x"); // strcpy (mem(MEM_XRAM)->addr_format, "0x%06x"); - #include "ddconfig.h" #include @@ -48,6 +45,12 @@ Software Foundation, 59 Temple Place - Suite 330, Boston, MA #include "glob.h" #include "uc390cl.h" #include "regs51.h" +#include "uc390hwcl.h" + + +#include "uc52cl.h" +#include "regs51.h" +#include "timer2cl.h" /* * Names of instructions @@ -325,6 +328,17 @@ t_uc390::t_uc390 (int Itype, int Itech, class cl_sim *asim): printf ("24-bit flat mode, warning: lots of sfr-functions not implemented!\n> "); flat24_flag = 1; } + // todo: add interrupt sources +} + +void +t_uc390::mk_hw_elements (void) +{ + class cl_hw *h; + + t_uc52::mk_hw_elements(); + hws->add (h = new cl_uc390_hw (this)); + h->init(); } /* @@ -361,8 +375,13 @@ t_uc390::clear_sfr(void) sfr->set(0xd2, 0x2f); /* MCNT1 */ sfr->set(0xe3, 0x09); /* C1C */ - prev_p1 = port_pins[1] & sfr->get(P1); - prev_p3 = port_pins[3] & sfr->get(P3); + sfr->/*set*/write(P0, 0xff); + sfr->/*set*/write(P1, 0xff); + sfr->/*set*/write(P2, 0xff); + sfr->/*set*/write(P3, 0xff); + sfr->/*set*/write(SP, 7); + prev_p1 = sfr->/*get*/read(P1); + prev_p3 = sfr->/*get*/read(P3); } t_addr @@ -387,8 +406,8 @@ t_uc390::get_mem_size (enum mem_class type) return 0; } -ulong -t_uc390::read_mem(enum mem_class type, t_mem addr) +t_mem +t_uc390::read_mem(enum mem_class type, t_addr addr) { if (type == MEM_XRAM && @@ -401,7 +420,7 @@ t_uc390::read_mem(enum mem_class type, t_mem addr) return t_uc51::read_mem (type, addr); /* 24 bit */ } -ulong +t_mem t_uc390::get_mem (enum mem_class type, t_addr addr) { if (type == MEM_XRAM && @@ -444,63 +463,53 @@ t_uc390::set_mem (enum mem_class type, t_addr addr, t_mem val) *____________________________________________________________________________ */ -int -t_uc390::push_byte (uchar uc) +void +t_uc390::push_byte (t_mem uc) { - int res; + t_addr sp; - sfr->add (SP, 1); + sp = sfr->wadd (SP, 1); if (sfr->get (ACON) & 0x04) /* SA: 10 bit stack */ { - uint sp10; - - if (get_mem (MEM_SFR, SP) == 0x00) /* overflow SP */ - sfr->add (ESP, 1); - sp10 = (get_mem (MEM_SFR, ESP) & 0x3) * 256 + - get_mem (MEM_SFR, SP); - write_mem (MEM_IXRAM, sp10, uc); - res = 0; + if (sp == 0) /* overflow SP */ + sfr->wadd (ESP, 1); + sp += (sfr->read (ESP) & 0x3) * 256; + write_mem (MEM_IXRAM, sp, uc); // fixme } else { - uchar *sp; + class cl_cell *stck; - sp = get_indirect (sfr->get (SP), &res); - if (res != resGO) - res = resSTACK_OV; - *sp = uc; + stck = iram->get_cell (sp); + stck->write (uc); } - return res; } -uchar -t_uc390::pop_byte (int *Pres) +t_mem +t_uc390::pop_byte (void) { - uchar uc; + t_mem temp; + t_addr sp; if (sfr->get (ACON) & 0x04) /* SA: 10 bit stack */ { - uint sp10; - - sp10 = (get_mem (MEM_SFR, ESP) & 0x3) * 256 + - get_mem (MEM_SFR, SP); - sfr->add (SP, -1); - if (get_mem (MEM_SFR, SP) == 0xff) /* underflow SP */ - sfr->add (ESP, -1); - uc = get_mem (MEM_IXRAM, sp10); - *Pres = 0; + sp = sfr->read (SP); + sp += (sfr->read (ESP) & 0x3) * 256; + temp = read_mem (MEM_IXRAM, sp); // fixme + sp = sfr->wadd (SP, -1); + if (sp == 0xff) /* underflow SP */ + sfr->wadd (ESP, -1); + return temp; } else { - uchar *sp; + class cl_cell *stck; - sp = get_indirect (get_mem (MEM_SFR, SP), Pres); - if (*Pres != resGO) - *Pres = resSTACK_OV; - sfr->add (SP, -1); - uc = *sp; + stck = iram->get_cell (sfr->get (SP)); + temp = stck->read(); + sp = sfr->wadd (SP, -1); + return temp; } - return uc; } /* @@ -517,7 +526,7 @@ t_uc390::inst_inc_dptr (uchar code) uchar pl, ph, px, dps; dps = sfr->get (DPS); - if (dps & 1) + if (dps & 0x01) { pl = DPL1; ph = DPH1; @@ -530,21 +539,21 @@ t_uc390::inst_inc_dptr (uchar code) px = DPX; } - dptr = sfr->get (ph) * 256 + sfr->get (pl); + dptr = sfr->read (ph) * 256 + sfr->read (pl); if (sfr->get (ACON) & 0x02) /* AM1 set: 24-bit flat? */ - dptr += sfr->get (px) *256*256; + dptr += sfr->read (px) *256*256; if (dps & 0x80) /* decr set */ dptr--; else dptr++; if (sfr->get (ACON) & 0x02) /* AM1 set: 24-bit flat? */ - sfr->set (px, (dptr >> 16) & 0xff); - sfr->set (event_at.ws = ph, (dptr >> 8) & 0xff); - sfr->set (pl, dptr & 0xff); + sfr->write (px, (dptr >> 16) & 0xff); + sfr->write (ph, (dptr >> 8) & 0xff); + sfr->write (pl, dptr & 0xff); if (dps & 0x20) /* auto-switch dptr */ - sfr->set (DPS, dps ^ 1); /* toggle dual-dptr switch */ + sfr->write (DPS, dps ^ 1); /* toggle dual-dptr switch */ tick (1); return resGO; } @@ -561,7 +570,7 @@ t_uc390::inst_jmp_$a_dptr (uchar code) uchar pl, ph, px, dps; dps = sfr->get (DPS); - if (dps & 1) + if (dps & 0x01) { pl = DPL1; ph = DPH1; @@ -574,11 +583,10 @@ t_uc390::inst_jmp_$a_dptr (uchar code) px = DPX; } - PC = (sfr->get (ph) * 256 + sfr->get (pl) + - read_mem (MEM_SFR, ACC)) & - (EROM_SIZE - 1); + PC = (sfr->read (ph) * 256 + sfr->read (pl) + acc->read()) & + (EROM_SIZE - 1); if (sfr->get (ACON) & 0x02) /* AM1 set: 24-bit flat? */ - PC += sfr->get (px) * 256*256; + PC += sfr->read (px) * 256*256; tick (1); return resGO; @@ -596,7 +604,7 @@ t_uc390::inst_mov_dptr_$data (uchar code) uchar pl, ph, px, dps; dps = sfr->get (DPS); - if (dps & 1) + if (dps & 0x01) { pl = DPL1; ph = DPH1; @@ -610,12 +618,12 @@ t_uc390::inst_mov_dptr_$data (uchar code) } if (sfr->get (ACON) & 0x02) /* AM1 set: 24-bit flat? */ - sfr->set (px, fetch ()); - sfr->set (event_at.ws = ph, fetch ()); - sfr->set (pl, fetch ()); + sfr->write (px, fetch ()); + sfr->write (ph, fetch ()); + sfr->write (pl, fetch ()); if (dps & 0x20) /* auto-switch dptr */ - sfr->set (DPS, dps ^ 1); /* toggle dual-dptr switch */ + sfr->write (DPS, dps ^ 1); /* toggle dual-dptr switch */ tick (1); return resGO; @@ -634,7 +642,7 @@ t_uc390::inst_movc_a_$a_dptr (uchar code) uchar pl, ph, px, dps; dps = sfr->get (DPS); - if (dps & 1) + if (dps & 0x01) { pl = DPL1; ph = DPH1; @@ -648,17 +656,16 @@ t_uc390::inst_movc_a_$a_dptr (uchar code) } if (sfr->get (ACON) & 0x02) /* AM1 set: 24-bit flat? */ - sfr->set (ACC, get_mem (MEM_ROM, - event_at.rc = - (sfr->get (px) * 256*256 + sfr->get (ph) * 256 + sfr->get (pl) + - sfr->get (ACC)) & (EROM_SIZE-1))); + acc->write (read_mem (MEM_ROM, + (sfr->read (px) * 256*256 + sfr->read (ph) * 256 + sfr->read (pl) + + acc->read()))); else - sfr->set (ACC, get_mem (MEM_ROM, event_at.rc = - (sfr->get (ph) * 256 + sfr->get (pl) + - sfr->get (ACC)) & (EROM_SIZE-1))); + acc->write (read_mem (MEM_ROM, + (sfr->read (ph) * 256 + sfr->read (pl) + + acc->read()))); if (dps & 0x20) /* auto-switch dptr */ - sfr->set (DPS, dps ^ 1); /* toggle dual-dptr switch */ + sfr->write (DPS, dps ^ 1); /* toggle dual-dptr switch */ tick (1); return resGO; @@ -673,13 +680,12 @@ t_uc390::inst_movc_a_$a_dptr (uchar code) int t_uc390::inst_push (uchar code) { - uchar *addr; - int res; + class cl_cell *cell; - addr = get_direct (fetch (), &event_at.wi, &event_at.ws); - res = push_byte (read (addr)); + cell = get_direct(fetch()); + push_byte (cell->read()); tick (1); - return res; + return resGO; } @@ -692,14 +698,12 @@ t_uc390::inst_push (uchar code) int t_uc390::inst_pop (uchar code) { - uchar *addr; - int res; + class cl_cell *cell; - addr = get_direct (fetch (), &event_at.wi, &event_at.ws); - *addr = pop_byte (&res); - proc_write (addr); + cell = get_direct (fetch()); + cell->write (pop_byte()); tick (1); - return res; + return resGO; } @@ -715,7 +719,7 @@ t_uc390::inst_movx_a_$dptr (uchar code) uchar pl, ph, px, dps; dps = sfr->get (DPS); - if (dps & 1) + if (dps & 0x01) { pl = DPL1; ph = DPH1; @@ -729,16 +733,14 @@ t_uc390::inst_movx_a_$dptr (uchar code) } if (sfr->get (ACON) & 0x02) /* AM1 set: 24-bit flat? */ - sfr->set (event_at.ws = ACC, - get_mem (MEM_XRAM, - event_at.rx = sfr->get (px) * 256*256 + sfr->get (ph) * 256 + sfr->get (pl))); + acc->write (read_mem (MEM_XRAM, + sfr->read (px) * 256*256 + sfr->read (ph) * 256 + sfr->read (pl))); else - sfr->set (event_at.ws = ACC, - get_mem (MEM_XRAM, - event_at.rx = sfr->get (ph) * 256 + sfr->get (pl))); + acc->write (read_mem (MEM_XRAM, + sfr->read (ph) * 256 + sfr->read (pl))); if (dps & 0x20) /* auto-switch dptr */ - sfr->set (DPS, dps ^ 1); /* toggle dual-dptr switch */ + sfr->write (DPS, dps ^ 1); /* toggle dual-dptr switch */ tick (1); return resGO; @@ -756,7 +758,7 @@ t_uc390::inst_movx_$dptr_a (uchar code) uchar pl, ph, px, dps; dps = sfr->get (DPS); - if (dps & 1) + if (dps & 0x01) { pl = DPL1; ph = DPH1; @@ -770,16 +772,16 @@ t_uc390::inst_movx_$dptr_a (uchar code) } if (sfr->get (ACON) & 0x02) /* AM1 set: 24-bit flat? */ - set_mem (MEM_XRAM, - event_at.wx = sfr->get (px) * 256*256 + sfr->get (ph) * 256 + sfr->get (pl), - sfr->get (event_at.rs = ACC)); + write_mem (MEM_XRAM, + sfr->read (px) * 256*256 + sfr->read (ph) * 256 + sfr->read (pl), + acc->read()); else - set_mem (MEM_XRAM, - event_at.wx = sfr->get (ph) * 256 + sfr->get (pl), - sfr->get (event_at.rs = ACC)); + write_mem (MEM_XRAM, + sfr->read (ph) * 256 + sfr->read (pl), + acc->read()); if (dps & 0x20) /* auto-switch dptr */ - sfr->set (DPS, dps ^ 1); /* toggle dual-dptr switch */ + sfr->write (DPS, dps ^ 1); /* toggle dual-dptr switch */ tick (1); return resGO; @@ -850,8 +852,7 @@ t_uc390::inst_ljmp (uchar code) int t_uc390::inst_acall_addr (uchar code) { - uchar x, h, l, *sp, *aof_SP; - int res; + uchar x, h, l; if (sfr->get (ACON) & 0x02) /* AM1 set: 24-bit flat? */ { @@ -859,39 +860,31 @@ t_uc390::inst_acall_addr (uchar code) h = fetch (); l = fetch (); - res = push_byte ( PC & 0xff); /* push low byte */ - res = push_byte ((PC >> 8) & 0xff); /* push high byte */ - res = push_byte ((PC >> 16) & 0xff); /* push x byte */ + push_byte ( PC & 0xff); /* push low byte */ + push_byte ((PC >> 8) & 0xff); /* push high byte */ + push_byte ((PC >> 16) & 0xff); /* push x byte */ PC = (PC & 0xf800) | (x * 256*256 + h * 256 + l); } else { /* stock mcs51 mode */ - h = (code >> 5) & 0x07; - l = fetch (); - aof_SP = &((sfr->umem8)[SP]); - - //MEM(MEM_SFR)[SP]++; - (*aof_SP)++; - proc_write_sp (*aof_SP); - sp = get_indirect (*aof_SP/*sfr->get (SP)*/, &res); - if (res != resGO) - res = resSTACK_OV; - *sp = PC & 0xff; // push low byte - - //MEM(MEM_SFR)[SP]++; - (*aof_SP)++; - proc_write_sp (*aof_SP); - sp = get_indirect (*aof_SP/*sfr->get (SP)*/, &res); - if (res != resGO) - res = resSTACK_OV; - *sp = (PC >> 8) & 0xff; // push high byte + class cl_cell *stck; + t_mem sp; - PC = (PC & 0xf800) | (h * 256 + l); + h = (code >> 5) & 0x07; + l = fetch(); + sp = sfr->wadd (SP, 1); + stck = iram->get_cell (sp); + stck->write (PC & 0xff); // push low byte + + sp = sfr->wadd (SP, 1); + stck = iram->get_cell (sp); + stck->write ((PC >> 8) & 0xff); // push high byte + PC = (PC & 0xf800) | (h*256 + l); } tick (1); - return res; + return resGO; } @@ -905,7 +898,6 @@ int t_uc390::inst_lcall (uchar code, uint addr) { uchar x = 0, h = 0, l = 0; - int res; if (!addr) { /* this is a normal lcall */ @@ -916,12 +908,12 @@ t_uc390::inst_lcall (uchar code, uint addr) } /* else, this is interrupt processing */ - res = push_byte ( PC & 0xff); /* push low byte */ - res = push_byte ((PC >> 8) & 0xff); /* push high byte */ + push_byte ( PC & 0xff); /* push low byte */ + push_byte ((PC >> 8) & 0xff); /* push high byte */ if (sfr->get (ACON) & 0x02) /* AM1 set: 24-bit flat? */ { - res = push_byte ((PC >> 16) & 0xff); /* push x byte */ + push_byte ((PC >> 16) & 0xff); /* push x byte */ if (addr) PC = addr & 0xfffful; /* if interrupt: x-Byte is 0 */ else @@ -934,7 +926,7 @@ t_uc390::inst_lcall (uchar code, uint addr) else PC = h * 256 + l; } - return res; + return resGO; } /* @@ -947,12 +939,11 @@ int t_uc390::inst_ret (uchar code) { uchar x = 0, h, l; - int res; if (sfr->get (ACON) & 0x02) /* AM1 set: 24-bit flat? */ - x = pop_byte (&res); - h = pop_byte (&res); - l = pop_byte (&res); + x = pop_byte (); + h = pop_byte (); + l = pop_byte (); tick (1); @@ -964,7 +955,7 @@ t_uc390::inst_ret (uchar code) else PC = h * 256 + l; - return res; + return resGO; } /* @@ -977,12 +968,11 @@ int t_uc390::inst_reti (uchar code) { uchar x = 0, h, l; - int res; if (sfr->get (ACON) & 0x02) /* AM1 set: 24-bit flat? */ - x = pop_byte (&res); - h = pop_byte (&res); - l = pop_byte (&res); + x = pop_byte (); + h = pop_byte (); + l = pop_byte (); tick (1); if (sfr->get (ACON) & 0x02) /* AM1 set: 24-bit flat? */ @@ -993,7 +983,7 @@ t_uc390::inst_reti (uchar code) else PC = h * 256 + l; - was_reti = DD_TRUE; + interrupt->was_reti = DD_TRUE; class it_level *il = (class it_level *) (it_levels->top ()); if (il && il->level >= 0) @@ -1002,142 +992,7 @@ t_uc390::inst_reti (uchar code) delete il; } - return res; -} - -/* - * Processing write operation to IRAM - * - * It starts serial transmition if address is in SFR and it is - * SBUF. Effect on IE is also checked. - */ - -void -t_uc390::proc_write(uchar *addr) -{ - if (addr == &((sfr->umem8)[SBUF])) - { - s_out= sfr->get(SBUF); - s_sending= DD_TRUE; - s_tr_bit = 0; - s_tr_tick= 0; - s_tr_t1 = 0; - } - else if (addr == &((sfr->umem8)[IE])) - was_reti= DD_TRUE; - else if (addr == &((sfr->umem8)[DPS])) - { - *addr &= 0xe5; - *addr |= 0x04; - } - else if (addr == &((sfr->umem8)[EXIF])) - { - } - else if (addr == &((sfr->umem8)[P4CNT])) - { - ; - } - else if (addr == &((sfr->umem8)[ACON])) - { - *addr |= 0xf8; - /* lockout: IDM1:IDM0 and SA can't be set at the same time */ - if (((sfr->umem8)[MCON] & 0xc0) == 0xc0) /* IDM1 and IDM0 set? */ - *addr &= ~0x04; /* lockout SA */ - } - else if (addr == &((sfr->umem8)[P5CNT])) - { - ; - } - else if (addr == &((sfr->umem8)[C0C])) - { - ; - } - else if (addr == &((sfr->umem8)[PMR])) - { - *addr |= 0x03; - // todo: check previous state - if ((*addr & 0xd0) == 0x90) /* CD1:CD0 set to 10, CTM set */ - { - ctm_ticks = ticks->ticks; - (sfr->umem8)[EXIF] &= ~0x08; /* clear CKRDY */ - } - else - ctm_ticks = 0; - } - else if (addr == &((sfr->umem8)[MCON])) - { - *addr |= 0x10; - /* lockout: IDM1:IDM0 and SA can't be set at the same time */ - if (((sfr->umem8)[ACON] & 0x04) == 0x04) /* SA set? */ - *addr &= ~0xc0; /* lockout IDM1:IDM0 */ - } - else if (addr == &((sfr->umem8)[TA])) - { - if (*addr == 0x55) - { - timed_access_ticks = ticks->ticks; - timed_access_state = 1; - } - else if (*addr == 0xaa && - timed_access_state == 1 && - timed_access_ticks == ticks->ticks + 1) - { - timed_access_ticks = ticks->ticks; - timed_access_state = 2; - } - else - timed_access_state = 0; - } - else if (addr == &((sfr->umem8)[T2MOD])) - *addr |= 0xe0; - else if (addr == &((sfr->umem8)[COR])) - { - ; - } - else if (addr == &((sfr->umem8)[WDCON])) - { - ; - } - else if (addr == &((sfr->umem8)[C1C])) - { - ; - } - else if (addr == &((sfr->umem8)[MCNT1])) - *addr |= 0x0f; -} - - -/* - * Reading IRAM or SFR, but if address points to a port, it reads - * port pins instead of port latches - */ - -uchar -t_uc390::read(uchar *addr) -{ - //if (addr == &(MEM(MEM_SFR)[P1])) - if (addr == &(sfr->umem8[P1])) - return get_mem (MEM_SFR, P1) & port_pins[1]; - //if (addr == &(MEM(MEM_SFR)[P2])) - else if (addr == &(sfr->umem8[P2])) - return get_mem (MEM_SFR, P2) & port_pins[2]; - //if (addr == &(MEM(MEM_SFR)[P3])) - else if (addr == &(sfr->umem8[P3])) - return get_mem (MEM_SFR, P3) & port_pins[3]; - //if (addr == &(MEM(MEM_SFR)[P4])) - else if (addr == &(sfr->umem8[P4])) - return get_mem (MEM_SFR, P4) & port_pins[4]; - //if (addr == &(MEM(MEM_SFR)[P5])) - else if (addr == &(sfr->umem8[P5])) - return get_mem (MEM_SFR, P5) & port_pins[5]; - else if (addr == &(sfr->umem8[EXIF])) - if (ctm_ticks && - ticks->ticks >= ctm_ticks + 65535) - { - *addr |= 0x08; /* set CKRDY */ - ctm_ticks = 0; - } - return *addr; + return resGO; } @@ -1168,7 +1023,7 @@ t_uc390::disass (t_addr addr, char *sep) code = get_mem (MEM_ROM, addr); p = work; - b = dis_tbl ()[code].mnemonic; + b = dis_tbl()[code].mnemonic; while (*b) { if (*b == '%') @@ -1184,55 +1039,55 @@ t_uc390::disass (t_addr addr, char *sep) // get_mem (MEM_ROM, addr + 1))); sprintf (temp, "%06lx", - (addr & 0xf80000) | + (addr & 0xf80000L) | (((code >> 5) & 0x07) * (256 * 256) + (get_mem (MEM_ROM, addr + 1) * 256) + get_mem (MEM_ROM, addr + 2))); break; case 'l': // long address sprintf (temp, "%06lx", - get_mem (MEM_ROM, addr + 1) * (256*256) + + get_mem (MEM_ROM, addr + 1) * (256*256L) + get_mem (MEM_ROM, addr + 2) * 256 + get_mem (MEM_ROM, addr + 3)); // get_mem (MEM_ROM, addr + 1) * 256 + get_mem (MEM_ROM, addr + 2)); break; case 'a': // addr8 (direct address) at 2nd byte if (!get_name (get_mem (MEM_ROM, addr + 1), sfr_tbl (), temp)) - sprintf (temp, "%02lx", get_mem (MEM_ROM, addr + 1)); + sprintf (temp, "%02"_M_"x", get_mem (MEM_ROM, addr + 1)); break; case '8': // addr8 (direct address) at 3rd byte if (!get_name (get_mem (MEM_ROM, addr + 2), sfr_tbl (), temp)) - sprintf (temp, "%02lx", get_mem (MEM_ROM, addr + 1)); - sprintf (temp, "%02lx", get_mem (MEM_ROM, addr + 2)); + sprintf (temp, "%02"_M_"x", get_mem (MEM_ROM, addr + 2)); break; case 'b': // bitaddr at 2nd byte - if (get_name (get_mem (MEM_ROM, addr + 1), bit_tbl (), temp)) - break; - if (get_name (get_bitidx (get_mem (MEM_ROM, addr + 1)), - sfr_tbl (), temp)) - { - strcat (temp, "."); - sprintf (c, "%1ld", get_mem (MEM_ROM, addr + 1) & 0x07); - strcat (temp, c); - break; - } - sprintf (temp, "%02x.%ld", - get_bitidx (get_mem (MEM_ROM, addr + 1)), - get_mem (MEM_ROM, addr + 1) & 0x07); - break; + { + t_addr ba = get_mem (MEM_ROM, addr+1); + if (get_name (ba, bit_tbl(), temp)) + break; + if (get_name ((ba<128) ? ((ba/8)+32) : (ba&0xf8), sfr_tbl(), temp)) + { + strcat (temp, "."); + sprintf (c, "%1"_M_"d", ba & 0x07); + strcat (temp, c); + break; + } + sprintf (temp, "%02x.%"_M_"d", (ba<128) ? ((ba/8)+32) : (ba&0xf8), + ba & 0x07); + break; + } case 'r': // rel8 address at 2nd byte - sprintf (temp, "%04lx", - addr + 2 + (signed char) (get_mem (MEM_ROM, addr + 1))); + sprintf (temp, "%04"_A_"x", + t_addr (addr + 2 + (signed char) (get_mem (MEM_ROM, addr + 1)))); break; case 'R': // rel8 address at 3rd byte - sprintf (temp, "%04lx", - addr + 3 + (signed char) (get_mem (MEM_ROM, addr + 2))); + sprintf (temp, "%04"_A_"x", + t_addr (addr + 3 + (signed char) (get_mem (MEM_ROM, addr + 2)))); break; case 'd': // data8 at 2nd byte - sprintf (temp, "%02lx", get_mem (MEM_ROM, addr + 1)); + sprintf (temp, "%02"_M_"x", get_mem (MEM_ROM, addr + 1)); break; case 'D': // data8 at 3rd byte - sprintf (temp, "%02lx", get_mem (MEM_ROM, addr + 2)); + sprintf (temp, "%02"_M_"x", get_mem (MEM_ROM, addr + 2)); break; default: strcpy (temp, "?"); @@ -1274,7 +1129,7 @@ void t_uc390::print_regs (class cl_console *con) { t_addr start; - uchar data; + t_mem data; if (! (sfr->get (ACON) & 0x02)) /* AM1 set: 24-bit flat? */ { diff --git a/sim/ucsim/s51.src/uc390cl.h b/sim/ucsim/s51.src/uc390cl.h index ca8e4f4f..d1bdf70d 100644 --- a/sim/ucsim/s51.src/uc390cl.h +++ b/sim/ucsim/s51.src/uc390cl.h @@ -37,15 +37,16 @@ class t_uc390: public t_uc52 { public: t_uc390(int Itype, int Itech, class cl_sim *asim); + virtual void mk_hw_elements (void); - virtual void clear_sfr(void); + virtual void clear_sfr (void); // making objects virtual t_addr get_mem_size (enum mem_class type); // manipulating memories - virtual ulong read_mem (enum mem_class type, t_mem addr); - virtual ulong get_mem (enum mem_class type, t_addr addr); + virtual t_mem read_mem (enum mem_class type, t_addr addr); + virtual t_mem get_mem (enum mem_class type, t_addr addr); virtual void write_mem (enum mem_class type, t_addr addr, t_mem val); virtual void set_mem (enum mem_class type, t_addr addr, t_mem val); @@ -69,9 +70,6 @@ public: virtual int inst_push (uchar code); virtual int inst_pop (uchar code); - /* miscellaneous */ - virtual void proc_write(uchar *addr); - /* mods for disassembly of flat24 */ virtual struct dis_entry *dis_tbl(void); virtual char * disass(t_addr addr, char *sep); @@ -79,12 +77,8 @@ public: protected: int flat24_flag; /* true if processor == ds390f */ - unsigned long ctm_ticks; /* mini-state-machine for "crystal multiplier" */ - unsigned long timed_access_ticks; - int timed_access_state; /* 0: idle; 1: $aa written; 2: $55 written */ - virtual int push_byte (uchar uc); - virtual uchar pop_byte (int *Pres); - virtual uchar read(uchar *addr); + virtual void push_byte (t_mem uc); + virtual t_mem pop_byte (void); }; /* End of s51.src/uc390cl.h */ diff --git a/sim/ucsim/s51.src/uc390hw.cc b/sim/ucsim/s51.src/uc390hw.cc new file mode 100644 index 00000000..d8bae360 --- /dev/null +++ b/sim/ucsim/s51.src/uc390hw.cc @@ -0,0 +1,313 @@ +/* + * Simulator of microcontrollers (serial.cc) + * + * Copyright (C) 1999,99 Drotos Daniel, Talker Bt. + * + * To contact author send email to drdani@mazsola.iit.uni-miskolc.hu + * + */ + +/* This file is part of microcontroller simulator: ucsim. + +UCSIM is free software; you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation; either version 2 of the License, or +(at your option) any later version. + +UCSIM is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU General Public License for more details. + +You should have received a copy of the GNU General Public License +along with UCSIM; see the file COPYING. If not, write to the Free +Software Foundation, 59 Temple Place - Suite 330, Boston, MA +02111-1307, USA. */ +/*@1@*/ + +#include "ddconfig.h" + +#include +#include + +// local +#include "uc390hwcl.h" +#include "regs51.h" +#include "uc51cl.h" + + +cl_uc390_hw::cl_uc390_hw (class cl_uc *auc): + cl_hw (auc, HW_DUMMY, 0, "ds390hw") +{ + uc390 = (class t_uc390 *) uc; +} + +int +cl_uc390_hw::init(void) +{ + class cl_mem *sfr; + + sfr = uc->mem (MEM_SFR); + if (sfr) + { + /*cell_dps = sfr->register_hw (DPS , this, 0); + cell_p4cnt = sfr->register_hw (P4CNT, this, 0); + cell_exif = sfr->register_hw (EXIF , this, 0); + cell_acon = sfr->register_hw (ACON , this, 0); + cell_p5cnt = sfr->register_hw (P5CNT, this, 0); + cell_c0c = sfr->register_hw (C0C , this, 0); + cell_pmr = sfr->register_hw (PMR , this, 0); + cell_mcon = sfr->register_hw (MCON , this, 0); + cell_ta = sfr->register_hw (TA , this, 0); + cell_cor = sfr->register_hw (COR , this, 0); + cell_mcnt0 = sfr->register_hw (MCNT0, this, 0); + cell_mcnt1 = sfr->register_hw (MCNT1, this, 0); + cell_ma = sfr->register_hw (MA , this, 0); + cell_mb = sfr->register_hw (MB , this, 0); + cell_mc = sfr->register_hw (MC , this, 0); + cell_wdcon = sfr->register_hw (WDCON, this, 0); + cell_c1c = sfr->register_hw (C1C , this, 0);*/ + register_cell (sfr, DPS , &cell_dps , wtd_restore); + register_cell (sfr, P4CNT, &cell_p4cnt, wtd_restore); + register_cell (sfr, EXIF , &cell_exif , wtd_restore); + register_cell (sfr, ACON , &cell_acon , wtd_restore); + register_cell (sfr, P5CNT, &cell_p5cnt, wtd_restore); + register_cell (sfr, C0C , &cell_c0c , wtd_restore); + register_cell (sfr, PMR , &cell_pmr , wtd_restore); + register_cell (sfr, MCON , &cell_mcon , wtd_restore); + register_cell (sfr, TA , &cell_ta , wtd_restore); + register_cell (sfr, COR , &cell_cor , wtd_restore); + register_cell (sfr, MCNT0, &cell_mcnt0, wtd_restore); + register_cell (sfr, MCNT1, &cell_mcnt1, wtd_restore); + register_cell (sfr, MA , &cell_ma , wtd_restore); + register_cell (sfr, MB , &cell_mb , wtd_restore); + register_cell (sfr, MC , &cell_mc , wtd_restore); + register_cell (sfr, WDCON, &cell_wdcon, wtd_restore); + register_cell (sfr, C1C , &cell_c1c , wtd_restore); + } + return 0; +} + +t_mem +cl_uc390_hw::read (class cl_cell *cell) +{ + if (cell == cell_exif) + { + if (ctm_ticks && + uc390->ticks->ticks >= ctm_ticks + 65535) + { + ctm_ticks = 0; + cell->set (cell->get() | 0x08); /* set CKRDY */ + } + } + return cell->get(); +} + +void +cl_uc390_hw::write (class cl_cell *cell, t_mem *val) +{ + if (cell == cell_dps) + *val = (*val & 0xe5) | 0x04; + else if (cell == cell_exif) + { + /* Bit 0 (BGS) is TA-protected */ + if (timed_access_state != 2 || + timed_access_ticks + 2*12 < uc390->ticks->ticks) // fixme: 3 cycles + *val = (*val & ~0x01) | (cell_exif->get() & 0x01); + + /* CKRDY and RGMD are read-only */ + *val = (*val & 0x0c) | (*val & ~0x0c); + } + else if (cell == cell_p4cnt) + { + /* P4CNT is TA-protected */ + if (timed_access_state != 2 || + timed_access_ticks + 2*12 < uc390->ticks->ticks) // fixme: 3 cycles + *val = cell_p4cnt->get(); + *val |= 0x80; /* always 1 */ + } + else if (cell == cell_acon) + { + /* ACON is TA-protected */ + if (timed_access_state != 2 || + timed_access_ticks + 2*12 < uc390->ticks->ticks) // fixme: 3 cycles + *val = cell_acon->get(); + else + { + + /* lockout: IDM1:IDM0 and SA can't be set at the same time */ + if ((cell_mcon->get() & 0xc0) == 0xc0) /* IDM1 and IDM0 set? */ + *val &= ~0x04; /* lockout SA */ + } + *val |= 0xf8; /* always 1 */ + } + else if (cell == cell_p5cnt) + { + /* Bits 0...2 are TA-protected */ + if (timed_access_state != 2 || + timed_access_ticks + 2*12 < uc390->ticks->ticks) // fixme: 3 cycles + *val = (*val & ~0x07) | (cell_p5cnt->get() & 0x07); + } + else if (cell == cell_c0c) + { + /* Bit 3 (CRST) is TA-protected */ + if (timed_access_state != 2 || + timed_access_ticks + 2*12 < uc390->ticks->ticks) // fixme: 3 cycles + *val = (*val & ~0x08) | (cell_c0c->get() & 0x08); + } + else if (cell == cell_pmr) + { + /* fixme: check previous state */ + if ((*val & 0xd0) == 0x90) /* CD1:CD0 set to 10, CTM set */ + { + ctm_ticks = uc390->ticks->ticks; + cell_exif->set (cell_exif->get() & ~0x08); /* clear CKRDY */ + } + else + ctm_ticks = 0; + *val |= 0x03; /* always 1 */ + } + else if (cell == cell_mcon) + { + /* MCON is TA-protected */ + if (timed_access_state != 2 || + timed_access_ticks + 2*12 < uc390->ticks->ticks) // fixme: 3 cycles + *val = cell_mcon->get(); + else + /* lockout: IDM1:IDM0 and SA can't be set at the same time */ + if ((cell_acon->get() & 0x04) == 0x04) /* SA set? */ + *val &= ~0xc0; /* lockout IDM1:IDM0 */ + *val |= 0x10; /* always 1 */ + } + else if (cell == cell_ta) + { + if (*val == 0xAA) + { + timed_access_state = 1; + timed_access_ticks = uc390->ticks->ticks; + } + else if (*val == 0x55 && + timed_access_state == 1 && + timed_access_ticks + 2*12 >= uc390->ticks->ticks) // fixme: 3 cycles + { + timed_access_state = 2; + timed_access_ticks = uc390->ticks->ticks; + } + else + timed_access_state = 0; + } + else if (cell == cell_cor) + { + /* COR is TA-protected */ + if (timed_access_state != 2 || + timed_access_ticks + 2*12 < uc390->ticks->ticks) // fixme: 3 cycles + *val = cell_cor->get(); + } + else if (cell == cell_mcnt0) + { + ; + } + else if (cell == cell_mcnt1) + { + *val |= 0x0f; /* always 1 */ + } + else if (cell == cell_ma) + { + ; + } + else if (cell == cell_mb) + { + ; + } + else if (cell == cell_mc) + { + ; + } + else if (cell == cell_wdcon) + { + /* Bits 0, 1, 3 and 6 are TA-protected */ + if (timed_access_state != 2 || + timed_access_ticks + 2*12 < uc390->ticks->ticks) // fixme: 3 cycles + *val = (*val & ~0x4b) | (cell_wdcon->get() & 0x4b); + } + else if (cell == cell_c1c) + { + /* Bit 3 (CRST) is TA-protected */ + if (timed_access_state != 2 || + timed_access_ticks + 2*12 < uc390->ticks->ticks) // fixme: 3 cycles + *val = (*val & ~0x08) | (cell_c1c->get() & 0x08); + } +} + +/*void +cl_uc390_hw::mem_cell_changed (class cl_mem *mem, t_addr addr) +{ + class cl_mem *sfr = uc->mem (MEM_SFR); + + if (mem && sfr && mem == sfr) + switch (addr) + { + case DPS: cell_dps = sfr->get_cell (DPS); break; + case P4CNT: cell_p4cnt = sfr->get_cell (P4CNT); break; + case EXIF: cell_exif = sfr->get_cell (EXIF); break; + case ACON: cell_acon = sfr->get_cell (ACON); break; + case P5CNT: cell_p5cnt = sfr->get_cell (P5CNT); break; + case C0C: cell_c0c = sfr->get_cell (C0C); break; + case PMR: cell_pmr = sfr->get_cell (PMR); break; + case MCON: cell_mcon = sfr->get_cell (MCON); break; + case TA: cell_ta = sfr->get_cell (TA); break; + case COR: cell_cor = sfr->get_cell (COR); break; + case MCNT0: cell_mcnt0 = sfr->get_cell (MCNT0); break; + case MCNT1: cell_mcnt1 = sfr->get_cell (MCNT1); break; + case MA: cell_ma = sfr->get_cell (MA); break; + case MB: cell_mb = sfr->get_cell (MB); break; + case MC: cell_mc = sfr->get_cell (MC); break; + case WDCON: cell_wdcon = sfr->get_cell (WDCON); break; + case C1C: cell_c1c = sfr->get_cell (C1C); break; + } +}*/ + +void +cl_uc390_hw::reset(void) +{ + ctm_ticks = 0; + timed_access_state = 0; +} + +void +cl_uc390_hw::print_info(class cl_console *con) +{ + int i; + long l; + + i = uc->get_mem (MEM_SFR, EXIF); + con->dd_printf ("%s" + " EXIF 0x%02x: IE5 %c IE4 %c IE3 %c IE2 %c CKRDY %c RGMD %c RGSL %c BGS %c\n", + id_string, + i, + (i & 0x80) ? '1' : '0', + (i & 0x40) ? '1' : '0', + (i & 0x20) ? '1' : '0', + (i & 0x10) ? '1' : '0', + (i & 0x08) ? '1' : '0', + (i & 0x04) ? '1' : '0', + (i & 0x02) ? '1' : '0', + (i & 0x01) ? '1' : '0'); + i = uc->get_mem (MEM_SFR, DPS); + con->dd_printf ("\tDPS 0x%02x: ID1 %c ID0 %c TSL %c SEL %c\n", + i, + (i & 0x80) ? '1' : '0', + (i & 0x40) ? '1' : '0', + (i & 0x20) ? '1' : '0', + (i & 0x01) ? '1' : '0'); + l = uc->get_mem (MEM_SFR, DPX) * 256*256 + + uc->get_mem (MEM_SFR, DPH) * 256 + + uc->get_mem (MEM_SFR, DPL); + con->dd_printf ("\tDPTR 0x%06x\n", l); + l = uc->get_mem (MEM_SFR, DPX1) * 256*256 + + uc->get_mem (MEM_SFR, DPH1) * 256 + + uc->get_mem (MEM_SFR, DPL1); + con->dd_printf ("\tDPTR1 0x%06x\n", l); +} + +/* End of s51.src/uc390hw.cc */ diff --git a/sim/ucsim/s51.src/uc390hwcl.h b/sim/ucsim/s51.src/uc390hwcl.h new file mode 100644 index 00000000..e0b0ca01 --- /dev/null +++ b/sim/ucsim/s51.src/uc390hwcl.h @@ -0,0 +1,63 @@ +/* + * Simulator of microcontrollers (serialcl.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 UC390HWCL_HEADER +#define UC390HWCL_HEADER + +#include "uccl.h" + +#include "uc390cl.h" + + +class cl_uc390_hw: public cl_hw +{ +protected: + class cl_cell *cell_dps, *cell_exif, *cell_p4cnt, *cell_acon, + *cell_p5cnt, *cell_c0c, *cell_pmr, *cell_mcon, + *cell_ta, *cell_cor, *cell_mcnt0, *cell_mcnt1, + *cell_ma, *cell_mb, *cell_mc, *cell_wdcon, *cell_c1c; + class t_uc390 *uc390; + unsigned long ctm_ticks; /* mini-state-machine for "crystal multiplier" */ + unsigned long timed_access_ticks; + int timed_access_state; /* 0: idle; 1: $aa written; 2: $55 written */ +public: + cl_uc390_hw (class cl_uc *auc); + virtual int init (void); + + virtual t_mem read (class cl_cell *cell); + virtual void write (class cl_cell *cell, t_mem *val); + + //virtual void mem_cell_changed (class cl_mem *mem, t_addr addr); + + virtual void reset (void); + virtual void print_info (class cl_console *con); +}; + + +#endif + +/* End of s51.src/serialcl.h */ diff --git a/sim/ucsim/s51.src/uc51.cc b/sim/ucsim/s51.src/uc51.cc index 0ea18fe6..02e4aedb 100644 --- a/sim/ucsim/s51.src/uc51.cc +++ b/sim/ucsim/s51.src/uc51.cc @@ -53,6 +53,7 @@ Software Foundation, 59 Temple Place - Suite 330, Boston, MA #include "serialcl.h" #include "portcl.h" #include "interruptcl.h" +#include "types51.h" /* @@ -62,9 +63,10 @@ Software Foundation, 59 Temple Place - Suite 330, Boston, MA t_uc51::t_uc51(int Itype, int Itech, class cl_sim *asim): cl_uc(asim) { - int i; + //int i; + /* struct termios tattr; - + */ type= Itype; technology= Itech; @@ -76,6 +78,7 @@ t_uc51::t_uc51(int Itype, int Itech, class cl_sim *asim): options->add(new cl_cons_debug_opt(asim->app, "debug", "Debug messages appears on this console.")); + /* serial_in = (FILE*)asim->app->args->get_parg(0, "Ser_in"); serial_out= (FILE*)asim->app->args->get_parg(0, "Ser_out"); if (serial_in) @@ -128,21 +131,22 @@ t_uc51::t_uc51(int Itype, int Itech, class cl_sim *asim): fprintf(stderr, "Warning: serial output interface connected to a " "non-terminal file.\n"); } - - for (i= 0; i < 4; i++) - port_pins[i]= 0xff; - it_sources->add(new cl_it_src(bmEX0, TCON, bmIE0, 0x0003, true, - "external #0")); - it_sources->add(new cl_it_src(bmET0, TCON, bmTF0, 0x000b, true, - "timer #0")); - it_sources->add(new cl_it_src(bmEX1, TCON, bmIE1, 0x0013, true, - "external #1")); - it_sources->add(new cl_it_src(bmET1, TCON, bmTF1, 0x001b, true, - "timer #1")); - it_sources->add(new cl_it_src(bmES , SCON, bmTI , 0x0023, false, + */ + + /*for (i= 0; i < 4; i++) + port_pins[i]= 0xff;*/ + /*it_sources->add(new cl_it_src(bmEX0, TCON, bmIE0, 0x0003, true, + "external #0"));*/ + /*it_sources->add(new cl_it_src(bmET0, TCON, bmTF0, 0x000b, true, + "timer #0"));*/ + /*it_sources->add(new cl_it_src(bmEX1, TCON, bmIE1, 0x0013, true, + "external #1"));*/ + /*it_sources->add(new cl_it_src(bmET1, TCON, bmTF1, 0x001b, true, + "timer #1"));*/ + /*it_sources->add(new cl_it_src(bmES , SCON, bmTI , 0x0023, false, "serial transmit")); it_sources->add(new cl_it_src(bmES , SCON, bmRI , 0x0023, false, - "serial receive")); + "serial receive"));*/ } @@ -178,9 +182,12 @@ t_uc51::mk_hw_elements(void) { class cl_hw *h; - hws->add(h= new cl_timer0(this)); + acc= sfr->get_cell(ACC); + psw= sfr->get_cell(PSW); + + hws->add(h= new cl_timer0(this, 0, "timer0")); h->init(); - hws->add(h= new cl_timer1(this)); + hws->add(h= new cl_timer1(this, 1, "timer1")); h->init(); hws->add(h= new cl_serial(this)); h->init(); @@ -192,8 +199,14 @@ t_uc51::mk_hw_elements(void) h->init(); hws->add(h= new cl_port(this, 3)); h->init(); - hws->add(h= new cl_interrupt(this)); + hws->add(interrupt= new cl_interrupt(this)); + interrupt->init(); + hws->add(h= new cl_uc51_dummy_hw(this)); h->init(); + /* + acc= sfr->get_cell(ACC); + psw= sfr->get_cell(PSW); + */ } class cl_mem * @@ -214,6 +227,7 @@ t_uc51::mk_mem(enum mem_class type, char *class_name) t_uc51::~t_uc51(void) { + /* if (serial_out) { if (isatty(fileno(serial_out))) @@ -226,6 +240,7 @@ t_uc51::~t_uc51(void) tcsetattr(fileno(serial_in), TCSANOW, &saved_attributes_in); fclose(serial_in); } + */ } @@ -280,56 +295,59 @@ t_uc51::disass(t_addr addr, char *sep) switch (*(b++)) { case 'A': // absolute address - sprintf(temp, "%04lx", - (addr&0xf800)| - (((code>>5)&0x07)*256 + - get_mem(MEM_ROM, addr+1))); + sprintf(temp, "%04"_A_"x", + t_addr((addr&0xf800)| + (((code>>5)&0x07)*256 + + get_mem(MEM_ROM, addr+1)))); break; case 'l': // long address - sprintf(temp, "%04lx", - get_mem(MEM_ROM, addr+1)*256 + get_mem(MEM_ROM, addr+2)); + sprintf(temp, "%04"_A_"x", + t_addr(get_mem(MEM_ROM, addr+1)*256 + + get_mem(MEM_ROM, addr+2))); break; case 'a': // addr8 (direct address) at 2nd byte if (!get_name(get_mem(MEM_ROM, addr+1), sfr_tbl(), temp)) - sprintf(temp, "%02lx", get_mem(MEM_ROM, addr+1)); + sprintf(temp, "%02"_M_"x", get_mem(MEM_ROM, addr+1)); break; case '8': // addr8 (direct address) at 3rd byte if (!get_name(get_mem(MEM_ROM, addr+2), sfr_tbl(), temp)) - sprintf(temp, "%02lx", get_mem(MEM_ROM, addr+1)); - sprintf(temp, "%02lx", get_mem(MEM_ROM, addr+2)); + sprintf(temp, "%02"_M_"x", get_mem(MEM_ROM, addr+1)); + sprintf(temp, "%02"_M_"x", get_mem(MEM_ROM, addr+2)); break; case 'b': // bitaddr at 2nd byte - if (get_name(get_mem(MEM_ROM, addr+1), bit_tbl(), temp)) - break; - if (get_name(get_bitidx(get_mem(MEM_ROM, addr+1)), - sfr_tbl(), temp)) - { - strcat(temp, "."); - sprintf(c, "%1ld", get_mem(MEM_ROM, addr+1)&0x07); - strcat(temp, c); + { + t_addr ba= get_mem(MEM_ROM, addr+1); + if (get_name(ba, bit_tbl(), temp)) break; - } - sprintf(temp, "%02x.%ld", - get_bitidx(get_mem(MEM_ROM, addr+1)), - get_mem(MEM_ROM, addr+1)&0x07); - break; + if (get_name((ba<128)?((ba/8)+32):(ba&0xf8), sfr_tbl(), temp)) + { + strcat(temp, "."); + sprintf(c, "%1"_M_"d", ba & 0x07); + strcat(temp, c); + break; + } + sprintf(temp, "%02x.%"_M_"d", (ba<128)?((ba/8)+32):(ba&0xf8), + ba & 0x07); + break; + } case 'r': // rel8 address at 2nd byte - sprintf(temp, "%04lx", - addr+2+(signed char)(get_mem(MEM_ROM, addr+1))); + sprintf(temp, "%04"_A_"x", + t_addr(addr+2+(signed char)(get_mem(MEM_ROM, addr+1)))); break; case 'R': // rel8 address at 3rd byte - sprintf(temp, "%04lx", - addr+3+(signed char)(get_mem(MEM_ROM, addr+2))); + sprintf(temp, "%04"_A_"x", + t_addr(addr+3+(signed char)(get_mem(MEM_ROM, addr+2)))); break; case 'd': // data8 at 2nd byte - sprintf(temp, "%02lx", get_mem(MEM_ROM, addr+1)); + sprintf(temp, "%02"_M_"x", get_mem(MEM_ROM, addr+1)); break; case 'D': // data8 at 3rd byte - sprintf(temp, "%02lx", get_mem(MEM_ROM, addr+2)); + sprintf(temp, "%02"_M_"x", get_mem(MEM_ROM, addr+2)); break; case '6': // data16 at 2nd(H)-3rd(L) byte - sprintf(temp, "%04lx", - get_mem(MEM_ROM, addr+1)*256 + get_mem(MEM_ROM, addr+2)); + sprintf(temp, "%04"_A_"x", + t_addr(get_mem(MEM_ROM, addr+1)*256 + + get_mem(MEM_ROM, addr+2))); break; default: strcpy(temp, "?"); @@ -376,54 +394,59 @@ t_uc51::print_regs(class cl_console *con) t_addr start; uchar data; - start= sfr->get(PSW) & 0x18; + start= psw->get() & 0x18; //dump_memory(iram, &start, start+7, 8, /*sim->cmd_out()*/con, sim); iram->dump(start, start+7, 8, con); - start= sfr->get(PSW) & 0x18; + start= psw->get() & 0x18; data= iram->get(iram->get(start)); con->dd_printf("%06x %02x %c", - iram->get(start), data, isprint(data)?data:'.'); + iram->get(start), data, isprint(data)?data:'.'); - con->dd_printf(" ACC= 0x%02x %3d %c B= 0x%02x", - sfr->get(ACC), sfr->get(ACC), - isprint(sfr->get(ACC))?(sfr->get(ACC)):'.', sfr->get(B)); + con->dd_printf(" ACC= 0x%02x %3d %c B= 0x%02x", sfr->get(ACC), sfr->get(ACC), + isprint(sfr->get(ACC))?(sfr->get(ACC)):'.', sfr->get(B)); eram2xram(); data= get_mem(MEM_XRAM, sfr->get(DPH)*256+sfr->get(DPL)); con->dd_printf(" DPTR= 0x%02x%02x @DPTR= 0x%02x %3d %c\n", sfr->get(DPH), - sfr->get(DPL), data, data, isprint(data)?data:'.'); + sfr->get(DPL), data, data, isprint(data)?data:'.'); data= iram->get(iram->get(start+1)); con->dd_printf("%06x %02x %c", iram->get(start+1), data, - isprint(data)?data:'.'); - data= sfr->get(PSW); + isprint(data)?data:'.'); + data= psw->get(); con->dd_printf(" PSW= 0x%02x CY=%c AC=%c OV=%c P=%c\n", data, - (data&bmCY)?'1':'0', (data&bmAC)?'1':'0', - (data&bmOV)?'1':'0', (data&bmP)?'1':'0'); + (data&bmCY)?'1':'0', (data&bmAC)?'1':'0', + (data&bmOV)?'1':'0', (data&bmP)?'1':'0'); print_disass(PC, con); } -bool -t_uc51::extract_bit_address(t_addr bit_address, - class cl_mem **mem, - t_addr *mem_addr, - t_mem *bit_mask) +/* + * Converting bit address into real memory + */ + +class cl_mem * +t_uc51::bit2mem(t_addr bitaddr, t_addr *memaddr, t_mem *bitmask) { - if (mem) - *mem= sfr; - if (bit_address > 0xff) - return(DD_FALSE); - if (bit_mask) - *bit_mask= 1 << (bit_address % 8); - if (mem_addr) + class cl_mem *m; + t_addr ma; + + bitaddr&= 0xff; + if (bitaddr < 128) { - if (bit_address < 0x80) - *mem_addr= bit_address/8 + 0x20; - else - *mem_addr= bit_address & 0xf8; + m= iram; + ma= bitaddr/8 + 0x20; } - return(DD_TRUE); + else + { + m= sfr; + ma= bitaddr & 0xf8; + } + if (memaddr) + *memaddr= ma; + if (bitmask) + *bitmask= 1 << (bitaddr & 0x7); + return(m); } @@ -440,18 +463,7 @@ t_uc51::reset(void) result= resGO; - was_reti= DD_FALSE; - - s_tr_t1 = 0; - s_rec_t1 = 0; - s_tr_tick = 0; - s_rec_tick = 0; - s_in = 0; - s_out = 0; - s_sending = DD_FALSE; - s_receiving= DD_FALSE; - s_rec_bit = 0; - s_tr_bit = 0; + //was_reti= DD_FALSE; } @@ -466,13 +478,13 @@ t_uc51::clear_sfr(void) for (i= 0; i < SFR_SIZE; i++) sfr->set(i, 0); - sfr->set(P0, 0xff); - sfr->set(P1, 0xff); - sfr->set(P2, 0xff); - sfr->set(P3, 0xff); - sfr->set(SP, 7); - prev_p1= port_pins[1] & sfr->get(P1); - prev_p3= port_pins[3] & sfr->get(P3); + sfr->/*set*/write(P0, 0xff); + sfr->/*set*/write(P1, 0xff); + sfr->/*set*/write(P2, 0xff); + sfr->/*set*/write(P3, 0xff); + sfr->/*set*/write(SP, 7); + prev_p1= /*port_pins[1] &*/ sfr->/*get*/read(P1); + prev_p3= /*port_pins[3] &*/ sfr->/*get*/read(P3); } @@ -545,17 +557,21 @@ t_uc51::analyze(t_addr addr) * Inform hardware elements that `cycles' machine cycles have elapsed */ -int -t_uc51::tick(int cycles) +/*int +t_uc51::tick_hw(int cycles) { - int l; + cl_uc::tick_hw(cycles); + //do_hardware(cycles); + return(0); +}*/ +/*int +t_uc51::tick(int cycles) +{ cl_uc::tick(cycles); - do_hardware(cycles); - s_tr_tick+= (l= cycles * clock_per_cycle()); - s_rec_tick+= l; + //do_hardware(cycles); return(0); -} +}*/ /* @@ -565,35 +581,13 @@ t_uc51::tick(int cycles) * or an SFR. */ -uchar * -t_uc51::get_direct(t_mem addr, t_addr *ev_i, t_addr *ev_s) +class cl_cell * +t_uc51::get_direct(t_mem addr) { if (addr < SFR_START) - { - return(&(iram->umem8[*ev_i= addr])); - //return(&(MEM(MEM_IRAM)[*ev_i= addr])); - } - else - { - return(&(sfr->umem8[*ev_s= addr])); - //return(&(MEM(MEM_SFR)[*ev_s= addr])); - } -} - -/* - * Calculating address of indirectly addressed IRAM cell - * If CPU is 8051 and addr is over 127, it must be illegal! - */ - -uchar * -t_uc51::get_indirect(uchar addr, int *res) -{ - if (addr >= SFR_START) - *res= resINV_ADDR; + return(iram->get_cell(addr)); else - *res= resGO; - return(&(iram->umem8[addr])); - //return(&(MEM(MEM_IRAM)[addr])); + return(sfr->get_cell(addr)); } @@ -601,115 +595,11 @@ t_uc51::get_indirect(uchar addr, int *res) * Calculating address of specified register cell in IRAM */ -uchar * +class cl_cell * t_uc51::get_reg(uchar regnum) { - return(&(iram->umem8[(sfr->get(PSW) & (bmRS0|bmRS1)) | - (regnum & 0x07)])); - //return(&(MEM(MEM_IRAM)[(sfr->get(PSW) & (bmRS0|bmRS1)) | - // (regnum & 0x07)])); -} - -uchar * -t_uc51::get_reg(uchar regnum, t_addr *event) -{ - return(&(iram->umem8[*event= (sfr->get(PSW) & (bmRS0|bmRS1)) | - (regnum & 0x07)])); - //return(&(MEM(MEM_IRAM)[*event= (sfr->get(PSW) & (bmRS0|bmRS1)) | - // (regnum & 0x07)])); -} - - -/* - * Calculating address of IRAM or SFR cell which contains addressed bit - * Next function returns index of cell which contains addressed bit. - */ - -uchar * -t_uc51::get_bit(uchar bitaddr) -{ - if (bitaddr < 128) - { - return(&(iram->umem8[(bitaddr/8)+32])); - //return(&(MEM(MEM_IRAM)[(bitaddr/8)+32])); - } - return(&(iram->umem8[bitaddr & 0xf8])); - //return(&(MEM(MEM_SFR)[bitaddr & 0xf8])); -} - -uchar * -t_uc51::get_bit(uchar bitaddr, t_addr *ev_i, t_addr *ev_s) -{ - if (bitaddr < 128) - { - return(&(iram->umem8[*ev_i= (bitaddr/8)+32])); - //return(&(MEM(MEM_IRAM)[*ev_i= (bitaddr/8)+32])); - } - return(&(sfr->umem8[*ev_s= bitaddr & 0xf8])); - //return(&(MEM(MEM_SFR)[*ev_s= bitaddr & 0xf8])); -} - -uchar -t_uc51::get_bitidx(uchar bitaddr) -{ - if (bitaddr < 128) - return((bitaddr/8)+32); - return(bitaddr & 0xf8); -} - - -/* - * Processing write operation to IRAM - * - * It starts serial transmition if address is in SFR and it is - * SBUF. Effect on IE is also checked. - */ - -void -t_uc51::proc_write(uchar *addr) -{ - if (addr == &((sfr->umem8)[SBUF])) - { - s_out= sfr->get(SBUF); - s_sending= DD_TRUE; - s_tr_bit = 0; - s_tr_tick= 0; - s_tr_t1 = 0; - } - if (addr == &((sfr->umem8)[IE])) - was_reti= DD_TRUE; -} - -void -t_uc51::proc_write_sp(uchar val) -{ - if (val > sp_max) - sp_max= val; - sp_avg= (sp_avg+val)/2; -} - - -/* - * Reading IRAM or SFR, but if address points to a port, it reads - * port pins instead of port latches - */ - -uchar -t_uc51::read(uchar *addr) -{ - //if (addr == &(MEM(MEM_SFR)[P0])) - if (addr == &(sfr->umem8[P0])) - return(get_mem(MEM_SFR, P0) & port_pins[0]); - //if (addr == &(MEM(MEM_SFR)[P1])) - if (addr == &(sfr->umem8[P1])) - return(get_mem(MEM_SFR, P1) & port_pins[1]); - //if (addr == &(MEM(MEM_SFR)[P2])) - if (addr == &(sfr->umem8[P2])) - return(get_mem(MEM_SFR, P2) & port_pins[2]); - //if (addr == &(MEM(MEM_SFR)[P3])) - if (addr == &(sfr->umem8[P3])) - return(get_mem(MEM_SFR, P3) & port_pins[3]); - return(*addr); + t_addr a= (psw->get() & (bmRS0|bmRS1)) | (regnum & 0x07); + return(iram->get_cell(a)); } @@ -717,27 +607,17 @@ t_uc51::read(uchar *addr) * Fetching one instruction and executing it */ -void -t_uc51::pre_inst(void) -{ - event_at.wi= (t_addr)-1; - event_at.ri= (t_addr)-1; - event_at.wx= (t_addr)-1; - event_at.rx= (t_addr)-1; - event_at.ws= (t_addr)-1; - event_at.rs= (t_addr)-1; - event_at.rc= (t_addr)-1; -} - int t_uc51::exec_inst(void) { - ulong code; + t_mem code; int res; //pr_inst(); + instPC= PC; if (fetch(&code)) return(resBREAKPOINT); + //tick_hw(1); tick(1); switch (code) { @@ -904,12 +784,12 @@ t_uc51::do_inst(int step) step--; if (state == stGO) { - was_reti= DD_FALSE; + interrupt->was_reti= DD_FALSE; pre_inst(); result= exec_inst(); post_inst(); - if (result == resGO) - result= check_events(); + /*if (result == resGO) + result= check_events();*/ } else { @@ -957,35 +837,33 @@ t_uc51::do_inst(int step) return(result); } -void +/*void t_uc51::post_inst(void) -{ - uint tcon= sfr->get(TCON); - uint p3= sfr->get(P3); - - set_p_flag(); +{*/ + //uint tcon= sfr->get(TCON); + //uint p3= sfr->read(P3); - // Read of SBUF must be serial input data - sfr->set(SBUF, s_in); + //cl_uc::post_inst(); + //set_p_flag(); // Setting up external interrupt request bits (IEx) - if ((tcon & bmIT0)) + /*if ((tcon & bmIT0)) { // IE0 edge triggered - if ((prev_p3 & bm_INT0) && - !(p3 & port_pins[3] & bm_INT0)) - // falling edge on INT0 + if (p3_int0_edge) { + // falling edge on INT0 sim->app->get_commander()-> debug("%g sec (%d clks): Falling edge detected on INT0 (P3.2)\n", get_rtime(), ticks->ticks); sfr->set_bit1(TCON, bmIE0); + p3_int0_edge= 0; } } else { // IE0 level triggered - if (p3 & port_pins[3] & bm_INT0) + if (p3 & bm_INT0) sfr->set_bit0(TCON, bmIE0); else sfr->set_bit1(TCON, bmIE0); @@ -993,413 +871,35 @@ t_uc51::post_inst(void) if ((tcon & bmIT1)) { // IE1 edge triggered - if ((prev_p3 & bm_INT1) && - !(p3 & port_pins[3] & bm_INT1)) - // falling edge on INT1 - sfr->set_bit1(TCON, bmIE1); + if (p3_int1_edge) + { + // falling edge on INT1 + sfr->set_bit1(TCON, bmIE1); + p3_int1_edge= 0; + } } else { // IE1 level triggered - if (p3 & port_pins[3] & bm_INT1) + if (p3 & bm_INT1) sfr->set_bit0(TCON, bmIE1); else sfr->set_bit1(TCON, bmIE1); - } - prev_p3= p3 & port_pins[3]; - prev_p1= p3 & port_pins[1]; -} - - -/* - * Setting up parity flag - */ - -void -t_uc51::set_p_flag(void) -{ - bool p; - int i; - uchar uc; - - p = DD_FALSE; - uc= sfr->get(ACC); - for (i= 0; i < 8; i++) - { - if (uc & 1) - p= !p; - uc>>= 1; - } - SET_BIT(p, PSW, bmP); -} - -/* - * Simulating hardware elements - */ - -int -t_uc51::do_hardware(int cycles) -{ - int res; - - if ((res= do_timers(cycles)) != resGO) - return(res); - if ((res= do_serial(cycles)) != resGO) - return(res); - return(do_wdt(cycles)); -} - - -/* - * - */ - -int -t_uc51::serial_bit_cnt(int mode) -{ - int /*mode,*/ divby= 12; - int *tr_src= 0, *rec_src= 0; - - //mode= sfr->get(SCON) >> 6; - switch (mode) - { - case 0: - divby = 12; - tr_src = &s_tr_tick; - rec_src= &s_rec_tick; - break; - case 1: - case 3: - divby = (sfr->get(PCON)&bmSMOD)?16:32; - tr_src = &s_tr_t1; - rec_src= &s_rec_t1; - break; - case 2: - divby = (sfr->get(PCON)&bmSMOD)?16:32; - tr_src = &s_tr_tick; - rec_src= &s_rec_tick; - break; - } - if (s_sending) - { - while (*tr_src >= divby) - { - (*tr_src)-= divby; - s_tr_bit++; - } - } - if (s_receiving) - { - while (*rec_src >= divby) - { - (*rec_src)-= divby; - s_rec_bit++; - } - } - return(0); -} - - -/* - * Simulating serial line - */ - -int -t_uc51::do_serial(int cycles) -{ - int mode, bits= 8; - char c; - uint scon= sfr->get(SCON); - - mode= scon >> 6; - switch (mode) - { - case 0: - bits= 8; - break; - case 1: - bits= 10; - break; - case 2: - case 3: - bits= 11; - break; - } - serial_bit_cnt(mode); - if (s_sending && - (s_tr_bit >= bits)) - { - s_sending= DD_FALSE; - sfr->set_bit1(SCON, bmTI); - if (serial_out) - { - putc(s_out, serial_out); - fflush(serial_out); - } - s_tr_bit-= bits; - } - if ((scon & bmREN) && - serial_in && - !s_receiving) - { - fd_set set; static struct timeval timeout= {0,0}; - FD_ZERO(&set); - FD_SET(fileno(serial_in), &set); - int i= select(fileno(serial_in)+1, &set, NULL, NULL, &timeout); - if (i > 0 && - FD_ISSET(fileno(serial_in), &set)) - { - s_receiving= DD_TRUE; - s_rec_bit= 0; - s_rec_tick= s_rec_t1= 0; - } - } - if (s_receiving && - (s_rec_bit >= bits)) - { - if (::read(fileno(serial_in), &c, 1) == 1) - { - s_in= c; - sfr->set(SBUF, s_in); - received(c); - } - s_receiving= DD_FALSE; - s_rec_bit-= bits; - } - return(resGO); -} - -void -t_uc51::received(int c) -{ - sfr->set_bit1(SCON, bmRI); -} - - -/* - * Simulating timers - */ - -int -t_uc51::do_timers(int cycles) -{ - int res; - - if ((res= do_timer0(cycles)) != resGO) - return(res); - return(do_timer1(cycles)); -} - - -/* - * Simulating timer 0 - */ - -int -t_uc51::do_timer0(int cycles) -{ - uint tmod= sfr->get(TMOD); - uint tcon= sfr->get(TCON); - uint p3= sfr->get(P3); - - if (((tmod & bmGATE0) && - (p3 & port_pins[3] & bm_INT0)) || - (tcon & bmTR0)) - { - if (!(tmod & bmC_T0) || - ((prev_p3 & bmT0) && - !(p3 & port_pins[3] & bmT0))) - { - if (!(tmod & bmM00) && - !(tmod & bmM10)) - { - if (tmod & bmC_T0) - cycles= 1; - while (cycles--) - { - // mod 0, TH= 8 bit t/c, TL= 5 bit precounter - //(MEM(MEM_SFR)[TL0])++; - sfr->add(TL0, 1); - if ((sfr->get(TL0) & 0x1f) == 0) - { - //sfr->set_bit0(TL0, ~0x1f); - sfr->set(TL0, 0); - if (!/*++(MEM(MEM_SFR)[TH0])*/sfr->add(TH0, 1)) - { - sfr->set_bit1(TCON, bmTF0); - t0_overflow(); - } - } - } - } - else if ((tmod & bmM00) && - !(tmod & bmM10)) - { - if (tmod & bmC_T0) - cycles= 1; - while (cycles--) - { - // mod 1 TH+TL= 16 bit t/c - if (!/*++(MEM(MEM_SFR)[TL0])*/sfr->add(TL0, 1)) - { - if (!/*++(MEM(MEM_SFR)[TH0])*/sfr->add(TH0, 1)) - { - sfr->set_bit1(TCON, bmTF0); - t0_overflow(); - } - } - } - } - else if (!(tmod & bmM00) && - (tmod & bmM10)) - { - if (tmod & bmC_T0) - cycles= 1; - while (cycles--) - { - // mod 2 TL= 8 bit t/c auto reload from TH - if (!/*++(MEM(MEM_SFR)[TL0])*/sfr->add(TL0, 1)) - { - sfr->set(TL0, sfr->get(TH0)); - sfr->set_bit1(TCON, bmTF0); - t0_overflow(); - } - } - } - else - { - // mod 3 TL= 8 bit t/c - // TH= 8 bit timer controlled with T1's bits - if (!/*++(MEM(MEM_SFR)[TL0])*/sfr->add(TL0, 1)) - { - sfr->set_bit1(TCON, bmTF0); - t0_overflow(); - } - } - } - } - if ((tmod & bmM00) && - (tmod & bmM10)) - { - if (((tmod & bmGATE1) && - (p3 & port_pins[3] & bm_INT1)) || - (tcon & bmTR1)) - { - if (!/*++(MEM(MEM_SFR)[TH0])*/sfr->add(TH0, 1)) - { - sfr->set_bit1(TCON, bmTF1); - s_tr_t1++; - s_rec_t1++; - t0_overflow(); - } - } - } - return(resGO); -} - -/* - * Called every time when T0 overflows - */ - -int -t_uc51::t0_overflow(void) -{ - return(0); -} - - -/* - * Simulating timer 1 - */ - -int -t_uc51::do_timer1(int cycles) -{ - uint tmod= sfr->get(TMOD); - uint tcon= sfr->get(TCON); - uint p3= sfr->get(P3); - - if (((tmod & bmGATE1) && - (p3 & port_pins[3] & bm_INT1)) || - (tcon & bmTR1)) - { - if (!(tmod & bmC_T1) || - ((prev_p3 & bmT1) && - !(p3 & port_pins[3] & bmT1))) - { - if (!(tmod & bmM01) && - !(tmod & bmM11)) - { - if (tmod & bmC_T0) - cycles= 1; - while (cycles--) - { - // mod 0, TH= 8 bit t/c, TL= 5 bit precounter - if (/*++(MEM(MEM_SFR)[TL1])*/(sfr->add(TL1, 1) & 0x1f) == 0) - { - //sfr->set_bit0(TL1, ~0x1f); - sfr->set(TL1, 0); - if (!/*++(MEM(MEM_SFR)[TH1])*/sfr->add(TH1, 1)) - { - sfr->set_bit1(TCON, bmTF1); - s_tr_t1++; - s_rec_t1++; - } - } - } - } - else if ((tmod & bmM01) && - !(tmod & bmM11)) - { - if (tmod & bmC_T0) - cycles= 1; - while (cycles--) - { - // mod 1 TH+TL= 16 bit t/c - if (!/*++(MEM(MEM_SFR)[TL1])*/sfr->add(TL1, 1)) - if (!/*++(MEM(MEM_SFR)[TH1])*/sfr->add(TH1, 1)) - { - sfr->set_bit1(TCON, bmTF1); - s_tr_t1++; - s_rec_t1++; - } - } - } - else if (!(tmod & bmM01) && - (tmod & bmM11)) - { - if (tmod & bmC_T1) - cycles= 1; - while (cycles--) - { - // mod 2 TL= 8 bit t/c auto reload from TH - if (!/*++(MEM(MEM_SFR)[TL1])*/sfr->add(TL1, 1)) - { - sfr->set(TL1, sfr->get(TH1)); - sfr->set_bit1(TCON, bmTF1); - s_tr_t1++; - s_rec_t1++; - } - } - } - else - // mod 3 stop - ; - } - } - return(resGO); -} + }*/ + //prev_p3= p3 & port_pins[3]; + //prev_p1= p3 & port_pins[1]; +//} /* * Abstract method to handle WDT */ -int +/*int t_uc51::do_wdt(int cycles) { return(resGO); -} +}*/ /* @@ -1411,9 +911,9 @@ t_uc51::do_interrupt(void) { int i, ie= 0; - if (was_reti) + if (interrupt->was_reti) { - was_reti= DD_FALSE; + interrupt->was_reti= DD_FALSE; return(resGO); } if (!((ie= sfr->get(IE)) & bmEA)) @@ -1434,7 +934,7 @@ t_uc51::do_interrupt(void) { state= stGO; sfr->set_bit0(PCON, bmIDL); - was_reti= 1; + interrupt->was_reti= DD_TRUE; return(resGO); } if (is->clr_bit) @@ -1513,7 +1013,7 @@ t_uc51::idle_pd(void) * Checking if EVENT break happened */ -int +/*int t_uc51::check_events(void) { int i; @@ -1528,6 +1028,22 @@ t_uc51::check_events(void) return(resBREAKPOINT); } return(resGO); +}*/ + + +/* + */ + +void +t_uc51::mem_cell_changed(class cl_mem *mem, t_addr addr) +{ + if (mem == sfr) + switch (addr) + { + case ACC: acc= mem->get_cell(ACC); break; + case PSW: psw= mem->get_cell(PSW); break; + } + cl_uc::mem_cell_changed(mem, addr); } @@ -1567,9 +1083,7 @@ t_uc51::inst_nop(uchar code) int t_uc51::inst_clr_a(uchar code) { - ulong d= 0; - - sfr->write(ACC, &d); + acc->write(0); return(resGO); } @@ -1583,10 +1097,86 @@ t_uc51::inst_swap(uchar code) { uchar temp; - temp= (sfr->read(ACC) >> 4) & 0x0f; - sfr->set(ACC, (sfr->get(ACC) << 4) | temp); + temp= (acc->read() >> 4) & 0x0f; + sfr->write(ACC, (acc->get() << 4) | temp); return(resGO); } +/* + */ + +cl_uc51_dummy_hw::cl_uc51_dummy_hw(class cl_uc *auc): + cl_hw(auc, HW_DUMMY, 0, "_51_dummy") +{ + //uc51= (class t_uc51 *)uc; +} + +int +cl_uc51_dummy_hw::init(void) +{ + class cl_mem *sfr= uc->mem(MEM_SFR); + if (!sfr) + { + fprintf(stderr, "No SFR to register %s[%d] into\n", id_string, id); + } + //acc= sfr->register_hw(ACC, this, 0); + //sp = sfr->register_hw(SP , this, 0); + use_cell(sfr, PSW, &cell_psw, wtd_restore); + register_cell(sfr, ACC, &cell_acc, wtd_restore_write); + register_cell(sfr, SP , &cell_sp , wtd_restore); + return(0); +} + +void +cl_uc51_dummy_hw::write(class cl_cell *cell, t_mem *val) +{ + if (cell == cell_acc) + { + bool p; + int i; + uchar uc; + + p = DD_FALSE; + uc= *val; + for (i= 0; i < 8; i++) + { + if (uc & 1) + p= !p; + uc>>= 1; + } + if (p) + cell_psw->set_bit1(bmP); + else + cell_psw->set_bit0(bmP); + } + else if (cell == cell_sp) + { + if (*val > uc->sp_max) + uc->sp_max= *val; + uc->sp_avg= (uc->sp_avg+(*val))/2; + } +} + +/*void +cl_uc51_dummy_hw::happen(class cl_hw *where, enum hw_event he, void *params) +{ + struct ev_port_changed *ep= (struct ev_port_changed *)params; + + if (where->cathegory == HW_PORT && + he == EV_PORT_CHANGED && + ep->id == 3) + { + t_mem p3o= ep->pins & ep->prev_value; + t_mem p3n= ep->new_pins & ep->new_value; + if ((p3o & bm_INT0) && + !(p3n & bm_INT0)) + uc51->p3_int0_edge++; + if ((p3o & bm_INT1) && + !(p3n & bm_INT1)) + uc51->p3_int1_edge++; + } +}*/ + + /* End of s51.src/uc51.cc */ diff --git a/sim/ucsim/s51.src/uc51cl.h b/sim/ucsim/s51.src/uc51cl.h index 840b8343..01ff7fbb 100644 --- a/sim/ucsim/s51.src/uc51cl.h +++ b/sim/ucsim/s51.src/uc51cl.h @@ -40,6 +40,8 @@ Software Foundation, 59 Temple Place - Suite 330, Boston, MA #include "brkcl.h" #include "stypes.h" +#include "interruptcl.h" + class t_uc51: public cl_uc { @@ -47,44 +49,28 @@ public: // Options bool debug; bool stop_at_it; -int jaj; - // Data for breakpoint handling - struct event_rec event_at; - - FILE *serial_in; // Serial line input - FILE *serial_out; // Serial line output + // memories and cells for faster access class cl_mem *sfr, *iram; + class cl_cell *acc, *psw; -protected: - struct termios saved_attributes_in; // Attributes of serial interface - struct termios saved_attributes_out; - +public: // Help to detect external it requests (falling edge) uchar prev_p1; // Prev state of P1 uchar prev_p3; // Prev state of P3 - - // Seral line simulation - uchar s_in; // Serial channel input reg - uchar s_out; // Serial channel output reg - bool s_sending; // Transmitter is working - bool s_receiving; // Receiver is working - int s_rec_bit; // Bit counter of receiver - int s_tr_bit; // Bit counter of transmitter - int s_rec_t1; // T1 overflows for receiving - int s_tr_t1; // T1 overflows for sending - int s_rec_tick; // Machine cycles for receiving - int s_tr_tick; // Machine cycles for sending + int p3_int0_edge, p3_int1_edge; +public: // Simulation of interrupt system - bool was_reti; // Instruction had an effect on IE + class cl_interrupt *interrupt; + //bool was_reti; // Instruction had an effect on IE public: int result; // result of instruction execution t_uc51(int Itype, int Itech, class cl_sim *asim); - ~t_uc51(void); + virtual ~t_uc51(void); virtual int init(void); virtual char *id_string(void); virtual void mk_hw_elements(void); @@ -95,50 +81,30 @@ public: virtual struct dis_entry *dis_tbl(void); virtual struct name_entry *sfr_tbl(void); virtual struct name_entry *bit_tbl(void); - //virtual char *disass(uint addr, char *sep); virtual char *disass(t_addr addr, char *sep); virtual void print_regs(class cl_console *con); - virtual bool extract_bit_address(t_addr bit_address, - class cl_mem **mem, - t_addr *mem_addr, - t_mem *bit_mask); + virtual class cl_mem *bit2mem(t_addr bitaddr, + t_addr *memaddr, t_mem *bitmask); virtual void reset(void); virtual void clear_sfr(void); virtual void analyze(t_addr addr); - virtual void set_p_flag(void); - virtual void proc_write(uchar *addr); - virtual void proc_write_sp(uchar val); - virtual uchar *get_bit(uchar bitaddr); - virtual uchar *get_bit(uchar bitaddr, t_addr *ev_i, t_addr *ev_s); virtual int it_priority(uchar ie_mask); virtual int do_inst(int step); + virtual void mem_cell_changed(class cl_mem *mem, t_addr addr); + protected: - virtual int do_hardware(int cycles); virtual int do_interrupt(void); virtual int accept_it(class it_level *il); - virtual int serial_bit_cnt(int mode); - virtual int do_serial(int cycles); - virtual void received(int c); - virtual int do_timers(int cycles); - virtual int do_timer0(int cycles); - virtual int t0_overflow(void); - virtual int do_timer1(int cycles); - virtual int do_wdt(int cycles); +protected: virtual int idle_pd(void); - virtual int tick(int cycles); - virtual int check_events(void); - virtual uchar *get_direct(t_mem addr, t_addr *ev_i, t_addr *ev_s); - virtual uchar *get_indirect(uchar addr, int *res); - virtual uchar *get_reg(uchar regnum); - virtual uchar *get_reg(uchar regnum, t_addr *event); - virtual uchar get_bitidx(uchar bitaddr); - virtual uchar read(uchar *addr); - virtual void pre_inst(void); + virtual class cl_cell *get_direct(t_mem addr); + virtual class cl_cell *get_reg(uchar regnum); + virtual int exec_inst(void); - virtual void post_inst(void); + //virtual void post_inst(void); virtual int inst_unknown(uchar code); virtual int inst_nop(uchar code); /* 00 */ @@ -254,6 +220,20 @@ protected: }; +class cl_uc51_dummy_hw: public cl_hw +{ +protected: + //class t_uc51 *uc51; + class cl_cell *cell_acc, *cell_sp, *cell_psw; +public: + cl_uc51_dummy_hw(class cl_uc *auc); + virtual int init(void); + + virtual void write(class cl_cell *cell, t_mem *val); + //virtual void happen(class cl_hw *where, enum hw_event he, void *params); +}; + + #endif /* End of s51.src/uc51cl.h */ diff --git a/sim/ucsim/s51.src/uc51r.cc b/sim/ucsim/s51.src/uc51r.cc index f3f9da63..44a2c995 100644 --- a/sim/ucsim/s51.src/uc51r.cc +++ b/sim/ucsim/s51.src/uc51r.cc @@ -32,6 +32,8 @@ Software Foundation, 59 Temple Place - Suite 330, Boston, MA // local #include "uc51rcl.h" #include "regs51.h" +#include "types51.h" +#include "wdtcl.h" /* @@ -49,6 +51,17 @@ t_uc51r::t_uc51r(int Itype, int Itech, class cl_sim *asim): } +void +t_uc51r::mk_hw_elements(void) +{ + class cl_hw *h; + + t_uc52::mk_hw_elements(); + hws->add(h= new cl_wdt(this, 0x3fff)); + h->init(); +} + + /* * Resetting of the microcontroller * @@ -59,9 +72,6 @@ void t_uc51r::reset(void) { t_uc52::reset(); - WDT= -1; // Disable WDT - wdtrst= 0; - //MEM(MEM_SFR)[SADDR]= MEM(MEM_SFR)[SADEN]= 0; sfr->set(SADDR, 0); sfr->set(SADEN, 0); } @@ -93,293 +103,24 @@ t_uc51r::xram2eram(void) } -/* - * Processing write operation of SFR - * - * Inherited method is extended with WDT handling. - */ - -void -t_uc51r::proc_write(uchar *addr) -{ - t_uc52::proc_write(addr); - // Handling WDT - if (addr == &(/*MEM(MEM_SFR)*/sfr->umem8[WDTRST])) - { - if ((wdtrst == 0x1e) && - (*addr == 0xe1)) - { - WDT= 0; - sim->app->get_commander()-> - debug("%g sec (%d tick): Watchdog timer enabled/reset PC= 0x%06x" - "\n", get_rtime(), ticks->ticks, PC); - } - wdtrst= *addr; - } -} - - -/* - * Simulating timers - * - * Calling inherited method to simulate timer #0 and #1 and then - * simulating timer #2. - */ - -int -t_uc51r::do_timers(int cycles) -{ - int res; - - if ((res= t_uc51::do_timers(cycles)) != resGO) - return(res); - return(do_timer2(cycles)); -} - - -/* - * Simulating timer 2 - * - * It is something wrong: T2MOD is not implemented in 52?! - */ - -int -t_uc51r::do_timer2(int cycles) -{ - bool nocount= DD_FALSE; - uint t2mod= get_mem(MEM_SFR, T2MOD); - uint t2con= get_mem(MEM_SFR, T2CON); - uint p1= get_mem(MEM_SFR, P1); - - exf2it->activate(); - if (!(t2con & bmTR2)) - /* Timer OFF */ - return(resGO); - - if (t2mod & bmT2OE) - return(do_t2_clockout(cycles)); - - if (t2con & (bmRCLK | bmTCLK)) - return(do_t2_baud(cycles)); - - /* Determining nr of input clocks */ - if (!(t2con & bmTR2)) - nocount= DD_TRUE; // Timer OFF - else - if (t2con & bmC_T2) - { - // Counter mode, falling edge on P1.0 (T2) - if ((prev_p1 & bmT2) && - !(p1 & port_pins[1] & bmT2)) - cycles= 1; - else - nocount= DD_TRUE; - } - /* Counting */ - while (cycles--) - { - if (t2con & bmCP_RL2) - do_t2_capture(&cycles, nocount); - else - { - int overflow; - overflow= 0; - /* Auto-Relode mode */ - if (t2mod & bmDCEN) - { - /* DCEN= 1 */ - exf2it->deactivate(); - if (nocount) - cycles= 0; - else - { - if (p1 & port_pins[1] & bmT2EX) - { - // UP - if (!/*++(MEM(MEM_SFR)[TL2])*/sfr->add(TL2, 1)) - if (!/*++(MEM(MEM_SFR)[TH2])*/sfr->add(TH2, 1)) - { - overflow++; - //MEM(MEM_SFR)[TH2]= MEM(MEM_SFR)[RCAP2H]; - sfr->set(TH2, sfr->get(RCAP2H)); - //MEM(MEM_SFR)[TL2]= MEM(MEM_SFR)[RCAP2L]; - sfr->set(TL2, sfr->get(RCAP2L)); - mem(MEM_SFR)->set_bit1(T2CON, bmTF2); - } - } - else - { - // DOWN - //MEM(MEM_SFR)[TL2]--; - if (/*MEM(MEM_SFR)[TL2]*/sfr->add(TL2, -1) == 0xff) - /*MEM(MEM_SFR)[TH2]--*/sfr->add(TH2, -1); - /*if (MEM(MEM_SFR)[TH2] == MEM(MEM_SFR)[RCAP2H] && - MEM(MEM_SFR)[TL2] == MEM(MEM_SFR)[RCAP2L])*/ - if (sfr->get(TH2) == sfr->get(RCAP2H) && - sfr->get(TL2) == sfr->get(RCAP2L)) - { - overflow++; - //MEM(MEM_SFR)[TH2]= MEM(MEM_SFR)[TL2]= 0xff; - sfr->set(TH2, 0xff); - sfr->set(TL2, 0xff); - mem(MEM_SFR)->set_bit1(T2CON, bmTF2); - } - } - while (overflow--) - //MEM(MEM_SFR)[P1]^= bmEXF2; - sfr->set(P1, sfr->get(P1) ^ bmEXF2); - } - } - else - /* DCEN= 0 */ - do_t2_reload(&cycles, nocount); - } - }// while cycles - - return(resGO); -} - - -/* - * Clock out mode of Timer #2 - */ - -int -t_uc51r::do_t2_clockout(int cycles) -{ - uint t2con= get_mem(MEM_SFR, T2CON); - uint p1= get_mem(MEM_SFR, P1); - - /* Programmable Clock Out Mode */ - if ((prev_p1 & bmT2EX) && - !(p1 & port_pins[1] & bmT2EX) && - (t2con & bmEXEN2)) - mem(MEM_SFR)->set_bit1(T2CON, bmEXF2); - if (t2con & bmCP_RL2) - return(resGO); - if (t2con & bmC_T2) - { - if ((prev_p1 & bmT2) && - !(p1 & port_pins[1] & bmT2)) - cycles= 1; - else - cycles= 0; - } - else - cycles*= 6; - if (t2con & bmTR2) - while (cycles--) - { - if (!/*++(MEM(MEM_SFR)[TL2])*/sfr->add(TL2, 1)) - if (!/*++(MEM(MEM_SFR)[TH2])*/sfr->add(TH2, 1)) - { - //MEM(MEM_SFR)[TH2]= MEM(MEM_SFR)[RCAP2H]; - sfr->set(TH2, sfr->get(RCAP2H)); - //MEM(MEM_SFR)[TL2]= MEM(MEM_SFR)[RCAP2L]; - sfr->set(TL2, sfr->get(RCAP2L)); - clock_out++; - if (!(t2con & bmC_T2)) - { - SET_BIT((clock_out&1), P1, bmT2); - } - } - } - return(resGO); -} - - -/* - * Handling serial line - */ - -int -t_uc51r::serial_bit_cnt(int mode) -{ - int divby= 12; - int *tr_src= 0, *rec_src= 0; - - switch (mode) - { - case 0: - divby = 12; - tr_src = &s_tr_tick; - rec_src= &s_rec_tick; - break; - case 1: - case 3: - divby = (get_mem(MEM_SFR, PCON)&bmSMOD)?16:32; - tr_src = (get_mem(MEM_SFR, T2CON)&bmTCLK)?(&s_tr_t2):(&s_tr_t1); - rec_src= (get_mem(MEM_SFR, T2CON)&bmTCLK)?(&s_rec_t2):(&s_rec_t1); - break; - case 2: - divby = (get_mem(MEM_SFR, PCON)&bmSMOD)?16:32; - tr_src = &s_tr_tick; - rec_src= &s_rec_tick; - break; - } - if (s_sending) - { - while (*tr_src >= divby) - { - (*tr_src)-= divby; - s_tr_bit++; - } - } - if (s_receiving) - { - while (*rec_src >= divby) - { - (*rec_src)-= divby; - s_rec_bit++; - } - } - return(0); -} - void t_uc51r::received(int c) { - uint br= get_mem(MEM_SFR, SADDR) | get_mem(MEM_SFR, SADEN); - int scon= get_mem(MEM_SFR, SCON); + t_mem br= sfr->get(SADDR) | sfr->get(SADEN); + int scon= sfr->get(SCON); if ((0 < scon >> 6) && (scon & bmSM2)) { - if ( - /* Check for individual address */ - ((get_mem(MEM_SFR, SADDR) & get_mem(MEM_SFR, SADEN)) == - (c & get_mem(MEM_SFR, SADEN))) + if (/* Check for individual address */ + ((sfr->get(SADDR) & sfr->get(SADEN)) == (c & sfr->get(SADEN))) || /* Check for broadcast address */ - (br == (br & c)) - ) - mem(MEM_SFR)->set_bit1(SCON, bmRI); + (br == (br & c))) + sfr->set_bit1(SCON, bmRI); return; } - mem(MEM_SFR)->set_bit1(SCON, bmRI); -} - - -/* - * Handling WDT - */ - -int -t_uc51r::do_wdt(int cycles) -{ - if (WDT >= 0) - { - WDT+= cycles; - if (WDT & ~(0x3fff)) - { - sim->app->get_commander()-> - debug("%g sec (%d ticks): Watchdog timer resets the CPU, " - "PC= 0x%06x\n", get_rtime(), ticks->ticks, PC); - reset(); - return(resWDTRESET); - } - } - return(resGO); + sfr->set_bit1(SCON, bmRI); } @@ -392,20 +133,13 @@ t_uc51r::do_wdt(int cycles) int t_uc51r::inst_movx_a_$dptr(uchar code) { - if ((get_mem(MEM_SFR, AUXR) & bmEXTRAM) || - /*MEM(MEM_SFR)[DPH]*/sfr->get(DPH)) - /*MEM(MEM_SFR)[event_at.ws= ACC]= read_mem(MEM_XRAM, - event_at.rx= - MEM(MEM_SFR)[DPH]*256+ - MEM(MEM_SFR)[DPL]);*/ - sfr->set(event_at.ws= ACC, read_mem(MEM_XRAM, - event_at.rx= - /*MEM(MEM_SFR)[DPH]*/sfr->get(DPH)*256+ - /*MEM(MEM_SFR)[DPL]*/sfr->get(DPL))); + if ((sfr->get(AUXR) & bmEXTRAM) || + sfr->get(DPH)) + acc->write(read_mem(MEM_XRAM, + sfr->read(DPH)*256+ + sfr->read(DPL))); else - //MEM(MEM_SFR)[event_at.ws= ACC]= ERAM[event_at.rx= MEM(MEM_SFR)[DPL]]; - sfr->set(event_at.ws= ACC, ERAM[event_at.rx= - /*MEM(MEM_SFR)[DPL]*/sfr->get(DPL)]); + acc->write(ERAM[sfr->read(DPL)]); tick(1); return(resGO); } @@ -420,23 +154,17 @@ t_uc51r::inst_movx_a_$dptr(uchar code) int t_uc51r::inst_movx_a_$ri(uchar code) { - uchar *addr; - int res; - - addr= get_indirect(*(get_reg(code & 0x01)), &res); - if (get_mem(MEM_SFR, AUXR) & bmEXTRAM) - /*MEM(MEM_SFR)[event_at.ws= ACC]= - read_mem(MEM_XRAM, - event_at.rx= (MEM(MEM_SFR)[P2]&port_pins[2])*256+*addr);*/ - sfr->set(event_at.ws= ACC, - read_mem(MEM_XRAM, - event_at.rx= - (/*MEM(MEM_SFR)[P2]*/sfr->get(P2)&port_pins[2])*256+*addr)); + class cl_cell *cell; + t_mem d= 0; + + cell= iram->get_cell(get_reg(code & 0x01)->read()); + d= cell->read(); + if (sfr->get(AUXR) & bmEXTRAM) + acc->write(read_mem(MEM_XRAM, sfr->read(P2)*256+d)); else - //MEM(MEM_SFR)[event_at.ws= ACC]= ERAM[event_at.rx= *addr]; - sfr->set(event_at.ws= ACC, ERAM[event_at.rx= *addr]); + acc->write(ERAM[d]); tick(1); - return(res); + return(resGO); } @@ -449,15 +177,11 @@ t_uc51r::inst_movx_a_$ri(uchar code) int t_uc51r::inst_movx_$dptr_a(uchar code) { - if ((get_mem(MEM_SFR, AUXR) & bmEXTRAM) || - /*MEM(MEM_SFR)[DPH]*/sfr->get(DPH)) - write_mem(MEM_XRAM, - event_at.wx= /*MEM(MEM_SFR)[DPH]*/sfr->get(DPH)*256 + - /*MEM(MEM_SFR)[DPL]*/sfr->get(DPL), - /*MEM(MEM_SFR)[event_at.rs= ACC]*/sfr->get(event_at.rs= ACC)); + if ((sfr->get(AUXR) & bmEXTRAM) || + sfr->get(DPH)) + write_mem(MEM_XRAM, sfr->read(DPH)*256 + sfr->read(DPL), acc->read()); else - ERAM[event_at.wx= /*MEM(MEM_SFR)[DPL]*/sfr->get(DPL)]= - /*MEM(MEM_SFR)[*/sfr->get(event_at.rs= ACC)/*]*/; + ERAM[sfr->read(DPL)]= acc->read(); return(resGO); } @@ -471,19 +195,17 @@ t_uc51r::inst_movx_$dptr_a(uchar code) int t_uc51r::inst_movx_$ri_a(uchar code) { - uchar *addr; - int res; - - addr= get_indirect(event_at.wi= *(get_reg(code & 0x01)), &res); - if (get_mem(MEM_SFR, AUXR) & bmEXTRAM) - write_mem(MEM_XRAM, - event_at.wx= - (/*MEM(MEM_SFR)[P2]*/sfr->get(P2) & port_pins[2])*256 + *addr, - /*MEM(MEM_SFR)[ACC]*/sfr->get(ACC)); + class cl_cell *cell; + t_mem d= 0; + + cell= iram->get_cell(get_reg(code & 0x01)->read()); + d= cell->read(); + if (sfr->get(AUXR) & bmEXTRAM) + write_mem(MEM_XRAM, sfr->read(P2)*256 + d, acc->read()); else - ERAM[event_at.wx= *addr]= /*MEM(MEM_SFR)[ACC]*/sfr->get(ACC); + ERAM[d]= acc->read(); tick(1); - return(res); + return(resGO); } diff --git a/sim/ucsim/s51.src/uc51rcl.h b/sim/ucsim/s51.src/uc51rcl.h index 535ceb9f..210750e5 100644 --- a/sim/ucsim/s51.src/uc51rcl.h +++ b/sim/ucsim/s51.src/uc51rcl.h @@ -36,30 +36,24 @@ Software Foundation, 59 Temple Place - Suite 330, Boston, MA class t_uc51r: public t_uc52 { -protected: +public: int clock_out; - int WDT; // If negative then WDT is disabled - uchar wdtrst; public: uchar ERAM[ERAM_SIZE]; public: t_uc51r(int Itype, int Itech, class cl_sim *asim); + virtual void mk_hw_elements(void); virtual void reset(void); virtual void eram2xram(void); virtual void xram2eram(void); - virtual void proc_write(uchar *addr); + //virtual void proc_write(t_addr addr); - virtual int do_timers(int cycles); - virtual int do_timer2(int cycles); - virtual int do_t2_clockout(int cycles); - virtual int serial_bit_cnt(int mode); virtual void received(int c); - virtual int do_wdt(int cycles); virtual int inst_movx_a_$dptr(uchar code); /* e0 */ virtual int inst_movx_a_$ri(uchar code); /* e2,e3 */ diff --git a/sim/ucsim/s51.src/uc52.cc b/sim/ucsim/s51.src/uc52.cc index ea79cabb..122164d3 100644 --- a/sim/ucsim/s51.src/uc52.cc +++ b/sim/ucsim/s51.src/uc52.cc @@ -42,11 +42,11 @@ Software Foundation, 59 Temple Place - Suite 330, Boston, MA t_uc52::t_uc52(int Itype, int Itech, class cl_sim *asim): t_uc51(Itype, Itech, asim) { - it_sources->add(new cl_it_src(bmET2, T2CON, bmTF2, 0x002b, false, - "timer #2 TF2")); - exf2it= new cl_it_src(bmET2, T2CON, bmEXF2, 0x002b, false, + /*it_sources->add(new cl_it_src(bmET2, T2CON, bmTF2, 0x002b, false, + "timer #2 TF2"));*/ + /*exf2it= new cl_it_src(bmET2, T2CON, bmEXF2, 0x002b, false, "timer #2 EXF2"); - it_sources->add(exf2it); + it_sources->add(exf2it);*/ } @@ -56,11 +56,23 @@ t_uc52::mk_hw_elements(void) class cl_hw *h; t_uc51::mk_hw_elements(); - hws->add(h= new cl_timer2(this)); + hws->add(h= new cl_timer2(this, 2, "timer2", t2_default|t2_down)); h->init(); } +t_addr +t_uc52::get_mem_size(enum mem_class type) +{ + switch (type) + { + case MEM_IRAM: return(0x100); + default: return(t_uc51::get_mem_size(type)); + } + return(0); +} + + /* * Calculating address of indirectly addressed IRAM cell * @@ -69,11 +81,11 @@ t_uc52::mk_hw_elements(void) * */ -uchar * +class cl_cell * t_uc52::get_indirect(uchar addr, int *res) { *res= resGO; - return(&(/*MEM(MEM_IRAM)*/iram->umem8[addr])); + return(iram->get_cell(addr)); } @@ -85,22 +97,18 @@ t_uc52::get_indirect(uchar addr, int *res) * */ -int -t_uc52::do_timers(int cycles) +/*void +t_uc52::do_extra_hw(int cycles) { - int res; - - if ((res= t_uc51::do_timers(cycles)) != resGO) - return(res); - return(do_timer2(cycles)); -} + do_timer2(cycles); +}*/ /* * Simulating timer 2 */ -int +/*int t_uc52::do_timer2(int cycles) { bool nocount= DD_FALSE; @@ -108,13 +116,13 @@ t_uc52::do_timer2(int cycles) exf2it->activate(); if (!(t2con & bmTR2)) - /* Timer OFF */ + // Timer OFF return(resGO); if (t2con & (bmRCLK | bmTCLK)) return(do_t2_baud(cycles)); - /* Determining nr of input clocks */ + // Determining nr of input clocks if (!(t2con & bmTR2)) nocount= DD_TRUE; // Timer OFF else @@ -122,12 +130,12 @@ t_uc52::do_timer2(int cycles) { // Counter mode, falling edge on P1.0 (T2) if ((prev_p1 & bmT2) && - !(get_mem(MEM_SFR, P1) & port_pins[1] & bmT2)) + !(sfr->read(P1) & bmT2)) cycles= 1; else nocount= DD_TRUE; } - /* Counting */ + // Counting while (cycles--) { if (t2con & bmCP_RL2) @@ -137,28 +145,28 @@ t_uc52::do_timer2(int cycles) }// while cycles return(resGO); -} +}*/ /* * Baud rate generator mode of Timer #2 */ -int +/*int t_uc52::do_t2_baud(int cycles) { - uint t2con= get_mem(MEM_SFR, T2CON); - uint p1= get_mem(MEM_SFR, P1); + t_mem t2con= sfr->get(T2CON); + //uint p1= get_mem(MEM_SFR, P1); - /* Baud Rate Generator */ + // Baud Rate Generator if ((prev_p1 & bmT2EX) && - !(p1 & port_pins[1] & bmT2EX) && + !(sfr->read(P1) & bmT2EX) && (t2con & bmEXEN2)) mem(MEM_SFR)->set_bit1(T2CON, bmEXF2); if (t2con & bmC_T2) { if ((prev_p1 & bmT2) && - !(p1 & port_pins[1] & bmT2)) + !(sfr->read(P1) & bmT2)) cycles= 1; else cycles= 0; @@ -168,107 +176,101 @@ t_uc52::do_t2_baud(int cycles) if (t2con & bmTR2) while (cycles--) { - if (!/*++(MEM(MEM_SFR)[TL2])*/sfr->add(TL2, 1)) - if (!/*++(MEM(MEM_SFR)[TH2])*/sfr->add(TH2, 1)) + if (!sfr->add(TL2, 1)) + if (!sfr->add(TH2, 1)) { - //MEM(MEM_SFR)[TH2]= MEM(MEM_SFR)[RCAP2H]; sfr->set(TH2, sfr->get(RCAP2H)); - //MEM(MEM_SFR)[TL2]= MEM(MEM_SFR)[RCAP2L]; sfr->set(TL2, sfr->get(RCAP2L)); s_rec_t2++; s_tr_t2++; } } return(resGO); -} +}*/ /* * Capture function of Timer #2 */ -void +/*void t_uc52::do_t2_capture(int *cycles, bool nocount) { - uint p1= get_mem(MEM_SFR, P1); - uint t2con= get_mem(MEM_SFR, T2CON); + //uint p1= get_mem(MEM_SFR, P1); + t_mem t2con= sfr->get(T2CON); - /* Capture mode */ + // Capture mode if (nocount) *cycles= 0; else { - if (!/*++(MEM(MEM_SFR)[TL2])*/sfr->add(TL2, 1)) + if (!sfr->add(TL2, 1)) { - if (!/*++(MEM(MEM_SFR)[TH2])*/sfr->add(TH2, 1)) + if (!sfr->add(TH2, 1)) mem(MEM_SFR)->set_bit1(T2CON, bmTF2); } } // capture if ((prev_p1 & bmT2EX) && - !(p1 & port_pins[1] & bmT2EX) && + !(sfr->read(P1) & bmT2EX) && (t2con & bmEXEN2)) { - //MEM(MEM_SFR)[RCAP2H]= MEM(MEM_SFR)[TH2]; sfr->set(RCAP2H, sfr->get(TH2)); - //MEM(MEM_SFR)[RCAP2L]= MEM(MEM_SFR)[TL2]; sfr->set(RCAP2L, sfr->get(TL2)); mem(MEM_SFR)->set_bit1(T2CON, bmEXF2); prev_p1&= ~bmT2EX; // Falling edge has been handled } -} +}*/ /* * Auto Reload mode of Timer #2, counting UP */ -void +/*void t_uc52::do_t2_reload(int *cycles, bool nocount) { int overflow; bool ext2= 0; - /* Auto-Relode mode */ + // Auto-Relode mode overflow= 0; if (nocount) *cycles= 0; else { - if (!/*++(MEM(MEM_SFR)[TL2])*/sfr->add(TL2, 1)) + if (!sfr->add(TL2, 1)) { - if (!/*++(MEM(MEM_SFR)[TH2])*/sfr->add(TH2, 1)) + if (!sfr->add(TH2, 1)) { - mem(MEM_SFR)->set_bit1(T2CON, bmTF2); + sfr->set_bit1(T2CON, bmTF2); overflow++; } } } // reload if ((prev_p1 & bmT2EX) && - !(get_mem(MEM_SFR, P1) & port_pins[1] & bmT2EX) && - (get_mem(MEM_SFR, T2CON) & bmEXEN2)) + !(sfr->read(P1) & bmT2EX) && + (sfr->get(T2CON) & bmEXEN2)) { ext2= DD_TRUE; - mem(MEM_SFR)->set_bit1(T2CON, bmEXF2); + sfr->set_bit1(T2CON, bmEXF2); prev_p1&= ~bmT2EX; // Falling edge has been handled } if (overflow || ext2) { - //MEM(MEM_SFR)[TH2]= MEM(MEM_SFR)[RCAP2H]; sfr->set(TH2, sfr->get(RCAP2H)); - //MEM(MEM_SFR)[TL2]= MEM(MEM_SFR)[RCAP2L]; sfr->set(TL2, sfr->get(RCAP2L)); } -} +}*/ /* * */ -int +/*int t_uc52::serial_bit_cnt(int mode) { int divby= 12; @@ -308,9 +310,9 @@ t_uc52::serial_bit_cnt(int mode) (*rec_src)-= divby; s_rec_bit++; } - } + } return(0); -} +}*/ /* End of s51.src/uc52.cc */ diff --git a/sim/ucsim/s51.src/uc52cl.h b/sim/ucsim/s51.src/uc52cl.h index e0d6e61a..ff153785 100644 --- a/sim/ucsim/s51.src/uc52cl.h +++ b/sim/ucsim/s51.src/uc52cl.h @@ -37,22 +37,23 @@ Software Foundation, 59 Temple Place - Suite 330, Boston, MA class t_uc52: public t_uc51 { protected: - class cl_it_src *exf2it; - int s_rec_t2; // T2 overflows for receiving - int s_tr_t2; // T2 overflows for sending + //class cl_it_src *exf2it; + //int s_rec_t2; // T2 overflows for receiving + //int s_tr_t2; // T2 overflows for sending public: t_uc52(int Itype, int Itech, class cl_sim *asim); virtual void mk_hw_elements(void); - virtual uchar *get_indirect(uchar addr, int *res); + virtual class cl_cell *get_indirect(uchar addr, int *res); + virtual t_addr get_mem_size(enum mem_class type); - virtual int do_timers(int cycles); + /*virtual void do_extra_hw(int cycles); virtual int do_timer2(int cycles); virtual int do_t2_baud(int cycles); virtual void do_t2_capture(int *cycles, bool nocount); virtual void do_t2_reload(int *cycles, bool nocount); - virtual int serial_bit_cnt(int mode); + virtual int serial_bit_cnt(int mode);*/ }; diff --git a/sim/ucsim/s51.src/uc89c51r.cc b/sim/ucsim/s51.src/uc89c51r.cc index 8021dbdc..3b831f76 100644 --- a/sim/ucsim/s51.src/uc89c51r.cc +++ b/sim/ucsim/s51.src/uc89c51r.cc @@ -32,12 +32,13 @@ Software Foundation, 59 Temple Place - Suite 330, Boston, MA // local #include "uc89c51rcl.h" #include "regs51.h" +#include "pcacl.h" t_uc89c51r::t_uc89c51r(int Itype, int Itech, class cl_sim *asim): t_uc51r(Itype, Itech, asim) { - it_sources->add_at(4, new cl_it_src(bmEC, CCON, bmCCF4, 0x0033, false, + /*it_sources->add_at(4, new cl_it_src(bmEC, CCON, bmCCF4, 0x0033, false, "PCA module #4")); it_sources->add_at(4, new cl_it_src(bmEC, CCON, bmCCF3, 0x0033, false, "PCA module #3")); @@ -48,11 +49,12 @@ t_uc89c51r::t_uc89c51r(int Itype, int Itech, class cl_sim *asim): it_sources->add_at(4, new cl_it_src(bmEC, CCON, bmCCF0, 0x0033, false, "PCA module #0")); it_sources->add_at(4, new cl_it_src(bmEC, CCON, bmCF, 0x0033, false, - "PCA counter")); + "PCA counter"));*/ } void +<<<<<<< uc89c51r.cc t_uc89c51r::reset(void) { t_uc51r::reset(); @@ -68,7 +70,11 @@ t_uc89c51r::reset(void) void t_uc89c51r::proc_write(uchar *addr) +======= +t_uc89c51r::mk_hw_elements(void) +>>>>>>> 1.2.2.3 { +<<<<<<< uc89c51r.cc t_uc51r::proc_write(addr); if (addr == &(/*MEM(MEM_SFR)*/sfr->umem8[CCAP0L])) @@ -95,15 +101,43 @@ t_uc89c51r::proc_write(uchar *addr) mem(MEM_SFR)->set_bit0(CCAPM4, bmECOM); if (addr == &(/*MEM(MEM_SFR)*/sfr->umem8[CCAP4H])) mem(MEM_SFR)->set_bit1(CCAPM4, bmECOM); +======= + class cl_hw *h; +>>>>>>> 1.2.2.3 +<<<<<<< uc89c51r.cc if (addr == &(/*MEM(MEM_SFR)*/sfr->umem8[AUXR])) mem(MEM_SFR)->set_bit0(AUXR, 0x04); +======= + t_uc51r::mk_hw_elements(); + hws->add(h= new cl_pca(this, 0)); + h->init(); + /*hws->add(h= new cl_pca(this, 1)); + h->init(); + hws->add(h= new cl_pca(this, 2)); + h->init(); + hws->add(h= new cl_pca(this, 3)); + h->init(); + hws->add(h= new cl_pca(this, 4)); + h->init();*/ + hws->add(h= new cl_89c51r_dummy_hw(this)); + h->init(); +>>>>>>> 1.2.2.3 } -uchar -t_uc89c51r::read(uchar *addr) + +void +t_uc89c51r::reset(void) { - return(t_uc51r::read(addr)); + t_uc51r::reset(); + sfr->set_bit1(CCAPM0, bmECOM); + sfr->set_bit1(CCAPM1, bmECOM); + sfr->set_bit1(CCAPM2, bmECOM); + sfr->set_bit1(CCAPM3, bmECOM); + sfr->set_bit1(CCAPM4, bmECOM); + //t0_overflows= 0; + dpl0= dph0= dpl1= dph1= 0; + sfr->set(IPH, 0); } int @@ -111,8 +145,8 @@ t_uc89c51r::it_priority(uchar ie_mask) { uchar l, h; - l= get_mem(MEM_SFR, IP) & ie_mask; - h= get_mem(MEM_SFR, IPH) & ie_mask; + l= sfr->get(IP) & ie_mask; + h= sfr->get(IPH) & ie_mask; if (!h && !l) return(0); if (!h && l) @@ -127,39 +161,44 @@ t_uc89c51r::it_priority(uchar ie_mask) void t_uc89c51r::pre_inst(void) { - if (get_mem(MEM_SFR, AUXR1) & bmDPS) + if (sfr->get(AUXR1) & bmDPS) { - set_mem(MEM_SFR, DPL, dpl1); - set_mem(MEM_SFR, DPH, dph1); + sfr->set(DPL, dpl1); + sfr->set(DPH, dph1); } else { - set_mem(MEM_SFR, DPL, dpl0); - set_mem(MEM_SFR, DPH, dph0); + sfr->set(DPL, dpl0); + sfr->set(DPH, dph0); } + t_uc51r::pre_inst(); } void t_uc89c51r::post_inst(void) { - if (get_mem(MEM_SFR, AUXR1) & bmDPS) + if (sfr->get(AUXR1) & bmDPS) { - dpl1= get_mem(MEM_SFR, DPL); - dph1= get_mem(MEM_SFR, DPH); + dpl1= sfr->get(DPL); + dph1= sfr->get(DPH); } else { - dpl0= get_mem(MEM_SFR, DPL); - dph0= get_mem(MEM_SFR, DPH); + dpl0= sfr->get(DPL); + dph0= sfr->get(DPH); } + t_uc51r::post_inst(); } /* +<<<<<<< uc89c51r.cc * Simulating timers * * Calling inherited method to simulate timer #0, #1, #2 and then * simulating Programmable Counter Array +======= +>>>>>>> 1.2.2.3 */ int @@ -167,14 +206,25 @@ t_uc89c51r::do_timers(int cycles) { int res; +<<<<<<< uc89c51r.cc if ((res= t_uc51r::do_timers(cycles)) != resGO) return(res); return(do_pca(cycles)); } +======= +cl_89c51r_dummy_hw::cl_89c51r_dummy_hw(class cl_uc *auc): + cl_hw(auc, HW_DUMMY, 0, "_89c51r_dummy") +{} +>>>>>>> 1.2.2.3 int +<<<<<<< uc89c51r.cc t_uc89c51r::t0_overflow(void) +======= +cl_89c51r_dummy_hw::init(void) +>>>>>>> 1.2.2.3 { +<<<<<<< uc89c51r.cc uchar cmod= get_mem(MEM_SFR, CMOD) & (bmCPS0|bmCPS1); if (cmod == bmCPS1) @@ -224,91 +274,23 @@ int t_uc89c51r::do_pca_counter(int cycles) { while (cycles--) +======= + class cl_mem *sfr= uc->mem(MEM_SFR); + if (!sfr) +>>>>>>> 1.2.2.3 { - if (/*++(MEM(MEM_SFR)[CL])*/sfr->add(CL, 1) == 0) - { - if (/*++(MEM(MEM_SFR)[CH])*/sfr->add(CH, 1) == 0) - { - /* CH,CL overflow */ - mem(MEM_SFR)->set_bit1(CCON, bmCF); - do_pca_module(0); - do_pca_module(1); - do_pca_module(2); - do_pca_module(3); - do_pca_module(4); - } - } + fprintf(stderr, "No SFR to register %s[%d] into\n", id_string, id); } - return(resGO); + //auxr= sfr->register_hw(AUXR, this, 0); + register_cell(sfr, AUXR, &auxr, wtd_restore); + return(0); } -int -t_uc89c51r::do_pca_module(int nr) +void +cl_89c51r_dummy_hw::write(class cl_cell *cell, t_mem *val) { - uchar CCAPM[5]= {0xda, 0xdb, 0xdc, 0xdd, 0xde}; - uchar CCAPL[5]= {0xea, 0xeb, 0xec, 0xed, 0xee}; - uchar CCAPH[5]= {0xfa, 0xfb, 0xfc, 0xfd, 0xfe}; - uchar bmCEX[5]= {bmCEX0, bmCEX1, bmCEX2, bmCEX3, bmCEX4}; - uchar bmCCF[5]= {bmCCF0, bmCCF1, bmCCF2, bmCCF3, bmCCF4}; - uchar ccapm= get_mem(MEM_SFR, CCAPM[nr]); - uint p1= get_mem(MEM_SFR, P1); - - if ( - ((ccapm & bmCAPP) && - (prev_p1 & bmCEX[nr]) == 0 && - (p1 & bmCEX[nr]) != 0) - || - ((ccapm & bmCAPN) && - (prev_p1 & bmCEX[nr]) != 0 && - (p1 & bmCEX[nr]) == 0) - ) - { - /* Capture */ - //MEM(MEM_SFR)[CCAPL[nr]]= MEM(MEM_SFR)[CL]; - sfr->set(CCAPL[nr], sfr->get(CL)); - //MEM(MEM_SFR)[CCAPH[nr]]= MEM(MEM_SFR)[CH]; - sfr->set(CCAPH[nr], sfr->get(CH)); - mem(MEM_SFR)->set_bit1(CCON, bmCCF[nr]); - } - - if (ccapm & bmECOM) - { - /* Comparator enabled */ - /*if (MEM(MEM_SFR)[CL] == MEM(MEM_SFR)[CCAPL[nr]] && - MEM(MEM_SFR)[CH] == MEM(MEM_SFR)[CCAPH[nr]])*/ - if (sfr->get(CL) == sfr->get(CCAPL[nr]) && - sfr->get(CH) == sfr->get(CCAPH[nr])) - { - /* Match */ - if (nr == 4 && - (/*MEM(MEM_SFR)[CMOD]*/sfr->get(CMOD) & bmWDTE)) - { - reset(); - } - mem(MEM_SFR)->set_bit1(CCON, bmCCF[nr]); - if (ccapm & bmTOG) - { - /* Toggle */ - //MEM(MEM_SFR)[P1]^= bmCEX[nr]; - sfr->set(P1, sfr->get(P1) ^ bmCEX[nr]); - } - } - if (ccapm & bmPWM) - { - /* PWM */ - if (/*MEM(MEM_SFR)[CL]*/sfr->get(CL) == 0) - //MEM(MEM_SFR)[CCAPL[nr]]= MEM(MEM_SFR)[CCAPH[nr]]; - sfr->set(CCAPL[nr], sfr->get(CCAPH[nr])); - if (/*MEM(MEM_SFR)[CL]*/sfr->get(CL) < - /*MEM(MEM_SFR)[CCAPL[nr]]*/sfr->get(CCAPL[nr])) - //MEM(MEM_SFR)[P1]&= ~(bmCEX[nr]); - sfr->set(P1, sfr->get(P1) & ~(bmCEX[nr])); - else - mem(MEM_SFR)->set_bit1(P1, bmCEX[nr]); - } - } - - return(resGO); + if (cell == auxr) + auxr->set_bit0(0x04); } diff --git a/sim/ucsim/s51.src/uc89c51rcl.h b/sim/ucsim/s51.src/uc89c51rcl.h index d0df66b1..02936ee3 100644 --- a/sim/ucsim/s51.src/uc89c51rcl.h +++ b/sim/ucsim/s51.src/uc89c51rcl.h @@ -36,27 +36,36 @@ Software Foundation, 59 Temple Place - Suite 330, Boston, MA class t_uc89c51r: public t_uc51r { public: - int t0_overflows; + //int t0_overflows; uchar dpl0, dph0; uchar dpl1, dph1; public: t_uc89c51r(int Itype, int Itech, class cl_sim *asim); + virtual void mk_hw_elements(void); virtual void reset(void); - virtual void proc_write(uchar *addr); - virtual uchar read(uchar *addr); virtual void pre_inst(void); virtual void post_inst(void); virtual int it_priority(uchar ie_mask); - virtual int do_timers(int cycles); - virtual int t0_overflow(void); - virtual int do_pca(int cycles); + //virtual void do_extra_hw(int cycles); + //virtual int t0_overflow(void); + /*virtual int do_pca(int cycles); virtual int do_pca_counter(int cycles); - virtual int do_pca_module(int nr); + virtual int do_pca_module(int nr);*/ }; +class cl_89c51r_dummy_hw: public cl_hw +{ +protected: + class cl_cell *auxr; +public: + cl_89c51r_dummy_hw(class cl_uc *auc); + virtual int init(void); + + virtual void write(class cl_cell *cell, t_mem *val); +}; #endif diff --git a/sim/ucsim/s51.src/wdt.cc b/sim/ucsim/s51.src/wdt.cc new file mode 100644 index 00000000..7e7141e0 --- /dev/null +++ b/sim/ucsim/s51.src/wdt.cc @@ -0,0 +1,106 @@ +/* + * Simulator of microcontrollers (wdt.cc) + * + * Copyright (C) 1999,99 Drotos Daniel, Talker Bt. + * + * To contact author send email to drdani@mazsola.iit.uni-miskolc.hu + * + */ + +/* This file is part of microcontroller simulator: ucsim. + +UCSIM is free software; you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation; either version 2 of the License, or +(at your option) any later version. + +UCSIM is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU General Public License for more details. + +You should have received a copy of the GNU General Public License +along with UCSIM; see the file COPYING. If not, write to the Free +Software Foundation, 59 Temple Place - Suite 330, Boston, MA +02111-1307, USA. */ +/*@1@*/ + +#include + +// local +#include "wdtcl.h" +#include "regs51.h" + + +cl_wdt::cl_wdt(class cl_uc *auc, long resetvalue): + cl_hw(auc, HW_WDT, 0, "wdt") +{ + reset_value= resetvalue; + wdt= -1; + written_since_reset= DD_FALSE; +} + +int +cl_wdt::init(void) +{ + class cl_mem *sfr= uc->mem(MEM_SFR); + + if (!sfr) + { + fprintf(stderr, "No SFR to register WDT into\n"); + } + //wdtrst= sfr->register_hw(WDTRST, this, (int*)0); + register_cell(sfr, WDTRST, &wdtrst, wtd_restore); + return(0); +} + +void +cl_wdt::write(class cl_cell *cell, t_mem *val) +{ + if (cell == wdtrst && + (((*val)&0xff) == 0xe1) && + (wdtrst->get() == 0x1e) && + written_since_reset) + { + wdt= 0; + /*uc->sim->app->get_commander()-> + debug("%g sec (%d tick): Watchdog timer enabled/reset PC= 0x%06x" + "\n", uc->get_rtime(), uc->ticks->ticks, uc51r->PC);*/ + } + written_since_reset= DD_TRUE; +} + +int +cl_wdt::tick(int cycles) +{ + if (wdt >= 0) + { + wdt+= cycles; + if (wdt > reset_value) + { + /*sim->app->get_commander()-> + debug("%g sec (%d ticks): Watchdog timer resets the CPU, " + "PC= 0x%06x\n", get_rtime(), ticks->ticks, PC);*/ + uc->reset(); + //return(resWDTRESET); + } + } + return(0); +} + +void +cl_wdt::reset(void) +{ + written_since_reset= DD_FALSE; + wdt= -1; +} + +void +cl_wdt::print_info(class cl_console *con) +{ + con->dd_printf("%s[%d] %s counter=%d (remains=%d)\n", id_string, id, + (wdt>=0)?"ON":"OFF", wdt, (wdt>=0)?(reset_value-wdt):0); +} + + +/* End of s51.src/wdt.cc */ diff --git a/sim/ucsim/s51.src/wdtcl.h b/sim/ucsim/s51.src/wdtcl.h new file mode 100644 index 00000000..88ff39a1 --- /dev/null +++ b/sim/ucsim/s51.src/wdtcl.h @@ -0,0 +1,65 @@ +/* + * Simulator of microcontrollers (wdtcl.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 S51_WDTCL_HEADER +#define S51_WDTCL_HEADER + +// sim.src +//#include "stypes.h" +//#include "pobjcl.h" +#include "uccl.h" + +// local +//#include "newcmdcl.h" +#include "uc51rcl.h" + + +class cl_wdt: public cl_hw +{ +protected: + long wdt, reset_value; + class cl_cell *wdtrst; + bool written_since_reset; +public: + cl_wdt(class cl_uc *auc, long resetvalue); + virtual int init(void); + + //virtual t_mem read(class cl_cell *cell); + virtual void write(class cl_cell *cell, t_mem *val); + + //virtual t_mem set_cmd(t_mem value); + + virtual int tick(int cycles); + virtual void reset(void); + + virtual void print_info(class cl_console *con); +}; + + +#endif + +/* End of s51.src/wdtcl.h */ diff --git a/sim/ucsim/sim.src/Makefile.in b/sim/ucsim/sim.src/Makefile.in index 98fed8ec..9bfd6468 100644 --- a/sim/ucsim/sim.src/Makefile.in +++ b/sim/ucsim/sim.src/Makefile.in @@ -34,16 +34,16 @@ man2dir = $(mandir)/man2 infodir = @infodir@ srcdir = @srcdir@ -OBJECTS = app.o sim.o itsrc.o brk.o option.o arg.o stack.o \ - guiobj.o uc.o hw.o mem.o +OBJECTS = mem.o app.o sim.o itsrc.o brk.o option.o arg.o stack.o \ + guiobj.o uc.o hw.o # Compiling entire program or any subproject # ------------------------------------------ all: checkconf sim_lib -test_mem_speed: $(PRJDIR)/libsim.a $(PRJDIR)/libutil.a test_mem_speed.o - $(CC) -o $@ test_mem_speed.o -L$(PRJDIR) -lsim -lutil +test_mem_speed: $(PRJDIR)/lib*.a test_mem_speed.o + $(CC) -o $@ test_mem_speed.o -L$(PRJDIR) -lsim -lutil -lcmd -lsim sim.src: all @@ -60,8 +60,10 @@ uninstall: # Performing self-test # -------------------- -check: +check: test + ./test_mem_speed +test: test_mem_speed # Performing installation test # ---------------------------- @@ -73,8 +75,6 @@ installcheck: installdirs: -test: test_mem_speed - # Creating dependencies # --------------------- dep: main.dep @@ -95,7 +95,7 @@ include clean.mk sim_lib: $(PRJDIR)/libsim.a $(PRJDIR)/libsim.a: $(OBJECTS) - $(AR) -rcu $*.a $(OBJECTS) + ar -rcu $*.a $(OBJECTS) $(RANLIB) $*.a .cc.o: diff --git a/sim/ucsim/sim.src/app.cc b/sim/ucsim/sim.src/app.cc index 433f9a32..5ba9e9f7 100644 --- a/sim/ucsim/sim.src/app.cc +++ b/sim/ucsim/sim.src/app.cc @@ -462,7 +462,19 @@ cl_app::get_cmd(class cl_cmdline *cmdline) } -/* Adding and removing comonents */ +/* + * Messages to broadcast + */ + +void +cl_app::mem_cell_changed(class cl_mem *mem, t_addr addr) +{ + if (sim) + sim->mem_cell_changed(mem, addr); +} + + +/* Adding and removing components */ void cl_app::set_simulator(class cl_sim *simulator) diff --git a/sim/ucsim/sim.src/appcl.h b/sim/ucsim/sim.src/appcl.h index b5e8a263..1b26482b 100644 --- a/sim/ucsim/sim.src/appcl.h +++ b/sim/ucsim/sim.src/appcl.h @@ -35,6 +35,7 @@ Software Foundation, 59 Temple Place - Suite 330, Boston, MA // local, sim.src #include "argcl.h" +#include "simcl.h" /* Options */ @@ -58,7 +59,7 @@ public: public: cl_option(int atype, char sn, char *ln); - ~cl_option(void); + virtual ~cl_option(void); virtual int add_value(char *value); virtual char *get_value(int index); @@ -85,7 +86,7 @@ public: public: cl_app(void); - ~cl_app(void); + virtual ~cl_app(void); public: virtual int init(int argc , char *argv[]); @@ -100,6 +101,9 @@ public: class cl_commander *get_commander(void) { return(commander); } virtual class cl_cmd *get_cmd(class cl_cmdline *cmdline); +public: // messages to broadcast + virtual void mem_cell_changed(class cl_mem *mem, t_addr addr); + public: virtual void set_simulator(class cl_sim *simulator); virtual void remove_simulator(void); diff --git a/sim/ucsim/sim.src/arg.cc b/sim/ucsim/sim.src/arg.cc index fe2e6811..3e6f5cd7 100644 --- a/sim/ucsim/sim.src/arg.cc +++ b/sim/ucsim/sim.src/arg.cc @@ -214,7 +214,10 @@ cl_cmd_int_arg::get_bit_address(class cl_uc *uc, // input if (!get_address(uc, &bit_addr)) return(DD_FALSE); - return(uc->extract_bit_address(bit_addr, mem, mem_addr, bit_mask)); + + if (mem) + *mem= uc->bit2mem(bit_addr, mem_addr, bit_mask); + return(mem && *mem); } bool @@ -272,7 +275,9 @@ cl_cmd_sym_arg::get_bit_address(class cl_uc *uc, // input get_svalue(), uc)) == NULL) return(DD_FALSE); - return(uc->extract_bit_address(ne->addr, mem, mem_addr, bit_mask)); + if (mem) + *mem= uc->bit2mem(ne->addr, mem_addr, bit_mask); + return(mem && *mem); } bool diff --git a/sim/ucsim/sim.src/argcl.h b/sim/ucsim/sim.src/argcl.h index 5bc0bbbe..9d65226b 100644 --- a/sim/ucsim/sim.src/argcl.h +++ b/sim/ucsim/sim.src/argcl.h @@ -52,7 +52,7 @@ public: cl_arg(char *lv); cl_arg(double fv); cl_arg(void *pv); - ~cl_arg(void); + virtual ~cl_arg(void); virtual bool get_ivalue(long *value); virtual char *get_svalue(void); @@ -101,7 +101,7 @@ public: { /*uc= iuc;*/ interpreted_as_string= DD_FALSE; } cl_cmd_arg(/*class cl_uc *iuc,*/ char *s): cl_arg(s) { /*uc= iuc;*/ interpreted_as_string= DD_FALSE; } - ~cl_cmd_arg(void); + virtual ~cl_cmd_arg(void); virtual int is_string(void) { return(DD_FALSE); } virtual bool get_address(class cl_uc *uc, t_addr *addr) { return(DD_FALSE); } @@ -158,7 +158,7 @@ public: public: cl_cmd_bit_arg(/*class cl_uc *iuc,*/ class cl_cmd_arg *asfr, class cl_cmd_arg *abit); - ~cl_cmd_bit_arg(void); + virtual ~cl_cmd_bit_arg(void); virtual bool get_address(class cl_uc *uc, t_addr *addr); virtual bool get_bit_address(class cl_uc *uc, // input @@ -175,7 +175,7 @@ public: public: cl_cmd_array_arg(/*class cl_uc *iuc,*/ class cl_cmd_arg *aname, class cl_cmd_arg *aindex); - ~cl_cmd_array_arg(void); + virtual ~cl_cmd_array_arg(void); virtual bool as_hw(class cl_uc *uc); }; @@ -195,7 +195,7 @@ public: cl_prg_arg(char sn, char *ln, char *lv); cl_prg_arg(char sn, char *ln, double fv); cl_prg_arg(char sn, char *ln, void *pv); - ~cl_prg_arg(void); + virtual ~cl_prg_arg(void); }; diff --git a/sim/ucsim/sim.src/brk.cc b/sim/ucsim/sim.src/brk.cc index 17a1e1ac..b18b89f3 100644 --- a/sim/ucsim/sim.src/brk.cc +++ b/sim/ucsim/sim.src/brk.cc @@ -28,6 +28,7 @@ Software Foundation, 59 Temple Place - Suite 330, Boston, MA #include "ddconfig.h" #include +#include #include "pobjcl.h" #include "brkcl.h" @@ -37,9 +38,11 @@ Software Foundation, 59 Temple Place - Suite 330, Boston, MA * Base object of breakpoints */ -cl_brk::cl_brk(int inr, t_addr iaddr, enum brk_perm iperm, int ihit): +cl_brk::cl_brk(class cl_mem *imem, int inr, t_addr iaddr, + enum brk_perm iperm, int ihit): cl_base() { + mem = imem; nr = inr; addr = iaddr; perm = iperm; @@ -50,6 +53,20 @@ cl_brk::cl_brk(int inr, t_addr iaddr, enum brk_perm iperm, int ihit): cl_brk::~cl_brk(void) {} +void +cl_brk::activate(void) +{ + if (mem) + mem->set_brk(addr, this); +} + +void +cl_brk::inactivate(void) +{ + if (mem) + mem->del_brk(addr, this); +} + bool cl_brk::do_hit(void) { @@ -67,8 +84,9 @@ cl_brk::do_hit(void) * FETCH type of breakpoint */ -cl_fetch_brk::cl_fetch_brk(int inr, t_addr iaddr, enum brk_perm iperm, int ihit): - cl_brk(inr, iaddr, iperm, ihit) +cl_fetch_brk::cl_fetch_brk(class cl_mem *imem, int inr, t_addr iaddr, + enum brk_perm iperm, int ihit): + cl_brk(imem, inr, iaddr, iperm, ihit) { code = 0; } @@ -84,12 +102,36 @@ cl_fetch_brk::type(void) * Base of EVENT type of breakpoints */ -cl_ev_brk::cl_ev_brk(int inr, t_addr iaddr, enum brk_perm iperm, int ihit, +cl_ev_brk::cl_ev_brk(class cl_mem *imem, int inr, t_addr iaddr, + enum brk_perm iperm, int ihit, enum brk_event ievent, const char *iid): - cl_brk(inr, iaddr, iperm, ihit) + cl_brk(imem, inr, iaddr, iperm, ihit) { event= ievent; id = iid; + mem = imem; +} + +cl_ev_brk::cl_ev_brk(class cl_mem *imem, int inr, t_addr iaddr, + enum brk_perm iperm, int ihit, char op): + cl_brk(imem, inr, iaddr, iperm, ihit) +{ + mem = imem; + if ((op= toupper(op)) == 'R') + { + event= brkREAD; + id= "read"; + } + else if (op == 'W') + { + event= brkWRITE; + id= "write"; + } + else + { + event= brkACCESS; + id= "access"; + } } enum brk_type @@ -109,105 +151,112 @@ cl_ev_brk::match(struct event_rec *ev) * WRITE IRAM type of EVENT breakpoints */ -cl_wi_brk::cl_wi_brk(int inr, t_addr iaddr, enum brk_perm iperm, int ihit): - cl_ev_brk(inr, iaddr, iperm, ihit, brkWIRAM, "wi") +/*cl_wi_brk::cl_wi_brk(class cl_mem *imem, int inr, t_addr iaddr, + enum brk_perm iperm, int ihit): + cl_ev_brk(imem, inr, iaddr, iperm, ihit, brkWIRAM, "wi") {} bool cl_wi_brk::match(struct event_rec *ev) { return(ev->wi == addr); -} +}*/ /* * READ IRAM type of EVENT breakpoints */ -cl_ri_brk::cl_ri_brk(int inr, t_addr iaddr, enum brk_perm iperm, int ihit): - cl_ev_brk(inr, iaddr, iperm, ihit, brkRIRAM, "ri") +/*cl_ri_brk::cl_ri_brk(class cl_mem *imem, int inr, t_addr iaddr, + enum brk_perm iperm, int ihit): + cl_ev_brk(imem, inr, iaddr, iperm, ihit, brkRIRAM, "ri") {} bool cl_ri_brk::match(struct event_rec *ev) { return(ev->ri == addr); -} +}*/ /* * WRITE XRAM type of EVENT breakpoints */ -cl_wx_brk::cl_wx_brk(int inr, t_addr iaddr, enum brk_perm iperm, int ihit): - cl_ev_brk(inr, iaddr, iperm, ihit, brkWXRAM, "wx") +/*cl_wx_brk::cl_wx_brk(class cl_mem *imem, int inr, t_addr iaddr, + enum brk_perm iperm, int ihit): + cl_ev_brk(imem, inr, iaddr, iperm, ihit, brkWXRAM, "wx") {} bool cl_wx_brk::match(struct event_rec *ev) { return(ev->wx == addr); -} +}*/ /* * READ XRAM type of EVENT breakpoints */ -cl_rx_brk::cl_rx_brk(int inr, t_addr iaddr, enum brk_perm iperm, int ihit): - cl_ev_brk(inr, iaddr, iperm, ihit, brkRXRAM, "rx") +/*cl_rx_brk::cl_rx_brk(class cl_mem *imem, int inr, t_addr iaddr, + enum brk_perm iperm, int ihit): + cl_ev_brk(imem, inr, iaddr, iperm, ihit, brkRXRAM, "rx") {} bool cl_rx_brk::match(struct event_rec *ev) { return(ev->rx == addr); -} +}*/ /* * WRITE SFR type of EVENT breakpoints */ -cl_ws_brk::cl_ws_brk(int inr, t_addr iaddr, enum brk_perm iperm, int ihit): - cl_ev_brk(inr, iaddr, iperm, ihit, brkWSFR, "ws") +/*cl_ws_brk::cl_ws_brk(class cl_mem *imem, int inr, t_addr iaddr, + enum brk_perm iperm, int ihit): + cl_ev_brk(imem, inr, iaddr, iperm, ihit, brkWSFR, "ws") {} bool cl_ws_brk::match(struct event_rec *ev) { return(ev->ws == addr); -} +}*/ /* * READ SFR type of EVENT breakpoints */ -cl_rs_brk::cl_rs_brk(int inr, t_addr iaddr, enum brk_perm iperm, int ihit): - cl_ev_brk(inr, iaddr, iperm, ihit, brkRSFR, "rs") +/*cl_rs_brk::cl_rs_brk(class cl_mem *imem, int inr, t_addr iaddr, + enum brk_perm iperm, int ihit): + cl_ev_brk(imem, inr, iaddr, iperm, ihit, brkRSFR, "rs") {} bool cl_rs_brk::match(struct event_rec *ev) { return(ev->rs == addr); -} +}*/ /* * READ CODE type of EVENT breakpoints */ -cl_rc_brk::cl_rc_brk(int inr, t_addr iaddr, enum brk_perm iperm, int ihit): - cl_ev_brk(inr, iaddr, iperm, ihit, brkRCODE, "rc") +/*cl_rc_brk::cl_rc_brk(class cl_mem *imem, int inr, t_addr iaddr, + enum brk_perm iperm, int ihit): + cl_ev_brk(imem, inr, iaddr, iperm, ihit, brkRCODE, "rc") {} bool cl_rc_brk::match(struct event_rec *ev) { return(ev->rc == addr); -} +}*/ /* @@ -216,7 +265,7 @@ cl_rc_brk::match(struct event_rec *ev) * This is a sorted collection, sorted by nr field of brk items. */ -brk_coll::brk_coll(t_index alimit, t_index adelta, class cl_rom *arom): +brk_coll::brk_coll(t_index alimit, t_index adelta, class cl_mem *arom): cl_sorted_list(alimit, adelta) { rom= arom; @@ -280,21 +329,45 @@ void brk_coll::add_bp(class cl_brk *bp) { add(bp); - if (rom && + bp->activate(); + return; + /*if (rom && bp->addr < rom->size) - rom->bp_map->set(bp->addr); + / *rom->bp_map->set(bp->addr)* /rom->set_brk(bp->addr, bp);*/ } void brk_coll::del_bp(t_addr addr) { int idx; + class cl_brk *bp; - if (get_bp(addr, &idx)) - free_at(idx); - if (rom && + if ((bp= get_bp(addr, &idx))) + { + bp->inactivate(); + free_at(idx); + } + return; + /*if (rom && addr < rom->size) - rom->bp_map->clear(addr); + { + fprintf(stderr, "brk_coll::del_bp(0x%"_A_"x\n", addr);//FIXME + //rom->bp_map->clear(addr); + }*/ +} + +void +brk_coll::del_bp(t_index idx, int /*dummy*/) +{ + class cl_brk *bp; + + if (idx >= count) + return; + bp= (class cl_brk *)(at(idx)); + if (!bp) + return; + bp->inactivate(); + free_at(idx); } class cl_brk * @@ -302,7 +375,8 @@ brk_coll::get_bp(t_addr addr, int *idx) { if (rom && addr < rom->size && - rom->bp_map->get(addr)) + /*rom->bp_map->get(addr)*/ + rom->get_cell_flag(addr, CELL_FETCH_BRK)) { for (*idx= 0; *idx < count; (*idx)++) { @@ -333,7 +407,8 @@ brk_coll::bp_at(t_addr addr) { return(rom && addr < rom->size && - rom->bp_map->get(addr)); + /*rom->bp_map->get(addr)*/ + rom->get_cell_flag(addr, CELL_FETCH_BRK)); } diff --git a/sim/ucsim/sim.src/brkcl.h b/sim/ucsim/sim.src/brkcl.h index 59fe1a77..b5ed8a80 100644 --- a/sim/ucsim/sim.src/brkcl.h +++ b/sim/ucsim/sim.src/brkcl.h @@ -44,6 +44,8 @@ Software Foundation, 59 Temple Place - Suite 330, Boston, MA class cl_brk: public cl_base { +protected: + class cl_mem *mem; public: int nr; t_addr addr; @@ -51,10 +53,14 @@ public: int hit; int cnt; - cl_brk(int inr, t_addr iaddr, enum brk_perm iperm, int ihit); - ~cl_brk(void); + cl_brk(class cl_mem *imem, int inr, t_addr iaddr, + enum brk_perm iperm, int ihit); + virtual ~cl_brk(void); + virtual void activate(void); + virtual void inactivate(void); virtual enum brk_type type(void)= 0; + virtual enum brk_event get_event(void)= 0; virtual bool do_hit(void); }; @@ -68,9 +74,11 @@ class cl_fetch_brk: public cl_brk public: uchar code; - cl_fetch_brk(int inr, t_addr iaddr, enum brk_perm iperm, int ihit); + cl_fetch_brk(class cl_mem *imem, int inr, t_addr iaddr, + enum brk_perm iperm, int ihit); virtual enum brk_type type(void); + virtual enum brk_event get_event(void) { return(brkNONE); } }; @@ -81,13 +89,15 @@ public: class cl_ev_brk: public cl_brk { public: - cl_ev_brk(int inr, t_addr iaddr, enum brk_perm iperm, int ihit, - enum brk_event ievent, const char *iid); - + cl_ev_brk(class cl_mem *imem, int inr, t_addr iaddr, enum brk_perm iperm, + int ihit, enum brk_event ievent, const char *iid); + cl_ev_brk(class cl_mem *imem, int inr, t_addr iaddr, enum brk_perm iperm, + int ihit, char op); enum brk_event event; const char *id; virtual enum brk_type type(void); + virtual enum brk_event get_event(void) { return(event); } virtual bool match(struct event_rec *ev); }; @@ -96,91 +106,98 @@ public: * WRITE IRAM */ -class cl_wi_brk: public cl_ev_brk +/*class cl_wi_brk: public cl_ev_brk { public: - cl_wi_brk(int inr, t_addr iaddr, enum brk_perm iperm, int ihit); + cl_wi_brk(class cl_mem *imem, int inr, t_addr iaddr, enum brk_perm iperm, + int ihit); virtual bool match(struct event_rec *ev); -}; +};*/ /* * READ IRAM */ -class cl_ri_brk: public cl_ev_brk +/*class cl_ri_brk: public cl_ev_brk { public: - cl_ri_brk(int inr, t_addr iaddr, enum brk_perm iperm, int ihit); + cl_ri_brk(class cl_mem *imem, int inr, t_addr iaddr, enum brk_perm iperm, + int ihit); virtual bool match(struct event_rec *ev); -}; +};*/ /* * WRITE XRAM */ -class cl_wx_brk: public cl_ev_brk +/*class cl_wx_brk: public cl_ev_brk { public: - cl_wx_brk(int inr, t_addr iaddr, enum brk_perm iperm, int ihit); + cl_wx_brk(class cl_mem *imem, int inr, t_addr iaddr, enum brk_perm iperm, + int ihit); virtual bool match(struct event_rec *ev); -}; +};*/ /* * READ XRAM */ -class cl_rx_brk: public cl_ev_brk +/*class cl_rx_brk: public cl_ev_brk { public: - cl_rx_brk(int inr, t_addr iaddr, enum brk_perm iperm, int ihit); + cl_rx_brk(class cl_mem *imem, int inr, t_addr iaddr, enum brk_perm iperm, + int ihit); virtual bool match(struct event_rec *ev); -}; +};*/ /* * WRITE SFR */ -class cl_ws_brk: public cl_ev_brk +/*class cl_ws_brk: public cl_ev_brk { public: - cl_ws_brk(int inr, t_addr iaddr, enum brk_perm iperm, int ihit); + cl_ws_brk(class cl_mem *imem, int inr, t_addr iaddr, enum brk_perm iperm, + int ihit); virtual bool match(struct event_rec *ev); -}; +};*/ /* * READ SFR */ -class cl_rs_brk: public cl_ev_brk +/*class cl_rs_brk: public cl_ev_brk { public: - cl_rs_brk(int inr, t_addr iaddr, enum brk_perm iperm, int ihit); + cl_rs_brk(class cl_mem *imem, int inr, t_addr iaddr, enum brk_perm iperm, + int ihit); virtual bool match(struct event_rec *ev); -}; +};*/ /* * READ CODE */ -class cl_rc_brk: public cl_ev_brk +/*class cl_rc_brk: public cl_ev_brk { public: - cl_rc_brk(int inr, t_addr iaddr, enum brk_perm iperm, int ihit); + cl_rc_brk(class cl_mem *imem, int inr, t_addr iaddr, enum brk_perm iperm, + int ihit); virtual bool match(struct event_rec *ev); -}; +};*/ /* @@ -190,9 +207,9 @@ public: class brk_coll: public cl_sorted_list { public: - class cl_rom *rom; + class cl_mem/*rom*/ *rom; public: - brk_coll(t_index alimit, t_index adelta, class cl_rom *arom); + brk_coll(t_index alimit, t_index adelta, class cl_mem/*rom*/ *arom); virtual void *key_of(void *item); virtual int compare(void *key1, void *key2); @@ -201,6 +218,7 @@ public: virtual void add_bp(class cl_brk *bp); virtual void del_bp(t_addr addr); + virtual void del_bp(t_index idx, int /*dummy*/); virtual class cl_brk *get_bp(t_addr addr, int *idx); virtual class cl_brk *get_bp(int nr); virtual bool bp_at(t_addr addr); diff --git a/sim/ucsim/sim.src/hw.cc b/sim/ucsim/sim.src/hw.cc index b876327a..167c1cad 100644 --- a/sim/ucsim/sim.src/hw.cc +++ b/sim/ucsim/sim.src/hw.cc @@ -34,6 +34,71 @@ Software Foundation, 59 Temple Place - Suite 330, Boston, MA #include "hwcl.h" +/* + *____________________________________________________________________________ + */ + +cl_watched_cell::cl_watched_cell(class cl_mem *amem, t_addr aaddr, + class cl_cell **astore, + enum what_to_do_on_cell_change awtd) +{ + mem= amem; + addr= aaddr; + store= astore; + wtd= awtd; + if (mem) + { + cell= mem->get_cell(addr); + if (store) + *store= cell; + } +} + +void +cl_watched_cell::mem_cell_changed(class cl_mem *amem, t_addr aaddr, + class cl_hw *hw) +{ + if (mem && + mem == amem && + addr == aaddr) + { + cell= mem->get_cell(addr); + if (store && + (wtd & WTD_RESTORE)) + *store= cell; + if (wtd & WTD_WRITE) + { + t_mem d= cell->get(); + hw->write(cell, &d); + } + } +} + +/*void +cl_used_cell::mem_cell_changed(class cl_mem *amem, t_addr aaddr, +class cl_hw *hw) +{ + if (mem && + mem == amem && + addr == aaddr) + { + cell= mem->get_cell(addr); + if (store && + (wtd & WTD_RESTORE)) + *store= cell; + if (wtd & WTD_WRITE) + { + t_mem d= cell->get(); + hw->write(cell, &d); + } + } +}*/ + + +/* + *____________________________________________________________________________ + */ + cl_hw::cl_hw(class cl_uc *auc, enum hw_cath cath, int aid, char *aid_string): cl_guiobj() { @@ -46,11 +111,46 @@ cl_hw::cl_hw(class cl_uc *auc, enum hw_cath cath, int aid, char *aid_string): id_string= strdup(aid_string); else id_string= strdup("unknown hw element"); + partners= new cl_list(2, 2); + watched_cells= new cl_list(2, 2); } cl_hw::~cl_hw(void) { free(id_string); + //hws_to_inform->disconn_all(); + delete partners; + delete watched_cells; +} + + +void +cl_hw::new_hw_adding(class cl_hw *new_hw) +{ +} + +void +cl_hw::new_hw_added(class cl_hw *new_hw) +{ + int i; + + for (i= 0; i < partners->count; i++) + { + class cl_partner_hw *ph= (class cl_partner_hw *)(partners->at(i)); + ph->refresh(new_hw); + } +} + +class cl_hw * +cl_hw::make_partner(enum hw_cath cath, int id) +{ + class cl_partner_hw *ph; + class cl_hw *hw; + + ph= new cl_partner_hw(uc, cath, id); + partners->add(ph); + hw= ph->get_partner(); + return(hw); } @@ -58,17 +158,63 @@ cl_hw::~cl_hw(void) * Callback functions for changing memory locations */ -t_mem +/*t_mem cl_hw::read(class cl_mem *mem, t_addr addr) { // Simply return the value return(mem->get(addr)); -} +}*/ -void +/*void cl_hw::write(class cl_mem *mem, t_addr addr, t_mem *val) { // Do not change *val by default +}*/ + + +class cl_cell * +cl_hw::register_cell(class cl_mem *mem, t_addr addr, class cl_cell **store, + enum what_to_do_on_cell_change awtd) +{ + class cl_watched_cell *wc; + class cl_cell *cell; + + if (mem) + mem->register_hw(addr, this, (int*)0, DD_FALSE); + wc= new cl_watched_cell(mem, addr, &cell, awtd); + if (store) + *store= cell; + watched_cells->add(wc); + // announce + uc->sim->mem_cell_changed(mem, addr); + return(cell); +} + +class cl_cell * +cl_hw::use_cell(class cl_mem *mem, t_addr addr, class cl_cell **store, + enum what_to_do_on_cell_change awtd) +{ + class cl_watched_cell *wc; + class cl_cell *cell; + + wc= new cl_used_cell(mem, addr, &cell, awtd); + if (store) + *store= cell; + watched_cells->add(wc); + return(cell); +} + +void +cl_hw::mem_cell_changed(class cl_mem *mem, t_addr addr) +{ + int i; + + for (i= 0; i < watched_cells->count; i++) + { + class cl_watched_cell *wc= + (class cl_watched_cell *)(watched_cells->at(i)); + wc->mem_cell_changed(mem, addr, this); + } } @@ -82,6 +228,19 @@ cl_hw::tick(int cycles) return(0); } +void +cl_hw::inform_partners(enum hw_event he, void *params) +{ + int i; + + for (i= 0; i < partners->count; i++) + { + class cl_partner_hw *ph= (class cl_partner_hw *)(partners->at(i)); + ph->happen(this, he, params); + } +} + + void cl_hw::print_info(class cl_console *con) { @@ -99,7 +258,7 @@ cl_hws::add(void *item) for (i= 0; i < count; i++) { class cl_hw *hw= (class cl_hw *)(at(i)); - hw->adding((class cl_hw *)item); + hw->new_hw_adding((class cl_hw *)item); } // add res= cl_list::add(item); @@ -107,10 +266,90 @@ cl_hws::add(void *item) for (i= 0; i < count; i++) { class cl_hw *hw= (class cl_hw *)(at(i)); - hw->added((class cl_hw *)item); + hw->new_hw_added((class cl_hw *)item); } + ((class cl_hw *)item)->added_to_uc(); return(res); } +void +cl_hws::mem_cell_changed(class cl_mem *mem, t_addr addr) +{ + int i; + + for (i= 0; i < count; i++) + { + class cl_hw *hw= (class cl_hw *)(at(i)); + hw->mem_cell_changed(mem, addr); + } +} + + +/* + *____________________________________________________________________________ + */ + +cl_partner_hw::cl_partner_hw(class cl_uc *auc, enum hw_cath cath, int aid): + cl_base() +{ + uc= auc; + cathegory= cath; + id= aid; + partner= uc->get_hw(cathegory, id, 0); +} + +class cl_hw * +cl_partner_hw::get_partner(void) +{ + return(partner); +} + +void +cl_partner_hw::refresh(void) +{ + class cl_hw *hw= uc->get_hw(cathegory, id, 0); + + if (!hw) + return; + if (partner) + { + // partner is already set + if (partner != hw) + { + // partner changed? + partner= hw; + } + else + partner= hw; + } + partner= hw; +} + +void +cl_partner_hw::refresh(class cl_hw *new_hw) +{ + if (!new_hw) + return; + if (cathegory == new_hw->cathegory && + id == new_hw->id) + { + if (partner) + { + // partner changed? + partner= new_hw; + } + else + partner= new_hw; + } +} + +void +cl_partner_hw::happen(class cl_hw *where, enum hw_event he, void *params) +{ + if (partner) + partner->happen(where, he, params); +} + + /* End of hw.cc */ diff --git a/sim/ucsim/sim.src/hwcl.h b/sim/ucsim/sim.src/hwcl.h index daf35b63..a67921e0 100644 --- a/sim/ucsim/sim.src/hwcl.h +++ b/sim/ucsim/sim.src/hwcl.h @@ -32,11 +32,55 @@ Software Foundation, 59 Temple Place - Suite 330, Boston, MA #include "stypes.h" #include "pobjcl.h" -#include "uccl.h" #include "guiobjcl.h" +// cmd.src #include "newcmdcl.h" +// local +#include "memcl.h" +#include "uccl.h" + + +enum what_to_do_on_cell_change { + wtd_none = 0x01, + wtd_write = 0x02, + wtd_restore = 0x04, + wtd_restore_write = 0x08 +}; + +#define WTD_WRITE (wtd_write|wtd_restore_write) +#define WTD_RESTORE (wtd_restore|wtd_restore_write) + +class cl_hw; // forward + +class cl_watched_cell: public cl_base +{ +protected: + class cl_mem *mem; + t_addr addr; + class cl_cell *cell; + class cl_cell **store; +public: + enum what_to_do_on_cell_change wtd; +public: + cl_watched_cell(class cl_mem *amem, t_addr aaddr, class cl_cell **astore, + enum what_to_do_on_cell_change awtd); + + virtual void mem_cell_changed(class cl_mem *amem, t_addr aaddr, + class cl_hw *hw); +}; + +class cl_used_cell: public cl_watched_cell +{ +public: + cl_used_cell(class cl_mem *amem, t_addr aaddr, class cl_cell **astore, + enum what_to_do_on_cell_change awtd): + cl_watched_cell(amem, aaddr, astore, awtd) {} + + /*virtual void mem_cell_changed(class cl_mem *amem, t_addr aaddr, + class cl_hw *hw);*/ +}; class cl_hw: public cl_guiobj { @@ -46,17 +90,36 @@ public: enum hw_cath cathegory; int id; char *id_string; - +protected: + class cl_list *partners; + class cl_list *watched_cells; public: cl_hw(class cl_uc *auc, enum hw_cath cath, int aid, char *aid_string); - ~cl_hw(void); + virtual ~cl_hw(void); + + virtual void new_hw_adding(class cl_hw *new_hw); + virtual void new_hw_added(class cl_hw *new_hw); + virtual void added_to_uc(void) {} + virtual class cl_hw *make_partner(enum hw_cath cath, int id); - virtual void adding(class cl_hw *new_hw) {} - virtual void added(class cl_hw *new_hw) {} - virtual t_mem read(class cl_mem *mem, t_addr addr); - virtual void write(class cl_mem *mem, t_addr addr, t_mem *val); + virtual t_mem read(class cl_cell *cell) { return(cell->get()); } + virtual void write(class cl_cell */*cell*/, t_mem */*val*/) {} + + virtual void set_cmd(class cl_cmdline *cmdline, class cl_console *con) {} + virtual class cl_cell *register_cell(class cl_mem *mem, t_addr addr, + class cl_cell **store, + enum what_to_do_on_cell_change awtd); + virtual class cl_cell *use_cell(class cl_mem *mem, t_addr addr, + class cl_cell **store, + enum what_to_do_on_cell_change awtd); + virtual void mem_cell_changed(class cl_mem *mem, t_addr addr); virtual int tick(int cycles); + virtual void reset(void) {} + virtual void happen(class cl_hw */*where*/, enum hw_event /*he*/, + void */*params*/) {} + virtual void inform_partners(enum hw_event he, void *params); + virtual void print_info(class cl_console *con); }; @@ -65,6 +128,25 @@ class cl_hws: public cl_list public: cl_hws(void): cl_list(2, 2) {} virtual t_index add(void *item); + virtual void mem_cell_changed(class cl_mem *mem, t_addr addr); +}; + + +class cl_partner_hw: public cl_base +{ +protected: + class cl_uc *uc; + enum hw_cath cathegory; + int id; + class cl_hw *partner; +public: + cl_partner_hw(class cl_uc *auc, enum hw_cath cath, int aid); + + virtual class cl_hw *get_partner(void); + virtual void refresh(void); + virtual void refresh(class cl_hw *new_hw); + + virtual void happen(class cl_hw *where, enum hw_event he, void *params); }; diff --git a/sim/ucsim/sim.src/itsrc.cc b/sim/ucsim/sim.src/itsrc.cc index de784289..0a5636c8 100644 --- a/sim/ucsim/sim.src/itsrc.cc +++ b/sim/ucsim/sim.src/itsrc.cc @@ -46,9 +46,11 @@ cl_it_src::cl_it_src(uchar Iie_mask, uchar Isrc_mask, uint Iaddr, bool Iclr_bit, - char *Iname): + char *Iname, + int apoll_priority): cl_base() { + poll_priority= apoll_priority; ie_mask = Iie_mask; src_reg = Isrc_reg; src_mask= Isrc_mask; @@ -91,6 +93,35 @@ cl_it_src::deactivate(void) } +/* + */ + +cl_irqs::cl_irqs(t_index alimit, t_index adelta): + cl_sorted_list(alimit, adelta) +{ + Duplicates= DD_TRUE; +} + +void * +cl_irqs::key_of(void *item) +{ + class cl_it_src *itsrc= (class cl_it_src *)item; + return(&itsrc->poll_priority); +} + +int +cl_irqs::compare(void *key1, void *key2) +{ + int *k1= (int*)key1, *k2= (int*)key2; + + if (*k1 == *k2) + return(0); + else if (*k1 < *k2) + return(-1); + return(1); +} + + /* * Interrupt level ****************************************************************************** diff --git a/sim/ucsim/sim.src/itsrccl.h b/sim/ucsim/sim.src/itsrccl.h index d585af9a..5752241b 100644 --- a/sim/ucsim/sim.src/itsrccl.h +++ b/sim/ucsim/sim.src/itsrccl.h @@ -39,6 +39,7 @@ Software Foundation, 59 Temple Place - Suite 330, Boston, MA class cl_it_src: public cl_base { public: + int poll_priority; uchar ie_mask; // Mask in IE register uchar src_reg; // Register in SFR of source uchar src_mask; // Mask of source bit in src_reg @@ -52,8 +53,9 @@ public: uchar Isrc_mask, uint Iaddr, bool Iclr_bit, - char *Iname); - ~cl_it_src(void); + char *Iname, + int apoll_priority); + virtual ~cl_it_src(void); bool is_active(void); virtual void set_active_status(bool Aactive); @@ -62,6 +64,15 @@ public: }; +class cl_irqs: public cl_sorted_list +{ +public: + cl_irqs(t_index alimit, t_index adelta); + virtual void *key_of(void *item); + virtual int compare(void *key1, void *key2); +}; + + /* * This class is used to follow levels of accepted interrupts * It used on a stack of active interrupt services (it_levels of cl_uc) diff --git a/sim/ucsim/sim.src/mem.cc b/sim/ucsim/sim.src/mem.cc index 24849b4c..12d16869 100644 --- a/sim/ucsim/sim.src/mem.cc +++ b/sim/ucsim/sim.src/mem.cc @@ -34,6 +34,9 @@ Software Foundation, 59 Temple Place - Suite 330, Boston, MA #include "utils.h" #include "globals.h" +// sim +#include "simcl.h" + // cmd #include "newcmdcl.h" @@ -46,21 +49,21 @@ Software Foundation, 59 Temple Place - Suite 330, Boston, MA * Memory location handled specially by a hw element */ -cl_memloc::cl_memloc(t_addr addr): +/*cl_memloc::cl_memloc(t_addr addr): cl_base() { address= addr; hws= new cl_list(2, 2); hws->init(); -} +}*/ -cl_memloc::~cl_memloc(void) +/*cl_memloc::~cl_memloc(void) { hws->disconn_all(); delete hws; -} +}*/ -ulong +/*ulong cl_memloc::read(class cl_mem *mem) { uchar ret= 0; @@ -72,9 +75,9 @@ cl_memloc::read(class cl_mem *mem) if ((hw= (class cl_hw *)(hws->at(0)))) ret= hw->read(mem, address); return(ret); -} +}*/ -void +/*void cl_memloc::write(class cl_mem *mem, t_addr addr, t_mem *val) { class cl_hw *hw; @@ -87,24 +90,24 @@ cl_memloc::write(class cl_mem *mem, t_addr addr, t_mem *val) hw= (class cl_hw *)hws->at(0); hw->write(mem, addr, val); } -} +}*/ /* Sorted collection of memory locations */ -cl_memloc_coll::cl_memloc_coll(void): +/*cl_memloc_coll::cl_memloc_coll(void): cl_sorted_list(2, 2) { Duplicates= DD_FALSE; -} +}*/ -void * +/*void * cl_memloc_coll::key_of(void *item) { return(&(((class cl_memloc *)item)->address)); -} +}*/ -int +/*int cl_memloc_coll::compare(void *key1, void *key2) { if (*(long*)key1 > *(long*)key2) @@ -114,9 +117,9 @@ cl_memloc_coll::compare(void *key1, void *key2) return(-1); else return(0); -} +}*/ -class cl_memloc * +/*class cl_memloc * cl_memloc_coll::get_loc(t_addr address) { t_index i; @@ -124,172 +127,21 @@ cl_memloc_coll::get_loc(t_addr address) if (search(&address, i)) return((class cl_memloc*)(at(i))); return(0); -} - - -/* - */ - -cl_cell::cl_cell(int awidth): - cl_base() -{ - data= 0; - mask= 1; - for (; awidth; awidth--) - { - mask<<= 1; - mask|= 1; - } -} - -/*t_mem -cl_cell::read(void) -{ - return(data); -}*/ - -/*t_mem -cl_cell::get(void) -{ - return(data); -}*/ - -/*void -cl_cell::write(t_mem *val) -{ - data= *val= (*val & mask); -}*/ - -/*void -cl_cell::set(t_mem val) -{ - data= val & mask; }*/ -cl_registered_cell::cl_registered_cell(int awidth): - cl_cell(awidth) -{ - hws= new cl_list(1, 1); - hardwares= 0; - nuof_hws= 0; -} - -cl_registered_cell::~cl_registered_cell(void) -{ - hws->disconn_all(); - delete hws; -} - -t_mem -cl_registered_cell::read(void) -{ - int i; - - /*if (hws->count) - for (i= 0; i < hws->count; i++) - { - class cl_hw *hw= (class cl_hw *)(hws->at(i)); - ; - }*/ - if (nuof_hws) - for (i= 0; i < nuof_hws; i++) - { - //hardwares[i]; - ; - } - return(data); -} - -void -cl_registered_cell::write(t_mem *val) -{ - int i; - - /*if (hws->count) - for (i= 0; i < hws->count; i++) - { - class cl_hw *hw= (class cl_hw *)(hws->at(i)); - ; - }*/ - if (nuof_hws) - for (i= 0; i < nuof_hws; i++) - { - //hardwares[i]; - ; - } - data= *val= (*val & mask); -} - - -/* - */ - -cl_m::cl_m(t_addr asize, int awidth): - cl_mem(MEM_SFR, "sfr", 0, awidth) -{ - t_addr a; - - size= asize; - width= awidth; - array= (class cl_cell **)malloc(size * sizeof(class cl_cell *)); - for (a= 0; a < size; a++) - array[a]= new cl_registered_cell(width); -} - -cl_m::~cl_m(void) -{ - t_addr a; - - for (a= 0; a < size; a++) - delete array[a]; - free(array); -} - -t_mem -cl_m::read(t_addr addr) -{ - if (addr >= size) - return(0); - return(array[addr]->read()); -} - -t_mem -cl_m::get(t_addr addr) -{ - if (addr >= size) - return(0); - return(array[addr]->get()); -} - -void -cl_m::write(t_addr addr, t_mem *val) -{ - if (addr >= size) - return; - array[addr]->write(val); -} - -void -cl_m::set(t_addr addr, t_mem val) -{ - if (addr >= size) - return; - array[addr]->set(val); -} - - /* * Memory ****************************************************************************** */ cl_mem::cl_mem(enum mem_class atype, char *aclass_name, - t_addr asize, int awidth): + t_addr asize, int awidth, class cl_uc *auc): cl_guiobj() { int i; - + + uc= auc; type= atype; class_name= aclass_name; width= awidth; @@ -297,25 +149,19 @@ cl_mem::cl_mem(enum mem_class atype, char *aclass_name, mem= 0; for (i= width, mask= 0; i; i--) mask= (mask<<1) | 1; - if (width <= 8) + if (width == 0 || + size == 0) + mem= 0; + else if (width <= 8) mem= (TYPE_UBYTE *)malloc(size); else if (width <= 16) mem= (TYPE_UWORD *)malloc(size*sizeof(TYPE_WORD)); else mem= (TYPE_UDWORD *)malloc(size*sizeof(TYPE_DWORD)); - read_locs= new cl_memloc_coll(); - write_locs= new cl_memloc_coll(); + //read_locs= new cl_memloc_coll(); + //write_locs= new cl_memloc_coll(); dump_finished= 0; - addr_format= (char *)malloc(10); - sprintf(addr_format, "0x%%0%dx", - size-1<=0xf?1: - (size-1<=0xff?2: - (size-1<=0xfff?3: - (size-1<=0xffff?4: - (size-1<=0xfffff?5: - (size-1<=0xffffff?6:12)))))); - data_format= (char *)malloc(10); - sprintf(data_format, "%%0%dx", width/4+((width%4)?1:0)); + addr_format= data_format= 0; } cl_mem::~cl_mem(void) @@ -326,8 +172,8 @@ cl_mem::~cl_mem(void) free(addr_format); if (data_format) free(data_format); - delete read_locs; - delete write_locs; + //delete read_locs; + //delete write_locs; } int @@ -335,6 +181,17 @@ cl_mem::init(void) { t_addr i; + addr_format= (char *)malloc(10); + sprintf(addr_format, "0x%%0%dx", + size-1<=0xf?1: + (size-1<=0xff?2: + (size-1<=0xfff?3: + (size-1<=0xffff?4: + (size-1<=0xfffff?5: + (size-1<=0xffffff?6:12)))))); + data_format= (char *)malloc(10); + sprintf(data_format, "%%0%dx", width/4+((width%4)?1:0)); + for (i= 0; i < size; i++) set(i, (type==MEM_ROM)?(-1):0); return(0); @@ -351,16 +208,16 @@ cl_mem::id_string(void) t_mem cl_mem::read(t_addr addr) { - class cl_memloc *loc; + //class cl_memloc *loc; if (addr >= size) { //FIXME - fprintf(stderr, "Address 0x%06lx is over 0x%06lx\n", addr, size); + fprintf(stderr, "Address 0x%06"_A_"x is over 0x%06"_A_"x\n", addr, size); return(0); } - if ((loc= read_locs->get_loc(addr))) - return(loc->read(this)); + /*if ((loc= read_locs->get_loc(addr))) + return(loc->read(this));*/ if (width <= 8) return((((TYPE_UBYTE*)mem)[addr])&mask); else if (width <= 16) @@ -389,10 +246,10 @@ cl_mem::get(t_addr addr) /* Write calls callbacks of HW elements */ -void -cl_mem::write(t_addr addr, t_mem *val) +t_mem +cl_mem::write(t_addr addr, t_mem val) { - class cl_memloc *loc; + /* class cl_memloc *loc; if (addr >= size) return; @@ -403,7 +260,10 @@ cl_mem::write(t_addr addr, t_mem *val) else if (width <= 16) ((TYPE_UWORD*)mem)[addr]= (*val)&mask; else - ((TYPE_UDWORD*)mem)[addr]= (*val)&mask; + ((TYPE_UDWORD*)mem)[addr]= (*val)&mask;*/ + fprintf(stderr, "FIXME cl_mem::write(0x%06"_A_"x, 0x%04"_M_"x)\n", + addr, val); + return(0); } /* Set doesn't call callbacks */ @@ -488,7 +348,7 @@ cl_mem::dump(t_addr start, t_addr stop, int bpl, class cl_console *con) (start+i <= stop); i++) { - con->dd_printf(data_format, read(start+i)); con->dd_printf(" "); + con->dd_printf(data_format, /*read*/get(start+i)); con->dd_printf(" "); } while (i < bpl) { @@ -577,7 +437,7 @@ cl_mem::search_next(bool case_sensitive, t_mem *array, int len, t_addr *addr) * Bitmap */ -cl_bitmap::cl_bitmap(t_addr asize): +/*cl_bitmap::cl_bitmap(t_addr asize): cl_base() { map= (uchar*)malloc(size= asize/(8*SIZEOF_CHAR)); @@ -620,14 +480,14 @@ cl_bitmap::empty(void) for (i= 0; i < size && map[i] == 0; i++) ; return(i == size); -} +}*/ /* * Special memory for code (ROM) */ -cl_rom::cl_rom(t_addr asize, int awidth): - cl_mem(MEM_ROM, get_id_string(mem_classes, MEM_ROM), asize, awidth) +/*cl_rom::cl_rom(t_addr asize, int awidth, class cl_uc *auc): + cl_mem(MEM_ROM, get_id_string(mem_classes, MEM_ROM), asize, awidth, auc) { bp_map= new cl_bitmap(asize); inst_map= new cl_bitmap(asize); @@ -637,6 +497,934 @@ cl_rom::~cl_rom(void) { delete bp_map; delete inst_map; +}*/ + + +/* + * New type of memory simulation + */ + +cl_normal_cell::cl_normal_cell(uchar awidth): + cl_cell() +{ + type= CELL_NORMAL; + data= 0; + mask= 1; + width= awidth; + for (--awidth; awidth; awidth--) + { + mask<<= 1; + mask|= 1; + } +} + +t_mem +cl_normal_cell::add(long what) +{ + t_mem d; + + if (width <= 8) + d= TYPE_BYTE(data) + what; + else if (width <= 16) + d= TYPE_WORD(data) + what; + else + d= TYPE_DWORD(data) + what; + return(data= d & mask); +} + +t_mem +cl_normal_cell::wadd(long what) +{ + t_mem d; + + if (width <= 8) + d= TYPE_BYTE(data) + what; + else if (width <= 16) + d= TYPE_WORD(data) + what; + else + d= TYPE_DWORD(data) + what; + return(write(d)); +} + +void +cl_normal_cell::set_bit1(t_mem bits) +{ + bits&= mask; + data|= bits; +} + +void +cl_normal_cell::set_bit0(t_mem bits) +{ + bits&= mask; + data&= ~bits; +} + + +/* + */ + +cl_registered_cell::cl_registered_cell(uchar awidth): + cl_normal_cell(awidth) +{ + type= CELL_HW_READ | CELL_HW_WRITE; + //hws= new cl_list(1, 1); + hardwares= 0; + nuof_hws= 0; +} + +cl_registered_cell::~cl_registered_cell(void) +{ + if (hardwares) + free(hardwares); +} + +/*void +cl_registered_cell::destroy(void) +{ + hardwares= 0; + nuof_hws= 0; +}*/ + +t_mem +cl_registered_cell::read(void) +{ + int i; + t_mem d= data; + + if (nuof_hws) + for (i= 0; i < nuof_hws; i++) + { + d= hardwares[i]->read(this); + ; + } + return(d & mask); +} + +t_mem +cl_registered_cell::read(enum hw_cath skip) +{ + int i; + t_mem d= data; + + if (nuof_hws) + for (i= 0; i < nuof_hws; i++) + { + if ((skip & hardwares[i]->cathegory) == 0) + d= hardwares[i]->read(this); + ; + } + return(d & mask); +} + +t_mem +cl_registered_cell::write(t_mem val) +{ + int i; + + val&= mask; + if (nuof_hws) + for (i= 0; i < nuof_hws; i++) + { + hardwares[i]->write(this, &val); + ; + } + return(data= val & mask); +} + +class cl_cell * +cl_registered_cell::add_hw(class cl_hw *hw, int *ith) +{ + if (!hw) + { + /* Whatta hell!? */ + return(0); + } + if (!hardwares) + hardwares= (class cl_hw **)malloc(sizeof(class cl_hw *)); + else + hardwares= (class cl_hw **)realloc(hardwares, + sizeof(class c_hw *) * (nuof_hws+1)); + hardwares[nuof_hws]= hw; + nuof_hws++; + if (ith) + *ith= nuof_hws-1; + return(this); +} + +class cl_hw * +cl_registered_cell::get_hw(int ith) +{ + if (ith >= nuof_hws) + return(0); + return(hardwares[ith]); +} + + +/* + */ + +cl_event_handler::cl_event_handler(class cl_uc *auc): + cl_base() +{ + uc= auc; + read_bps= new cl_list(1, 1); + write_bps= new cl_list(1, 1); +} + +cl_event_handler::~cl_event_handler(void) +{ + read_bps->disconn_all(); + write_bps->disconn_all(); + delete read_bps; + delete write_bps; +} + +void +cl_event_handler::write(void) +{ + int i; + + for (i= 0; i < write_bps->count; i++) + { + class cl_brk *bp= (class cl_brk *)(write_bps->at(i)); + uc->events->add(bp); + } +} + +void +cl_event_handler::read(void) +{ + int i; + + for (i= 0; i < read_bps->count; i++) + { + class cl_brk *bp= (class cl_brk *)(read_bps->at(i)); + uc->events->add(bp); + } +} + +int +cl_event_handler::add_bp(class cl_brk *bp) +{ + int t= CELL_NORMAL; + + if (!bp) + return(CELL_NORMAL); + switch (bp->get_event()) + { + case brkWRITE: case brkWXRAM: case brkWIRAM: case brkWSFR: + t|= CELL_WRITE_BRK; + write_bps->add(bp); + break; + case brkREAD: case brkRXRAM: case brkRCODE: case brkRIRAM: case brkRSFR: + t|= CELL_READ_BRK; + read_bps->add(bp); + break; + default: + t|= CELL_READ_BRK | CELL_WRITE_BRK; + read_bps->add(bp); + write_bps->add(bp); + break; + } + return(t); +} + +int +cl_event_handler::copy_from(class cl_event_handler *eh) +{ + int i, t= CELL_NORMAL; + + if (!eh) + return(t); + for (i= 0; i < eh->read_bps->count; i++) + { + class cl_brk *bp= (class cl_brk *)(eh->read_bps->at(i)); + t|= add_bp(bp); + } + for (i= 0; i < eh->write_bps->count; i++) + { + class cl_brk *bp= (class cl_brk *)(eh->write_bps->at(i)); + t|= add_bp(bp); + } + return(t); +} + +int +cl_event_handler::del_bp(class cl_brk *bp) +{ + int t= CELL_NORMAL; + + write_bps->disconn(bp); + read_bps->disconn(bp); + if (write_bps->count) + t|= CELL_WRITE_BRK; + if (read_bps->count) + t|= CELL_READ_BRK; + return(t); +} + + +/* + */ + +cl_event_cell::cl_event_cell(uchar awidth, class cl_uc *auc): + cl_normal_cell(awidth) +{ + eh= new cl_event_handler(auc); +} + +cl_event_cell::~cl_event_cell(void) +{ + delete eh; +} + +t_mem +cl_event_cell::read(void) +{ + if (type & CELL_READ_BRK) + eh->read(); + return(cl_normal_cell::read()); +} + +t_mem +cl_event_cell::write(t_mem val) +{ + if (type & CELL_WRITE_BRK) + eh->write(); + return(cl_normal_cell::write(val)); +} + + +/* + */ + +cl_ev_reg_cell::cl_ev_reg_cell(uchar awidth, class cl_uc *auc): + cl_registered_cell(awidth) +{ + eh= new cl_event_handler(auc); +} + +cl_ev_reg_cell::~cl_ev_reg_cell(void) +{} + +t_mem +cl_ev_reg_cell::read(void) +{ + if (type & CELL_READ_BRK) + eh->read(); + return(cl_registered_cell::read()); +} + +t_mem +cl_ev_reg_cell::write(t_mem val) +{ + if (type & CELL_WRITE_BRK) + eh->write(); + return(cl_registered_cell::write(val)); +} + + +/* + */ + +cl_mapped_cell::cl_mapped_cell(class cl_cell *realcell) +{ + real_cell= realcell; +} + +cl_mapped_cell::~cl_mapped_cell(void) +{} + +t_mem +cl_mapped_cell::read(void) +{ + return(real_cell->read()); +} + +t_mem +cl_mapped_cell::read(enum hw_cath skip) +{ + return(real_cell->read(skip)); +} + +t_mem +cl_mapped_cell::get(void) +{ + return(real_cell->get()); +} + +t_mem +cl_mapped_cell::write(t_mem val) +{ + return(real_cell->write(val)); +} + +t_mem +cl_mapped_cell::set(t_mem val) +{ + return(real_cell->set(val)); +} + +t_mem +cl_mapped_cell::add(long what) +{ + return(real_cell->add(what)); +} + +t_mem +cl_mapped_cell::wadd(long what) +{ + return(real_cell->wadd(what)); +} + +void +cl_mapped_cell::set_bit1(t_mem bits) +{ + return(real_cell->set_bit1(bits)); +} + +void +cl_mapped_cell::set_bit0(t_mem bits) +{ + return(real_cell->set_bit0(bits)); +} + +class cl_cell * +cl_mapped_cell::add_hw(class cl_hw *hw, int *ith) +{ + return(real_cell->add_hw(hw, ith)); +} + +class cl_hw * +cl_mapped_cell::get_hw(int ith) +{ + return(real_cell->get_hw(ith)); +} + +class cl_event_handler * +cl_mapped_cell::get_event_handler(void) +{ + return(real_cell->get_event_handler()); +} + + +/* + */ + +cl_m::cl_m(enum mem_class atype, char *aclass_name, t_addr asize, int awidth, + class cl_uc *auc): + cl_mem(atype, aclass_name, 0, awidth, auc) +{ + t_addr a; + + size= asize; + width= awidth; + array= (class cl_cell **)calloc(size, sizeof(class cl_cell *)); + for (a= 0; a < size; a++) + array[a]= new cl_normal_cell(width); + bus_mask= 0; + t_addr i; + for (i= 1; i < size; i<<=1) + bus_mask= (bus_mask<<1)|1; + dummy= new cl_normal_cell(width); + //mk_cell(size, 0); +} + +cl_m::~cl_m(void) +{ + t_addr a; + + for (a= 0; a < size; a++) + delete array[a]; + free(array); + delete dummy; +} + +void +cl_m::err_inv_addr(t_addr addr) +{ + if (!uc) + return; + class cl_error *e= new cl_err_inv_addr(this, addr); + uc->error(e); +} + +/*void +cl_m::mk_cell(t_addr addr, class cl_cell *cell) +{ + if (!cell) + cell= new cl_cell(width); + class cl_cell *p; + if (addr >= size) + p= dummy; + else + p= array[addr]; + if (p == 0) + { + p= (class cl_cell *)calloc(1, sizeof(*cell)); + } + else + { + p->destroy(); + p= (class cl_cell *)realloc(p, sizeof(cell)); + } + memcpy(p, cell, sizeof(*cell)); + cell->destroy(); + delete cell; +}*/ + +int +cl_m::get_cell_flag(t_addr addr) +{ + if (addr >= size) + { + return(dummy->get_type()); + } + return(array[addr]->get_type()); +} + +bool +cl_m::get_cell_flag(t_addr addr, int flag) +{ + if (addr >= size) + { + return(dummy->get_type() & flag); + } + return(array[addr]->get_type() & flag); +} + +void +cl_m::set_cell_flag(t_addr addr, bool set_to, int flag) +{ + class cl_cell *cell; + + if (addr >= size) + { + cell= dummy; + } + else + cell= array[addr]; + if (set_to) + cell->set_type(cell->get_type() | flag); + else + cell->set_type(cell->get_type() & ~flag); +} + +t_mem +cl_m::read(t_addr addr) +{ + //addr&= bus_mask; + if (addr >= size) + { + err_inv_addr(addr); + return(dummy->read()); + } + return(array[addr]->read()); +} + +t_mem +cl_m::read(t_addr addr, enum hw_cath skip) +{ + //addr&= bus_mask; + if (addr >= size) + { + err_inv_addr(addr); + return(dummy->read(skip)); + } + return(array[addr]->read(skip)); +} + +t_mem +cl_m::get(t_addr addr) +{ + addr&= bus_mask; + if (addr >= size) + { + err_inv_addr(addr); + return(dummy->get()); + } + return(array[addr]->get()); +} + +t_mem +cl_m::write(t_addr addr, t_mem val) +{ + //addr&= bus_mask; + if (addr >= size) + { + err_inv_addr(addr); + return(dummy->write(val)); + } + return(array[addr]->write(val)); +} + +void +cl_m::set(t_addr addr, t_mem val) +{ + if (addr >= size) + { + err_inv_addr(addr); + //addr&= bus_mask; + dummy->set(val); + return; + } + //addr&= bus_mask; + array[addr]->set(val); +} + +class cl_cell * +cl_m::get_cell(t_addr addr) +{ + //addr&= bus_mask; + if (addr >= size) + { + err_inv_addr(addr); + return(dummy); + } + return(array[addr]); +} + + +/* Set or clear bits, without callbacks */ + +void +cl_m::set_bit1(t_addr addr, t_mem bits) +{ + class cl_cell *cell; + + addr&= bus_mask; + if (addr >= size) + { + err_inv_addr(addr); + cell= dummy; + } + else + cell= array[addr]; + bits&= cell->get_mask(); + cell->set(cell->get() | bits); +} + +void +cl_m::write_bit1(t_addr addr, t_mem bits) +{ + class cl_cell *cell; + + addr&= bus_mask; + if (addr >= size) + { + err_inv_addr(addr); + cell= dummy; + } + else + cell= array[addr]; + bits&= cell->get_mask(); + cell->write(cell->get() | bits); +} + +void +cl_m::set_bit0(t_addr addr, t_mem bits) +{ + class cl_cell *cell; + + addr&= bus_mask; + if (addr >= size) + { + err_inv_addr(addr); + cell= dummy; + } + else + cell= array[addr]; + bits&= cell->get_mask(); + cell->set(cell->get() & ~bits); +} + +void +cl_m::write_bit0(t_addr addr, t_mem bits) +{ + class cl_cell *cell; + + addr&= bus_mask; + if (addr >= size) + { + err_inv_addr(addr); + cell =dummy; + } + else + cell= array[addr]; + bits&= cell->get_mask(); + cell->write(cell->get() & ~bits); +} + +t_mem +cl_m::add(t_addr addr, long what) +{ + addr&= bus_mask; + if (addr >= size) + { + err_inv_addr(addr); + return(dummy->add(what)); + } + return(array[addr]->add(what)); +} + +t_mem +cl_m::wadd(t_addr addr, long what) +{ + addr&= bus_mask; + if (addr >= size) + { + err_inv_addr(addr); + return(dummy->wadd(what)); + } + return(array[addr]->wadd(what)); +} + +class cl_cell * +cl_m::register_hw(t_addr addr, class cl_hw *hw, int *ith, bool announce) +{ + class cl_cell *cell, *nc; + + addr&= bus_mask; + if (addr >= size) + cell= dummy; + else + cell= array[addr]; + + if (cell->get_type() & (CELL_HW_READ | CELL_HW_WRITE)) + { + /* Already registered */ + return(cell->add_hw(hw, ith)); + } + else if (cell->get_type() & (CELL_READ_BRK | CELL_WRITE_BRK)) + { + /* Event break is set on it, now register hw */ + nc= new cl_ev_reg_cell(width, uc); + nc->set(cell->get()); + nc->set_type(nc->get_type() & + ~(CELL_GENERAL|CELL_READ_BRK|CELL_WRITE_BRK)); + nc->set_type(nc->get_type() | (cell->get_type() & CELL_GENERAL)); + class cl_event_handler *eh= nc->get_event_handler(); + if (eh) + nc->set_type(nc->get_type() | eh->copy_from(cell->get_event_handler())); + nc->add_hw(hw, ith); + } + else + { + /* Normal cell, register hw */ + nc= new cl_registered_cell(width); + nc->set(cell->get()); + nc->set_type(nc->get_type() & ~CELL_GENERAL); + nc->set_type(nc->get_type() | (cell->get_type() & CELL_GENERAL)); + nc->add_hw(hw, ith); + } + + if (addr >= size) + { + delete dummy; + dummy= nc; + } + else + { + delete array[addr]; + array[addr]= nc; + } + if (announce) + uc->sim->/*app->*/mem_cell_changed(this, addr); + return(nc); +} + +void +cl_m::set_brk(t_addr addr, class cl_brk *brk) +{ + class cl_cell *cell, *nc; + char e= '_'; + + addr&= bus_mask; + if (addr >= size) + cell= dummy; + else + cell= array[addr]; + + switch (brk->get_event()) + { + case brkWRITE: case brkWXRAM: case brkWIRAM: case brkWSFR: + e= 'W'; + break; + case brkREAD: case brkRXRAM: case brkRCODE: case brkRIRAM: case brkRSFR: + e= 'R'; + break; + case brkNONE: + set_cell_flag(addr, DD_TRUE, CELL_FETCH_BRK); + return; + break; + default: e= '.'; break; + } + + if (cell->get_type() & (CELL_HW_READ | CELL_HW_WRITE)) + { + /* Hw is registered on it, now set event break */ + nc= new cl_ev_reg_cell(width, uc); + nc->set(cell->get()); + nc->set_type(nc->get_type() & ~CELL_GENERAL); + nc->set_type(nc->get_type() | (cell->get_type() & CELL_GENERAL)); + int i= 0; + class cl_hw *hw; + while ((hw= cell->get_hw(i)) != 0) + { + nc->add_hw(hw, 0); + i++; + } + if (((class cl_registered_cell *)cell)->hardwares) + { + free(((class cl_registered_cell *)cell)->hardwares); + ((class cl_registered_cell *)cell)->hardwares= 0; + } + class cl_event_handler *eh; + if ((eh= nc->get_event_handler())) + nc->set_type(nc->get_type() | eh->add_bp(brk)); + } + else if (cell->get_type() & (CELL_READ_BRK | CELL_WRITE_BRK)) + { + /* Break is already set on it */ + class cl_event_handler *eh; + if ((eh= cell->get_event_handler())) + cell->set_type(cell->get_type() | eh->add_bp(brk)); + return; + } + else + { + /* Normal cell, set event break */ + nc= new cl_event_cell(width, uc); + nc->set(cell->get()); + nc->set_type(nc->get_type() & ~CELL_GENERAL); + nc->set_type(nc->get_type() | (cell->get_type() & CELL_GENERAL)); + class cl_event_handler *eh; + if ((eh= nc->get_event_handler())) + nc->set_type(nc->get_type() | eh->add_bp(brk)); + } + + if (addr >= size) + { + delete dummy; + dummy= nc; + } + else + { + delete array[addr]; + array[addr]= nc; + } + uc->sim->/*app->*/mem_cell_changed(this, addr); +} + +void +cl_m::del_brk(t_addr addr, class cl_brk *brk) +{ + class cl_cell *cell, *nc; + char e= '_'; + + addr&= bus_mask; + if (addr >= size) + cell= dummy; + else + cell= array[addr]; + + switch (brk->get_event()) + { + case brkWRITE: case brkWXRAM: case brkWIRAM: case brkWSFR: e= 'W'; break; + case brkREAD: case brkRXRAM: case brkRCODE: case brkRIRAM: case brkRSFR: + e= 'R'; + break; + case brkNONE: + set_cell_flag(addr, DD_FALSE, CELL_FETCH_BRK); + return; + break; + default: e= '.'; break; + } + + if (cell->get_type() & (CELL_HW_READ | CELL_HW_WRITE)) + { + /* Hw is registered on it, delete event break */ + class cl_event_handler *eh; + int t= CELL_NORMAL; + if ((eh= cell->get_event_handler())) + t= eh->del_bp(brk); + if (t & (CELL_READ_BRK|CELL_WRITE_BRK)) + { + cell->set_type(cell->get_type() & ~(CELL_READ_BRK|CELL_WRITE_BRK)); + cell->set_type(cell->get_type() | t); + return; + } + nc= new cl_registered_cell(width); + nc->set(cell->get()); + nc->set_type(cell->get_type() & ~CELL_GENERAL); + nc->set_type(cell->get_type() | (cell->get_type() & CELL_GENERAL)); + int i= 0; + class cl_hw *hw; + while ((hw= cell->get_hw(i)) != 0) + { + nc->add_hw(hw, 0); + i++; + } + if (((class cl_registered_cell *)cell)->hardwares) + free(((class cl_registered_cell *)cell)->hardwares); + } + else if (cell->get_type() & (CELL_READ_BRK | CELL_WRITE_BRK)) + { + /* Break already set on it, delete brk */ + class cl_event_handler *eh; + int t= CELL_NORMAL; + if ((eh= cell->get_event_handler())) + t= eh->del_bp(brk); + if (t & (CELL_READ_BRK|CELL_WRITE_BRK)) + { + cell->set_type(cell->get_type() & ~(CELL_READ_BRK|CELL_WRITE_BRK)); + cell->set_type(cell->get_type() | t); + return; + } + nc= new cl_normal_cell(width); + nc->set(cell->get()); + nc->set_type(cell->get_type() & ~CELL_GENERAL); + nc->set_type(cell->get_type() | (cell->get_type() & CELL_GENERAL)); + return; + } + else + { + /* Normal cell */ + return; + } + + if (addr >= size) + { + delete dummy; + dummy= nc; + } + else + { + delete array[addr]; + array[addr]= nc; + } + uc->sim->/*app->*/mem_cell_changed(this, addr); +} + + +/* + * Errors in memory handling + */ + +cl_err_inv_addr::cl_err_inv_addr(class cl_mem *amem, t_addr aaddr): + cl_error() +{ + mem= amem; + addr= aaddr; +} + +void +cl_err_inv_addr::print(class cl_commander *c) +{ + c->dd_printf("Error: invalid address "); + c->dd_printf(mem->addr_format, addr); + c->dd_printf(" in memory %s.\n", mem->class_name); } diff --git a/sim/ucsim/sim.src/memcl.h b/sim/ucsim/sim.src/memcl.h index 85f9462d..4788d7d5 100644 --- a/sim/ucsim/sim.src/memcl.h +++ b/sim/ucsim/sim.src/memcl.h @@ -28,17 +28,95 @@ Software Foundation, 59 Temple Place - Suite 330, Boston, MA #ifndef SIM_MEMCL_HEADER #define SIM_MEMCL_HEADER + +// prj #include "stypes.h" #include "pobjcl.h" +// gui.src #include "guiobjcl.h" class cl_mem; +class cl_event_handler; + + +// Cell types +#define CELL_NORMAL 0x00 /* Nothing special */ +#define CELL_HW_READ 0x01 /* Hw handles read */ +#define CELL_HW_WRITE 0x02 /* Hw catches write */ +#define CELL_INST 0x04 /* Marked as instruction */ +#define CELL_FETCH_BRK 0x08 /* Fetch breakpoint */ +#define CELL_READ_BRK 0x10 /* Read event breakpoint */ +#define CELL_WRITE_BRK 0x20 /* Write event breakpoint */ + +#define CELL_GENERAL (CELL_NORMAL|CELL_INST|CELL_FETCH_BRK) + + +class cl_cell: public cl_base +{ +public: + cl_cell(void): cl_base() {} +public: + virtual TYPE_UBYTE get_type(void)= 0; + virtual void set_type(TYPE_UBYTE what)= 0; + virtual t_mem get_mask(void)= 0; + + virtual t_mem read(void)=0 ; + virtual t_mem read(enum hw_cath /*skip*/)=0; + virtual t_mem get(void)=0; + virtual t_mem write(t_mem val)=0; + virtual t_mem set(t_mem val)=0; + virtual t_mem add(long what)=0; + virtual t_mem wadd(long what)=0; + + virtual void set_bit1(t_mem bits)=0; + virtual void set_bit0(t_mem bits)=0; + + virtual class cl_cell *add_hw(class cl_hw */*hw*/, int */*ith*/)=0; + virtual class cl_hw *get_hw(int ith)=0; + virtual class cl_event_handler *get_event_handler(void)=0; +}; + +class cl_normal_cell: public cl_cell +{ +public: + t_mem data; + TYPE_UBYTE type; // See CELL_XXXX + //protected: + t_mem mask; + uchar width; + +public: + cl_normal_cell(uchar awidth); + //virtual void destroy(void) {} + + virtual TYPE_UBYTE get_type(void) { return(type); } + virtual void set_type(TYPE_UBYTE what) { type= what; } + virtual t_mem get_mask(void) { return(mask); } + + virtual t_mem read(void) { return(data); } + virtual t_mem read(enum hw_cath /*skip*/) { return(data); } + virtual t_mem get(void) { return(data); } + virtual t_mem write(t_mem val) { data= val & mask; return(data); } + virtual t_mem set(t_mem val) { return(data= val & mask); } + virtual t_mem add(long what); + virtual t_mem wadd(long what); + + virtual void set_bit1(t_mem bits); + virtual void set_bit0(t_mem bits); + + virtual class cl_cell *add_hw(class cl_hw */*hw*/, int */*ith*/) + { return(0); } + virtual class cl_hw *get_hw(int ith) { return(0); } + //virtual class cl_brk *get_brk(void) { return(0); } + virtual class cl_event_handler *get_event_handler(void) { return(0); } +}; + /* Memory location handled specially by a hw element */ -class cl_memloc: public cl_base +/*class cl_memloc: public cl_base { public: t_addr address; @@ -46,13 +124,13 @@ public: public: cl_memloc(t_addr addr); - ~cl_memloc(void); + virtual ~cl_memloc(void); virtual ulong read(class cl_mem *mem); virtual void write(class cl_mem *mem, t_addr addr, t_mem *val); -}; +};*/ -class cl_memloc_coll: public cl_sorted_list +/*class cl_memloc_coll: public cl_sorted_list { public: cl_memloc_coll(void); @@ -61,7 +139,7 @@ public: virtual int compare(void *key1, void *key2); class cl_memloc *get_loc(t_addr address); -}; +};*/ /* Memory */ @@ -78,39 +156,56 @@ public: void *mem; uchar *umem8; }; - class cl_memloc_coll *read_locs, *write_locs; + //class cl_memloc_coll *read_locs, *write_locs; + class cl_uc *uc; t_addr dump_finished; public: - cl_mem(enum mem_class atype, char *aclass_name, t_addr asize, int awidth); - ~cl_mem(void); + cl_mem(enum mem_class atype, char *aclass_name, t_addr asize, int awidth, + class cl_uc *auc); + virtual ~cl_mem(void); virtual int init(void); virtual char *id_string(void); + virtual int get_cell_flag(t_addr /*addr*/) { return(CELL_NORMAL); } + virtual bool get_cell_flag(t_addr /*addr*/, int /*flag*/) + { return(DD_FALSE); } + virtual void set_cell_flag(t_addr addr, bool set_to, int flag) {} virtual t_mem read(t_addr addr); + virtual t_mem read(t_addr addr, enum hw_cath /*skip*/) {return(read(addr));} virtual t_mem get(t_addr addr); - virtual void write(t_addr addr, t_mem *val); + virtual t_mem write(t_addr addr, t_mem val); virtual void set(t_addr addr, t_mem val); virtual void set_bit1(t_addr addr, t_mem bits); virtual void set_bit0(t_addr addr, t_mem bits); + virtual void write_bit1(t_addr addr, t_mem bits) { set_bit1(addr, bits); } + virtual void write_bit0(t_addr addr, t_mem bits) { set_bit0(addr, bits); } virtual t_mem add(t_addr addr, long what); + virtual t_mem wadd(t_addr addr, long what) { return(add(addr, what)); } virtual t_addr dump(t_addr start, t_addr stop, int bpl, class cl_console *con); virtual t_addr dump(class cl_console *con); virtual bool search_next(bool case_sensitive, t_mem *array, int len, t_addr *addr); + + virtual class cl_cell *get_cell(t_addr addr) {return(0);} + virtual class cl_cell *register_hw(t_addr addr, class cl_hw *hw, int *ith, + bool announce) + { return(0); } + virtual void set_brk(t_addr /*addr*/, class cl_brk */*brk*/) {} + virtual void del_brk(t_addr addr, class cl_brk *brk) {} }; /* Spec for CODE */ -class cl_bitmap: public cl_base +/*class cl_bitmap: public cl_base { public: uchar *map; int size; public: cl_bitmap(t_addr asize); - ~cl_bitmap(void); + virtual ~cl_bitmap(void); virtual void set(t_addr pos); virtual void clear(t_addr pos); virtual bool get(t_addr pos); @@ -123,55 +218,176 @@ public: class cl_bitmap *bp_map; class cl_bitmap *inst_map; public: +<<<<<<< memcl.h cl_rom(t_addr asize, int awidth); ~cl_rom(void); }; /* New type */ +======= + cl_rom(t_addr asize, int awidth, class cl_uc *auc); + virtual ~cl_rom(void); +};*/ + +/* + * New type of memory simulation + */ +>>>>>>> 1.4.2.2 +<<<<<<< memcl.h class cl_cell: public cl_base { public: t_mem data; +======= +class cl_registered_cell: public cl_normal_cell +{ +public: + //class cl_list *hws; + class cl_hw **hardwares; + int nuof_hws; +public: + cl_registered_cell(uchar awidth); + virtual ~cl_registered_cell(void); + //virtual void destroy(void); + + virtual t_mem read(void); + virtual t_mem read(enum hw_cath skip); + virtual t_mem write(t_mem val); + + virtual class cl_cell *add_hw(class cl_hw *hw, int *ith); + virtual class cl_hw *get_hw(int ith); +}; + +class cl_event_handler: public cl_base +{ +public: + class cl_list *read_bps, *write_bps; + class cl_uc *uc; +public: + cl_event_handler(class cl_uc *auc); + virtual ~cl_event_handler(void); + + virtual void write(void); + virtual void read(void); + + virtual int add_bp(class cl_brk *bp); + virtual int copy_from(class cl_event_handler *eh); + virtual bool del_bp(class cl_brk *bp); +}; + +class cl_event_cell: public cl_normal_cell +{ +>>>>>>> 1.4.2.2 protected: - t_mem mask; + class cl_event_handler *eh; +public: + cl_event_cell(uchar awidth, class cl_uc *auc); + virtual ~cl_event_cell(void); + virtual t_mem read(void); + virtual t_mem write(t_mem val); + //virtual void event(void); + + //virtual class cl_brk *get_brk(void) { return(brk); } + virtual class cl_event_handler *get_event_handler(void) { return(eh); } +}; + +class cl_ev_reg_cell: public cl_registered_cell +{ +protected: + class cl_event_handler *eh; public: - cl_cell(int awidth); - virtual t_mem read(void) { return(data); } - virtual t_mem get(void) { return(data); } - virtual void write(t_mem *val) { data= *val= (*val & mask); } - virtual void set(t_mem val) { data= val & mask; } + cl_ev_reg_cell(uchar awidth, class cl_uc *auc); + virtual ~cl_ev_reg_cell(void); + + virtual t_mem read(void); + virtual t_mem write(t_mem val); + //virtual void event(void); + + //virtual class cl_brk *get_brk(void) { return(brk); } + virtual class cl_event_handler *get_event_handler(void) { return(eh); } }; -class cl_registered_cell: public cl_cell +class cl_mapped_cell: public cl_cell { protected: - class cl_list *hws; - class cl_hw *hardwares; - int nuof_hws; + class cl_cell *real_cell; public: - cl_registered_cell(int awidth); - ~cl_registered_cell(void); + cl_mapped_cell(class cl_cell *realcell); + virtual ~cl_mapped_cell(void); + virtual t_mem read(void); - virtual void write(t_mem *val); + virtual t_mem read(enum hw_cath skip); + virtual t_mem get(void); + virtual t_mem write(t_mem val); + virtual t_mem set(t_mem val); + virtual t_mem add(long what); + virtual t_mem wadd(long what); + + virtual void set_bit1(t_mem bits); + virtual void set_bit0(t_mem bits); + + virtual class cl_cell *add_hw(class cl_hw *hw, int *ith); + virtual class cl_hw *get_hw(int ith); + virtual class cl_event_handler *get_event_handler(void); }; class cl_m: public cl_mem { protected: class cl_cell **array; + class cl_cell *dummy; + t_addr bus_mask; public: - t_addr size; - int width; + //t_addr size; + //int width; public: + cl_m(enum mem_class atype, char *aclass_name, t_addr asize, int awidth, + class cl_uc *auc); cl_m(t_addr asize, int awidth); - ~cl_m(void); + virtual ~cl_m(void); + virtual void err_inv_addr(t_addr addr); + virtual int get_cell_flag(t_addr addr); + virtual bool get_cell_flag(t_addr addr, int flag); + virtual void set_cell_flag(t_addr addr, bool set_to, int flag); + virtual t_mem read(t_addr addr); + virtual t_mem read(t_addr addr, enum hw_cath skip); virtual t_mem get(t_addr addr); - virtual void write(t_addr addr, t_mem *val); + virtual t_mem write(t_addr addr, t_mem val); virtual void set(t_addr addr, t_mem val); + virtual class cl_cell *get_cell(t_addr addr); + + virtual void set_bit1(t_addr addr, t_mem bits); + virtual void set_bit0(t_addr addr, t_mem bits); + virtual void write_bit1(t_addr addr, t_mem bits); + virtual void write_bit0(t_addr addr, t_mem bits); + virtual t_mem add(t_addr addr, long what); + virtual t_mem wadd(t_addr addr, long what); + + virtual class cl_cell *register_hw(t_addr addr, class cl_hw *hw, int *ith, + bool announce); + virtual void set_brk(t_addr addr, class cl_brk *brk); + virtual void del_brk(t_addr addr, class cl_brk *brk); +}; + + +#include "errorcl.h" + +/* + * Errors in memory handling + */ + +class cl_err_inv_addr: public cl_error +{ +protected: + class cl_mem *mem; + t_addr addr; +public: + cl_err_inv_addr(class cl_mem *amem, t_addr aaddr); + virtual void print(class cl_commander *c); }; diff --git a/sim/ucsim/sim.src/optioncl.h b/sim/ucsim/sim.src/optioncl.h index 5ee8d7e8..32075e5b 100644 --- a/sim/ucsim/sim.src/optioncl.h +++ b/sim/ucsim/sim.src/optioncl.h @@ -46,7 +46,7 @@ public: public: cl_option(void *opt, char *Iid, char *Ihelp); - ~cl_option(void); + virtual ~cl_option(void); virtual void print(class cl_console *con)= 0; diff --git a/sim/ucsim/sim.src/sim.cc b/sim/ucsim/sim.src/sim.cc index 602a9f32..6803633c 100644 --- a/sim/ucsim/sim.src/sim.cc +++ b/sim/ucsim/sim.src/sim.cc @@ -183,7 +183,7 @@ cl_sim::stop(int reason) break; case resINV_INST: cmd->frozen_console->dd_printf("Invalid instruction 0x%04x\n", - uc->get_mem(MEM_ROM, uc->PC)); + uc->get_mem(MEM_ROM, uc->PC)); break; default: cmd->frozen_console->dd_printf("Unknown reason\n"); @@ -251,4 +251,18 @@ cl_sim::build_cmdset(class cl_cmdset *cmdset) } +/* + * Messages to broadcast + */ + +void +cl_sim::mem_cell_changed(class cl_mem *mem, t_addr addr) +{ + if (uc) + uc->mem_cell_changed(mem, addr); + else + printf("JAJ sim\n"); +} + + /* End of sim.src/sim.cc */ diff --git a/sim/ucsim/sim.src/simcl.h b/sim/ucsim/sim.src/simcl.h index d3e293d1..0ea3f8b7 100644 --- a/sim/ucsim/sim.src/simcl.h +++ b/sim/ucsim/sim.src/simcl.h @@ -60,12 +60,15 @@ public: public: cl_sim(class cl_app *the_app); - ~cl_sim(void); + virtual ~cl_sim(void); virtual int init(void); virtual class cl_uc *mk_controller(void); virtual void build_cmdset(class cl_cmdset *cmdset); + // messages from app to handle and broadcast + virtual void mem_cell_changed(class cl_mem *mem, t_addr addr); + virtual int main(void); virtual void start(class cl_console *con); virtual void stop(int reason); diff --git a/sim/ucsim/sim.src/stackcl.h b/sim/ucsim/sim.src/stackcl.h index 98747ff4..6e391abb 100644 --- a/sim/ucsim/sim.src/stackcl.h +++ b/sim/ucsim/sim.src/stackcl.h @@ -52,7 +52,7 @@ public: cl_stack_op(enum stack_op itype, t_addr iPC, t_addr iaddr, t_mem idata, t_addr iSP_before, t_addr iSP_after); - ~cl_stack_op(void); + virtual ~cl_stack_op(void); }; diff --git a/sim/ucsim/sim.src/test_mem_speed.cc b/sim/ucsim/sim.src/test_mem_speed.cc index d2359fdf..5f40e9eb 100644 --- a/sim/ucsim/sim.src/test_mem_speed.cc +++ b/sim/ucsim/sim.src/test_mem_speed.cc @@ -3,6 +3,9 @@ #include #include "memcl.h" +#include "hwcl.h" + +#include "newcmdcl.h" static int go; @@ -13,54 +16,83 @@ alarmed(int sig) signal(sig, alarmed); } -int -main(void) +class cl_hw_test: public cl_hw { - class cl_mem *mem; - class cl_m *m2; +public: + cl_hw_test(void): cl_hw(0, HW_PORT, 0, "0") {} + virtual t_mem r(class cl_cell *cell, t_addr addr); + virtual void write(class cl_mem *mem, t_addr addr, t_mem *val); +}; + +t_mem +cl_hw_test::r(class cl_cell *cell, t_addr addr) +{ + return(cell->get()); +} + +void +cl_hw_test::write(class cl_mem *mem, t_addr addr, t_mem *val) +{ +} + +double +do_rw_test(class cl_mem *mem, int time) +{ + double counter; t_addr a; t_mem d; - double counter; - signal(SIGALRM, alarmed); - - mem= new cl_mem(MEM_SFR, "egy", 0x10000, 8); go= 1; counter= 0; - alarm(10); + alarm(time); while (go) for (a= 0; go && a < mem->size; a++) { t_mem d2; - for (d2= 0; d2 <= 255; d2++) + for (d2= 0; go && d2 <= 255; d2++) { - mem->write(a, &d2); + d2= mem->write(a, d2); d= mem->read(a); if (d != d2) - printf("%ld written to mem and %ld read back!\n", d2, d); + printf("%"_M_"d written to mem and %"_M_"d read back!\n", d2, d); counter+= 1; } } - printf("%g operations on classic memory within 10 sec\n", counter); + return(counter); +} - m2= new cl_m(0x10000, 8); - go= 1; - counter= 0; - alarm(10); - while (go) - for (a= 0; go && a < m2->size; a++) - { - t_mem d2; - for (d2= 0; d2 <= 255; d2++) - { - m2->write(a, &d2); - d= m2->read(a); - if (d != d2) - printf("%ld written to m2 and %ld read back!\n", d2, d); - counter+= 1; - } - } - printf("%g operations on new memory within 10 sec\n", counter); +int +main(void) +{ + int i; + class cl_mem *mem; + class cl_m *m2; + class cl_console *con; + + signal(SIGALRM, alarmed); + con= new cl_console(stdin, stdout, 0); + + mem= new cl_mem(MEM_SFR, "egy", 0x10000, 8); + mem->init(); + printf("%g operations on classic memory within 5 sec\n", + do_rw_test(mem, 5)); + //mem->dump(con); + + m2= new cl_m(MEM_TYPES, "test", 0x10000, 8); + m2->init(); + printf("%g operations on new memory within 5 sec\n", + do_rw_test(m2, 5)); + + class cl_hw_test *hw= new cl_hw_test(); + for (i= 0; i < 0x10000; i++) + { + class cl_cell *c= m2->get_cell(i); + if (c) + c->add_hw(hw); + } + printf("%g operations on new memory within 5 sec with hw read\n", + do_rw_test(m2, 5)); + //m2->dump(con); return(0); } diff --git a/sim/ucsim/sim.src/uc.cc b/sim/ucsim/sim.src/uc.cc index bae85328..eda2c9c0 100644 --- a/sim/ucsim/sim.src/uc.cc +++ b/sim/ucsim/sim.src/uc.cc @@ -122,12 +122,15 @@ cl_uc::cl_uc(class cl_sim *asim): idle_ticks= new cl_ticker(+1, TICK_IDLE, "idle"); counters= new cl_list(2, 2); it_levels= new cl_list(2, 2); - it_sources= new cl_list(2, 2); + it_sources= new cl_irqs(2, 2); class it_level *il= new it_level(-1, 0, 0, 0); it_levels->push(il); st_ops= new cl_list(2, 2); + errors= new cl_list(2, 2); + events= new cl_list(2, 2); sp_max= 0; sp_avg= 0; + inst_exec= DD_FALSE; } @@ -140,11 +143,15 @@ cl_uc::~cl_uc(void) delete isr_ticks; delete idle_ticks; delete counters; + events->disconn_all(); + delete events; delete fbrk; delete ebrk; delete it_levels; delete it_sources; delete st_ops; + errors->free_all(); + delete errors; } @@ -165,8 +172,8 @@ cl_uc::init(void) get_id_string(mem_classes, mc)); mems->put_at(mc, m); } - ebrk= new brk_coll(2, 2, (class cl_rom *)mem(MEM_ROM)); - fbrk= new brk_coll(2, 2, (class cl_rom *)mem(MEM_ROM)); + ebrk= new brk_coll(2, 2, /*(class cl_rom *)*/mem(MEM_ROM)); + fbrk= new brk_coll(2, 2, /*(class cl_rom *)*/mem(MEM_ROM)); fbrk->Duplicates= DD_FALSE; brk_counter= 0; mk_hw_elements(); @@ -214,6 +221,13 @@ cl_uc::reset(void) } sp_max= 0; sp_avg= 0; + + int i; + for (i= 0; i < hws->count; i++) + { + class cl_hw *hw= (class cl_hw *)(hws->at(i)); + hw->reset(); + } } /* @@ -225,13 +239,10 @@ cl_uc::mk_mem(enum mem_class type, char *class_name) { class cl_mem *m; - if (get_mem_size(type) <= 0) + if (get_mem_size(type) < 0) return(0); - if (type == MEM_ROM) - m= new cl_rom(get_mem_size(type), get_mem_width(type)); - else - m= new cl_mem(type, get_id_string(mem_classes, type), - get_mem_size(type), get_mem_width(type)); + m= new cl_m(type, get_id_string(mem_classes, type), + get_mem_size(type), get_mem_width(type), this); m->init(); return(m); } @@ -243,7 +254,7 @@ cl_uc::get_mem_size(enum mem_class type) { case MEM_ROM: return(0x10000); case MEM_XRAM: return(0x10000); - case MEM_IRAM: return(0x100); + case MEM_IRAM: return(0x80); case MEM_SFR: return(0x100); case MEM_TYPES: default: return(0); @@ -406,9 +417,11 @@ cl_uc::build_cmdset(class cl_cmdset *cmdset) "set bit addr 0|1 Set specified bit to 0 or 1", "long help of set bit")); cmd->init(); - cset->add(cmd= new cl_set_port_cmd("port", 0, -"set port hw data Set data connected to port", -"long help of set port")); + cset->add(cmd= new cl_set_hw_cmd("hardware", 0, +"set hardware cathegory params...\n" +" Set parameters of specified hardware element", +"long help of set hardware")); + cmd->add_name("hw"); cmd->init(); cset->add(cmd= new cl_set_option_cmd("option", 0, "set option name value\n" @@ -437,7 +450,7 @@ cl_uc::build_cmdset(class cl_cmdset *cmdset) "info hardware cathegory\n" " Status of hardware elements of the CPU", "long help of info hardware")); - cmd->add_name("h w"); + cmd->add_name("hw"); cmd->init(); } cmdset->add(cmd= new cl_super_cmd("info", 0, @@ -462,28 +475,24 @@ cl_uc::build_cmdset(class cl_cmdset *cmdset) * Read/write simulated memory */ -ulong -cl_uc::read_mem(enum mem_class type, t_mem addr) +t_mem +cl_uc::read_mem(enum mem_class type, t_addr addr) { class cl_mem *m; - if ((m= (class cl_mem*)mems->at(type))) - return(m->read(addr)); - //FIXME -fprintf(stderr, "cl_uc::read_mem(type= %d, 0x%06lx) TROUBLE\n", type, addr); - return(0); + if ((m= (class cl_mem*)mems->at(type)) == 0) + m= (class cl_mem*)(mems->at(MEM_DUMMY)); + return(m->read(addr)); } -ulong +t_mem cl_uc::get_mem(enum mem_class type, t_addr addr) { class cl_mem *m; - if ((m= (class cl_mem*)mems->at(type))) - return(m->get(addr)); - //FIXME -printf("cl_uc::get_mem(type= %d, 0x%06lx) TROUBLE\n", type, addr); - return(0); + if ((m= (class cl_mem*)mems->at(type)) == 0) + m= (class cl_mem*)(mems->at(MEM_DUMMY)); + return(m->get(addr)); } void @@ -491,13 +500,9 @@ cl_uc::write_mem(enum mem_class type, t_addr addr, t_mem val) { class cl_mem *m; - if ((m= (class cl_mem*)mems->at(type))) - { - m->write(addr, &val); - //m->mem[addr]= val; - } - //FIXME -else printf("cl_uc::write_mem(type= %d, 0x%06lx, 0x%lx) TROUBLE\n", type, addr, val); + if ((m= (class cl_mem*)mems->at(type)) == 0) + m= (class cl_mem*)(mems->at(MEM_DUMMY)); + m->write(addr, val); } void @@ -505,20 +510,21 @@ cl_uc::set_mem(enum mem_class type, t_addr addr, t_mem val) { class cl_mem *m; - if ((m= (class cl_mem*)mems->at(type))) - m->set(addr, val); - //FIXME -else printf("cl_uc::set_mem(type= %d, 0x%06lx, 0x%lx) TROUBLE\n", type, addr, val); + if ((m= (class cl_mem*)mems->at(type)) == 0) + m= (class cl_mem*)(mems->at(MEM_DUMMY)); + m->set(addr, val); } class cl_mem * cl_uc::mem(enum mem_class type) { + class cl_mem *m; + if (mems->count < type) - //FIXME -{printf("TROUBLE\n"); return(0); -} - return((class cl_mem *)(mems->at(type))); + m= (class cl_mem *)(mems->at(MEM_DUMMY)); + else + m= (class cl_mem *)(mems->at(type)); + return(m); } class cl_mem * @@ -564,21 +570,6 @@ cl_uc::mem(char *class_name) return(0); } -/*TYPE_UBYTE * -cl_uc::MEM(enum mem_class type) -{ - class cl_mem *m; - - if ((m= mem(type)) == 0) - //FIXME -{printf("TROUBLE\n"); return(0); -} - return((TYPE_UBYTE *)(m->mem)); -}*/ - - -/* Local function for `read_hex_file' method to read some bytes */ - static long ReadInt(FILE *f, bool *ok, int bytes) { @@ -700,14 +691,13 @@ cl_uc::read_hex_file(const char *name) if (sim->app->args->get_iarg('V', 0) && rtyp != 1) sim->app->get_commander()-> - dd_printf("Unknown record type %d(0x%x)\n", - rtyp, rtyp); + dd_printf("Unknown record type %d(0x%x)\n", rtyp, rtyp); } else if (sim->app->args->get_iarg('V', 0)) sim->app->get_commander()-> dd_printf("Checksum error (%x instead of %x) in " - "record %ld.\n", chk, sum, recnum); + "record %ld.\n", chk, sum, recnum); } else if (sim->app->args->get_iarg('V', 0)) @@ -722,8 +712,7 @@ cl_uc::read_hex_file(const char *name) if (name) fclose(f); if (sim->app->args->get_iarg('V', 0)) - sim->app->get_commander()->dd_printf("%ld records have been read\n", - recnum); + sim->app->get_commander()->dd_printf("%ld records have been read\n", recnum); analyze(0); return(written); } @@ -741,39 +730,47 @@ cl_uc::read_hex_file(const char *name) bool cl_uc::inst_at(t_addr addr) { - class cl_rom *rom= (class cl_rom *)mem(MEM_ROM); + class cl_mem/*rom*/ *rom= /*(class cl_rom *)*/mem(MEM_ROM); if (!rom) return(0); - return(rom->inst_map->get(addr)); + //return(rom->inst_map->get(addr)); + return(rom->get_cell_flag(addr, CELL_INST)); } void cl_uc::set_inst_at(t_addr addr) { - class cl_rom *rom= (class cl_rom *)mem(MEM_ROM); + class cl_mem/*rom*/ *rom= /*(class cl_rom *)*/mem(MEM_ROM); if (rom) - rom->inst_map->set(addr); + //rom->inst_map->set(addr); + rom->set_cell_flag(addr, DD_TRUE, CELL_INST); } void cl_uc::del_inst_at(t_addr addr) { - class cl_rom *rom= (class cl_rom *)mem(MEM_ROM); + class cl_mem/*rom*/ *rom= /*(class cl_rom *)*/mem(MEM_ROM); if (rom) - rom->inst_map->clear(addr); + //rom->inst_map->clear(addr); + rom->set_cell_flag(addr, DD_FALSE, CELL_INST); } bool cl_uc::there_is_inst(void) { - class cl_rom *rom= (class cl_rom *)mem(MEM_ROM); + class cl_mem/*rom*/ *rom= /*(class cl_rom *)*/mem(MEM_ROM); if (!rom) return(0); - return(!(rom->inst_map->empty())); + //return(!(rom->inst_map->empty())); + bool got= DD_FALSE; + t_addr addr; + for (addr= 0; addr < rom->size && !got; addr++) + got= rom->get_cell_flag(addr, CELL_INST); + return(got); } @@ -784,7 +781,7 @@ cl_uc::there_is_inst(void) /* Register callback hw objects for mem read/write */ -void +/*void cl_uc::register_hw_read(enum mem_class type, t_addr addr, class cl_hw *hw) { class cl_mem *m; @@ -802,12 +799,12 @@ cl_uc::register_hw_read(enum mem_class type, t_addr addr, class cl_hw *hw) } else printf("cl_uc::register_hw_read TROUBLE\n"); -} +}*/ -void +/*void cl_uc::register_hw_write(enum mem_class type, t_addr addr, class cl_hw *hw) { -} +}*/ /* Looking for a specific HW element */ @@ -927,7 +924,7 @@ cl_uc::disass(t_addr addr, char *sep) char *buf; buf= (char*)malloc(100); - strcpy(buf, "uc::do_disass unimplemented\n"); + strcpy(buf, "uc::disass() unimplemented\n"); return(buf); } @@ -951,7 +948,7 @@ cl_uc::print_disass(t_addr addr, class cl_console *con) con->dd_printf("%c ", inst_at(addr)?' ':'?'); con->dd_printf(rom->addr_format, addr); con->dd_printf(" "); con->dd_printf(rom->data_format, code); - for (i= 1; i < inst_length(code); i++) + for (i= 1; i < inst_length(addr); i++) { con->dd_printf(" "); con->dd_printf(rom->data_format, get_mem(MEM_ROM, addr+i)); @@ -976,13 +973,28 @@ cl_uc::print_regs(class cl_console *con) } int -cl_uc::inst_length(t_mem code) +cl_uc::inst_length(t_addr addr) { struct dis_entry *tabl= dis_tbl(); int i; + t_mem code; + code = get_mem(MEM_ROM, addr); for (i= 0; tabl[i].mnemonic && (code & tabl[i].mask) != tabl[i].code; i++) ; - return(tabl[i].mnemonic?tabl[i].length:1); + return(tabl[i].mnemonic?tabl[i].length:1); +} + +int +cl_uc::inst_branch(t_addr addr) +{ + struct dis_entry *tabl= dis_tbl(); + int i; + t_mem code; + + code = get_mem(MEM_ROM, addr); + for (i= 0; tabl[i].mnemonic && (code & tabl[i].mask) != tabl[i].code; i++) + ; + return tabl[i].branch; } int @@ -1068,14 +1080,113 @@ cl_uc::symbolic_bit_name(t_addr bit_address, } +/* + * Messages to broadcast + */ + +void +cl_uc::mem_cell_changed(class cl_mem *mem, t_addr addr) +{ + if (hws) + hws->mem_cell_changed(mem, addr); + else + printf("JAJ uc\n");//FIXME + if (mems && + mems->count) + { + int i; + for (i= 0; i < mems->count; i++) + { + } + } +} + + +/* + * Error handling + */ + +void +cl_uc::error(class cl_error *error) +{ + errors->add(error); + if ((error->inst= inst_exec)) + error->PC= instPC; +} + +void +cl_uc::check_errors(void) +{ + int i; + class cl_commander *c= sim->app->get_commander(); + + if (c) + { + for (i= 0; i < errors->count; i++) + { + class cl_error *error= (class cl_error *)(errors->at(i)); + error->print(c); + if (error->inst) + { + class cl_console *con; + con= c->actual_console; + if (!con) + con= c->frozen_console; + if (con) + print_disass(error->PC, con); + } + } + errors->free_all(); + } + else + fprintf(stderr, "no actual console, %d errors\n", errors->count); +} + + +/* + * Converting bit address into real memory + */ + +class cl_mem * +cl_uc::bit2mem(t_addr bitaddr, t_addr *memaddr, t_mem *bitmask) +{ + if (memaddr) + *memaddr= bitaddr; + if (bitmask) + *bitmask= 1 << (bitaddr & 0x7); + return(0); // abstract... +} + + /* * Execution */ int -cl_uc::tick(int cycles) +cl_uc::tick_hw(int cycles) { class cl_hw *hw; + int i;//, cpc= clock_per_cycle(); + + // tick hws + for (i= 0; i < hws->count; i++) + { + hw= (class cl_hw *)(hws->at(i)); + if (hw->flags & HWF_INSIDE) + hw->tick(cycles); + } + do_extra_hw(cycles); + return(0); +} + +void +cl_uc::do_extra_hw(int cycles) +{} + +int +cl_uc::tick(int cycles) +{ + //class cl_hw *hw; int i, cpc= clock_per_cycle(); // increase time @@ -1096,13 +1207,8 @@ cl_uc::tick(int cycles) } } - // tick hws - for (i= 0; i < hws->count; i++) - { - hw= (class cl_hw *)(hws->at(i)); - if (hw->flags & HWF_INSIDE) - hw->tick(cycles); - } + // tick for hardwares + inst_ticks+= cycles; return(0); } @@ -1209,7 +1315,8 @@ cl_uc::fetch(void) } /* - * Fetch but checking for breakpoint hit first + * Fetch but checking for breakpoint hit first, returns TRUE if + * a breakpoint is hit */ bool @@ -1222,7 +1329,8 @@ cl_uc::fetch(t_mem *code) return(0); if (sim->state & SIM_GO) { - if ((brk= fbrk->get_bp(PC, &idx)) && + if (mem(MEM_ROM)->get_cell_flag(PC, CELL_FETCH_BRK) && + (brk= fbrk->get_bp(PC, &idx)) && (brk->do_hit())) { if (brk->perm == brkDYNAMIC) @@ -1255,17 +1363,29 @@ cl_uc::do_inst(int step) void cl_uc::pre_inst(void) -{} +{ + inst_exec= DD_TRUE; + inst_ticks= 0; + events->disconn_all(); +} int cl_uc::exec_inst(void) { + instPC= PC; return(resGO); } void cl_uc::post_inst(void) -{} +{ + tick_hw(inst_ticks); + if (errors->count) + check_errors(); + if (events->count) + check_events(); + inst_exec= DD_FALSE; +} /* @@ -1399,21 +1519,28 @@ cl_uc::rm_ebrk(t_addr addr, char *id) eb= (class cl_ev_brk *)(ebrk->at(i)); if (eb->addr == addr && !strcmp(eb->id, id)) - ebrk->free_at(i); + ebrk->del_bp(i, 0); } } /* Remove a breakpoint specified by its number */ -void +bool cl_uc::rm_brk(int nr) { class cl_brk *bp; if ((bp= brk_by_nr(fbrk, nr))) - fbrk->del_bp(bp->addr); + { + fbrk->del_bp(bp->addr); + return(DD_TRUE); + } else if ((bp= brk_by_nr(ebrk, nr))) - ebrk->free_at(ebrk->index_of(bp)); + { + ebrk->del_bp(ebrk->index_of(bp), 0); + return(DD_TRUE); + } + return(DD_FALSE); } void @@ -1431,7 +1558,7 @@ cl_uc::remove_all_breaks(void) fbrk->del_bp(brk->addr); } while (ebrk->count) - ebrk->free_at(ebrk->count-1); + ebrk->del_bp(ebrk->count-1, 0); } int @@ -1452,44 +1579,16 @@ cl_uc::mk_ebrk(enum brk_perm perm, class cl_mem *mem, class cl_ev_brk *b; op= toupper(op); - switch (mem->type) - { - case MEM_ROM: - if (op == 'R') - b= new cl_rc_brk(make_new_brknr(), addr, perm, hit); - else - return(0); - break; - case MEM_IRAM: - if (op == 'R') - b= new cl_ri_brk(make_new_brknr(), addr, perm, hit); - else if (op == 'W') - b= new cl_wi_brk(make_new_brknr(), addr, perm, hit); - else - return(0); - break; - case MEM_XRAM: - if (op == 'R') - b= new cl_rx_brk(make_new_brknr(), addr, perm, hit); - else if (op == 'W') - b= new cl_wx_brk(make_new_brknr(), addr, perm, hit); - else - return(0); - break; - case MEM_SFR: - if (op == 'R') - b= new cl_rs_brk(make_new_brknr(), addr, perm, hit); - else if (op == 'W') - b= new cl_ws_brk(make_new_brknr(), addr, perm, hit); - else - return(0); - break; - default: - return(0); - } + b= new cl_ev_brk(mem, make_new_brknr(), addr, perm, hit, op); b->init(); return(b); } +void +cl_uc::check_events(void) +{ + sim->stop(resBREAKPOINT); +} + /* End of uc.cc */ diff --git a/sim/ucsim/sim.src/uccl.h b/sim/ucsim/sim.src/uccl.h index 63e5365f..32ce9fd7 100644 --- a/sim/ucsim/sim.src/uccl.h +++ b/sim/ucsim/sim.src/uccl.h @@ -53,7 +53,7 @@ public: char *name; cl_ticker(int adir, int in_isr, char *aname); - ~cl_ticker(void); + virtual ~cl_ticker(void); virtual int tick(int nr); virtual double get_rtime(double xtal); @@ -71,11 +71,13 @@ public: int state; // GO, IDLE, PD class cl_list *options; - t_addr PC; // Program Counter + t_addr PC, instPC; // Program Counter + bool inst_exec; // Instruction is executed class cl_ticker *ticks; // Nr of XTAL clocks class cl_ticker *isr_ticks; // Time in ISRs class cl_ticker *idle_ticks; // Time in idle mode class cl_list *counters; // User definable timers (tickers) + int inst_ticks; // ticks of an instruction double xtal; // Clock speed int brk_counter; // Number of breakpoints @@ -85,16 +87,19 @@ public: class cl_list *mems; class cl_hws *hws; - class cl_list *it_sources; // Sources of interrupts + class cl_irqs *it_sources; // Sources of interrupts class cl_list *it_levels; // Follow interrupt services class cl_list *st_ops; // Track stack operations + class cl_list *errors; // Errors of instruction execution + class cl_list *events; // Events happened during inst exec + t_addr sp_max; t_addr sp_avg; public: cl_uc(class cl_sim *asim); - ~cl_uc(void); + virtual ~cl_uc(void); virtual int init(void); virtual char *id_string(void); virtual void reset(void); @@ -107,13 +112,12 @@ public: virtual void build_cmdset(class cl_cmdset *cmdset); // manipulating memories - virtual ulong read_mem(enum mem_class type, t_addr addr); - virtual ulong get_mem(enum mem_class type, t_addr addr); + virtual t_mem read_mem(enum mem_class type, t_addr addr); + virtual t_mem get_mem(enum mem_class type, t_addr addr); virtual void write_mem(enum mem_class type, t_addr addr, t_mem val); virtual void set_mem(enum mem_class type, t_addr addr, t_mem val); virtual class cl_mem *mem(enum mem_class type); virtual class cl_mem *mem(char *class_name); - //virtual TYPE_UBYTE *MEM(enum mem_class type); // file handling virtual long read_hex_file(const char *name); @@ -126,14 +130,14 @@ public: virtual bool there_is_inst(void); // manipulating hw elements - virtual void register_hw_read(enum mem_class, t_addr addr, class cl_hw *hw); - virtual void register_hw_write(enum mem_class, t_addr addr, class cl_hw *hw); virtual class cl_hw *get_hw(enum hw_cath cath, int *idx); virtual class cl_hw *get_hw(char *id_string, int *idx); virtual class cl_hw *get_hw(enum hw_cath cath, int hwid, int *idx); virtual class cl_hw *get_hw(char *id_string, int hwid, int *idx); // "virtual" timers + virtual int tick_hw(int cycles); + virtual void do_extra_hw(int cycles); virtual int tick(int cycles); virtual class cl_ticker *get_counter(int nr); virtual class cl_ticker *get_counter(char *name); @@ -163,16 +167,16 @@ public: // breakpoints virtual class cl_fetch_brk *fbrk_at(t_addr addr); virtual class cl_ev_brk *ebrk_at(t_addr addr, char *id); - //virtual void rm_fbrk(long addr); virtual class cl_brk *brk_by_nr(int nr); virtual class cl_brk *brk_by_nr(class brk_coll *bpcoll, int nr); virtual void rm_ebrk(t_addr addr, char *id); - virtual void rm_brk(int nr); + virtual bool rm_brk(int nr); virtual void put_breaks(void); virtual void remove_all_breaks(void); virtual int make_new_brknr(void); virtual class cl_ev_brk *mk_ebrk(enum brk_perm perm, class cl_mem *mem, char op, t_addr addr, int hit); + virtual void check_events(void); // disassembling and symbol recognition virtual char *disass(t_addr addr, char *sep); @@ -181,26 +185,29 @@ public: virtual struct name_entry *bit_tbl(void); virtual void print_disass(t_addr addr, class cl_console *con); virtual void print_regs(class cl_console *con); - virtual int inst_length(t_mem code); + virtual int inst_length(t_addr addr); + virtual int inst_branch(t_addr addr); virtual int longest_inst(void); virtual bool get_name(t_addr addr, struct name_entry tab[], char *buf); - virtual bool extract_bit_address(t_addr bit_address, - class cl_mem **mem, - t_addr *mem_addr, - t_mem *bit_mask) {return(DD_FALSE);} virtual char *symbolic_bit_name(t_addr bit_address, class cl_mem *mem, t_addr mem_addr, t_mem bit_mask); + /* Converting abstract address spaces into real ones */ + virtual class cl_mem *bit2mem(t_addr bitaddr, + t_addr *memaddr, t_mem *bitmask); + + // messages from app to handle and broadcast + virtual void mem_cell_changed(class cl_mem *mem, t_addr addr); + + // Error handling + virtual void error(class cl_error *error); + virtual void check_errors(void); + /* Following fields and virtual methods defined in uc51 I don't have energy to redesign them:-( */ public: - uchar port_pins[6]; // Port pins; 0...5 for DS390 -public: - virtual void proc_write(uchar *addr) {} - virtual void set_p_flag(void) {} - virtual uchar *get_bit(uchar bitaddr) { return(0); } virtual void eram2xram(void) {} // Dirty hack for 51R virtual void xram2eram(void) {} }; diff --git a/sim/ucsim/stypes.h b/sim/ucsim/stypes.h index e39f7645..543b671c 100644 --- a/sim/ucsim/stypes.h +++ b/sim/ucsim/stypes.h @@ -34,8 +34,9 @@ Software Foundation, 59 Temple Place - Suite 330, Boston, MA typedef unsigned char uchar; typedef unsigned int uint; typedef unsigned long ulong; -typedef unsigned long t_addr; -typedef unsigned long t_mem; +typedef TYPE_UDWORD t_addr; /* 32 bit max */ +typedef TYPE_UWORD t_mem; /* 16 bit max */ +typedef TYPE_WORD t_smem; /* signed 16 bit memory */ struct id_element { @@ -75,8 +76,8 @@ struct cpu_entry #define CPU_51R 0x0010 #define CPU_89C51R 0x0020 #define CPU_251 0x0040 -#define CPU_DS390 0x0080 -#define CPU_DS390F 0x0100 +#define CPU_DS390 0x0080 +#define CPU_DS390F 0x0100 #define CPU_ALL_51 (CPU_51|CPU_31) #define CPU_ALL_52 (CPU_52|CPU_32|CPU_51R|CPU_89C51R|CPU_251|CPU_DS390|CPU_DS390F) @@ -86,6 +87,9 @@ struct cpu_entry #define CPU_Z80 0x0001 #define CPU_ALL_Z80 (CPU_Z80) +#define CPU_XA 0x0001 +#define CPU_ALL_XA (CPU_XA) + #define CPU_CMOS 0x0001 #define CPU_HMOS 0x0002 @@ -96,6 +100,7 @@ enum mem_class MEM_XRAM, MEM_IRAM, MEM_SFR, + MEM_DUMMY, MEM_IXRAM, MEM_TYPES }; @@ -128,22 +133,9 @@ enum mem_class #define resBREAKPOINT 104 /* Breakpoint */ #define resUSER 105 /* Stopped by user */ #define resINV_INST 106 /* Invalid instruction */ - +#define resBITADDR 107 /* Bit address is uninterpretable */ #define BIT_MASK(bitaddr) (1 << (bitaddr & 0x07)) -#define SET_BIT(newbit, reg, bitmask) \ -if (newbit) \ - (mem(MEM_SFR))->set_bit1((reg), (bitmask)); \ -else \ - (mem(MEM_SFR))->set_bit0((reg), (bitmask)); -#define SFR_SET_BIT(newbit, reg, bitmask) \ -if (newbit) \ - sfr->set_bit1((reg), (bitmask)); \ -else \ - sfr->set_bit0((reg), (bitmask)); -#define GET_C (get_mem(MEM_SFR, PSW) & bmCY) -#define SFR_GET_C (sfr->get(PSW) & bmCY) -#define SET_C(newC) SET_BIT((newC), PSW, bmCY) #define IRAM_SIZE 256 /* Size of Internal RAM */ #define SFR_SIZE 256 /* Size of SFR area */ @@ -176,19 +168,22 @@ enum brk_event brkWIRAM, /* wi */ brkRIRAM, /* ri */ brkWSFR, /* ws */ - brkRSFR /* rs */ + brkRSFR, /* rs */ + brkREAD, + brkWRITE, + brkACCESS }; -struct event_rec -{ - t_addr wx; /* write to XRAM at this address, else -1 */ - t_addr rx; /* read from XRAM at this address, else -1 */ - t_addr wi; /* write to IRAM at this address, else -1 */ - t_addr ri; /* read from IRAM at this address, else -1 */ - t_addr ws; /* write to SFR at this address, else -1 */ - t_addr rs; /* read from SFR at this address, else -1 */ - t_addr rc; /* read from ROM at this address, else -1 */ -}; +//struct event_rec +//{ +// t_addr wx; /* write to XRAM at this address, else -1 */ +// t_addr rx; /* read from XRAM at this address, else -1 */ +// t_addr wi; /* write to IRAM at this address, else -1 */ +// t_addr ri; /* read from IRAM at this address, else -1 */ +// t_addr ws; /* write to SFR at this address, else -1 */ +// t_addr rs; /* read from SFR at this address, else -1 */ +// t_addr rc; /* read from ROM at this address, else -1 */ +//}; /* Interrupt levels */ //#define IT_NO -1 /* not in interroupt service */ @@ -197,12 +192,20 @@ struct event_rec /* cathegories of hw elements (peripherials) */ enum hw_cath { - HW_TIMER, - HW_UART, - HW_PORT, - HW_PCA, - HW_INTERRUPT, - HW_WDT + HW_DUMMY = 0x0000, + HW_TIMER = 0x0002, + HW_UART = 0x0004, + HW_PORT = 0x0008, + HW_PCA = 0x0010, + HW_INTERRUPT = 0x0020, + HW_WDT = 0x0040 +}; + +// Events that can happen in peripherals +enum hw_event { + EV_OVERFLOW, + EV_PORT_CHANGED, + EV_T2_MODE_CHANGED }; // flags of hw units diff --git a/sim/ucsim/xa.src/(c).1 b/sim/ucsim/xa.src/(c).1 new file mode 100644 index 00000000..d673f9fd --- /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.in b/sim/ucsim/xa.src/Makefile.in new file mode 100644 index 00000000..d5a6d64a --- /dev/null +++ b/sim/ucsim/xa.src/Makefile.in @@ -0,0 +1,120 @@ +# +# 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@ + +PRJDIR = .. + +DEFS = $(subs -DHAVE_CONFIG_H,,@DEFS@) +CPPFLAGS = @CPPFLAGS@ -I. -I$(PRJDIR) \ + -I$(PRJDIR)/cmd.src -I$(PRJDIR)/sim.src -I$(PRJDIR)/gui.src +CFLAGS = @CFLAGS@ -Wall +CXXFLAGS = @CXXFLAGS@ -Wall +M_OR_MM = @M_OR_MM@ + +LIBS = @LIBS@ -L$(PRJDIR) -lsim -lcmd -lutil -lguiucsim + +prefix = @prefix@ +exec_prefix = @exec_prefix@ +bindir = @bindir@ +libdir = @libdir@ +datadir = @datadir@ +includedir = @includedir@ +mandir = @mandir@ +man1dir = $(mandir)/man1 +man2dir = $(mandir)/man2 +infodir = @infodir@ +srcdir = @srcdir@ + +OBJECTS = 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) -s sxa $(bindir) + + +# Deleting all the installed files +# -------------------------------- +uninstall: + rm -f $(bindir)/sxa + + +# Performing self-test +# -------------------- +check: + + +# Performing installation test +# ---------------------------- +installcheck: + + +# Creating installation directories +# --------------------------------- +installdirs: + test -d $(bindir) || $(INSTALL) -d $(bindir) + + +# Creating dependencies +# --------------------- +dep: Makefile.dep + +Makefile.dep: *.cc *.h + $(CXXCPP) $(CPPFLAGS) $(M_OR_MM) *.cc >Makefile.dep + +include Makefile.dep +include clean.mk + +# My rules +# -------- +.SUFFIXES: .asm .hex + +xa.src: sxa + +sxa: $(OBJECTS) $(PRJDIR)/*.a + $(CXX) $(CXXFLAGS) -o sxa $(OBJECTS) $(LIBS) + +otherlibs: + cd $(PRJDIR)/cmd.src && $(MAKE) all + cd $(PRJDIR)/sim.src && $(MAKE) all + +.cc.o: + $(CXX) $(CXXFLAGS) $(CPPFLAGS) $(TARGET_ARCH) -c $< -o $@ + +.asm.hex: + $(XAASM) -l $< -o $@ -e $<.lst + + +# Remaking configuration +# ---------------------- +checkconf: + @if [ -f $(PRJDIR)/devel ]; then\ + $(MAKE) -f conf.mk srcdir="$(srcdir)" PRJDIR="$(PRJDIR)" 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 00000000..4975190b --- /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 + + +# 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 00000000..1c008560 --- /dev/null +++ b/sim/ucsim/xa.src/conf.mk @@ -0,0 +1,10 @@ +# +# Makefile targets to remake configuration +# + +freshconf: Makefile + +Makefile: $(srcdir)/Makefile.in $(PRJDIR)/configure.in + cd $(PRJDIR) && $(SHELL) ./config.status + +# End of 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 00000000..1d9f4c59 --- /dev/null +++ b/sim/ucsim/xa.src/glob.cc @@ -0,0 +1,231 @@ +/* + * Simulator of microcontrollers (glob.cc) + * + * Copyright (C) 1999,99 Drotos Daniel, Talker Bt. + * + * Written by Karl Bongers karl@turbobit.com + * + * To contact author send email to drdani@mazsola.iit.uni-miskolc.hu + * + */ + +/* This file is part of microcontroller simulator: ucsim. + +UCSIM is free software; you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation; either version 2 of the License, or +(at your option) any later version. + +UCSIM is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU General Public License for more details. + +You should have received a copy of the GNU General Public License +along with UCSIM; see the file COPYING. If not, write to the Free +Software Foundation, 59 Temple Place - Suite 330, Boston, MA +02111-1307, USA. */ +/*@1@*/ + +#include + +#include "stypes.h" +#include "glob.h" + +char *op_mnemonic_str[] = { +"BAD_OPCODE", +"ADD", +"ADDC", +"SUB", +"SUBB", +"CMP", +"AND", +"OR", +"XOR", +"ADDS", +"NEG", +"SEXT", +"MUL", +"DIV", +"DA", +"ASL", +"ASR", +"LEA", +"CPL", +"LSR", +"NORM", +"RL", +"RLC", +"RR", +"RRC", +"MOVS", +"MOVC", +"MOVX", +"PUSH", +"POP", +"XCH", +"SETB", +"CLR", +"MOV", +"ANL", +"ORL", +"BR", +"JMP", +"CALL", +"RET", +"Bcc", +"JB", +"JNB", +"CJNE", +"DJNZ", +"JZ", +"JNZ", +"NOP", +"BKPT", +"TRAP", +"RESET" +}; + +struct dis_entry glob_disass_xa[]= { + { 0x0000, 0x00ff, ' ', 1, "nop" }, + { 0x0000, 0x00, 0, 0, NULL} +}; + +struct xa_dis_entry disass_xa[]= { + { 0x0000, 0xffff, ' ', 1, NOP, NO_OPERANDS }, // NOP 0 0 0 0 0 0 0 0 + + { 0x0840, 0xfffc, ' ', 3, ANL, C_BIT }, // ANL C, bit 0 0 0 0 1 0 0 0 0 1 0 0 0 0 bit: 2 + { 0x0850, 0xfffc, ' ', 3, ANL, NOTC_BIT }, // ANL C, /bit 0 0 0 0 1 0 0 0 0 1 0 1 0 0 bit: 2 + { 0x0850, 0xfffc, ' ', 3, ASL, REG_REG }, // ASL Rd, Rs 1 1 0 0 SZ1 SZ0 0 1 d d d d s s s s + + { 0x1408, 0xf780, ' ', 2, ADDS, REG_DATA4 }, // ADDS Rd, #data4 1 0 1 0 SZ 0 0 1 d d d d #data4 + { 0x1408, 0xf780, ' ', 2, ADDS, IREG_DATA4 }, // ADDS [Rd], #data4 1 0 1 0 SZ 0 1 0 0 d d d #data4 + { 0x1408, 0xf780, ' ', 2, ADDS, IREGINC_DATA4 }, // ADDS [Rd+], #data4 1 0 1 0 SZ 0 1 1 0 d d d #data4 + { 0x1408, 0xf780, ' ', 3, ADDS, IREGOFF8_DATA4 }, // ADDS [Rd+offset8], #data4 1 0 1 0 SZ 1 0 0 0 d d d #data4 + { 0x1408, 0xf780, ' ', 4, ADDS, IREGOFF16_DATA4}, // ADDS [Rd+offset16], #data4 1 0 1 0 SZ 1 0 1 0 d d d #data4 + { 0x1408, 0xf780, ' ', 3, ADDS, DIRECT_DATA4 }, // ADDS direct, #data4 1 0 1 0 SZ 1 1 0 0 direct: 3 bits #data4 + + { 0x0100, 0xf700, ' ', 2, ADD, REG_REG }, // ADD Rd, Rs 0 0 0 0 SZ 0 0 1 d d d d s s s s + { 0x0200, 0xf708, ' ', 2, ADD, REG_IREG }, // ADD Rd, [Rs] 0 0 0 0 SZ 0 1 0 d d d d 0 s s s + { 0x0208, 0xf708, ' ', 2, ADD, IREG_REG }, // ADD [Rd], Rs 0 0 0 0 SZ 0 1 0 s s s s 1 d d d + { 0x0400, 0xf708, ' ', 3, ADD, REG_IREGOFF8 }, // ADD Rd, [Rs+offset8] 0 0 0 0 SZ 1 0 0 d d d d 0 s s s + { 0x0408, 0xf708, ' ', 3, ADD, IREGOFF8_REG }, // ADD [Rd+offset8], Rs 0 0 0 0 SZ 1 0 0 s s s s 1 d d d + { 0x0500, 0xf708, ' ', 4, ADD, REG_IREGOFF16 }, // ADD Rd, [Rs+offset16] 0 0 0 0 SZ 1 0 1 d d d d 0 s s s + { 0x0508, 0xf708, ' ', 4, ADD, IREGOFF16_REG }, // ADD [Rd+offset16], Rs 0 0 0 0 SZ 1 0 1 s s s s 1 d d d + { 0x0300, 0xf708, ' ', 2, ADD, REG_IREGINC }, // ADD Rd, [Rs+] 0 0 0 0 SZ 0 1 1 d d d d 0 s s s + { 0x0308, 0xf708, ' ', 2, ADD, IREGINC_REG }, // ADD [Rd+], Rs 0 0 0 0 SZ 0 1 1 s s s s 1 d d d + { 0x0608, 0xf708, ' ', 3, ADD, DIRECT_REG }, // ADD direct, Rs 0 0 0 0 SZ 1 1 0 s s s s 1 direct: 3 bits + { 0x0600, 0xf708, ' ', 3, ADD, REG_DIRECT }, // ADD Rd, direct 0 0 0 0 SZ 1 1 0 d d d d 0 direct: 3 bits + { 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 + { 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 + { 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 + { 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 + { 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 + { 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 (Rd) <-- (Rd) + 2 + { 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 + { 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 + { 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 + { 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 + { 0x9600, 0xff8f, ' ', 4, ADD, DIRECT_DATA8 }, // ADD direct, #data8 1 0 0 1 0 1 1 0 0 direct: 3 bits 0 0 0 0 + { 0x9e00, 0xff8f, ' ', 5, ADD, DIRECT_DATA16 }, // ADD direct, #data16 1 0 0 1 0 1 1 0 1 0 0 1 1 1 1 0 0 direct: 3 bits 0 0 0 0 + + { 0x1100, 0xf700, ' ', 2,ADDC, REG_REG }, // ADDC Rd, Rs 0 0 0 1 SZ 0 0 1 d d d d s s s s + { 0x1200, 0xf780, ' ', 2,ADDC, REG_IREG }, // ADDC Rd, [Rs] 0 0 0 1 SZ 0 1 0 d d d d 0 s s s + { 0x1208, 0xf780, ' ', 2,ADDC, IREG_REG }, // ADDC [Rd], Rs 0 0 0 1 SZ 0 1 0 s s s s 1 d d d + { 0x1400, 0xf780, ' ', 3,ADDC, REG_IREGOFF8 }, // ADDC Rd, [Rs+offset8] 0 0 0 1 SZ 1 0 0 d d d d 0 s s s + { 0x1408, 0xf780, ' ', 3,ADDC, IREGOFF8_REG }, // ADDC [Rd+offset8], Rs 0 0 0 1 SZ 1 0 0 s s s s 1 d d d + { 0x1500, 0xf780, ' ', 4,ADDC, REG_IREGOFF16 }, // ADDC Rd, [Rs+offset16] 0 0 0 1 SZ 1 0 1 d d d d 0 s s s + { 0x1508, 0xf780, ' ', 4,ADDC, IREGOFF16_REG }, // ADDC [Rd+offset16], Rs 0 0 0 1 SZ 1 0 1 s s s s 1 d d d + { 0x1300, 0xf780, ' ', 2,ADDC, REG_IREGINC }, // ADDC Rd, [Rs+] 0 0 0 1 SZ 0 1 1 d d d d 0 s s s + { 0x1308, 0xf780, ' ', 2,ADDC, IREGINC_REG }, // ADDC [Rd+], Rs 0 0 0 1 SZ 0 1 1 s s s s 1 d d d + { 0x1608, 0xf780, ' ', 3,ADDC, DIRECT_REG }, // ADDC direct, Rs 0 0 0 1 SZ 1 1 0 s s s s 1 direct: 3 bits + { 0x1600, 0xf780, ' ', 3,ADDC, REG_DIRECT }, // ADDC Rd, direct 0 0 0 1 SZ 1 1 0 d d d d 0 direct: 3 bits + { 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 + { 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 + { 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 + { 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 + { 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 + { 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 + { 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 + { 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 + { 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 + { 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 + { 0x9601, 0xff8f, ' ', 4,ADDC, DIRECT_DATA8 }, // ADDC direct, #data8 1 0 0 1 0 1 1 0 0 direct: 3 bits 0 0 0 1 + { 0x9e01, 0xff8f, ' ', 5,ADDC, DIRECT_DATA16 }, // ADDC direct, #data16 1 0 0 1 1 1 1 0 0 direct: 3 bits 0 0 0 1 + + { 0x5100, 0xf700, ' ', 2, AND, REG_REG }, // AND Rd, Rs 0 1 0 1 SZ 0 0 1 d d d d s s s s + { 0x5200, 0xf708, ' ', 2, AND, REG_IREG }, // AND Rd, [Rs] 0 1 0 1 SZ 0 1 0 d d d d 0 s s s + { 0x5208, 0xf708, ' ', 2, AND, IREG_REG }, // AND [Rd], Rs 0 1 0 1 SZ 0 1 0 s s s s 1 d d d + { 0x5400, 0xf708, ' ', 3, AND, REG_IREGOFF8 }, // AND Rd, [Rs+offset8] 0 1 0 1 SZ 1 0 0 d d d d 0 s s s + { 0x5408, 0xf708, ' ', 3, AND, IREGOFF8_REG }, // AND [Rd+offset8], Rs 0 1 0 1 SZ 1 0 0 s s s s 1 d d d + { 0x5500, 0xf708, ' ', 4, AND, REG_IREGOFF16 }, // AND Rd, [Rs+offset16] 0 1 0 1 SZ 1 0 1 d d d d 0 s s s + { 0x5508, 0xf708, ' ', 4, AND, IREGOFF16_REG }, // AND [Rd+offset16], Rs 0 1 0 1 SZ 1 0 1 s s s s 1 d d d + { 0x5300, 0xf708, ' ', 2, AND, REG_IREGINC }, // AND Rd, [Rs+] 0 1 0 1 SZ 0 1 1 d d d d 0 s s s + { 0x5308, 0xf708, ' ', 2, AND, IREGINC_REG }, // AND [Rd+], Rs 0 1 0 1 SZ 0 1 1 s s s s 1 d d d + { 0x5608, 0xf708, ' ', 3, AND, DIRECT_REG }, // AND direct, Rs 0 1 0 1 SZ 1 1 0 s s s s 1 direct: 3 bits + { 0x5600, 0xf708, ' ', 3, AND, REG_DIRECT }, // AND Rd, direct 0 1 0 1 SZ 1 1 0 d d d d 0 direct: 3 bits + { 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 + { 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 + { 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 + { 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 + { 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 + { 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 (Rd) <-- (Rd) + 2 + { 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 + { 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 + { 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 + { 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 + { 0x9605, 0xff8f, ' ', 4, AND, DIRECT_DATA8 }, // AND direct, #data8 1 0 0 1 0 1 1 0 0 direct: 3 bits 0 1 0 1 + { 0x9e05, 0xff8f, ' ', 5, AND, DIRECT_DATA16 }, // AND direct, #data16 1 0 0 1 0 1 1 0 1 0 0 1 1 1 1 0 0 direct: 3 bits 0 1 0 1 + + { 0x4100, 0xf700, ' ', 2, CMP, REG_REG }, // CMP Rd, Rs 0 1 0 0 SZ 0 0 1 d d d d s s s s + { 0x4200, 0xf708, ' ', 2, CMP, REG_IREG }, // CMP Rd, [Rs] 0 1 0 0 SZ 0 1 0 d d d d 0 s s s + { 0x4208, 0xf708, ' ', 2, CMP, IREG_REG }, // CMP [Rd], Rs 0 1 0 0 SZ 0 1 0 s s s s 1 d d d + { 0x4400, 0xf708, ' ', 3, CMP, REG_IREGOFF8 }, // CMP Rd, [Rs+offset8] 0 1 0 0 SZ 1 0 0 d d d d 0 s s s + { 0x4408, 0xf708, ' ', 3, CMP, IREGOFF8_REG }, // CMP [Rd+offset8], Rs 0 1 0 0 SZ 1 0 0 s s s s 1 d d d + { 0x4500, 0xf708, ' ', 4, CMP, REG_IREGOFF16 }, // CMP Rd, [Rs+offset16] 0 1 0 0 SZ 1 0 1 d d d d 0 s s s + { 0x4508, 0xf708, ' ', 4, CMP, IREGOFF16_REG }, // CMP [Rd+offset16], Rs 0 1 0 0 SZ 1 0 1 s s s s 1 d d d + { 0x4300, 0xf708, ' ', 2, CMP, REG_IREGINC }, // CMP Rd, [Rs+] 0 1 0 0 SZ 0 1 1 d d d d 0 s s s + { 0x4308, 0xf708, ' ', 2, CMP, IREGINC_REG }, // CMP [Rd+], Rs 0 1 0 0 SZ 0 1 1 s s s s 1 d d d + { 0x4608, 0xf708, ' ', 3, CMP, DIRECT_REG }, // CMP direct, Rs 0 1 0 0 SZ 1 1 0 s s s s 1 direct: 3 bits + { 0x4600, 0xf708, ' ', 3, CMP, REG_DIRECT }, // CMP Rd, direct 0 1 0 0 SZ 1 1 0 d d d d 0 direct: 3 bits + { 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 + { 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 + { 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 + { 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 + { 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 + { 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 (Rd) <-- (Rd) + 2 + { 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 + { 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 + { 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 + { 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 + { 0x9604, 0xff8f, ' ', 4, CMP, DIRECT_DATA8 }, // CMP direct, #data8 1 0 0 1 0 1 1 0 0 direct: 3 bits 0 1 0 0 + { 0x9e04, 0xff8f, ' ', 5, CMP, DIRECT_DATA16 }, // CMP direct, #data16 1 0 0 1 0 1 1 0 1 0 0 1 1 1 1 0 0 direct: 3 bits 0 1 0 0 + + { 0x8100, 0xf700, ' ', 2, MOV, REG_REG }, // MOV Rd, Rs 1 0 0 0 SZ 0 0 1 d d d d s s s s + { 0x8200, 0xf708, ' ', 2, MOV, REG_IREG }, // MOV Rd, [Rs] 1 0 0 0 SZ 0 1 0 d d d d 0 s s s + { 0x8208, 0xf708, ' ', 2, MOV, IREG_REG }, // MOV [Rd], Rs 1 0 0 0 SZ 0 1 0 s s s s 1 d d d + { 0x8400, 0xf708, ' ', 3, MOV, REG_IREGOFF8 }, // MOV Rd, [Rs+offset8] 1 0 0 0 SZ 1 0 0 d d d d 0 s s s + { 0x8408, 0xf708, ' ', 3, MOV, IREGOFF8_REG }, // MOV [Rd+offset8], Rs 1 0 0 0 SZ 1 0 0 s s s s 1 d d d + { 0x8500, 0xf708, ' ', 4, MOV, REG_IREGOFF16 }, // MOV Rd, [Rs+offset16] 1 0 0 0 SZ 1 0 1 d d d d 0 s s s + { 0x8508, 0xf708, ' ', 4, MOV, IREGOFF16_REG }, // MOV [Rd+offset16], Rs 1 0 0 0 SZ 1 0 1 s s s s 1 d d d + { 0x8300, 0xf708, ' ', 2, MOV, REG_IREGINC }, // MOV Rd, [Rs+] 1 0 0 0 SZ 0 1 1 d d d d 0 s s s + { 0x8308, 0xf708, ' ', 2, MOV, IREGINC_REG }, // MOV [Rd+], Rs 1 0 0 0 SZ 0 1 1 s s s s 1 d d d + { 0x8608, 0xf708, ' ', 3, MOV, DIRECT_REG }, // MOV direct, Rs 1 0 0 0 SZ 1 1 0 s s s s 1 direct: 3 bits + { 0x8600, 0xf708, ' ', 3, MOV, REG_DIRECT }, // MOV Rd, direct 1 0 0 0 SZ 1 1 0 d d d d 0 direct: 3 bits + { 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 + { 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 + { 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 + { 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 + { 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 + { 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 (Rd) <-- (Rd) + 2 + { 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 + { 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 + { 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 + { 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 + { 0x9608, 0xff8f, ' ', 4, MOV, DIRECT_DATA8 }, // MOV direct, #data8 1 0 0 1 0 1 1 0 0 direct: 3 bits 1 0 0 0 + { 0x9e08, 0xff8f, ' ', 5, MOV, DIRECT_DATA16 }, // MOV direct, #data16 1 0 0 1 0 1 1 0 1 0 0 1 1 1 1 0 0 direct: 3 bits 1 0 0 0 + { 0x0000, 0x00, 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 00000000..4a697df5 --- /dev/null +++ b/sim/ucsim/xa.src/glob.h @@ -0,0 +1,160 @@ +/* + * Simulator of microcontrollers (glob.h) + * + * Copyright (C) 1999,99 Drotos Daniel, Talker Bt. + * + * Written by Karl Bongers karl@turbobit.com + * + * To contact author send email to drdani@mazsola.iit.uni-miskolc.hu + * + */ + +/* This file is part of microcontroller simulator: ucsim. + +UCSIM is free software; you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation; either version 2 of the License, or +(at your option) any later version. + +UCSIM is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU General Public License for more details. + +You should have received a copy of the GNU General Public License +along with UCSIM; see the file COPYING. If not, write to the Free +Software Foundation, 59 Temple Place - Suite 330, Boston, MA +02111-1307, USA. */ +/*@1@*/ + +#ifndef GLOB_HEADER +#define GLOB_HEADER + +#include "stypes.h" + + +#if 0 +enum { + REG, + IND_REG, + IND_REG_PLUS, + IND_REG_OFFSET, + DIRECT, + DATA8, + DATA16 +}; +#endif + +enum { +BAD_OPCODE=0, +ADD, +ADDC, +SUB, +SUBB, +CMP, +AND, +OR, +XOR, +ADDS, +NEG, +SEXT, +MUL, +DIV, +DA, +ASL, +ASR, +LEA, +CPL, +LSR, +NORM, +RL, +RLC, +RR, +RRC, +MOVS, +MOVC, +MOVX, +PUSH, +POP, +XCH, +SETB, +CLR, +MOV, +ANL, +ORL, +BR, +JMP, +CALL, +RET, +Bcc, +JB, +JNB, +CJNE, +DJNZ, +JZ, +JNZ, +NOP, +BKPT, +TRAP, +RESET, +}; + +extern char *op_mnemonic_str[]; + +enum op_operands { + // the repeating common parameter encoding for ADD, ADDC, SUB, AND... + 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 + C_BIT, + NOTC_BIT, + REG_DATA4, + IREG_DATA4, + IREGINC_DATA4, + IREGOFF8_DATA4, + IREGOFF16_DATA4, + DIRECT_DATA4 +}; + +// table of dissassembled instructions +struct xa_dis_entry +{ + uint code, mask; + char branch; + uchar length; +// enum op_mnemonic mnemonic; +// enum op_operands operands; + int mnemonic; + int operands; +}; + +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 00000000..984871bb --- /dev/null +++ b/sim/ucsim/xa.src/inst.cc @@ -0,0 +1,327 @@ +/* + * Simulator of microcontrollers (inst.cc) + * + * Copyright (C) 1999,99 Drotos Daniel, Talker Bt. + * + * Written by Karl Bongers karl@turbobit.com + * + * To contact author send email to drdani@mazsola.iit.uni-miskolc.hu + * + */ + +/* This file is part of microcontroller simulator: ucsim. + +UCSIM is free software; you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation; either version 2 of the License, or +(at your option) any later version. + +UCSIM is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU General Public License for more details. + +You should have received a copy of the GNU General Public License +along with UCSIM; see the file COPYING. If not, write to the Free +Software Foundation, 59 Temple Place - Suite 330, Boston, MA +02111-1307, USA. */ +/*@1@*/ + +#include "ddconfig.h" + +// local +#include "glob.h" +#include "xacl.h" +#include "regsxa.h" + +int +cl_xa::get_reg(int word_flag, unsigned int index) +{ + if (index < 3) { /* banked */ + if (word_flag) + return get_word_direct(0x400+index); + else + return mem_direct[0x400+index]; + } else { /* non-banked */ + if (word_flag) + return get_word_direct(0x400+index); + else + return mem_direct[0x400+index]; + } +} + +int +cl_xa::inst_NOP(uint code) +{ + return(resGO); +} + +#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 = code >> 16; // kludgy, param info + +#define FUNC1 add1 +#define FUNC2 add2 +#include "inst_gen.cc" + + return(resGO); +} + +int +cl_xa::inst_ADDC(uint code) +{ + int operands = code >> 16; // kludgy, param info + +#define FUNC1 addc1 +#define FUNC2 addc2 +#include "inst_gen.cc" + + return(resGO); +} + +int +cl_xa::inst_SUB(uint code) +{ + return(resGO); +} + +int +cl_xa::inst_SUBB(uint code) +{ + return(resGO); +} + +int +cl_xa::inst_CMP(uint code) +{ + return(resGO); +} +int +cl_xa::inst_AND(uint code) +{ + return(resGO); +} +int +cl_xa::inst_OR(uint code) +{ + return(resGO); +} +int +cl_xa::inst_XOR(uint code) +{ + return(resGO); +} +int +cl_xa::inst_ADDS(uint code) +{ + return(resGO); +} +int +cl_xa::inst_NEG(uint code) +{ + return(resGO); +} +int +cl_xa::inst_SEXT(uint code) +{ + return(resGO); +} +int +cl_xa::inst_MUL(uint code) +{ + return(resGO); +} +int +cl_xa::inst_DIV(uint code) +{ + return(resGO); +} +int +cl_xa::inst_DA(uint code) +{ + return(resGO); +} +int +cl_xa::inst_ASL(uint code) +{ + return(resGO); +} +int +cl_xa::inst_ASR(uint code) +{ + return(resGO); +} +int +cl_xa::inst_LEA(uint code) +{ + return(resGO); +} +int +cl_xa::inst_CPL(uint code) +{ + return(resGO); +} +int +cl_xa::inst_LSR(uint code) +{ + return(resGO); +} +int +cl_xa::inst_NORM(uint code) +{ + return(resGO); +} +int +cl_xa::inst_RL(uint code) +{ + return(resGO); +} +int +cl_xa::inst_RLC(uint code) +{ + return(resGO); +} +int +cl_xa::inst_RR(uint code) +{ + return(resGO); +} +int +cl_xa::inst_RRC(uint code) +{ + return(resGO); +} +int +cl_xa::inst_MOVS(uint code) +{ + return(resGO); +} +int +cl_xa::inst_MOVC(uint code) +{ + return(resGO); +} +int +cl_xa::inst_MOVX(uint code) +{ + return(resGO); +} +int +cl_xa::inst_PUSH(uint code) +{ + return(resGO); +} +int +cl_xa::inst_POP(uint code) +{ + return(resGO); +} +int +cl_xa::inst_XCH(uint code) +{ + return(resGO); +} +int +cl_xa::inst_SETB(uint code) +{ + return(resGO); +} +int +cl_xa::inst_CLR(uint code) +{ + return(resGO); +} +int +cl_xa::inst_MOV(uint code) +{ + return(resGO); +} +int +cl_xa::inst_ANL(uint code) +{ + return(resGO); +} +int +cl_xa::inst_ORL(uint code) +{ + return(resGO); +} +int +cl_xa::inst_BR(uint code) +{ + return(resGO); +} +int +cl_xa::inst_JMP(uint code) +{ + return(resGO); +} +int +cl_xa::inst_CALL(uint code) +{ + return(resGO); +} +int +cl_xa::inst_RET(uint code) +{ + return(resGO); +} +int +cl_xa::inst_Bcc(uint code) +{ + return(resGO); +} +int +cl_xa::inst_JB(uint code) +{ + return(resGO); +} +int +cl_xa::inst_JNB(uint code) +{ + return(resGO); +} +int +cl_xa::inst_CJNE(uint code) +{ + return(resGO); +} +int +cl_xa::inst_DJNZ(uint code) +{ + return(resGO); +} +int +cl_xa::inst_JZ(uint code) +{ + return(resGO); +} +int +cl_xa::inst_JNZ(uint code) +{ + return(resGO); +} +int +cl_xa::inst_BKPT(uint code) +{ + return(resGO); +} +int +cl_xa::inst_TRAP(uint code) +{ + return(resGO); +} +int +cl_xa::inst_RESET(uint code) +{ + 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 00000000..d37890dd --- /dev/null +++ b/sim/ucsim/xa.src/inst_gen.cc @@ -0,0 +1,274 @@ +/* + * 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, ... + * + * Written by Karl Bongers karl@turbobit.com + * + * Copyright (C) 1999,99 Drotos Daniel, Talker Bt. + * + * To contact author send email to drdani@mazsola.iit.uni-miskolc.hu + * + */ + +/* This file is part of microcontroller simulator: ucsim. + +UCSIM is free software; you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation; either version 2 of the License, or +(at your option) any later version. + +UCSIM is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU General Public License for more details. + +You should have received a copy of the GNU General Public License +along with UCSIM; see the file COPYING. If not, write to the Free +Software Foundation, 59 Temple Place - Suite 330, Boston, MA +02111-1307, USA. */ +/*@1@*/ + + 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_0F); + 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_0F, 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_0F, addr+1); + } + } + break; + + case IREGOFF8_REG : + case IREGOFF16_REG : + { + int offset; + if (operands == REG_IREGOFF8) { + offset = (int)((char) fetch()); + } else { + offset = (int)((short)fetch2()); + } + if (code & 0x0800) { /* word op */ + t_mem addr = reg2(RI_07) + offset; + unsigned short wtmp, wtotal; + wtmp = get2(addr); + wtotal = FUNC2( wtmp, reg2(RI_F0) ); + store2(addr, wtotal); + } else { + t_mem addr = reg2(RI_07) + ((short) fetch2()); + 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 { + int offset = (int)((short)fetch2()); + set_reg1( RI_F0, + FUNC1( reg1(RI_F0), + get1(reg2(RI_07)+offset) + ) + ); + } + } + break; + + case DIRECT_REG : + { + int addr = ((code & 0x3) << 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 & 0x3) << 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 : + set_reg1( RI_F0, FUNC1( reg1(RI_F0), fetch()) ); + break; + + case REG_DATA16 : + set_reg2( RI_F0, FUNC2( reg2(RI_F0), fetch()) ); + break; + + case IREGINC_DATA8 : + case IREG_DATA8 : + { + unsigned char total; + unsigned char tmp; + t_mem addr = reg2(RI_07); + tmp = get1(addr); + total = FUNC1(tmp, fetch() ); + store1(addr, total); + if (operands == IREGINC_DATA8) { + set_reg2(RI_07, 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_07, 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_07); + + store1( addr, + 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_07); + + store2( addr, + FUNC2( tmp, + get2(addr+offset) + ) + ); + } + break; + + case DIRECT_DATA8 : + { + int addr = ((code & 0x3) << 8) | 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 & 0x3) << 8) | 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 00000000..eafb01f6 --- /dev/null +++ b/sim/ucsim/xa.src/instcl.h @@ -0,0 +1,54 @@ +/* xa.src/instcl.h */ + + virtual int inst_NOP(uint code); + virtual int inst_ADD(uint code); + virtual int inst_ADDC(uint code); + virtual int inst_SUB(uint code); + virtual int inst_SUBB(uint code); + virtual int inst_CMP(uint code); + virtual int inst_AND(uint code); + virtual int inst_OR(uint code); + virtual int inst_XOR(uint code); + virtual int inst_ADDS(uint code); + virtual int inst_NEG(uint code); + virtual int inst_SEXT(uint code); + virtual int inst_MUL(uint code); + virtual int inst_DIV(uint code); + virtual int inst_DA(uint code); + virtual int inst_ASL(uint code); + virtual int inst_ASR(uint code); + virtual int inst_LEA(uint code); + virtual int inst_CPL(uint code); + virtual int inst_LSR(uint code); + virtual int inst_NORM(uint code); + virtual int inst_RL(uint code); + virtual int inst_RLC(uint code); + virtual int inst_RR(uint code); + virtual int inst_RRC(uint code); + virtual int inst_MOVS(uint code); + virtual int inst_MOVC(uint code); + virtual int inst_MOVX(uint code); + virtual int inst_PUSH(uint code); + virtual int inst_POP(uint code); + virtual int inst_XCH(uint code); + virtual int inst_SETB(uint code); + virtual int inst_CLR(uint code); + virtual int inst_MOV(uint code); + virtual int inst_ANL(uint code); + virtual int inst_ORL(uint code); + virtual int inst_BR(uint code); + virtual int inst_JMP(uint code); + virtual int inst_CALL(uint code); + virtual int inst_RET(uint code); + virtual int inst_Bcc(uint code); + virtual int inst_JB(uint code); + virtual int inst_JNB(uint code); + virtual int inst_CJNE(uint code); + virtual int inst_DJNZ(uint code); + virtual int inst_JZ(uint code); + virtual int inst_JNZ(uint code); + virtual int inst_BKPT(uint code); + virtual int inst_TRAP(uint code); + virtual int inst_RESET(uint code); + +/* 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 00000000..ee7134b4 --- /dev/null +++ b/sim/ucsim/xa.src/regsxa.h @@ -0,0 +1,192 @@ +/* + * Simulator of microcontrollers (regsxa.h) + * + * Copyright (C) 1999,99 Drotos Daniel, Talker Bt. + * + * Written by Karl Bongers karl@turbobit.com + * + * 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 REGSAVR_HEADER +#define REGSAVR_HEADER + +#include "ddconfig.h" + +struct t_regs +{ + int dummy; +}; + +/* direct is a special code space for built-in ram and SFR, 1K size */ +#ifdef WORDS_BIGENDIAN +#define set_word_direct(_index, _value) { \ + mem_direct[(_index)] = (_value >> 8); \ + mem_direct[(_index)] = (_value & 0xff); } + +#define get_word_direct(_index) \ + ( (mem_direct[(_index)] << 8) | mem_direct[(_index)+1] ) +#else +#define set_word_direct(_index, _value) { \ + wmem_direct[(_index) >> 1] = _value; } +#define get_word_direct(_index) (wmem_direct[(_index) >> 1] ) +#endif + +#define get_byte_direct(_index) (mem_direct[_index]) + +/* store to ram */ +#define store2(addr, val) { ram->set((t_addr) (addr), val & 0xff); \ + ram->set((t_addr) (addr+1), (val >> 8) & 0xff); } +#define store1(addr, val) ram->set((t_addr) (addr), val) + +/* get from ram */ +#define get1(addr) ram->get((t_addr) (addr)) +#define get2(addr) (ram->get((t_addr) (addr)) | (ram->get((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, (_index)) +#define reg1(_index) (unsigned char)get_reg(0, (_index)) + +#define set_byte_direct(_index, _value) { \ + mem_direct[_index] = _value; \ +} + +#define set_reg1(_index, _value) { \ + if ((_index) < 3) { /* banked */ \ + mem_direct[0x400+(_index)] = _value; \ + } else { /* non-banked */ \ + mem_direct[0x400+(_index)] = _value; \ + } \ +} + +#define set_reg2(_index, _value) { \ + if ((_index) < 3) { /* banked */ \ + set_word_direct((0x400+_index), _value); \ + } else { /* non-banked */ \ + set_word_direct((0x400+_index), _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 */ +#define set_sp(_value) { \ + { set_word_direct(0x400+(7*2), _value); } \ +} + +#define get_sp() ((TYPE_UWORD)(get_word_direct(0x400+(7*2)))) + +// fixme: I don't know where the psw is kept, just want to compile... +#define get_psw() ((TYPE_UWORD)(get_word_direct(0x400+(0x80*2)))) + +/* we also need to set flags, this scheme no setup well to do this yet... */ +#define add1(_a, _b) ( (unsigned char)((_a) + (_b)) ) +#define add2(_a, _b) ( (unsigned short)((_a) + (_b)) ) + +#define addc1(_a, _b) ( (unsigned char)((_a) + (_b)) ) +#define addc2(_a, _b) ( (unsigned short)((_a) + (_b)) ) + +#if 0 +-------------------------------------------------------------------- +Notes: + Register layout: + +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). +(note: trigger an exception in simulator if otherwise). + +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 +(note: trigger an exception in simulator if otherwise). + +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. + +#endif + + +// PSW bits... +#define BIT_C 0x80 +#define BIT_AC 0x40 +#define BIT_V 0x04 +#define BIT_N 0x02 +#define BIT_Z 0x01 + +#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 00000000..6120f2ba --- /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 00000000..1a22c5b7 --- /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 00000000..4242027c --- /dev/null +++ b/sim/ucsim/xa.src/sxa.cc @@ -0,0 +1,52 @@ +/* + * 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@*/ + +// sim.src +#include "appcl.h" + +// local +#include "simxacl.h" + + +int +main(int argc, char *argv[]) +{ + class cl_app *app; + class cl_sim *sim; + + app= new cl_app(); + app->init(argc, argv); + sim= new cl_simxa(app); + sim->init(); + app->set_simulator(sim); + app->run(); + delete app; + 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 00000000..244304f0 --- /dev/null +++ b/sim/ucsim/xa.src/xa.cc @@ -0,0 +1,650 @@ +/* + * Simulator of microcontrollers (xa.cc) + * + * Copyright (C) 1999,99 Drotos Daniel, Talker Bt. + * + * Written by Karl Bongers karl@turbobit.com + * + * To contact author send email to drdani@mazsola.iit.uni-miskolc.hu + * + */ + +/* This file is part of microcontroller simulator: ucsim. + +UCSIM is free software; you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation; either version 2 of the License, or +(at your option) any later version. + +UCSIM is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU General Public License for more details. + +You should have received a copy of the GNU General Public License +along with UCSIM; see the file COPYING. If not, write to the Free +Software Foundation, 59 Temple Place - Suite 330, Boston, MA +02111-1307, USA. */ +/*@1@*/ + +#include "ddconfig.h" + +#include +#include +#include +#include "i_string.h" + +// prj +#include "pobjcl.h" + +// sim +#include "simcl.h" + +// local +#include "xacl.h" +#include "glob.h" +#include "regsxa.h" + + +/* + * Base type of xa controllers + */ + +cl_xa::cl_xa(class cl_sim *asim): + cl_uc(asim) +{ + type= CPU_XA; +} + +int +cl_xa::init(void) +{ + cl_uc::init(); /* Memories now exist */ + ram= mem(MEM_XRAM); + rom= mem(MEM_ROM); + + wmem_direct = (TYPE_UWORD *) &mem_direct[0]; + + /* initialize SP to 100H */ + set_reg2(7*2, 0x100); + + printf("The XA Simulator is in development, UNSTABLE, DEVELOPERS ONLY!\n"); + + return(0); +} + +char * +cl_xa::id_string(void) +{ + return("unspecified XA"); +} + + +/* + * Making elements of the controller + */ + +t_addr +cl_xa::get_mem_size(enum mem_class type) +{ + switch(type) + { + case MEM_ROM: return(0x10000); + case MEM_XRAM: return(0x10000); + default: return(0); + } + return(cl_uc::get_mem_size(type)); +} + +void +cl_xa::mk_hw_elements(void) +{ + //class cl_base *o; + /* t_uc::mk_hw() does nothing */ +} + + +/* + * 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(0); +}*/ + +/*struct name_entry * +cl_xa::bit_tbl(void) +{ + //FIXME + return(0); +}*/ + +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; +} + +/*-------------------------------------------------------------------- +get_disasm_info - +|--------------------------------------------------------------------*/ +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= get_mem(MEM_ROM, addr++); + if (code == 0x00) { + i= 0; + while (disass_xa[i].mnemonic != NOP) + i++; + } else { + len = 2; + code = (code << 8) | get_mem(MEM_ROM, 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 char *w_reg_strs[] = { + "R0", "R1", + "R2", "R3", + "R4", "R5", + "R6", "R7", + "R8", "R9", + "R10", "R11", + "R12", "R13", + "R14", "R15"}; + +static char *b_reg_strs[] = { + "R0l", "R0h", + "R1l", "R1h", + "R2l", "R2h", + "R3l", "R3h", + "R4l", "R4h", + "R5l", "R5h", + "R6l", "R6h", + "R7l", "R7h"}; + +/*-------------------------------------------------------------------- +disass - +|--------------------------------------------------------------------*/ +char * +cl_xa::disass(t_addr addr, 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; + 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+%02d]", + reg_strs[((code >> 4) & 0xf)], + w_reg_strs[(code & 0x7)], + get_mem(MEM_ROM, addr+immed_offset)); + ++immed_offset; + break; + case IREGOFF8_REG : + sprintf(parm_str, "[%s+%02d],%s", + w_reg_strs[(code & 0x7)], + get_mem(MEM_ROM, addr+immed_offset), + reg_strs[((code >> 4) & 0xf)] ); + ++immed_offset; + break; + case REG_IREGOFF16 : + sprintf(parm_str, "%s,[%s+%04d]", + reg_strs[((code >> 4) & 0xf)], + w_reg_strs[(code & 0x7)], + (short)((get_mem(MEM_ROM, addr+immed_offset+1)) | + (get_mem(MEM_ROM, addr+immed_offset)<<8)) ); + ++immed_offset; + ++immed_offset; + break; + case IREGOFF16_REG : + sprintf(parm_str, "[%s+%04d],%s", + w_reg_strs[(code & 0x7)], + (short)((get_mem(MEM_ROM, addr+immed_offset+1)) | + (get_mem(MEM_ROM, 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, "0x%04x,%s", + ((code & 0x3) << 8) | get_mem(MEM_ROM, addr+immed_offset), + reg_strs[((code >> 4) & 0xf)] ); + ++immed_offset; + break; + case REG_DIRECT : + sprintf(parm_str, "%s, @0x%04x", + reg_strs[((code >> 4) & 0xf)], + ((code & 0x3) << 8) | get_mem(MEM_ROM, addr+immed_offset) ); + ++immed_offset; + break; + case REG_DATA8 : + sprintf(parm_str, "%s, #%02d", + b_reg_strs[((code >> 4) & 0xf)], + get_mem(MEM_ROM, addr+immed_offset) ); + ++immed_offset; + break; + case REG_DATA16 : + sprintf(parm_str, "%s, #%04d", + reg_strs[((code >> 4) & 0xf)], + (short)((get_mem(MEM_ROM, addr+immed_offset+1)) | + (get_mem(MEM_ROM, addr+immed_offset)<<8)) ); + ++immed_offset; + ++immed_offset; + break; + case IREG_DATA8 : + sprintf(parm_str, "[%s], 0x%02x", + w_reg_strs[((code >> 4) & 0x7)], + get_mem(MEM_ROM, addr+immed_offset) ); + ++immed_offset; + break; + case IREG_DATA16 : + sprintf(parm_str, "[%s], 0x%04x", + w_reg_strs[((code >> 4) & 0x7)], + (short)((get_mem(MEM_ROM, addr+immed_offset+1)) | + (get_mem(MEM_ROM, addr+immed_offset)<<8)) ); + ++immed_offset; + ++immed_offset; + break; + case IREGINC_DATA8 : + sprintf(parm_str, "[%s+], 0x%02x", + w_reg_strs[((code >> 4) & 0x7)], + get_mem(MEM_ROM, addr+immed_offset) ); + ++immed_offset; + break; + case IREGINC_DATA16 : + sprintf(parm_str, "[%s+], 0x%04x", + w_reg_strs[((code >> 4) & 0x7)], + (short)((get_mem(MEM_ROM, addr+immed_offset+1)) | + (get_mem(MEM_ROM, addr+immed_offset)<<8)) ); + ++immed_offset; + ++immed_offset; + break; + case IREGOFF8_DATA8 : + sprintf(parm_str, "[%s+%02d], 0x%02x", + w_reg_strs[((code >> 4) & 0x7)], + get_mem(MEM_ROM, addr+immed_offset), + get_mem(MEM_ROM, addr+immed_offset+1) ); + immed_offset += 2; + break; + case IREGOFF8_DATA16 : + sprintf(parm_str, "[%s+%02d], 0x%04x", + w_reg_strs[((code >> 4) & 0x7)], + get_mem(MEM_ROM, addr+immed_offset), + (short)((get_mem(MEM_ROM, addr+immed_offset+2)) | + (get_mem(MEM_ROM, addr+immed_offset+1)<<8)) ); + immed_offset += 3; + break; + case IREGOFF16_DATA8 : + sprintf(parm_str, "[%s+%04d], 0x%02x", + w_reg_strs[((code >> 4) & 0x7)], + (short)((get_mem(MEM_ROM, addr+immed_offset+1)) | + (get_mem(MEM_ROM, addr+immed_offset+0)<<8)), + get_mem(MEM_ROM, addr+immed_offset+2) ); + immed_offset += 3; + break; + case IREGOFF16_DATA16 : + sprintf(parm_str, "[%s+%04d], 0x%04x", + w_reg_strs[((code >> 4) & 0x7)], + (short)((get_mem(MEM_ROM, addr+immed_offset+1)) | + (get_mem(MEM_ROM, addr+immed_offset+0)<<8)), + (short)((get_mem(MEM_ROM, addr+immed_offset+3)) | + (get_mem(MEM_ROM, addr+immed_offset+2)<<8)) ); + immed_offset += 4; + break; + case DIRECT_DATA8 : + sprintf(parm_str, "#%04d 0x%02x", + ((code & 0x3) << 8) | get_mem(MEM_ROM, addr+immed_offset), + get_mem(MEM_ROM, addr+immed_offset+1) ); + immed_offset += 3; + break; + case DIRECT_DATA16 : + sprintf(parm_str, "#%04d 0x%04x", + ((code & 0x3) << 8) | get_mem(MEM_ROM, addr+immed_offset), + (short)((get_mem(MEM_ROM, addr+immed_offset+2)) | + (get_mem(MEM_ROM, addr+immed_offset+1)<<8)) ); + immed_offset += 3; + break; + +// odd-ball ones + case NO_OPERANDS : // for NOP + strcpy(parm_str, ""); + break; + case C_BIT : + strcpy(parm_str, "C_BIT"); + break; + case REG_DATA4 : + strcpy(parm_str, "REG_DATA4"); + 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 : + strcpy(parm_str, "DIRECT_DATA4"); + 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 - +|--------------------------------------------------------------------*/ +void +cl_xa::print_regs(class cl_console *con) +{ + unsigned char flags; + + flags = get_psw(); + con->dd_printf("CA---VNZ Flags: %02x ", flags); + con->dd_printf("R0:%04x R1:%04x R2:%04x R3:%04x\n", + get_reg(1,0), get_reg(1,2), get_reg(1,4), get_reg(1,6)); + + 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 R7(SP):%04x ES:%04x DS:%04x\n", + get_reg(1,8), get_reg(1,10), get_reg(1,12), get_reg(1,14), 0, 0); + + print_disass(PC, con); +} + + +/* + * Execution + */ + +int +cl_xa::exec_inst(void) +{ + t_mem code1, code2; + uint code; + int i; + + if (fetch(&code1)) + return(resBREAKPOINT); + tick(1); + + if (code1 == 0) // nop, 1 byte instr + return(inst_NOP(code1)); + + if (fetch(&code2)) + return(resBREAKPOINT); + code = (code1 << 8) | code2; + + i= 0; + while ((code & disass_xa[i].mask) != disass_xa[i].code && + disass_xa[i].mnemonic != BAD_OPCODE) + i++; + + code |= ((int)(disass_xa[i].operands)) << 16; // kludgy, tack on operands info + switch (disass_xa[i].mnemonic) + { + case ADD: + return inst_ADD(code); + case ADDC: + return inst_ADDC(code); + case SUB: + return inst_SUB(code); + case SUBB: + return inst_SUBB(code); + case CMP: + return inst_CMP(code); + case AND: + return inst_AND(code); + case OR: + return inst_OR(code); + case XOR: + return inst_XOR(code); + case ADDS: + return inst_ADDS(code); + case NEG: + return inst_NEG(code); + case SEXT: + return inst_SEXT(code); + case MUL: + return inst_MUL(code); + case DIV: + return inst_DIV(code); + case DA: + return inst_DA(code); + case ASL: + return inst_ASL(code); + case ASR: + return inst_ASR(code); + case LEA: + return inst_LEA(code); + case CPL: + return inst_CPL(code); + case LSR: + return inst_LSR(code); + case NORM: + return inst_NORM(code); + case RL: + return inst_RL(code); + case RLC: + return inst_RLC(code); + case RR: + return inst_RR(code); + case RRC: + return inst_RRC(code); + case MOVS: + return inst_MOVS(code); + case MOVC: + return inst_MOVC(code); + case MOVX: + return inst_MOVX(code); + case PUSH: + return inst_PUSH(code); + case POP: + return inst_POP(code); + case XCH: + return inst_XCH(code); + case SETB: + return inst_SETB(code); + case CLR: + return inst_CLR(code); + case MOV: + return inst_MOV(code); + case ANL: + return inst_ANL(code); + case ORL: + return inst_ORL(code); + case BR: + return inst_BR(code); + case JMP: + return inst_JMP(code); + case CALL: + return inst_CALL(code); + case RET: + return inst_RET(code); + case Bcc: + return inst_Bcc(code); + case JB: + return inst_JB(code); + case JNB: + return inst_JNB(code); + case CJNE: + return inst_CJNE(code); + case DJNZ: + return inst_DJNZ(code); + case JZ: + return inst_JZ(code); + case JNZ: + return inst_JNZ(code); + case NOP: + return inst_NOP(code); + case BKPT: + return inst_BKPT(code); + case TRAP: + return inst_TRAP(code); + case RESET: + return inst_RESET(code); + case BAD_OPCODE: + default: + break; + } + + if (PC) + PC--; + else + PC= get_mem_size(MEM_ROM)-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 00000000..e21d4f0e --- /dev/null +++ b/sim/ucsim/xa.src/xacl.h @@ -0,0 +1,87 @@ +/* + * Simulator of microcontrollers (xacl.h) + * + * Copyright (C) 1999,99 Drotos Daniel, Talker Bt. + * + * Written by Karl Bongers karl@turbobit.com + * + * 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 XACL_HEADER +#define XACL_HEADER + +#include "uccl.h" + +#include "regsxa.h" + +/* + * Base type of XA microcontrollers + */ + +class cl_xa: public cl_uc +{ +public: + cl_mem *ram; + cl_mem *rom; + struct t_regs regs; + + // 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 t_addr get_mem_size(enum mem_class type); + virtual void mk_hw_elements(void); + + virtual struct dis_entry *dis_tbl(void); + + virtual int inst_length(t_addr addr); + virtual int inst_branch(t_addr addr); + virtual int longest_inst(void); + + virtual 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, char *sep); + virtual void print_regs(class cl_console *con); + + virtual int exec_inst(void); + virtual int get_reg(int word_flag, unsigned int index); + +#include "instcl.h" +}; + + +#endif + +/* End of xa.src/xacl.h */ diff --git a/sim/ucsim/z80.src/Makefile.in b/sim/ucsim/z80.src/Makefile.in index b8f6bc4c..928dc93b 100644 --- a/sim/ucsim/z80.src/Makefile.in +++ b/sim/ucsim/z80.src/Makefile.in @@ -21,8 +21,12 @@ CPPFLAGS = @CPPFLAGS@ -I. -I$(PRJDIR) \ CFLAGS = @CFLAGS@ -Wall CXXFLAGS = @CXXFLAGS@ -Wall M_OR_MM = @M_OR_MM@ +PICOPT = @PICOPT@ +SHAREDLIB = @SHAREDLIB@ LIBS = @LIBS@ -L$(PRJDIR) -lsim -lcmd -lutil -lguiucsim +DL = @DL@ +dl_ok = @dl_ok@ prefix = @prefix@ exec_prefix = @exec_prefix@ @@ -36,15 +40,26 @@ man2dir = $(mandir)/man2 infodir = @infodir@ srcdir = @srcdir@ -OBJECTS = sz80.o glob.o \ +OBJECTS_SHARED = glob.o \ inst.o \ + inst_cb.o \ + inst_dd.o \ + inst_ed.o \ + inst_fd.o \ + inst_ddcb.o \ + inst_fdcb.o \ simz80.o z80.o +OBJECTS_EXE = sz80.o +OBJECTS = $(OBJECTS_SHARED) $(OBJECTS_EXE) Z80ASM = + +enable_dlso = @enable_dlso@ +dlso_ok = @dlso_ok@ + #TEST_OBJ = test_bit.hex test_dis.hex test_mov.hex test_jmp.hex \ # test_arith.hex - # Compiling entire program or any subproject # ------------------------------------------ all: checkconf otherlibs z80.src tests @@ -66,7 +81,9 @@ uninstall: # Performing self-test # -------------------- -check: +check: test + +test: # Performing installation test @@ -94,11 +111,22 @@ include clean.mk # -------- .SUFFIXES: .asm .hex -z80.src: sz80 +z80.src: sz80 shared_lib sz80: $(OBJECTS) $(PRJDIR)/*.a $(CXX) $(CXXFLAGS) -o sz80 $(OBJECTS) $(LIBS) +ifeq ($(dlso_ok),yes) +shared_lib: $(PRJDIR)/sz80.so +else +shared_lib: + @echo "No z80 shared lib made." + @echo "(SHAREDLIB="$(SHAREDLIB)",dl_ok="$(dl_ok)",enable_dlso="$(enable_dlso)")" +endif + +$(PRJDIR)/sz80.so: $(OBJECTS_SHARED) + $(CXX) -shared $(OBJECTS_SHARED) -o $(PRJDIR)/sz80.so + otherlibs: cd $(PRJDIR)/cmd.src && $(MAKE) all cd $(PRJDIR)/sim.src && $(MAKE) all diff --git a/sim/ucsim/z80.src/glob.cc b/sim/ucsim/z80.src/glob.cc index aae09598..85b25473 100644 --- a/sim/ucsim/z80.src/glob.cc +++ b/sim/ucsim/z80.src/glob.cc @@ -30,10 +30,1238 @@ Software Foundation, 59 Temple Place - Suite 330, Boston, MA #include "stypes.h" +/* +%d - signed compl.,byte jump +%w - 2-byte jump or imm. value +%b - byte imm. value + */ +/* uint code, mask; char branch; uchar length; char *mnemonic; */ struct dis_entry disass_z80[]= { - { 0x0000, 0x00ff, ' ', 1, "nop" }, + { 0x0000, 0x00ff, ' ', 1, "NOP" }, + { 0x0001, 0x00ff, ' ', 3, "LD BC,%w" }, + { 0x0002, 0x00ff, ' ', 1, "LD (BC),A" }, + { 0x0003, 0x00ff, ' ', 1, "INC BC" }, + { 0x0004, 0x00ff, ' ', 1, "INC B" }, + { 0x0005, 0x00ff, ' ', 1, "DEC B" }, + { 0x0006, 0x00ff, ' ', 2, "LD b,%b" }, + { 0x0007, 0x00ff, ' ', 1, "RLCA" }, + + { 0x0008, 0x00ff, ' ', 1, "EX AF,AF'" }, + { 0x0009, 0x00ff, ' ', 1, "ADD HL,BC" }, + { 0x000a, 0x00ff, ' ', 1, "LD A,(BC)" }, + { 0x000b, 0x00ff, ' ', 1, "DEC BC" }, + { 0x000c, 0x00ff, ' ', 1, "INC C" }, + { 0x000d, 0x00ff, ' ', 1, "DEC C" }, + { 0x000e, 0x00ff, ' ', 2, "LD C,%b" }, + { 0x000f, 0x00ff, ' ', 1, "RRCA" }, + + { 0x0010, 0x00ff, 'R', 2, "DJNZ %d" }, + { 0x0011, 0x00ff, ' ', 3, "LD DE,%w" }, + { 0x0012, 0x00ff, ' ', 1, "LD (DE),A" }, + { 0x0013, 0x00ff, ' ', 1, "INC DE" }, + { 0x0014, 0x00ff, ' ', 1, "INC D" }, + { 0x0015, 0x00ff, ' ', 1, "DEC D" }, + { 0x0016, 0x00ff, ' ', 2, "LD D,%b" }, + { 0x0017, 0x00ff, ' ', 1, "RLA" }, + + { 0x0018, 0x00ff, 'R', 2, "JR %d" }, + { 0x0019, 0x00ff, ' ', 3, "ADD HL,DE" }, + { 0x001a, 0x00ff, ' ', 1, "LD A,DE" }, + { 0x001b, 0x00ff, ' ', 1, "DEC DE" }, + { 0x001c, 0x00ff, ' ', 1, "INC E" }, + { 0x001d, 0x00ff, ' ', 1, "DEC E" }, + { 0x001e, 0x00ff, ' ', 2, "LD E" }, + { 0x001f, 0x00ff, ' ', 1, "RRA" }, + + { 0x0020, 0x00ff, 'R', 2, "JR NZ,%d" }, + { 0x0021, 0x00ff, ' ', 3, "LD HL,%w" }, + { 0x0022, 0x00ff, ' ', 3, "LD (%w),HL" }, + { 0x0023, 0x00ff, ' ', 1, "INC HL" }, + { 0x0024, 0x00ff, ' ', 1, "INC H" }, + { 0x0025, 0x00ff, ' ', 1, "DEC H" }, + { 0x0026, 0x00ff, ' ', 2, "LD H,%b" }, + { 0x0027, 0x00ff, ' ', 1, "DAA" }, + + { 0x0028, 0x00ff, 'R', 2, "JR Z,%d" }, + { 0x0029, 0x00ff, ' ', 1, "ADD HL,HL" }, + { 0x002a, 0x00ff, ' ', 3, "LD HL,(%w)" }, + { 0x002b, 0x00ff, ' ', 1, "DEC HL" }, + { 0x002c, 0x00ff, ' ', 1, "INC L" }, + { 0x002d, 0x00ff, ' ', 1, "DEC L" }, + { 0x002e, 0x00ff, ' ', 2, "LD L, %b" }, + { 0x002f, 0x00ff, ' ', 1, "CPL" }, + + { 0x0030, 0x00ff, 'R', 2, "JR NC,%d" }, + { 0x0031, 0x00ff, ' ', 3, "LD SP,%w" }, + { 0x0032, 0x00ff, ' ', 3, "LD (%w),A" }, + { 0x0033, 0x00ff, ' ', 1, "INC SP" }, + { 0x0034, 0x00ff, ' ', 1, "INC HL" }, + { 0x0035, 0x00ff, ' ', 1, "DEC HL" }, + { 0x0036, 0x00ff, ' ', 2, "LD (HL),%b" }, + { 0x0037, 0x00ff, ' ', 1, "SCF" }, + + { 0x0038, 0x00ff, 'R', 2, "JR C,%d" }, + { 0x0039, 0x00ff, ' ', 1, "ADD HL,SP" }, + { 0x003a, 0x00ff, ' ', 3, "LD A,(%w)" }, + { 0x003b, 0x00ff, ' ', 1, "DEC SP" }, + { 0x003c, 0x00ff, ' ', 1, "INC A" }, + { 0x003d, 0x00ff, ' ', 1, "DEC A" }, + { 0x003e, 0x00ff, ' ', 2, "LD A,%b" }, + { 0x003f, 0x00ff, ' ', 1, "CCF" }, + + { 0x0040, 0x00ff, ' ', 1, "LD B,B" }, + { 0x0041, 0x00ff, ' ', 1, "LD B,C" }, + { 0x0042, 0x00ff, ' ', 1, "LD B,D" }, + { 0x0043, 0x00ff, ' ', 1, "LD B,E" }, + { 0x0044, 0x00ff, ' ', 1, "LD B,H" }, + { 0x0045, 0x00ff, ' ', 1, "LD B,L" }, + { 0x0046, 0x00ff, ' ', 1, "LD B,(HL)" }, + { 0x0047, 0x00ff, ' ', 1, "LD B,a" }, + + { 0x0048, 0x00ff, ' ', 1, "LD C,B" }, + { 0x0049, 0x00ff, ' ', 1, "LD C,C" }, + { 0x004a, 0x00ff, ' ', 1, "LD C,D" }, + { 0x004b, 0x00ff, ' ', 1, "LD C,E" }, + { 0x004c, 0x00ff, ' ', 1, "LD C,H" }, + { 0x004d, 0x00ff, ' ', 1, "LD C,L" }, + { 0x004e, 0x00ff, ' ', 1, "LD C,(HL)" }, + { 0x004f, 0x00ff, ' ', 1, "LD C,A" }, + + { 0x0050, 0x00ff, ' ', 1, "LD D,B" }, + { 0x0051, 0x00ff, ' ', 1, "LD D,C" }, + { 0x0052, 0x00ff, ' ', 1, "LD D,D" }, + { 0x0053, 0x00ff, ' ', 1, "LD D,E" }, + { 0x0054, 0x00ff, ' ', 1, "LD D,H" }, + { 0x0055, 0x00ff, ' ', 1, "LD D,L" }, + { 0x0056, 0x00ff, ' ', 1, "LD D,(HL)" }, + { 0x0057, 0x00ff, ' ', 1, "LD D,A" }, + + { 0x0058, 0x00ff, ' ', 1, "LD E,B" }, + { 0x0059, 0x00ff, ' ', 1, "LD E,C" }, + { 0x005a, 0x00ff, ' ', 1, "LD E,D" }, + { 0x005b, 0x00ff, ' ', 1, "LD E,E" }, + { 0x005c, 0x00ff, ' ', 1, "LD E,H" }, + { 0x005d, 0x00ff, ' ', 1, "LD E,L" }, + { 0x005e, 0x00ff, ' ', 1, "LD E,(HL)" }, + { 0x005f, 0x00ff, ' ', 1, "LD E,A" }, + + { 0x0060, 0x00ff, ' ', 1, "LD H,B" }, + { 0x0061, 0x00ff, ' ', 1, "LD H,C" }, + { 0x0062, 0x00ff, ' ', 1, "LD H,D" }, + { 0x0063, 0x00ff, ' ', 1, "LD H,E" }, + { 0x0064, 0x00ff, ' ', 1, "LD H,H" }, + { 0x0065, 0x00ff, ' ', 1, "LD H,L" }, + { 0x0066, 0x00ff, ' ', 1, "LD H,(HL)" }, + { 0x0067, 0x00ff, ' ', 1, "LD H,A" }, + + { 0x0068, 0x00ff, ' ', 1, "LD L,B" }, + { 0x0069, 0x00ff, ' ', 1, "LD L,C" }, + { 0x006a, 0x00ff, ' ', 1, "LD L,D" }, + { 0x006b, 0x00ff, ' ', 1, "LD L,E" }, + { 0x006c, 0x00ff, ' ', 1, "LD L,H" }, + { 0x006d, 0x00ff, ' ', 1, "LD L,L" }, + { 0x006e, 0x00ff, ' ', 1, "LD L,(HL)" }, + { 0x006f, 0x00ff, ' ', 1, "LD L,A" }, + + { 0x0070, 0x00ff, ' ', 1, "LD (HL),B" }, + { 0x0071, 0x00ff, ' ', 1, "LD (HL),C" }, + { 0x0072, 0x00ff, ' ', 1, "LD (HL),D" }, + { 0x0073, 0x00ff, ' ', 1, "LD (HL),E" }, + { 0x0074, 0x00ff, ' ', 1, "LD (HL),H" }, + { 0x0075, 0x00ff, ' ', 1, "LD (HL),L" }, + { 0x0076, 0x00ff, ' ', 1, "HALT" }, + { 0x0077, 0x00ff, ' ', 1, "LD (HL),A" }, + + { 0x0078, 0x00ff, ' ', 1, "LD A,B" }, + { 0x0079, 0x00ff, ' ', 1, "LD A,C" }, + { 0x007a, 0x00ff, ' ', 1, "LD A,D" }, + { 0x007b, 0x00ff, ' ', 1, "LD A,E" }, + { 0x007c, 0x00ff, ' ', 1, "LD A,H" }, + { 0x007d, 0x00ff, ' ', 1, "LD A,L" }, + { 0x007e, 0x00ff, ' ', 1, "LD A,(HL)" }, + { 0x007f, 0x00ff, ' ', 1, "LD A,A" }, + + { 0x0080, 0x00ff, ' ', 1, "ADD A,B" }, + { 0x0081, 0x00ff, ' ', 1, "ADD A,C" }, + { 0x0082, 0x00ff, ' ', 1, "ADD A,D" }, + { 0x0083, 0x00ff, ' ', 1, "ADD A,E" }, + { 0x0084, 0x00ff, ' ', 1, "ADD A,H" }, + { 0x0085, 0x00ff, ' ', 1, "ADD A,L" }, + { 0x0086, 0x00ff, ' ', 1, "ADD A,(HL)" }, + { 0x0087, 0x00ff, ' ', 1, "ADD A,A" }, + + { 0x0088, 0x00ff, ' ', 1, "ADC A,B" }, + { 0x0089, 0x00ff, ' ', 1, "ADC A,C" }, + { 0x008a, 0x00ff, ' ', 1, "ADC A,D" }, + { 0x008b, 0x00ff, ' ', 1, "ADC A,E" }, + { 0x008c, 0x00ff, ' ', 1, "ADC A,H" }, + { 0x008d, 0x00ff, ' ', 1, "ADC A,L" }, + { 0x008e, 0x00ff, ' ', 1, "ADC A,(HL)" }, + { 0x008f, 0x00ff, ' ', 1, "ADC A,A" }, + + { 0x0090, 0x00ff, ' ', 1, "SUB A,B"}, + { 0x0091, 0x00ff, ' ', 1, "SUB A,C"}, + { 0x0092, 0x00ff, ' ', 1, "SUB A,D"}, + { 0x0093, 0x00ff, ' ', 1, "SUB A,E"}, + { 0x0094, 0x00ff, ' ', 1, "SUB A,H"}, + { 0x0095, 0x00ff, ' ', 1, "SUB A,L"}, + { 0x0096, 0x00ff, ' ', 1, "SUB A,(HL)"}, + { 0x0097, 0x00ff, ' ', 1, "SUB A,A"}, + + { 0x0098, 0x00ff, ' ', 1, "SBC A,B" }, + { 0x0099, 0x00ff, ' ', 1, "SBC A,C" }, + { 0x009a, 0x00ff, ' ', 1, "SBC A,D" }, + { 0x009b, 0x00ff, ' ', 1, "SBC A,E" }, + { 0x009c, 0x00ff, ' ', 1, "SBC A,H" }, + { 0x009d, 0x00ff, ' ', 1, "SBC A,L" }, + { 0x009e, 0x00ff, ' ', 1, "SBC A,(HL)" }, + { 0x009f, 0x00ff, ' ', 1, "SBC A,A" }, + + { 0x00a0, 0x00ff, ' ', 1, "AND B" }, + { 0x00a1, 0x00ff, ' ', 1, "AND C" }, + { 0x00a2, 0x00ff, ' ', 1, "AND D" }, + { 0x00a3, 0x00ff, ' ', 1, "AND E" }, + { 0x00a4, 0x00ff, ' ', 1, "AND H" }, + { 0x00a5, 0x00ff, ' ', 1, "AND L" }, + { 0x00a6, 0x00ff, ' ', 1, "AND (HL)" }, + { 0x00a7, 0x00ff, ' ', 1, "AND A" }, + + { 0x00a8, 0x00ff, ' ', 1, "XOR B" }, + { 0x00a9, 0x00ff, ' ', 1, "XOR C" }, + { 0x00aa, 0x00ff, ' ', 1, "XOR D" }, + { 0x00ab, 0x00ff, ' ', 1, "XOR E" }, + { 0x00ac, 0x00ff, ' ', 1, "XOR H" }, + { 0x00ad, 0x00ff, ' ', 1, "XOR L" }, + { 0x00ae, 0x00ff, ' ', 1, "XOR (HL)" }, + { 0x00af, 0x00ff, ' ', 1, "XOR A" }, + + { 0x00b0, 0x00ff, ' ', 1, "OR B" }, + { 0x00b1, 0x00ff, ' ', 1, "OR C" }, + { 0x00b2, 0x00ff, ' ', 1, "OR D" }, + { 0x00b3, 0x00ff, ' ', 1, "OR E" }, + { 0x00b4, 0x00ff, ' ', 1, "OR H" }, + { 0x00b5, 0x00ff, ' ', 1, "OR L" }, + { 0x00b6, 0x00ff, ' ', 1, "OR (HL)" }, + { 0x00b7, 0x00ff, ' ', 1, "OR A" }, + + { 0x00b8, 0x00ff, ' ', 1, "CP B" }, + { 0x00b9, 0x00ff, ' ', 1, "CP C" }, + { 0x00ba, 0x00ff, ' ', 1, "CP D" }, + { 0x00bb, 0x00ff, ' ', 1, "CP E" }, + { 0x00bc, 0x00ff, ' ', 1, "CP H" }, + { 0x00bd, 0x00ff, ' ', 1, "CP L" }, + { 0x00be, 0x00ff, ' ', 1, "CP (HL)" }, + { 0x00bf, 0x00ff, ' ', 1, "CP A" }, + + { 0x00c0, 0x00ff, ' ', 1, "RET NZ" }, + { 0x00c1, 0x00ff, ' ', 1, "POP BC" }, + { 0x00c2, 0x00ff, 'A', 3, "JP NZ, %w" }, + { 0x00c3, 0x00ff, 'A', 3, "JP %w" }, + { 0x00c4, 0x00ff, 'l', 3, "CALL NZ,%w" }, + { 0x00c5, 0x00ff, ' ', 1, "PUSH BC" }, + { 0x00c6, 0x00ff, ' ', 2, "ADD A,%b" }, + { 0x00c7, 0x00ff, ' ', 1, "RST 0" }, + + { 0x00c8, 0x00ff, ' ', 1, "RET Z" }, + { 0x00c9, 0x00ff, ' ', 1, "RET" }, + { 0x00ca, 0x00ff, 'A', 3, "JP Z,%w" }, + { 0x00cb, 0x00ff, ' ', 2, "?cb?" }, /* ESC code to lots of op-codes, all 2-byte */ + { 0x00cc, 0x00ff, 'l', 3, "CALL Z,%w" }, + { 0x00cd, 0x00ff, 'l', 3, "CALL %w" }, + { 0x00ce, 0x00ff, ' ', 2, "ADC A,%b" }, + { 0x00cf, 0x00ff, ' ', 1, "RST 8" }, + + { 0x00d0, 0x00ff, ' ', 1, "RET NC" }, + { 0x00d1, 0x00ff, ' ', 1, "POP DE" }, + { 0x00d2, 0x00ff, 'A', 3, "JP NC,%w" }, + { 0x00d3, 0x00ff, ' ', 2, "OUT (%b),A" }, + { 0x00d4, 0x00ff, 'l', 3, "CALL NC,%w" }, + { 0x00d5, 0x00ff, ' ', 1, "PUSH DE" }, + { 0x00d6, 0x00ff, ' ', 2, "sub %b" }, + { 0x00d7, 0x00ff, ' ', 1, "RST 10H" }, + + { 0x00d8, 0x00ff, ' ', 1, "RET C" }, + { 0x00d9, 0x00ff, ' ', 1, "EXX" }, + { 0x00da, 0x00ff, 'A', 3, "JP C,%w" }, + { 0x00db, 0x00ff, ' ', 2, "IN A,(%b)" }, + { 0x00dc, 0x00ff, 'l', 3, "CALL C,%w" }, + + { 0x00dd, 0x00ff, ' ', 2, "?dd?" }, /* 0xdd - ESC codes,about 284, vary lengths, IX centric */ + { 0x00de, 0x00ff, ' ', 2, "SBC A,%b" }, + { 0x00df, 0x00ff, ' ', 1, "RST 18H" }, + + { 0x00e0, 0x00ff, ' ', 1, "RET PO" }, + { 0x00e1, 0x00ff, ' ', 1, "POP HL" }, + { 0x00e2, 0x00ff, 'A', 3, "JP PO,%w" }, + { 0x00e3, 0x00ff, ' ', 1, "EX (SP),HL" }, + { 0x00e4, 0x00ff, 'l', 3, "CALL PO,%w" }, + { 0x00e5, 0x00ff, ' ', 1, "PUSH HL" }, + { 0x00e6, 0x00ff, ' ', 2, "AND %b" }, + { 0x00e7, 0x00ff, ' ', 1, "RST 20H" }, + + { 0x00e8, 0x00ff, ' ', 1, "RET PE" }, + { 0x00e9, 0x00ff, 'A', 1, "JP (HL)" }, + { 0x00ea, 0x00ff, 'A', 3, "JP PE,%w" }, + { 0x00eb, 0x00ff, ' ', 1, "EX DE,HL" }, + { 0x00ec, 0x00ff, 'l', 3, "CALL PE, %w" }, + { 0x00ed, 0x00ff, ' ', 2, "?ed?" }, /* ESC code to about 80 opcodes of various lengths */ + { 0x00ee, 0x00ff, ' ', 2, "XOR %b" }, + { 0x00ef, 0x00ff, ' ', 1, "RST 28H" }, + + { 0x00f0, 0x00ff, ' ', 1, "RET P" }, + { 0x00f1, 0x00ff, ' ', 1, "POP AF" }, + { 0x00f2, 0x00ff, 'A', 3, "JP P,%w" }, + { 0x00f3, 0x00ff, ' ', 1, "DI" }, + { 0x00f4, 0x00ff, 'l', 3, "CALL P,%w" }, + { 0x00f5, 0x00ff, ' ', 1, "PUSH AF" }, + { 0x00f6, 0x00ff, ' ', 2, "OR %b" }, + { 0x00f7, 0x00ff, ' ', 1, "RST 30H" }, + + { 0x00f8, 0x00ff, ' ', 1, "RET M" }, + { 0x00f9, 0x00ff, ' ', 1, "LD SP,HL" }, + { 0x00fa, 0x00ff, ' ', 3, "JP M,%w" }, + { 0x00fb, 0x00ff, ' ', 1, "EI" }, + { 0x00fc, 0x00ff, 'l', 3, "CALL M,%w" }, + { 0x00fd, 0x00ff, ' ', 1, "?fd?" }, /* ESC codes,about 284, vary lengths, IY centric */ + { 0x00fe, 0x00ff, ' ', 2, "CP %b" }, + { 0x00ff, 0x00ff, ' ', 1, "RST 38H" }, + + { 0, 0, 0, 0, NULL } +}; + + +struct dis_entry disass_z80_ed[]= { + { 0x0000, 0x00ff, ' ', 1, "RLC B" }, + { 0x0040, 0x00ff, ' ', 1, "IN B,(C)" }, + { 0x0041, 0x00ff, ' ', 1, "OUT (C),B" }, + { 0x0042, 0x00ff, ' ', 1, "SBC HL,BC" }, + { 0x0043, 0x00ff, ' ', 1, "LD (nnnn),BC" }, + { 0x0044, 0x00ff, ' ', 1, "NEG" }, + { 0x0045, 0x00ff, ' ', 1, "RETN" }, + { 0x0046, 0x00ff, ' ', 1, "IM 0" }, + { 0x0047, 0x00ff, ' ', 1, "LD IV,A" }, + { 0x0048, 0x00ff, ' ', 1, "IN C,(C)" }, + { 0x0049, 0x00ff, ' ', 1, "OUT (C),C" }, + { 0x004A, 0x00ff, ' ', 1, "ADC HL,BC" }, + { 0x004B, 0x00ff, ' ', 1, "LD BC,(nnnn)" }, + { 0x004D, 0x00ff, ' ', 1, "RETI" }, + { 0x004F, 0x00ff, ' ', 1, "LD R,A" }, + { 0x0050, 0x00ff, ' ', 1, "IN D,(C)" }, + { 0x0051, 0x00ff, ' ', 1, "OUT (C),D" }, + { 0x0052, 0x00ff, ' ', 1, "SBC HL,DE" }, + { 0x0053, 0x00ff, ' ', 1, "LD (nnnn),DE" }, + { 0x0056, 0x00ff, ' ', 1, "IM 1" }, + { 0x0057, 0x00ff, ' ', 1, "LD A,IV" }, + { 0x0058, 0x00ff, ' ', 1, "IN E,(C)" }, + { 0x0059, 0x00ff, ' ', 1, "OUT (C),E" }, + { 0x005A, 0x00ff, ' ', 1, "ADC HL,DE" }, + { 0x005B, 0x00ff, ' ', 1, "LD DE,(nnnn)" }, + { 0x005E, 0x00ff, ' ', 1, "IM 2" }, + { 0x005F, 0x00ff, ' ', 1, "LD A,R" }, + { 0x0060, 0x00ff, ' ', 1, "IN H,(C)" }, + { 0x0061, 0x00ff, ' ', 1, "OUT (C),H" }, + { 0x0062, 0x00ff, ' ', 1, "SBC HL,HL" }, + { 0x0063, 0x00ff, ' ', 1, "LD (nnnn),HL" }, + { 0x0067, 0x00ff, ' ', 1, "RRD" }, + { 0x0068, 0x00ff, ' ', 1, "IN L,(C)" }, + { 0x0069, 0x00ff, ' ', 1, "OUT (C),L" }, + { 0x006A, 0x00ff, ' ', 1, "ADC HL,HL" }, + { 0x006B, 0x00ff, ' ', 1, "LD HL,(nnnn)" }, + { 0x006F, 0x00ff, ' ', 1, "RLD" }, + { 0x0070, 0x00ff, ' ', 1, "IN (C)" }, + { 0x0071, 0x00ff, ' ', 1, " OUT (C),0" }, + { 0x0072, 0x00ff, ' ', 1, "SBC HL,SP" }, + { 0x0073, 0x00ff, ' ', 1, "LD (nnnn),SP" }, + { 0x0078, 0x00ff, ' ', 1, "IN A,(C)" }, + { 0x0079, 0x00ff, ' ', 1, "OUT (C),A" }, + { 0x007A, 0x00ff, ' ', 1, "ADC HL,SP" }, + { 0x007B, 0x00ff, ' ', 1, "LD SP,(nnnn)" }, + { 0x00A0, 0x00ff, ' ', 1, "LDI" }, + { 0x00A1, 0x00ff, ' ', 1, "CPI" }, + { 0x00A2, 0x00ff, ' ', 1, "INI" }, + { 0x00A3, 0x00ff, ' ', 1, "OUTI" }, + { 0x00A8, 0x00ff, ' ', 1, "LDD" }, + { 0x00A9, 0x00ff, ' ', 1, "CPD" }, + { 0x00AA, 0x00ff, ' ', 1, "IND" }, + { 0x00AB, 0x00ff, ' ', 1, "OUTD" }, + { 0x00B0, 0x00ff, ' ', 1, "LDIR" }, + { 0x00B1, 0x00ff, ' ', 1, "CPIR" }, + { 0x00B2, 0x00ff, ' ', 1, "INIR" }, + { 0x00B3, 0x00ff, ' ', 1, "OTIR" }, + { 0x00B8, 0x00ff, ' ', 1, "LDDR" }, + { 0x00B9, 0x00ff, ' ', 1, "CPDR" }, + { 0x00BA, 0x00ff, ' ', 1, "INDR" }, + { 0x00BB, 0x00ff, ' ', 1, "OTDR" }, + { 0, 0, 0, 0, NULL } +}; + +struct dis_entry disass_z80_cb[]= { + { 0x0000, 0x00ff, ' ', 1, "RLC B" }, + { 0x0001, 0x00ff, ' ', 1, "RLC C" }, + { 0x0002, 0x00ff, ' ', 1, "RLC D" }, + { 0x0003, 0x00ff, ' ', 1, "RLC E" }, + { 0x0004, 0x00ff, ' ', 1, "RLC H" }, + { 0x0005, 0x00ff, ' ', 1, "RLC L" }, + { 0x0006, 0x00ff, ' ', 1, "RLC (HL)" }, + { 0x0007, 0x00ff, ' ', 1, "RLC A" }, + { 0x0008, 0x00ff, ' ', 1, "RRC B" }, + { 0x0009, 0x00ff, ' ', 1, "RRC C" }, + { 0x000A, 0x00ff, ' ', 1, "RRC D" }, + { 0x000B, 0x00ff, ' ', 1, "RRC E" }, + { 0x000C, 0x00ff, ' ', 1, "RRC H" }, + { 0x000D, 0x00ff, ' ', 1, "RRC L" }, + { 0x000E, 0x00ff, ' ', 1, "RRC (HL)" }, + { 0x000F, 0x00ff, ' ', 1, "RRC A" }, + { 0x0010, 0x00ff, ' ', 1, "RL B" }, + { 0x0011, 0x00ff, ' ', 1, "RL C" }, + { 0x0012, 0x00ff, ' ', 1, "RL D" }, + { 0x0013, 0x00ff, ' ', 1, "RL E" }, + { 0x0014, 0x00ff, ' ', 1, "RL H" }, + { 0x0015, 0x00ff, ' ', 1, "RL L" }, + { 0x0016, 0x00ff, ' ', 1, "RL (HL)" }, + { 0x0017, 0x00ff, ' ', 1, "RL A" }, + { 0x0018, 0x00ff, ' ', 1, "RR B" }, + { 0x0019, 0x00ff, ' ', 1, "RR C" }, + { 0x001A, 0x00ff, ' ', 1, "RR D" }, + { 0x001B, 0x00ff, ' ', 1, "RR E" }, + { 0x001C, 0x00ff, ' ', 1, "RR H" }, + { 0x001D, 0x00ff, ' ', 1, "RR L" }, + { 0x001E, 0x00ff, ' ', 1, "RR (HL)" }, + { 0x001F, 0x00ff, ' ', 1, "RR A" }, + { 0x0020, 0x00ff, ' ', 1, "SLA B" }, + { 0x0021, 0x00ff, ' ', 1, "SLA C" }, + { 0x0022, 0x00ff, ' ', 1, "SLA D" }, + { 0x0023, 0x00ff, ' ', 1, "SLA E" }, + { 0x0024, 0x00ff, ' ', 1, "SLA H" }, + { 0x0025, 0x00ff, ' ', 1, "SLA L" }, + { 0x0026, 0x00ff, ' ', 1, "SLA (HL)" }, + { 0x0027, 0x00ff, ' ', 1, "SLA A" }, + { 0x0028, 0x00ff, ' ', 1, "SRA B" }, + { 0x0029, 0x00ff, ' ', 1, "SRA C" }, + { 0x002A, 0x00ff, ' ', 1, "SRA D" }, + { 0x002B, 0x00ff, ' ', 1, "SRA E" }, + { 0x002C, 0x00ff, ' ', 1, "SRA H" }, + { 0x002D, 0x00ff, ' ', 1, "SRA L" }, + { 0x002E, 0x00ff, ' ', 1, "SRA (HL)" }, + { 0x002F, 0x00ff, ' ', 1, "SRA A" }, + { 0x0030, 0x00ff, ' ', 1, "SLIA B" }, + { 0x0031, 0x00ff, ' ', 1, "SLIA C" }, + { 0x0032, 0x00ff, ' ', 1, "SLIA D" }, + { 0x0033, 0x00ff, ' ', 1, "SLIA E" }, + { 0x0034, 0x00ff, ' ', 1, "SLIA H" }, + { 0x0035, 0x00ff, ' ', 1, "SLIA L" }, + { 0x0036, 0x00ff, ' ', 1, "SLIA (HL)" }, + { 0x0037, 0x00ff, ' ', 1, "SLIA A" }, + { 0x0038, 0x00ff, ' ', 1, "SRL B" }, + { 0x0039, 0x00ff, ' ', 1, "SRL C" }, + { 0x003A, 0x00ff, ' ', 1, "SRL D" }, + { 0x003B, 0x00ff, ' ', 1, "SRL E" }, + { 0x003C, 0x00ff, ' ', 1, "SRL H" }, + { 0x003D, 0x00ff, ' ', 1, "SRL L" }, + { 0x003E, 0x00ff, ' ', 1, "SRL (HL)" }, + { 0x003F, 0x00ff, ' ', 1, "SRL A" }, + { 0x0040, 0x00ff, ' ', 1, "BIT 0,B" }, + { 0x0041, 0x00ff, ' ', 1, "BIT 0,C" }, + { 0x0042, 0x00ff, ' ', 1, "BIT 0,D" }, + { 0x0043, 0x00ff, ' ', 1, "BIT 0,E" }, + { 0x0044, 0x00ff, ' ', 1, "BIT 0,H" }, + { 0x0045, 0x00ff, ' ', 1, "BIT 0,L" }, + { 0x0046, 0x00ff, ' ', 1, "BIT 0,(HL)" }, + { 0x0047, 0x00ff, ' ', 1, "BIT 0,A" }, + { 0x0048, 0x00ff, ' ', 1, "BIT 1,B" }, + { 0x0049, 0x00ff, ' ', 1, "BIT 1,C" }, + { 0x004A, 0x00ff, ' ', 1, "BIT 1,D" }, + { 0x004B, 0x00ff, ' ', 1, "BIT 1,E" }, + { 0x004C, 0x00ff, ' ', 1, "BIT 1,H" }, + { 0x004D, 0x00ff, ' ', 1, "BIT 1,L" }, + { 0x004E, 0x00ff, ' ', 1, "BIT 1,(HL)" }, + { 0x004F, 0x00ff, ' ', 1, "BIT 1,A" }, + { 0x0050, 0x00ff, ' ', 1, "BIT 2,B" }, + { 0x0051, 0x00ff, ' ', 1, "BIT 2,C" }, + { 0x0052, 0x00ff, ' ', 1, "BIT 2,D" }, + { 0x0053, 0x00ff, ' ', 1, "BIT 2,E" }, + { 0x0054, 0x00ff, ' ', 1, "BIT 2,H" }, + { 0x0055, 0x00ff, ' ', 1, "BIT 2,L" }, + { 0x0056, 0x00ff, ' ', 1, "BIT 2,(HL)" }, + { 0x0057, 0x00ff, ' ', 1, "BIT 2,A" }, + { 0x0058, 0x00ff, ' ', 1, "BIT 3,B" }, + { 0x0059, 0x00ff, ' ', 1, "BIT 3,C" }, + { 0x005A, 0x00ff, ' ', 1, "BIT 3,D" }, + { 0x005B, 0x00ff, ' ', 1, "BIT 3,E" }, + { 0x005C, 0x00ff, ' ', 1, "BIT 3,H" }, + { 0x005D, 0x00ff, ' ', 1, "BIT 3,L" }, + { 0x005E, 0x00ff, ' ', 1, "BIT 3,(HL)" }, + { 0x005F, 0x00ff, ' ', 1, "BIT 3,A" }, + { 0x0060, 0x00ff, ' ', 1, "BIT 4,B" }, + { 0x0061, 0x00ff, ' ', 1, "BIT 4,C" }, + { 0x0062, 0x00ff, ' ', 1, "BIT 4,D" }, + { 0x0063, 0x00ff, ' ', 1, "BIT 4,E" }, + { 0x0064, 0x00ff, ' ', 1, "BIT 4,H" }, + { 0x0065, 0x00ff, ' ', 1, "BIT 4,L" }, + { 0x0066, 0x00ff, ' ', 1, "BIT 4,(HL)" }, + { 0x0067, 0x00ff, ' ', 1, "BIT 4,A" }, + { 0x0068, 0x00ff, ' ', 1, "BIT 5,B" }, + { 0x0069, 0x00ff, ' ', 1, "BIT 5,C" }, + { 0x006A, 0x00ff, ' ', 1, "BIT 5,D" }, + { 0x006B, 0x00ff, ' ', 1, "BIT 5,E" }, + { 0x006C, 0x00ff, ' ', 1, "BIT 5,H" }, + { 0x006D, 0x00ff, ' ', 1, "BIT 5,L" }, + { 0x006E, 0x00ff, ' ', 1, "BIT 5,(HL)" }, + { 0x006F, 0x00ff, ' ', 1, "BIT 5,A" }, + { 0x0070, 0x00ff, ' ', 1, "BIT 6,B" }, + { 0x0071, 0x00ff, ' ', 1, "BIT 6,C" }, + { 0x0072, 0x00ff, ' ', 1, "BIT 6,D" }, + { 0x0073, 0x00ff, ' ', 1, "BIT 6,E" }, + { 0x0074, 0x00ff, ' ', 1, "BIT 6,H" }, + { 0x0075, 0x00ff, ' ', 1, "BIT 6,L" }, + { 0x0076, 0x00ff, ' ', 1, "BIT 6,(HL)" }, + { 0x0077, 0x00ff, ' ', 1, "BIT 6,A" }, + { 0x0078, 0x00ff, ' ', 1, "BIT 7,B" }, + { 0x0079, 0x00ff, ' ', 1, "BIT 7,C" }, + { 0x007A, 0x00ff, ' ', 1, "BIT 7,D" }, + { 0x007B, 0x00ff, ' ', 1, "BIT 7,E" }, + { 0x007C, 0x00ff, ' ', 1, "BIT 7,H" }, + { 0x007D, 0x00ff, ' ', 1, "BIT 7,L" }, + { 0x007E, 0x00ff, ' ', 1, "BIT 7,(HL)" }, + { 0x007F, 0x00ff, ' ', 1, "BIT 7,A" }, + { 0x0080, 0x00ff, ' ', 1, "RES 0,B" }, + { 0x0081, 0x00ff, ' ', 1, "RES 0,C" }, + { 0x0082, 0x00ff, ' ', 1, "RES 0,D" }, + { 0x0083, 0x00ff, ' ', 1, "RES 0,E" }, + { 0x0084, 0x00ff, ' ', 1, "RES 0,H" }, + { 0x0085, 0x00ff, ' ', 1, "RES 0,L" }, + { 0x0086, 0x00ff, ' ', 1, "RES 0,(HL)" }, + { 0x0087, 0x00ff, ' ', 1, "RES 0,A" }, + { 0x0088, 0x00ff, ' ', 1, "RES 1,B" }, + { 0x0089, 0x00ff, ' ', 1, "RES 1,C" }, + { 0x008A, 0x00ff, ' ', 1, "RES 1,D" }, + { 0x008B, 0x00ff, ' ', 1, "RES 1,E" }, + { 0x008C, 0x00ff, ' ', 1, "RES 1,H" }, + { 0x008D, 0x00ff, ' ', 1, "RES 1,L" }, + { 0x008E, 0x00ff, ' ', 1, "RES 1,(HL)" }, + { 0x008F, 0x00ff, ' ', 1, "RES 1,A" }, + { 0x0090, 0x00ff, ' ', 1, "RES 2,B" }, + { 0x0091, 0x00ff, ' ', 1, "RES 2,C" }, + { 0x0092, 0x00ff, ' ', 1, "RES 2,D" }, + { 0x0093, 0x00ff, ' ', 1, "RES 2,E" }, + { 0x0094, 0x00ff, ' ', 1, "RES 2,H" }, + { 0x0095, 0x00ff, ' ', 1, "RES 2,L" }, + { 0x0096, 0x00ff, ' ', 1, "RES 2,(HL)" }, + { 0x0097, 0x00ff, ' ', 1, "RES 2,A" }, + { 0x0098, 0x00ff, ' ', 1, "RES 3,B" }, + { 0x0099, 0x00ff, ' ', 1, "RES 3,C" }, + { 0x009A, 0x00ff, ' ', 1, "RES 3,D" }, + { 0x009B, 0x00ff, ' ', 1, "RES 3,E" }, + { 0x009C, 0x00ff, ' ', 1, "RES 3,H" }, + { 0x009D, 0x00ff, ' ', 1, "RES 3,L" }, + { 0x009E, 0x00ff, ' ', 1, "RES 3,(HL)" }, + { 0x009F, 0x00ff, ' ', 1, "RES 3,A" }, + { 0x00A0, 0x00ff, ' ', 1, "RES 4,B" }, + { 0x00A1, 0x00ff, ' ', 1, "RES 4,C" }, + { 0x00A2, 0x00ff, ' ', 1, "RES 4,D" }, + { 0x00A3, 0x00ff, ' ', 1, "RES 4,E" }, + { 0x00A4, 0x00ff, ' ', 1, "RES 4,H" }, + { 0x00A5, 0x00ff, ' ', 1, "RES 4,L" }, + { 0x00A6, 0x00ff, ' ', 1, "RES 4,(HL)" }, + { 0x00A7, 0x00ff, ' ', 1, "RES 4,A" }, + { 0x00A8, 0x00ff, ' ', 1, "RES 5,B" }, + { 0x00A9, 0x00ff, ' ', 1, "RES 5,C" }, + { 0x00AA, 0x00ff, ' ', 1, "RES 5,D" }, + { 0x00AB, 0x00ff, ' ', 1, "RES 5,E" }, + { 0x00AC, 0x00ff, ' ', 1, "RES 5,H" }, + { 0x00AD, 0x00ff, ' ', 1, "RES 5,L" }, + { 0x00AE, 0x00ff, ' ', 1, "RES 5,(HL)" }, + { 0x00AF, 0x00ff, ' ', 1, "RES 5,A" }, + { 0x00B0, 0x00ff, ' ', 1, "RES 6,B" }, + { 0x00B1, 0x00ff, ' ', 1, "RES 6,C" }, + { 0x00B2, 0x00ff, ' ', 1, "RES 6,D" }, + { 0x00B3, 0x00ff, ' ', 1, "RES 6,E" }, + { 0x00B4, 0x00ff, ' ', 1, "RES 6,H" }, + { 0x00B5, 0x00ff, ' ', 1, "RES 6,L" }, + { 0x00B6, 0x00ff, ' ', 1, "RES 6,(HL)" }, + { 0x00B7, 0x00ff, ' ', 1, "RES 6,A" }, + { 0x00B8, 0x00ff, ' ', 1, "RES 7,B" }, + { 0x00B9, 0x00ff, ' ', 1, "RES 7,C" }, + { 0x00BA, 0x00ff, ' ', 1, "RES 7,D" }, + { 0x00BB, 0x00ff, ' ', 1, "RES 7,E" }, + { 0x00BC, 0x00ff, ' ', 1, "RES 7,H" }, + { 0x00BD, 0x00ff, ' ', 1, "RES 7,L" }, + { 0x00BE, 0x00ff, ' ', 1, "RES 7,(HL)" }, + { 0x00BF, 0x00ff, ' ', 1, "RES 7,A" }, + { 0x00C0, 0x00ff, ' ', 1, "SET 0,B" }, + { 0x00C1, 0x00ff, ' ', 1, "SET 0,C" }, + { 0x00C2, 0x00ff, ' ', 1, "SET 0,D" }, + { 0x00C3, 0x00ff, ' ', 1, "SET 0,E" }, + { 0x00C4, 0x00ff, ' ', 1, "SET 0,H" }, + { 0x00C5, 0x00ff, ' ', 1, "SET 0,L" }, + { 0x00C6, 0x00ff, ' ', 1, "SET 0,(HL)" }, + { 0x00C7, 0x00ff, ' ', 1, "SET 0,A" }, + { 0x00C8, 0x00ff, ' ', 1, "SET 1,B" }, + { 0x00C9, 0x00ff, ' ', 1, "SET 1,C" }, + { 0x00CA, 0x00ff, ' ', 1, "SET 1,D" }, + { 0x00CB, 0x00ff, ' ', 1, "SET 1,E" }, + { 0x00CC, 0x00ff, ' ', 1, "SET 1,H" }, + { 0x00CD, 0x00ff, ' ', 1, "SET 1,L" }, + { 0x00CE, 0x00ff, ' ', 1, "SET 1,(HL)" }, + { 0x00CF, 0x00ff, ' ', 1, "SET 1,A" }, + { 0x00D0, 0x00ff, ' ', 1, "SET 2,B" }, + { 0x00D1, 0x00ff, ' ', 1, "SET 2,C" }, + { 0x00D2, 0x00ff, ' ', 1, "SET 2,D" }, + { 0x00D3, 0x00ff, ' ', 1, "SET 2,E" }, + { 0x00D4, 0x00ff, ' ', 1, "SET 2,H" }, + { 0x00D5, 0x00ff, ' ', 1, "SET 2,L" }, + { 0x00D6, 0x00ff, ' ', 1, "SET 2,(HL)" }, + { 0x00D7, 0x00ff, ' ', 1, "SET 2,A" }, + { 0x00D8, 0x00ff, ' ', 1, "SET 3,B" }, + { 0x00D9, 0x00ff, ' ', 1, "SET 3,C" }, + { 0x00DA, 0x00ff, ' ', 1, "SET 3,D" }, + { 0x00DB, 0x00ff, ' ', 1, "SET 3,E" }, + { 0x00DC, 0x00ff, ' ', 1, "SET 3,H" }, + { 0x00DD, 0x00ff, ' ', 1, "SET 3,L" }, + { 0x00DE, 0x00ff, ' ', 1, "SET 3,(HL)" }, + { 0x00DF, 0x00ff, ' ', 1, "SET 3,A" }, + { 0x00E0, 0x00ff, ' ', 1, "SET 4,B" }, + { 0x00E1, 0x00ff, ' ', 1, "SET 4,C" }, + { 0x00E2, 0x00ff, ' ', 1, "SET 4,D" }, + { 0x00E3, 0x00ff, ' ', 1, "SET 4,E" }, + { 0x00E4, 0x00ff, ' ', 1, "SET 4,H" }, + { 0x00E5, 0x00ff, ' ', 1, "SET 4,L" }, + { 0x00E6, 0x00ff, ' ', 1, "SET 4,(HL)" }, + { 0x00E7, 0x00ff, ' ', 1, "SET 4,A" }, + { 0x00E8, 0x00ff, ' ', 1, "SET 5,B" }, + { 0x00E9, 0x00ff, ' ', 1, "SET 5,C" }, + { 0x00EA, 0x00ff, ' ', 1, "SET 5,D" }, + { 0x00EB, 0x00ff, ' ', 1, "SET 5,E" }, + { 0x00EC, 0x00ff, ' ', 1, "SET 5,H" }, + { 0x00ED, 0x00ff, ' ', 1, "SET 5,L" }, + { 0x00EE, 0x00ff, ' ', 1, "SET 5,(HL)" }, + { 0x00EF, 0x00ff, ' ', 1, "SET 5,A" }, + { 0x00F0, 0x00ff, ' ', 1, "SET 6,B" }, + { 0x00F1, 0x00ff, ' ', 1, "SET 6,C" }, + { 0x00F2, 0x00ff, ' ', 1, "SET 6,D" }, + { 0x00F3, 0x00ff, ' ', 1, "SET 6,E" }, + { 0x00F4, 0x00ff, ' ', 1, "SET 6,H" }, + { 0x00F5, 0x00ff, ' ', 1, "SET 6,L" }, + { 0x00F6, 0x00ff, ' ', 1, "SET 6,(HL)" }, + { 0x00F7, 0x00ff, ' ', 1, "SET 6,A" }, + { 0x00F8, 0x00ff, ' ', 1, "SET 7,B" }, + { 0x00F9, 0x00ff, ' ', 1, "SET 7,C" }, + { 0x00FA, 0x00ff, ' ', 1, "SET 7,D" }, + { 0x00FB, 0x00ff, ' ', 1, "SET 7,E" }, + { 0x00FC, 0x00ff, ' ', 1, "SET 7,H" }, + { 0x00FD, 0x00ff, ' ', 1, "SET 7,L" }, + { 0x00FE, 0x00ff, ' ', 1, "SET 7,(HL)" }, + { 0x00FF, 0x00ff, ' ', 1, "SET 7,A" }, { 0, 0, 0, 0, NULL } }; +struct dis_entry disass_z80_dd[]= { + { 0x0021, 0x00ff, ' ', 3, "LD IX,%w" }, + { 0x0022, 0x00ff, ' ', 3, "LD (%w),IX" }, + { 0x0026, 0x00ff, ' ', 2, "LD HX,%b" }, + { 0x002A, 0x00ff, ' ', 3, "LD IX,(%w)" }, + { 0x002E, 0x00ff, ' ', 2, "LD LX,%b" }, + { 0x0036, 0x00ff, ' ', 3, "LD (IX+%d),%b" }, + { 0x0044, 0x00ff, ' ', 1, "LD B,HX" }, + { 0x0045, 0x00ff, ' ', 1, "LD B,LX" }, + { 0x0046, 0x00ff, ' ', 2, "LD B,(IX+%d)" }, + { 0x004C, 0x00ff, ' ', 1, "LD C,HX" }, + { 0x004D, 0x00ff, ' ', 1, "LD C,LX" }, + { 0x004E, 0x00ff, ' ', 2, "LD C,(IX+%d)" }, + { 0x0054, 0x00ff, ' ', 1, "LD D,HX" }, + { 0x0055, 0x00ff, ' ', 1, "LD D,LX" }, + { 0x0056, 0x00ff, ' ', 2, "LD D,(IX+%d)" }, + { 0x005C, 0x00ff, ' ', 1, "LD E,H" }, + { 0x005D, 0x00ff, ' ', 1, "LD E,L" }, + { 0x005E, 0x00ff, ' ', 2, "LD E,(IX+%d)" }, + { 0x0060, 0x00ff, ' ', 1, "LD HX,B" }, + { 0x0061, 0x00ff, ' ', 1, "LD HX,C" }, + { 0x0062, 0x00ff, ' ', 1, "LD HX,D" }, + { 0x0063, 0x00ff, ' ', 1, "LD HX,E" }, + { 0x0064, 0x00ff, ' ', 1, "LD HX,HX" }, + { 0x0066, 0x00ff, ' ', 2, "LD H,(IX+%d)" }, + { 0x0067, 0x00ff, ' ', 1, "LD HX,A" }, + { 0x0068, 0x00ff, ' ', 1, "LD LX,B" }, + { 0x0069, 0x00ff, ' ', 1, "LD LX,C" }, + { 0x006A, 0x00ff, ' ', 1, "LD LX,D" }, + { 0x006B, 0x00ff, ' ', 1, "LD LX,E" }, + { 0x006C, 0x00ff, ' ', 1, "LD LX,HX" }, + { 0x006D, 0x00ff, ' ', 1, "LD LX,LX" }, + { 0x006E, 0x00ff, ' ', 2, "LD L,(IX+%d)" }, + { 0x006F, 0x00ff, ' ', 1, "LD LX,A" }, + { 0x0070, 0x00ff, ' ', 2, "LD (IX+%d),B" }, + { 0x0071, 0x00ff, ' ', 2, "LD (IX+%d),C" }, + { 0x0072, 0x00ff, ' ', 2, "LD (IX+%d),D" }, + { 0x0073, 0x00ff, ' ', 2, "LD (IX+%d),E" }, + { 0x0074, 0x00ff, ' ', 2, "LD (IX+%d),H" }, + { 0x0075, 0x00ff, ' ', 2, "LD (IX+%d),L" }, + { 0x0077, 0x00ff, ' ', 2, "LD (IX+%d),A" }, + { 0x007C, 0x00ff, ' ', 1, "LD A,HX" }, + { 0x007D, 0x00ff, ' ', 1, "LD A,LX" }, + { 0x007E, 0x00ff, ' ', 2, "LD A,(IX+%d)" }, + { 0x00F9, 0x00ff, ' ', 1, "LD SP,IX" }, + + { 0x0023, 0x00ff, ' ', 1, "INC IX" }, + { 0x0024, 0x00ff, ' ', 1, "INC HX" }, + { 0x002C, 0x00ff, ' ', 1, "INC LX" }, + { 0x0034, 0x00ff, ' ', 2, "INC (IX+%d)" }, + + { 0x0009, 0x00ff, ' ', 1, "ADD IX,BC" }, + { 0x0019, 0x00ff, ' ', 1, "ADD IX,DE" }, + { 0x0029, 0x00ff, ' ', 1, "ADD IX,IX" }, + { 0x0039, 0x00ff, ' ', 1, "ADD IX,SP" }, + { 0x0084, 0x00ff, ' ', 1, "ADD A,HX" }, + { 0x0085, 0x00ff, ' ', 1, "ADD A,LX" }, + { 0x0086, 0x00ff, ' ', 2, "ADD A,(IX+%d)" }, + + { 0x0025, 0x00ff, ' ', 1, "DEC HX" }, + { 0x002B, 0x00ff, ' ', 1, "DEC IX" }, + { 0x002D, 0x00ff, ' ', 1, "DEC LX" }, + { 0x0035, 0x00ff, ' ', 2, "DEC (IX+%d)" }, + + { 0x008C, 0x00ff, ' ', 1, "ADC A,HX" }, + { 0x008D, 0x00ff, ' ', 1, "ADC A,LX" }, + { 0x008E, 0x00ff, ' ', 2, "ADC A,(IX+%d)" }, + { 0x0094, 0x00ff, ' ', 1, "SUB HX" }, + { 0x0095, 0x00ff, ' ', 1, "SUB LX" }, + { 0x0096, 0x00ff, ' ', 2, "SUB (IX+%d)" }, + { 0x009C, 0x00ff, ' ', 1, "SBC A,HX" }, + { 0x009D, 0x00ff, ' ', 1, "SBC A,LX" }, + { 0x009E, 0x00ff, ' ', 2, "SBC A,(IX+%d)" }, + { 0x00A4, 0x00ff, ' ', 1, "AND HX" }, + { 0x00A5, 0x00ff, ' ', 1, "AND LX" }, + { 0x00A6, 0x00ff, ' ', 2, "AND (IX+%d)" }, + { 0x00AC, 0x00ff, ' ', 1, "XOR HX" }, + { 0x00AD, 0x00ff, ' ', 1, "XOR LX" }, + { 0x00AE, 0x00ff, ' ', 2, "XOR (IX+%d)" }, + { 0x00B4, 0x00ff, ' ', 1, "OR HX" }, + { 0x00B5, 0x00ff, ' ', 1, "OR LX" }, + { 0x00B6, 0x00ff, ' ', 2, "OR (IX+%d)" }, + { 0x00BC, 0x00ff, ' ', 1, "CP HX" }, + { 0x00BD, 0x00ff, ' ', 1, "CP LX" }, + { 0x00BE, 0x00ff, ' ', 2, "CP (IX+%d)" }, + { 0x00CB, 0x00ff, ' ', 1, "?cb?" }, + { 0x00E1, 0x00ff, ' ', 1, "POP IX" }, + { 0x00E3, 0x00ff, ' ', 1, "EX (SP),IX" }, + { 0x00E5, 0x00ff, ' ', 1, "PUSH IX" }, + { 0x00E9, 0x00ff, ' ', 1, "JP (IX)" }, + + { 0, 0, 0, 0, NULL } +}; + +struct dis_entry disass_z80_fd[]= { + { 0x0021, 0x00ff, ' ', 3, "LD IY,%w" }, + { 0x0022, 0x00ff, ' ', 3, "LD (%w),IY" }, + { 0x0026, 0x00ff, ' ', 2, "LD HX,%b" }, + { 0x002A, 0x00ff, ' ', 3, "LD IY,(%w)" }, + { 0x002E, 0x00ff, ' ', 2, "LD LX,%b" }, + { 0x0036, 0x00ff, ' ', 3, "LD (IY+%d),%b" }, + { 0x0044, 0x00ff, ' ', 1, "LD B,HX" }, + { 0x0045, 0x00ff, ' ', 1, "LD B,LX" }, + { 0x0046, 0x00ff, ' ', 2, "LD B,(IY+%d)" }, + { 0x004C, 0x00ff, ' ', 1, "LD C,HX" }, + { 0x004D, 0x00ff, ' ', 1, "LD C,LX" }, + { 0x004E, 0x00ff, ' ', 2, "LD C,(IY+%d)" }, + { 0x0054, 0x00ff, ' ', 1, "LD D,HX" }, + { 0x0055, 0x00ff, ' ', 1, "LD D,LX" }, + { 0x0056, 0x00ff, ' ', 2, "LD D,(IY+%d)" }, + { 0x005C, 0x00ff, ' ', 1, "LD E,H" }, + { 0x005D, 0x00ff, ' ', 1, "LD E,L" }, + { 0x005E, 0x00ff, ' ', 2, "LD E,(IY+%d)" }, + { 0x0060, 0x00ff, ' ', 1, "LD HX,B" }, + { 0x0061, 0x00ff, ' ', 1, "LD HX,C" }, + { 0x0062, 0x00ff, ' ', 1, "LD HX,D" }, + { 0x0063, 0x00ff, ' ', 1, "LD HX,E" }, + { 0x0064, 0x00ff, ' ', 1, "LD HX,HX" }, + { 0x0066, 0x00ff, ' ', 2, "LD H,(IY+%d)" }, + { 0x0067, 0x00ff, ' ', 1, "LD HX,A" }, + { 0x0068, 0x00ff, ' ', 1, "LD LX,B" }, + { 0x0069, 0x00ff, ' ', 1, "LD LX,C" }, + { 0x006A, 0x00ff, ' ', 1, "LD LX,D" }, + { 0x006B, 0x00ff, ' ', 1, "LD LX,E" }, + { 0x006C, 0x00ff, ' ', 1, "LD LX,HX" }, + { 0x006D, 0x00ff, ' ', 1, "LD LX,LX" }, + { 0x006E, 0x00ff, ' ', 2, "LD L,(IY+%d)" }, + { 0x006F, 0x00ff, ' ', 1, "LD LX,A" }, + { 0x0070, 0x00ff, ' ', 2, "LD (IY+%d),B" }, + { 0x0071, 0x00ff, ' ', 2, "LD (IY+%d),C" }, + { 0x0072, 0x00ff, ' ', 2, "LD (IY+%d),D" }, + { 0x0073, 0x00ff, ' ', 2, "LD (IY+%d),E" }, + { 0x0074, 0x00ff, ' ', 2, "LD (IY+%d),H" }, + { 0x0075, 0x00ff, ' ', 2, "LD (IY+%d),L" }, + { 0x0077, 0x00ff, ' ', 2, "LD (IY+%d),A" }, + { 0x007C, 0x00ff, ' ', 1, "LD A,HX" }, + { 0x007D, 0x00ff, ' ', 1, "LD A,LX" }, + { 0x007E, 0x00ff, ' ', 2, "LD A,(IY+%d)" }, + { 0x00F9, 0x00ff, ' ', 1, "LD SP,IY" }, + + { 0x0023, 0x00ff, ' ', 1, "INC IY" }, + { 0x0024, 0x00ff, ' ', 1, "INC HX" }, + { 0x002C, 0x00ff, ' ', 1, "INC LX" }, + { 0x0034, 0x00ff, ' ', 2, "INC (IY+%d)" }, + + { 0x0009, 0x00ff, ' ', 1, "ADD IY,BC" }, + { 0x0019, 0x00ff, ' ', 1, "ADD IY,DE" }, + { 0x0029, 0x00ff, ' ', 1, "ADD IY,IY" }, + { 0x0039, 0x00ff, ' ', 1, "ADD IY,SP" }, + { 0x0084, 0x00ff, ' ', 1, "ADD A,HX" }, + { 0x0085, 0x00ff, ' ', 1, "ADD A,LX" }, + { 0x0086, 0x00ff, ' ', 2, "ADD A,(IY+%d)" }, + + { 0x0025, 0x00ff, ' ', 1, "DEC HX" }, + { 0x002B, 0x00ff, ' ', 1, "DEC IY" }, + { 0x002D, 0x00ff, ' ', 1, "DEC LX" }, + { 0x0035, 0x00ff, ' ', 2, "DEC (IY+%d)" }, + + { 0x008C, 0x00ff, ' ', 1, "ADC A,HX" }, + { 0x008D, 0x00ff, ' ', 1, "ADC A,LX" }, + { 0x008E, 0x00ff, ' ', 2, "ADC A,(IY+%d)" }, + { 0x0094, 0x00ff, ' ', 1, "SUB HX" }, + { 0x0095, 0x00ff, ' ', 1, "SUB LX" }, + { 0x0096, 0x00ff, ' ', 2, "SUB (IY+%d)" }, + { 0x009C, 0x00ff, ' ', 1, "SBC A,HX" }, + { 0x009D, 0x00ff, ' ', 1, "SBC A,LX" }, + { 0x009E, 0x00ff, ' ', 2, "SBC A,(IY+%d)" }, + { 0x00A4, 0x00ff, ' ', 1, "AND HX" }, + { 0x00A5, 0x00ff, ' ', 1, "AND LX" }, + { 0x00A6, 0x00ff, ' ', 2, "AND (IY+%d)" }, + { 0x00AC, 0x00ff, ' ', 1, "XOR HX" }, + { 0x00AD, 0x00ff, ' ', 1, "XOR LX" }, + { 0x00AE, 0x00ff, ' ', 2, "XOR (IY+%d)" }, + { 0x00B4, 0x00ff, ' ', 1, "OR HX" }, + { 0x00B5, 0x00ff, ' ', 1, "OR LX" }, + { 0x00B6, 0x00ff, ' ', 2, "OR (IY+%d)" }, + { 0x00BC, 0x00ff, ' ', 1, "CP HX" }, + { 0x00BD, 0x00ff, ' ', 1, "CP LX" }, + { 0x00BE, 0x00ff, ' ', 2, "CP (IY+%d)" }, + { 0x00CB, 0x00ff, ' ', 1, "escape" }, + { 0x00E1, 0x00ff, ' ', 1, "POP IY" }, + { 0x00E3, 0x00ff, ' ', 1, "EX (SP),IY" }, + { 0x00E5, 0x00ff, ' ', 1, "PUSH IY" }, + { 0x00E9, 0x00ff, ' ', 1, "JP (IY)" }, + + { 0, 0, 0, 0, NULL } +}; + + +struct dis_entry disass_z80_ddcb[]= { + { 0x0000, 0x00ff, ' ', 2, "RLC (IX+%d)->B" }, + { 0x0001, 0x00ff, ' ', 2, "RLC (IX+%d)->C" }, + { 0x0002, 0x00ff, ' ', 2, "RLC (IX+%d)->D" }, + { 0x0003, 0x00ff, ' ', 2, "RLC (IX+%d)->E" }, + { 0x0004, 0x00ff, ' ', 2, "RLC (IX+%d)->H" }, + { 0x0005, 0x00ff, ' ', 2, "RLC (IX+%d)->L" }, + { 0x0006, 0x00ff, ' ', 2, "RLC (IX+%d)" }, + { 0x0007, 0x00ff, ' ', 2, "RLC (IX+%d)->A" }, + { 0x0008, 0x00ff, ' ', 2, "RRC (IX+%d)->B" }, + { 0x0009, 0x00ff, ' ', 2, "RRC (IX+%d)->C" }, + { 0x000A, 0x00ff, ' ', 2, "RRC (IX+%d)->D" }, + { 0x000B, 0x00ff, ' ', 2, "RRC (IX+%d)->E" }, + { 0x000C, 0x00ff, ' ', 2, "RRC (IX+%d)->H" }, + { 0x000D, 0x00ff, ' ', 2, "RRC (IX+%d)->L" }, + { 0x000E, 0x00ff, ' ', 2, "RRC (IX+%d)" }, + { 0x000F, 0x00ff, ' ', 2, "RRC (IX+%d)->A" }, + { 0x0010, 0x00ff, ' ', 2, "RL (IX+%d)->B" }, + { 0x0011, 0x00ff, ' ', 2, "RL (IX+%d)->C" }, + { 0x0012, 0x00ff, ' ', 2, "RL (IX+%d)->D" }, + { 0x0013, 0x00ff, ' ', 2, "RL (IX+%d)->E" }, + { 0x0014, 0x00ff, ' ', 2, "RL (IX+%d)->H" }, + { 0x0015, 0x00ff, ' ', 2, "RL (IX+%d)->L" }, + { 0x0016, 0x00ff, ' ', 2, "RL (IX+%d)" }, + { 0x0017, 0x00ff, ' ', 2, "RL (IX+%d)->A" }, + { 0x0018, 0x00ff, ' ', 2, "RR (IX+%d)->B" }, + { 0x0019, 0x00ff, ' ', 2, "RR (IX+%d)->C" }, + { 0x001A, 0x00ff, ' ', 2, "RR (IX+%d)->D" }, + { 0x001B, 0x00ff, ' ', 2, "RR (IX+%d)->E" }, + { 0x001C, 0x00ff, ' ', 2, "RR (IX+%d)->H" }, + { 0x001D, 0x00ff, ' ', 2, "RR (IX+%d)->L" }, + { 0x001E, 0x00ff, ' ', 2, "RR (IX+%d)" }, + { 0x001F, 0x00ff, ' ', 2, "RR (IX+%d)->A" }, + { 0x0020, 0x00ff, ' ', 2, "SLA (IX+%d)->B" }, + { 0x0021, 0x00ff, ' ', 2, "SLA (IX+%d)->C" }, + { 0x0022, 0x00ff, ' ', 2, "SLA (IX+%d)->D" }, + { 0x0023, 0x00ff, ' ', 2, "SLA (IX+%d)->E" }, + { 0x0024, 0x00ff, ' ', 2, "SLA (IX+%d)->H" }, + { 0x0025, 0x00ff, ' ', 2, "SLA (IX+%d)->L" }, + { 0x0026, 0x00ff, ' ', 2, "SLA (IX+%d)" }, + { 0x0027, 0x00ff, ' ', 2, "SLA (IX+%d)->A" }, + { 0x0028, 0x00ff, ' ', 2, "SRA (IX+%d)->B" }, + { 0x0029, 0x00ff, ' ', 2, "SRA (IX+%d)->C" }, + { 0x002A, 0x00ff, ' ', 2, "SRA (IX+%d)->D" }, + { 0x002B, 0x00ff, ' ', 2, "SRA (IX+%d)->E" }, + { 0x002C, 0x00ff, ' ', 2, "SRA (IX+%d)->H" }, + { 0x002D, 0x00ff, ' ', 2, "SRA (IX+%d)->L" }, + { 0x002E, 0x00ff, ' ', 2, "SRA (IX+%d)" }, + { 0x002F, 0x00ff, ' ', 2, "SRA (IX+%d)->A" }, + { 0x0030, 0x00ff, ' ', 2, "SLIA (IX+%d)->B" }, + { 0x0031, 0x00ff, ' ', 2, "SLIA (IX+%d)->C" }, + { 0x0032, 0x00ff, ' ', 2, "SLIA (IX+%d)->D" }, + { 0x0033, 0x00ff, ' ', 2, "SLIA (IX+%d)->E" }, + { 0x0034, 0x00ff, ' ', 2, "SLIA (IX+%d)->H" }, + { 0x0035, 0x00ff, ' ', 2, "SLIA (IX+%d)->L" }, + { 0x0036, 0x00ff, ' ', 2, "SLIA (IX+%d)" }, + { 0x0037, 0x00ff, ' ', 2, "SLIA (IX+%d)->A" }, + { 0x0038, 0x00ff, ' ', 2, "SRL (IX+%d)->B" }, + { 0x0039, 0x00ff, ' ', 2, "SRL (IX+%d)->C" }, + { 0x003A, 0x00ff, ' ', 2, "SRL (IX+%d)->D" }, + { 0x003B, 0x00ff, ' ', 2, "SRL (IX+%d)->E" }, + { 0x003C, 0x00ff, ' ', 2, "SRL (IX+%d)->H" }, + { 0x003D, 0x00ff, ' ', 2, "SRL (IX+%d)->L" }, + { 0x003E, 0x00ff, ' ', 2, "SRL (IX+%d)" }, + { 0x003F, 0x00ff, ' ', 2, "SRL A" }, + { 0x0040, 0x00ff, ' ', 2, "BIT (IX+%d)->0,B" }, + { 0x0041, 0x00ff, ' ', 2, "BIT (IX+%d)->0,C" }, + { 0x0042, 0x00ff, ' ', 2, "BIT (IX+%d)->0,D" }, + { 0x0043, 0x00ff, ' ', 2, "BIT (IX+%d)->0,E" }, + { 0x0044, 0x00ff, ' ', 2, "BIT (IX+%d)->0,H" }, + { 0x0045, 0x00ff, ' ', 2, "BIT (IX+%d)->0,L" }, + { 0x0046, 0x00ff, ' ', 2, "BIT 0,(IX+%d)" }, + { 0x004E, 0x00ff, ' ', 2, "BIT 1,(IX+%d)" }, + { 0x0056, 0x00ff, ' ', 2, "BIT 2,(IX+%d)" }, + { 0x005E, 0x00ff, ' ', 2, "BIT 3,(IX+%d)" }, + { 0x0066, 0x00ff, ' ', 2, "BIT 4,(IX+%d)" }, + { 0x006E, 0x00ff, ' ', 2, "BIT 5,(IX+%d)" }, + { 0x0076, 0x00ff, ' ', 2, "BIT 6,(IX+%d)" }, + { 0x007E, 0x00ff, ' ', 2, "BIT 7,(IX+%d)" }, + { 0x0080, 0x00ff, ' ', 2, "RES 0,(IX+%d)->B" }, + { 0x0081, 0x00ff, ' ', 2, "RES 0,(IX+%d)->C" }, + { 0x0082, 0x00ff, ' ', 2, "RES 0,(IX+%d)->D" }, + { 0x0083, 0x00ff, ' ', 2, "RES 0,(IX+%d)->E" }, + { 0x0084, 0x00ff, ' ', 2, "RES 0,(IX+%d)->H" }, + { 0x0085, 0x00ff, ' ', 2, "RES 0,(IX+%d)->L" }, + { 0x0086, 0x00ff, ' ', 2, "RES 0,(IX+%d)" }, + { 0x0087, 0x00ff, ' ', 2, "RES 0,(IX+%d)->A" }, + { 0x0088, 0x00ff, ' ', 2, "RES 1,(IX+%d)->B" }, + { 0x0089, 0x00ff, ' ', 2, "RES 1,(IX+%d)->C" }, + { 0x008A, 0x00ff, ' ', 2, "RES 1,(IX+%d)->D" }, + { 0x008B, 0x00ff, ' ', 2, "RES 1,(IX+%d)->E" }, + { 0x008C, 0x00ff, ' ', 2, "RES 1,(IX+%d)->H" }, + { 0x008D, 0x00ff, ' ', 2, "RES 1,(IX+%d)->L" }, + { 0x008E, 0x00ff, ' ', 2, "RES 1,(IX+%d)" }, + { 0x008F, 0x00ff, ' ', 2, "RES 1,(IX+%d)->A" }, + { 0x0090, 0x00ff, ' ', 2, "RES 2,(IX+%d)->B" }, + { 0x0091, 0x00ff, ' ', 2, "RES 2,(IX+%d)->C" }, + { 0x0092, 0x00ff, ' ', 2, "RES 2,(IX+%d)->D" }, + { 0x0093, 0x00ff, ' ', 2, "RES 2,(IX+%d)->E" }, + { 0x0094, 0x00ff, ' ', 2, "RES 2,(IX+%d)->H" }, + { 0x0095, 0x00ff, ' ', 2, "RES 2,(IX+%d)->L" }, + { 0x0096, 0x00ff, ' ', 2, "RES 2,(IX+%d)" }, + { 0x0097, 0x00ff, ' ', 2, "RES 2,(IX+%d)->A" }, + { 0x0098, 0x00ff, ' ', 2, "RES 3,(IX+%d)->B" }, + { 0x0099, 0x00ff, ' ', 2, "RES 3,(IX+%d)->C" }, + { 0x009A, 0x00ff, ' ', 2, "RES 3,(IX+%d)->D" }, + { 0x009B, 0x00ff, ' ', 2, "RES 3,(IX+%d)->E" }, + { 0x009C, 0x00ff, ' ', 2, "RES 3,(IX+%d)->H" }, + { 0x009D, 0x00ff, ' ', 2, "RES 3,(IX+%d)->L" }, + { 0x009E, 0x00ff, ' ', 2, "RES 3,(IX+%d)" }, + { 0x009F, 0x00ff, ' ', 2, "RES 3,(IX+%d)->A" }, + { 0x00A0, 0x00ff, ' ', 2, "RES 4,(IX+%d)->B" }, + { 0x00A1, 0x00ff, ' ', 2, "RES 4,(IX+%d)->C" }, + { 0x00A2, 0x00ff, ' ', 2, "RES 4,(IX+%d)->D" }, + { 0x00A3, 0x00ff, ' ', 2, "RES 4,(IX+%d)->E" }, + { 0x00A4, 0x00ff, ' ', 2, "RES 4,(IX+%d)->H" }, + { 0x00A5, 0x00ff, ' ', 2, "RES 4,(IX+%d)->L" }, + { 0x00A6, 0x00ff, ' ', 2, "RES 4,(IX+%d)" }, + { 0x00A7, 0x00ff, ' ', 2, "RES 4,(IX+%d)->A" }, + { 0x00A8, 0x00ff, ' ', 2, "RES 5,(IX+%d)->B" }, + { 0x00A9, 0x00ff, ' ', 2, "RES 5,(IX+%d)->C" }, + { 0x00AA, 0x00ff, ' ', 2, "RES 5,(IX+%d)->D" }, + { 0x00AB, 0x00ff, ' ', 2, "RES 5,(IX+%d)->E" }, + { 0x00AC, 0x00ff, ' ', 2, "RES 5,(IX+%d)->H" }, + { 0x00AD, 0x00ff, ' ', 2, "RES 5,(IX+%d)->L" }, + { 0x00AE, 0x00ff, ' ', 2, "RES 5,(IX+%d)" }, + { 0x00AF, 0x00ff, ' ', 2, "RES 5,(IX+%d)->A" }, + { 0x00B0, 0x00ff, ' ', 2, "RES 6,(IX+%d)->B" }, + { 0x00B1, 0x00ff, ' ', 2, "RES 6,(IX+%d)->C" }, + { 0x00B2, 0x00ff, ' ', 2, "RES 6,(IX+%d)->D" }, + { 0x00B3, 0x00ff, ' ', 2, "RES 6,(IX+%d)->E" }, + { 0x00B4, 0x00ff, ' ', 2, "RES 6,(IX+%d)->H" }, + { 0x00B5, 0x00ff, ' ', 2, "RES 6,(IX+%d)->L" }, + { 0x00B6, 0x00ff, ' ', 2, "RES 6,(IX+%d)" }, + { 0x00B7, 0x00ff, ' ', 2, "RES 6,(IX+%d)->A" }, + { 0x00B8, 0x00ff, ' ', 2, "RES 7,(IX+%d)->B" }, + { 0x00B9, 0x00ff, ' ', 2, "RES 7,(IX+%d)->C" }, + { 0x00BA, 0x00ff, ' ', 2, "RES 7,(IX+%d)->D" }, + { 0x00BB, 0x00ff, ' ', 2, "RES 7,(IX+%d)->E" }, + { 0x00BC, 0x00ff, ' ', 2, "RES 7,(IX+%d)->H" }, + { 0x00BD, 0x00ff, ' ', 2, "RES 7,(IX+%d)->L" }, + { 0x00BE, 0x00ff, ' ', 2, "RES 7,(IX+%d)" }, + { 0x00BF, 0x00ff, ' ', 2, "RES 7,(IX+%d)->A" }, + { 0x00C0, 0x00ff, ' ', 2, "SET 0,(IX+%d)->B" }, + { 0x00C1, 0x00ff, ' ', 2, "SET 0,(IX+%d)->C" }, + { 0x00C2, 0x00ff, ' ', 2, "SET 0,(IX+%d)->D" }, + { 0x00C3, 0x00ff, ' ', 2, "SET 0,(IX+%d)->E" }, + { 0x00C4, 0x00ff, ' ', 2, "SET 0,(IX+%d)->H" }, + { 0x00C5, 0x00ff, ' ', 2, "SET 0,(IX+%d)->L" }, + { 0x00C6, 0x00ff, ' ', 2, "SET 0,(IX+%d)" }, + { 0x00C7, 0x00ff, ' ', 2, "SET 0,(IX+%d)->A" }, + { 0x00C8, 0x00ff, ' ', 2, "SET 1,(IX+%d)->B" }, + { 0x00C9, 0x00ff, ' ', 2, "SET 1,(IX+%d)->C" }, + { 0x00CA, 0x00ff, ' ', 2, "SET 1,(IX+%d)->D" }, + { 0x00CB, 0x00ff, ' ', 2, "SET 1,(IX+%d)->E" }, + { 0x00CC, 0x00ff, ' ', 2, "SET 1,(IX+%d)->H" }, + { 0x00CD, 0x00ff, ' ', 2, "SET 1,(IX+%d)->L" }, + { 0x00CE, 0x00ff, ' ', 2, "SET 1,(IX+%d)" }, + { 0x00CF, 0x00ff, ' ', 2, "SET 1,(IX+%d)->A" }, + { 0x00D0, 0x00ff, ' ', 2, "SET 2,(IX+%d)->B" }, + { 0x00D1, 0x00ff, ' ', 2, "SET 2,(IX+%d)->C" }, + { 0x00D2, 0x00ff, ' ', 2, "SET 2,(IX+%d)->D" }, + { 0x00D3, 0x00ff, ' ', 2, "SET 2,(IX+%d)->E" }, + { 0x00D4, 0x00ff, ' ', 2, "SET 2,(IX+%d)->H" }, + { 0x00D5, 0x00ff, ' ', 2, "SET 2,(IX+%d)->L" }, + { 0x00D6, 0x00ff, ' ', 2, "SET 2,(IX+%d)" }, + { 0x00D7, 0x00ff, ' ', 2, "SET 2,(IX+%d)->A" }, + { 0x00D8, 0x00ff, ' ', 2, "SET 3,(IX+%d)->B" }, + { 0x00D9, 0x00ff, ' ', 2, "SET 3,(IX+%d)->C" }, + { 0x00DA, 0x00ff, ' ', 2, "SET 3,(IX+%d)->D" }, + { 0x00DB, 0x00ff, ' ', 2, "SET 3,(IX+%d)->E" }, + { 0x00DC, 0x00ff, ' ', 2, "SET 3,(IX+%d)->H" }, + { 0x00DD, 0x00ff, ' ', 2, "SET 3,(IX+%d)->L" }, + { 0x00DE, 0x00ff, ' ', 2, "SET 3,(IX+%d)" }, + { 0x00DF, 0x00ff, ' ', 2, "SET 3,(IX+%d)->A" }, + { 0x00E0, 0x00ff, ' ', 2, "SET 4,(IX+%d)->B" }, + { 0x00E1, 0x00ff, ' ', 2, "SET 4,(IX+%d)->C" }, + { 0x00E2, 0x00ff, ' ', 2, "SET 4,(IX+%d)->D" }, + { 0x00E3, 0x00ff, ' ', 2, "SET 4,(IX+%d)->E" }, + { 0x00E4, 0x00ff, ' ', 2, "SET 4,(IX+%d)->H" }, + { 0x00E5, 0x00ff, ' ', 2, "SET 4,(IX+%d)->L" }, + { 0x00E6, 0x00ff, ' ', 2, "SET 4,(IX+%d)" }, + { 0x00E7, 0x00ff, ' ', 2, "SET 4,(IX+%d)->A" }, + { 0x00E8, 0x00ff, ' ', 2, "SET 5,(IX+%d)->B" }, + { 0x00E9, 0x00ff, ' ', 2, "SET 5,(IX+%d)->C" }, + { 0x00EA, 0x00ff, ' ', 2, "SET 5,(IX+%d)->D" }, + { 0x00EB, 0x00ff, ' ', 2, "SET 5,(IX+%d)->E" }, + { 0x00EC, 0x00ff, ' ', 2, "SET 5,(IX+%d)->H" }, + { 0x00ED, 0x00ff, ' ', 2, "SET 5,(IX+%d)->L" }, + { 0x00EE, 0x00ff, ' ', 2, "SET 5,(IX+%d)" }, + { 0x00EF, 0x00ff, ' ', 2, "SET 5,(IX+%d)->A" }, + { 0x00F0, 0x00ff, ' ', 2, "SET 6,(IX+%d)->B" }, + { 0x00F1, 0x00ff, ' ', 2, "SET 6,(IX+%d)->C" }, + { 0x00F2, 0x00ff, ' ', 2, "SET 6,(IX+%d)->D" }, + { 0x00F3, 0x00ff, ' ', 2, "SET 6,(IX+%d)->E" }, + { 0x00F4, 0x00ff, ' ', 2, "SET 6,(IX+%d)->H" }, + { 0x00F5, 0x00ff, ' ', 2, "SET 6,(IX+%d)->L" }, + { 0x00F6, 0x00ff, ' ', 2, "SET 6,(IX+%d)" }, + { 0x00F7, 0x00ff, ' ', 2, "SET 6,(IX+%d)->A" }, + { 0x00F8, 0x00ff, ' ', 2, "SET 7,(IX+%d)->B" }, + { 0x00F9, 0x00ff, ' ', 2, "SET 7,(IX+%d)->C" }, + { 0x00FA, 0x00ff, ' ', 2, "SET 7,(IX+%d)->D" }, + { 0x00FB, 0x00ff, ' ', 2, "SET 7,(IX+%d)->E" }, + { 0x00FC, 0x00ff, ' ', 2, "SET 7,(IX+%d)->H" }, + { 0x00FD, 0x00ff, ' ', 2, "SET 7,(IX+%d)->L" }, + { 0x00FE, 0x00ff, ' ', 2, "SET 7,(IX+%d)" }, + { 0x00FF, 0x00ff, ' ', 2, "SET 7,(IX+%d)->A" }, + { 0, 0, 0, 0, NULL } +}; + +struct dis_entry disass_z80_fdcb[]= { + { 0x0000, 0x00ff, ' ', 2, "RLC (IY+%d)->B" }, + { 0x0001, 0x00ff, ' ', 2, "RLC (IY+%d)->C" }, + { 0x0002, 0x00ff, ' ', 2, "RLC (IY+%d)->D" }, + { 0x0003, 0x00ff, ' ', 2, "RLC (IY+%d)->E" }, + { 0x0004, 0x00ff, ' ', 2, "RLC (IY+%d)->H" }, + { 0x0005, 0x00ff, ' ', 2, "RLC (IY+%d)->L" }, + { 0x0006, 0x00ff, ' ', 2, "RLC (IY+%d)" }, + { 0x0007, 0x00ff, ' ', 2, "RLC (IY+%d)->A" }, + { 0x0008, 0x00ff, ' ', 2, "RRC (IY+%d)->B" }, + { 0x0009, 0x00ff, ' ', 2, "RRC (IY+%d)->C" }, + { 0x000A, 0x00ff, ' ', 2, "RRC (IY+%d)->D" }, + { 0x000B, 0x00ff, ' ', 2, "RRC (IY+%d)->E" }, + { 0x000C, 0x00ff, ' ', 2, "RRC (IY+%d)->H" }, + { 0x000D, 0x00ff, ' ', 2, "RRC (IY+%d)->L" }, + { 0x000E, 0x00ff, ' ', 2, "RRC (IY+%d)" }, + { 0x000F, 0x00ff, ' ', 2, "RRC (IY+%d)->A" }, + { 0x0010, 0x00ff, ' ', 2, "RL (IY+%d)->B" }, + { 0x0011, 0x00ff, ' ', 2, "RL (IY+%d)->C" }, + { 0x0012, 0x00ff, ' ', 2, "RL (IY+%d)->D" }, + { 0x0013, 0x00ff, ' ', 2, "RL (IY+%d)->E" }, + { 0x0014, 0x00ff, ' ', 2, "RL (IY+%d)->H" }, + { 0x0015, 0x00ff, ' ', 2, "RL (IY+%d)->L" }, + { 0x0016, 0x00ff, ' ', 2, "RL (IY+%d)" }, + { 0x0017, 0x00ff, ' ', 2, "RL (IY+%d)->A" }, + { 0x0018, 0x00ff, ' ', 2, "RR (IY+%d)->B" }, + { 0x0019, 0x00ff, ' ', 2, "RR (IY+%d)->C" }, + { 0x001A, 0x00ff, ' ', 2, "RR (IY+%d)->D" }, + { 0x001B, 0x00ff, ' ', 2, "RR (IY+%d)->E" }, + { 0x001C, 0x00ff, ' ', 2, "RR (IY+%d)->H" }, + { 0x001D, 0x00ff, ' ', 2, "RR (IY+%d)->L" }, + { 0x001E, 0x00ff, ' ', 2, "RR (IY+%d)" }, + { 0x001F, 0x00ff, ' ', 2, "RR (IY+%d)->A" }, + { 0x0020, 0x00ff, ' ', 2, "SLA (IY+%d)->B" }, + { 0x0021, 0x00ff, ' ', 2, "SLA (IY+%d)->C" }, + { 0x0022, 0x00ff, ' ', 2, "SLA (IY+%d)->D" }, + { 0x0023, 0x00ff, ' ', 2, "SLA (IY+%d)->E" }, + { 0x0024, 0x00ff, ' ', 2, "SLA (IY+%d)->H" }, + { 0x0025, 0x00ff, ' ', 2, "SLA (IY+%d)->L" }, + { 0x0026, 0x00ff, ' ', 2, "SLA (IY+%d)" }, + { 0x0027, 0x00ff, ' ', 2, "SLA (IY+%d)->A" }, + { 0x0028, 0x00ff, ' ', 2, "SRA (IY+%d)->B" }, + { 0x0029, 0x00ff, ' ', 2, "SRA (IY+%d)->C" }, + { 0x002A, 0x00ff, ' ', 2, "SRA (IY+%d)->D" }, + { 0x002B, 0x00ff, ' ', 2, "SRA (IY+%d)->E" }, + { 0x002C, 0x00ff, ' ', 2, "SRA (IY+%d)->H" }, + { 0x002D, 0x00ff, ' ', 2, "SRA (IY+%d)->L" }, + { 0x002E, 0x00ff, ' ', 2, "SRA (IY+%d)" }, + { 0x002F, 0x00ff, ' ', 2, "SRA (IY+%d)->A" }, + { 0x0030, 0x00ff, ' ', 2, "SLIA (IY+%d)->B" }, + { 0x0031, 0x00ff, ' ', 2, "SLIA (IY+%d)->C" }, + { 0x0032, 0x00ff, ' ', 2, "SLIA (IY+%d)->D" }, + { 0x0033, 0x00ff, ' ', 2, "SLIA (IY+%d)->E" }, + { 0x0034, 0x00ff, ' ', 2, "SLIA (IY+%d)->H" }, + { 0x0035, 0x00ff, ' ', 2, "SLIA (IY+%d)->L" }, + { 0x0036, 0x00ff, ' ', 2, "SLIA (IY+%d)" }, + { 0x0037, 0x00ff, ' ', 2, "SLIA (IY+%d)->A" }, + { 0x0038, 0x00ff, ' ', 2, "SRL (IY+%d)->B" }, + { 0x0039, 0x00ff, ' ', 2, "SRL (IY+%d)->C" }, + { 0x003A, 0x00ff, ' ', 2, "SRL (IY+%d)->D" }, + { 0x003B, 0x00ff, ' ', 2, "SRL (IY+%d)->E" }, + { 0x003C, 0x00ff, ' ', 2, "SRL (IY+%d)->H" }, + { 0x003D, 0x00ff, ' ', 2, "SRL (IY+%d)->L" }, + { 0x003E, 0x00ff, ' ', 2, "SRL (IY+%d)" }, + { 0x003F, 0x00ff, ' ', 2, "SRL A" }, + { 0x0040, 0x00ff, ' ', 2, "BIT (IY+%d)->0,B" }, + { 0x0041, 0x00ff, ' ', 2, "BIT (IY+%d)->0,C" }, + { 0x0042, 0x00ff, ' ', 2, "BIT (IY+%d)->0,D" }, + { 0x0043, 0x00ff, ' ', 2, "BIT (IY+%d)->0,E" }, + { 0x0044, 0x00ff, ' ', 2, "BIT (IY+%d)->0,H" }, + { 0x0045, 0x00ff, ' ', 2, "BIT (IY+%d)->0,L" }, + { 0x0046, 0x00ff, ' ', 2, "BIT 0,(IY+%d)" }, + { 0x004E, 0x00ff, ' ', 2, "BIT 1,(IY+%d)" }, + { 0x0056, 0x00ff, ' ', 2, "BIT 2,(IY+%d)" }, + { 0x005E, 0x00ff, ' ', 2, "BIT 3,(IY+%d)" }, + { 0x0066, 0x00ff, ' ', 2, "BIT 4,(IY+%d)" }, + { 0x006E, 0x00ff, ' ', 2, "BIT 5,(IY+%d)" }, + { 0x0076, 0x00ff, ' ', 2, "BIT 6,(IY+%d)" }, + { 0x007E, 0x00ff, ' ', 2, "BIT 7,(IY+%d)" }, + { 0x0080, 0x00ff, ' ', 2, "RES 0,(IY+%d)->B" }, + { 0x0081, 0x00ff, ' ', 2, "RES 0,(IY+%d)->C" }, + { 0x0082, 0x00ff, ' ', 2, "RES 0,(IY+%d)->D" }, + { 0x0083, 0x00ff, ' ', 2, "RES 0,(IY+%d)->E" }, + { 0x0084, 0x00ff, ' ', 2, "RES 0,(IY+%d)->H" }, + { 0x0085, 0x00ff, ' ', 2, "RES 0,(IY+%d)->L" }, + { 0x0086, 0x00ff, ' ', 2, "RES 0,(IY+%d)" }, + { 0x0087, 0x00ff, ' ', 2, "RES 0,(IY+%d)->A" }, + { 0x0088, 0x00ff, ' ', 2, "RES 1,(IY+%d)->B" }, + { 0x0089, 0x00ff, ' ', 2, "RES 1,(IY+%d)->C" }, + { 0x008A, 0x00ff, ' ', 2, "RES 1,(IY+%d)->D" }, + { 0x008B, 0x00ff, ' ', 2, "RES 1,(IY+%d)->E" }, + { 0x008C, 0x00ff, ' ', 2, "RES 1,(IY+%d)->H" }, + { 0x008D, 0x00ff, ' ', 2, "RES 1,(IY+%d)->L" }, + { 0x008E, 0x00ff, ' ', 2, "RES 1,(IY+%d)" }, + { 0x008F, 0x00ff, ' ', 2, "RES 1,(IY+%d)->A" }, + { 0x0090, 0x00ff, ' ', 2, "RES 2,(IY+%d)->B" }, + { 0x0091, 0x00ff, ' ', 2, "RES 2,(IY+%d)->C" }, + { 0x0092, 0x00ff, ' ', 2, "RES 2,(IY+%d)->D" }, + { 0x0093, 0x00ff, ' ', 2, "RES 2,(IY+%d)->E" }, + { 0x0094, 0x00ff, ' ', 2, "RES 2,(IY+%d)->H" }, + { 0x0095, 0x00ff, ' ', 2, "RES 2,(IY+%d)->L" }, + { 0x0096, 0x00ff, ' ', 2, "RES 2,(IY+%d)" }, + { 0x0097, 0x00ff, ' ', 2, "RES 2,(IY+%d)->A" }, + { 0x0098, 0x00ff, ' ', 2, "RES 3,(IY+%d)->B" }, + { 0x0099, 0x00ff, ' ', 2, "RES 3,(IY+%d)->C" }, + { 0x009A, 0x00ff, ' ', 2, "RES 3,(IY+%d)->D" }, + { 0x009B, 0x00ff, ' ', 2, "RES 3,(IY+%d)->E" }, + { 0x009C, 0x00ff, ' ', 2, "RES 3,(IY+%d)->H" }, + { 0x009D, 0x00ff, ' ', 2, "RES 3,(IY+%d)->L" }, + { 0x009E, 0x00ff, ' ', 2, "RES 3,(IY+%d)" }, + { 0x009F, 0x00ff, ' ', 2, "RES 3,(IY+%d)->A" }, + { 0x00A0, 0x00ff, ' ', 2, "RES 4,(IY+%d)->B" }, + { 0x00A1, 0x00ff, ' ', 2, "RES 4,(IY+%d)->C" }, + { 0x00A2, 0x00ff, ' ', 2, "RES 4,(IY+%d)->D" }, + { 0x00A3, 0x00ff, ' ', 2, "RES 4,(IY+%d)->E" }, + { 0x00A4, 0x00ff, ' ', 2, "RES 4,(IY+%d)->H" }, + { 0x00A5, 0x00ff, ' ', 2, "RES 4,(IY+%d)->L" }, + { 0x00A6, 0x00ff, ' ', 2, "RES 4,(IY+%d)" }, + { 0x00A7, 0x00ff, ' ', 2, "RES 4,(IY+%d)->A" }, + { 0x00A8, 0x00ff, ' ', 2, "RES 5,(IY+%d)->B" }, + { 0x00A9, 0x00ff, ' ', 2, "RES 5,(IY+%d)->C" }, + { 0x00AA, 0x00ff, ' ', 2, "RES 5,(IY+%d)->D" }, + { 0x00AB, 0x00ff, ' ', 2, "RES 5,(IY+%d)->E" }, + { 0x00AC, 0x00ff, ' ', 2, "RES 5,(IY+%d)->H" }, + { 0x00AD, 0x00ff, ' ', 2, "RES 5,(IY+%d)->L" }, + { 0x00AE, 0x00ff, ' ', 2, "RES 5,(IY+%d)" }, + { 0x00AF, 0x00ff, ' ', 2, "RES 5,(IY+%d)->A" }, + { 0x00B0, 0x00ff, ' ', 2, "RES 6,(IY+%d)->B" }, + { 0x00B1, 0x00ff, ' ', 2, "RES 6,(IY+%d)->C" }, + { 0x00B2, 0x00ff, ' ', 2, "RES 6,(IY+%d)->D" }, + { 0x00B3, 0x00ff, ' ', 2, "RES 6,(IY+%d)->E" }, + { 0x00B4, 0x00ff, ' ', 2, "RES 6,(IY+%d)->H" }, + { 0x00B5, 0x00ff, ' ', 2, "RES 6,(IY+%d)->L" }, + { 0x00B6, 0x00ff, ' ', 2, "RES 6,(IY+%d)" }, + { 0x00B7, 0x00ff, ' ', 2, "RES 6,(IY+%d)->A" }, + { 0x00B8, 0x00ff, ' ', 2, "RES 7,(IY+%d)->B" }, + { 0x00B9, 0x00ff, ' ', 2, "RES 7,(IY+%d)->C" }, + { 0x00BA, 0x00ff, ' ', 2, "RES 7,(IY+%d)->D" }, + { 0x00BB, 0x00ff, ' ', 2, "RES 7,(IY+%d)->E" }, + { 0x00BC, 0x00ff, ' ', 2, "RES 7,(IY+%d)->H" }, + { 0x00BD, 0x00ff, ' ', 2, "RES 7,(IY+%d)->L" }, + { 0x00BE, 0x00ff, ' ', 2, "RES 7,(IY+%d)" }, + { 0x00BF, 0x00ff, ' ', 2, "RES 7,(IY+%d)->A" }, + { 0x00C0, 0x00ff, ' ', 2, "SET 0,(IY+%d)->B" }, + { 0x00C1, 0x00ff, ' ', 2, "SET 0,(IY+%d)->C" }, + { 0x00C2, 0x00ff, ' ', 2, "SET 0,(IY+%d)->D" }, + { 0x00C3, 0x00ff, ' ', 2, "SET 0,(IY+%d)->E" }, + { 0x00C4, 0x00ff, ' ', 2, "SET 0,(IY+%d)->H" }, + { 0x00C5, 0x00ff, ' ', 2, "SET 0,(IY+%d)->L" }, + { 0x00C6, 0x00ff, ' ', 2, "SET 0,(IY+%d)" }, + { 0x00C7, 0x00ff, ' ', 2, "SET 0,(IY+%d)->A" }, + { 0x00C8, 0x00ff, ' ', 2, "SET 1,(IY+%d)->B" }, + { 0x00C9, 0x00ff, ' ', 2, "SET 1,(IY+%d)->C" }, + { 0x00CA, 0x00ff, ' ', 2, "SET 1,(IY+%d)->D" }, + { 0x00CB, 0x00ff, ' ', 2, "SET 1,(IY+%d)->E" }, + { 0x00CC, 0x00ff, ' ', 2, "SET 1,(IY+%d)->H" }, + { 0x00CD, 0x00ff, ' ', 2, "SET 1,(IY+%d)->L" }, + { 0x00CE, 0x00ff, ' ', 2, "SET 1,(IY+%d)" }, + { 0x00CF, 0x00ff, ' ', 2, "SET 1,(IY+%d)->A" }, + { 0x00D0, 0x00ff, ' ', 2, "SET 2,(IY+%d)->B" }, + { 0x00D1, 0x00ff, ' ', 2, "SET 2,(IY+%d)->C" }, + { 0x00D2, 0x00ff, ' ', 2, "SET 2,(IY+%d)->D" }, + { 0x00D3, 0x00ff, ' ', 2, "SET 2,(IY+%d)->E" }, + { 0x00D4, 0x00ff, ' ', 2, "SET 2,(IY+%d)->H" }, + { 0x00D5, 0x00ff, ' ', 2, "SET 2,(IY+%d)->L" }, + { 0x00D6, 0x00ff, ' ', 2, "SET 2,(IY+%d)" }, + { 0x00D7, 0x00ff, ' ', 2, "SET 2,(IY+%d)->A" }, + { 0x00D8, 0x00ff, ' ', 2, "SET 3,(IY+%d)->B" }, + { 0x00D9, 0x00ff, ' ', 2, "SET 3,(IY+%d)->C" }, + { 0x00DA, 0x00ff, ' ', 2, "SET 3,(IY+%d)->D" }, + { 0x00DB, 0x00ff, ' ', 2, "SET 3,(IY+%d)->E" }, + { 0x00DC, 0x00ff, ' ', 2, "SET 3,(IY+%d)->H" }, + { 0x00DD, 0x00ff, ' ', 2, "SET 3,(IY+%d)->L" }, + { 0x00DE, 0x00ff, ' ', 2, "SET 3,(IY+%d)" }, + { 0x00DF, 0x00ff, ' ', 2, "SET 3,(IY+%d)->A" }, + { 0x00E0, 0x00ff, ' ', 2, "SET 4,(IY+%d)->B" }, + { 0x00E1, 0x00ff, ' ', 2, "SET 4,(IY+%d)->C" }, + { 0x00E2, 0x00ff, ' ', 2, "SET 4,(IY+%d)->D" }, + { 0x00E3, 0x00ff, ' ', 2, "SET 4,(IY+%d)->E" }, + { 0x00E4, 0x00ff, ' ', 2, "SET 4,(IY+%d)->H" }, + { 0x00E5, 0x00ff, ' ', 2, "SET 4,(IY+%d)->L" }, + { 0x00E6, 0x00ff, ' ', 2, "SET 4,(IY+%d)" }, + { 0x00E7, 0x00ff, ' ', 2, "SET 4,(IY+%d)->A" }, + { 0x00E8, 0x00ff, ' ', 2, "SET 5,(IY+%d)->B" }, + { 0x00E9, 0x00ff, ' ', 2, "SET 5,(IY+%d)->C" }, + { 0x00EA, 0x00ff, ' ', 2, "SET 5,(IY+%d)->D" }, + { 0x00EB, 0x00ff, ' ', 2, "SET 5,(IY+%d)->E" }, + { 0x00EC, 0x00ff, ' ', 2, "SET 5,(IY+%d)->H" }, + { 0x00ED, 0x00ff, ' ', 2, "SET 5,(IY+%d)->L" }, + { 0x00EE, 0x00ff, ' ', 2, "SET 5,(IY+%d)" }, + { 0x00EF, 0x00ff, ' ', 2, "SET 5,(IY+%d)->A" }, + { 0x00F0, 0x00ff, ' ', 2, "SET 6,(IY+%d)->B" }, + { 0x00F1, 0x00ff, ' ', 2, "SET 6,(IY+%d)->C" }, + { 0x00F2, 0x00ff, ' ', 2, "SET 6,(IY+%d)->D" }, + { 0x00F3, 0x00ff, ' ', 2, "SET 6,(IY+%d)->E" }, + { 0x00F4, 0x00ff, ' ', 2, "SET 6,(IY+%d)->H" }, + { 0x00F5, 0x00ff, ' ', 2, "SET 6,(IY+%d)->L" }, + { 0x00F6, 0x00ff, ' ', 2, "SET 6,(IY+%d)" }, + { 0x00F7, 0x00ff, ' ', 2, "SET 6,(IY+%d)->A" }, + { 0x00F8, 0x00ff, ' ', 2, "SET 7,(IY+%d)->B" }, + { 0x00F9, 0x00ff, ' ', 2, "SET 7,(IY+%d)->C" }, + { 0x00FA, 0x00ff, ' ', 2, "SET 7,(IY+%d)->D" }, + { 0x00FB, 0x00ff, ' ', 2, "SET 7,(IY+%d)->E" }, + { 0x00FC, 0x00ff, ' ', 2, "SET 7,(IY+%d)->H" }, + { 0x00FD, 0x00ff, ' ', 2, "SET 7,(IY+%d)->L" }, + { 0x00FE, 0x00ff, ' ', 2, "SET 7,(IY+%d)" }, + { 0x00FF, 0x00ff, ' ', 2, "SET 7,(IY+%d)->A" }, + { 0, 0, 0, 0, NULL } +}; -/* End of z80.src/glob.cc */ +/* glob.cc */ diff --git a/sim/ucsim/z80.src/glob.h b/sim/ucsim/z80.src/glob.h index 99564021..5bfd9ff6 100644 --- a/sim/ucsim/z80.src/glob.h +++ b/sim/ucsim/z80.src/glob.h @@ -33,6 +33,13 @@ Software Foundation, 59 Temple Place - Suite 330, Boston, MA extern struct dis_entry disass_z80[]; +extern struct dis_entry disass_z80_ed[]; +extern struct dis_entry disass_z80_cb[]; +extern struct dis_entry disass_z80_dd[]; +extern struct dis_entry disass_z80_fd[]; +extern struct dis_entry disass_z80_ddcb[]; +extern struct dis_entry disass_z80_fdcb[]; + #endif diff --git a/sim/ucsim/z80.src/inst.cc b/sim/ucsim/z80.src/inst.cc index fc1befe5..e3f24b51 100644 --- a/sim/ucsim/z80.src/inst.cc +++ b/sim/ucsim/z80.src/inst.cc @@ -1,6 +1,8 @@ /* * Simulator of microcontrollers (inst.cc) * + * some z80 code base from Karl Bongers karl@turbobit.com + * * Copyright (C) 1999,99 Drotos Daniel, Talker Bt. * * To contact author send email to drdani@mazsola.iit.uni-miskolc.hu @@ -30,6 +32,7 @@ Software Foundation, 59 Temple Place - Suite 330, Boston, MA // local #include "z80cl.h" #include "regsz80.h" +#include "z80mac.h" /* @@ -40,10 +43,1317 @@ Software Foundation, 59 Temple Place - Suite 330, Boston, MA */ int -cl_z80::nop(t_mem code) +cl_z80::inst_nop(t_mem code) +{ + return(resGO); +} + +/* + * Load Instruction + * LD + * + *---------------------------------------------------------------------------- + */ + +int +cl_z80::inst_ld(t_mem code) +{ + switch(code) { + case 1: // LD BC,nnnn + regs.BC = fetch2(); + break; + case 2: // LD (BC),A + store1(regs.BC, regs.A); + break; + case 6: // LD B,nn + regs.bc.h = fetch(); + break; + case 0xa: // LD A,(BC) + regs.A = get1(regs.BC); + break; + case 0x0e: // LD C,nn + regs.bc.l = fetch(); + break; + case 0x11: // LD DE,nnnn + regs.DE = fetch2(); + break; + case 0x12: // LD (DE),A + store1(regs.DE, regs.A); + break; + case 0x16: // LD D,nn + regs.de.h = fetch(); + break; + case 0x1A: // LD A,(DE) + regs.A = get1(regs.DE); + break; + case 0x1E: // LD E,nn + regs.de.l = fetch(); + break; + case 0x21: // LD HL,nnnn + regs.HL = fetch2(); + break; + case 0x22: // LD (nnnn),HL + { + unsigned short tw; + tw = fetch2(); + store2(tw, regs.HL); + } + break; + case 0x26: // LD H,nn + regs.hl.h = fetch(); + break; + case 0x2A: // LD HL,(nnnn) + { + unsigned short tw; + tw = fetch2(); + regs.HL = get2(tw); + } + break; + case 0x2E: // LD L,nn + regs.hl.l = fetch(); + break; + case 0x31: // LD SP,nnnn + regs.SP = fetch2(); + break; + case 0x32: // LD (nnnn),A + { + unsigned short tw; + tw = fetch2(); + store1(tw, regs.A); + } + break; + case 0x36: // LD (HL),nn + store1(regs.HL, fetch()); + break; + case 0x3A: // LD A,(nnnn) + regs.A = get1(fetch2()); + break; + case 0x3E: // LD A,nn + regs.A = fetch(); + break; + case 0x40: // LD B,B + break; + case 0x41: // LD B,C + regs.bc.h = regs.bc.l; + break; + case 0x42: // LD B,D + regs.bc.h = regs.de.h; + break; + case 0x43: // LD B,E + regs.bc.h = regs.de.l; + break; + case 0x44: // LD B,H + regs.bc.h = regs.hl.h; + break; + case 0x45: // LD B,L + regs.bc.h = regs.hl.l; + break; + case 0x46: // LD B,(HL) + regs.bc.h = get1(regs.HL); + break; + case 0x47: // LD B,A + regs.bc.h = regs.A; + break; + case 0x48: // LD C,B + regs.bc.l = regs.bc.h; + break; + case 0x49: // LD C,C + break; + case 0x4A: // LD C,D + regs.bc.l = regs.de.h; + break; + case 0x4B: // LD C,E + regs.bc.l = regs.de.l; + break; + case 0x4C: // LD C,H + regs.bc.l = regs.hl.h; + break; + case 0x4D: // LD C,L + regs.bc.l = regs.hl.l; + break; + case 0x4E: // LD C,(HL) + regs.bc.l = get1(regs.HL); + break; + case 0x4F: // LD C,A + regs.bc.l = regs.A; + break; + case 0x50: // LD D,B + regs.de.h = regs.bc.h; + break; + case 0x51: // LD D,C + regs.de.h = regs.bc.l; + break; + case 0x52: // LD D,D + break; + case 0x53: // LD D,E + regs.de.h = regs.de.l; + break; + case 0x54: // LD D,H + regs.de.h = regs.hl.h; + break; + case 0x55: // LD D,L + regs.de.h = regs.hl.l; + break; + case 0x56: // LD D,(HL) + regs.de.h = get1(regs.HL); + break; + case 0x57: // LD D,A + regs.de.h = regs.A; + break; + case 0x58: // LD E,B + regs.de.l = regs.bc.h; + break; + case 0x59: // LD E,C + regs.de.l = regs.bc.l; + break; + case 0x5A: // LD E,D + regs.de.l = regs.de.h; + break; + case 0x5B: // LD E,E + break; + case 0x5C: // LD E,H + regs.de.l = regs.hl.h; + break; + case 0x5D: // LD E,L + regs.de.l = regs.hl.l; + break; + case 0x5E: // LD E,(HL) + regs.de.l = get1(regs.HL); + break; + case 0x5F: // LD E,A + regs.de.l = regs.A; + break; + case 0x60: // LD H,B + regs.hl.h = regs.bc.h; + break; + case 0x61: // LD H,C + regs.hl.h = regs.bc.l; + break; + case 0x62: // LD H,D + regs.hl.h = regs.de.h; + break; + case 0x63: // LD H,E + regs.hl.h = regs.de.l; + break; + case 0x64: // LD H,H + regs.hl.h = regs.hl.h; + break; + case 0x65: // LD H,L + regs.hl.h = regs.hl.l; + break; + case 0x66: // LD H,(HL) + regs.hl.h = get1(regs.HL); + break; + case 0x67: // LD H,A + regs.hl.h = regs.A; + break; + case 0x68: // LD L,B + regs.hl.l = regs.bc.h; + break; + case 0x69: // LD L,C + regs.hl.l = regs.bc.l; + break; + case 0x6A: // LD L,D + regs.hl.l = regs.de.h; + break; + case 0x6B: // LD L,E + regs.hl.l = regs.de.l; + break; + case 0x6C: // LD L,H + regs.hl.l = regs.hl.h; + break; + case 0x6D: // LD L,L + break; + case 0x6E: // LD L,(HL) + regs.hl.l = get1(regs.HL); + break; + case 0x6F: // LD L,A + regs.hl.l = regs.A; + break; + case 0x70: // LD (HL),B + store1(regs.HL, regs.bc.h); + break; + case 0x71: // LD (HL),C + store1(regs.HL, regs.bc.l); + break; + case 0x72: // LD (HL),D + store1(regs.HL, regs.de.h); + break; + case 0x73: // LD (HL),E + store1(regs.HL, regs.de.l); + break; + case 0x74: // LD (HL),H + store1(regs.HL, regs.hl.h); + break; + case 0x75: // LD (HL),L + store1(regs.HL, regs.hl.l); + break; + case 0x76: // HALT + return(resHALT); + + case 0x77: // LD (HL),A + store1(regs.HL, regs.A); + break; + case 0x78: // LD A,B + regs.A = regs.bc.h; + break; + case 0x79: // LD A,C + regs.A = regs.bc.l; + break; + case 0x7A: // LD A,D + regs.A = regs.de.h; + break; + case 0x7B: // LD A,E + regs.A = regs.de.l; + break; + case 0x7C: // LD A,H + regs.A = regs.hl.h; + break; + case 0x7D: // LD A,L + regs.A = regs.hl.l; + break; + case 0x7E: // LD A,(HL) + regs.A = get1(regs.HL); + break; + case 0x7F: // LD A,A + break; + case 0xF9: // LD SP,HL + regs.SP = regs.HL; + break; + default: + return(resINV_INST); + break; + } + return(resGO); +} + +int +cl_z80::inst_inc(t_mem code) +{ + switch(code) { + case 0x03: // INC BC + ++regs.BC; + break; + case 0x04: // INC B + inc(regs.bc.h); + break; + case 0x0C: // INC C + inc(regs.bc.l); + break; + case 0x13: // INC DE + ++regs.DE; + break; + case 0x14: // INC D + inc(regs.de.h); + break; + case 0x1C: // INC E + inc(regs.de.l); + break; + case 0x23: // INC HL + ++regs.HL; + break; + case 0x24: // INC H + inc(regs.hl.h); + break; + case 0x2C: // INC L + inc(regs.hl.l); + break; + case 0x33: // INC SP + ++regs.SP; + break; + case 0x34: // INC (HL) + {unsigned char t=get1(regs.HL); + inc(t); + store1(regs.HL, t); + } + break; + case 0x3C: // INC A + inc(regs.A); + break; + default: + return(resINV_INST); + break; + } + return(resGO); +} + +int +cl_z80::inst_dec(t_mem code) +{ + switch(code) { + case 0x05: // DEC B + dec(regs.bc.h); + break; + case 0x0B: // DEC BC + --regs.BC; + break; + case 0x0D: // DEC C + dec(regs.bc.l); + break; + case 0x15: // DEC D + dec(regs.de.h); + break; + case 0x1B: // DEC DE + --regs.DE; + break; + case 0x1D: // DEC E + dec(regs.de.l); + break; + case 0x25: // DEC H + dec(regs.hl.h); + break; + case 0x2B: // DEC HL + --regs.HL; + break; + case 0x2D: // DEC L + dec(regs.hl.l); + break; + case 0x35: // DEC (HL) + {unsigned char t=get1(regs.HL); + dec(t); + store1(regs.HL, t); + } + break; + case 0x3B: // DEC SP + --regs.SP; + break; + case 0x3D: // DEC A + dec(regs.A); + break; + default: + return(resINV_INST); + break; + } + return(resGO); +} + +int +cl_z80::inst_rlca(t_mem code) +{ + rlc_byte(regs.A); + + return(resGO); +} + +int +cl_z80::inst_rrca(t_mem code) +{ + rrc_byte(regs.A); + return(resGO); +} + +int +cl_z80::inst_ex(t_mem code) +{ + /* 0x08 // EX AF,AF' */ + unsigned char tmp; + TYPE_UWORD tempw; + + switch (code) { + case 0x08: // EX AF,AF' + tmp = regs.aA; + regs.aA = regs.A; + regs.A = tmp; + + tmp = regs.aF; + regs.aF = regs.F; + regs.F = tmp; + break; + + case 0xE3: // EX (SP),HL + tempw = regs.HL; + regs.HL = get2(regs.SP); + store2(regs.SP, tempw); + break; + + case 0xEB: // EX DE,HL + tempw = regs.DE; + regs.DE = regs.HL; + regs.HL = tempw; + break; + + default: + return(resINV_INST); + break; + } + + return(resGO); +} + +int +cl_z80::inst_add(t_mem code) +{ +#define add_HL_Word(wr) { \ + unsigned int tmp; \ + regs.F &= ~(BIT_ALL); /* clear these */ \ + tmp = (unsigned int)regs.HL + (unsigned int)(wr); \ + if (tmp > 0xffff) regs.F |= BIT_C; \ + regs.HL = (unsigned short) tmp; } + + switch(code) { + case 0x09: // ADD HL,BC + add_HL_Word(regs.BC); + break; + case 0x19: // ADD HL,DE + add_HL_Word(regs.DE); + break; + case 0x29: // ADD HL,HL + add_HL_Word(regs.HL); + break; + case 0x39: // ADD HL,SP + add_HL_Word(regs.SP); + break; + + case 0x80: // ADD A,B + add_A_bytereg(regs.bc.h); + break; + case 0x81: // ADD A,C + add_A_bytereg(regs.bc.l); + break; + case 0x82: // ADD A,D + add_A_bytereg(regs.de.h); + break; + case 0x83: // ADD A,E + add_A_bytereg(regs.de.l); + break; + case 0x84: // ADD A,H + add_A_bytereg(regs.hl.h); + break; + case 0x85: // ADD A,L + add_A_bytereg(regs.hl.l); + break; + + case 0x86: // ADD A,(HL) + { unsigned char utmp; + utmp = get1(regs.HL); + add_A_bytereg(utmp); + } + break; + + case 0x87: // ADD A,A + add_A_bytereg(regs.A); + break; + + case 0xC6: // ADD A,nn + { + unsigned char utmp1; + utmp1 = fetch(); + add_A_bytereg(utmp1); + } + break; + + default: + return(resINV_INST); + break; + } + + return(resGO); +} + +int +cl_z80::inst_djnz(t_mem code) +{ + signed char j; + + // 0x10: DJNZ dd + + j = fetch1(); + if ((--regs.bc.h != 0)) { + PC += j; + } else { + } + return(resGO); +} + +int +cl_z80::inst_rra(t_mem code) +{ + rr_byte(regs.A); + return(resGO); +} + +int +cl_z80::inst_rla(t_mem code) +{ + rl_byte(regs.A); + return(resGO); +} + +int +cl_z80::inst_jr(t_mem code) +{ + signed char j; + + j = fetch1(); + switch(code) { + case 0x18: // JR dd + PC += j; + break; + case 0x20: // JR NZ,dd + if (!(regs.F & BIT_Z)) { + PC += j; + } + break; + case 0x28: // JR Z,dd + if ((regs.F & BIT_Z)) { + PC += j; + } + break; + case 0x30: // JR NC,dd + if (!(regs.F & BIT_C)) { + PC += j; + } + break; + case 0x38: // JR C,dd + if ((regs.F & BIT_C)) { + PC += j; + } + break; + default: + return(resINV_INST); + break; + } + return(resGO); +} + +int +cl_z80::inst_daa(t_mem code) +{ + /************* from MH's z80ops.c: + unsigned char incr=0, carry=cy; + if((f&0x10) || (a&0x0f)>9) incr=6; + if((f&1) || (a>>4)>9) incr|=0x60; + if(f&2)suba(incr,0); + else { + if(a>0x90 && (a&15)>9)incr|=0x60; + adda(incr,0); + } + f=((f|carry)&0xfb); + ********/ + /* I have not tried to understand this archaic bit of BCD logic(kpb), + taking the lazy way out for now and just transcribing MH's code. + */ + unsigned char incr; + if ((regs.F & BIT_A) || ((regs.A & 0x0f) > 9)) + incr = 6; + else incr = 0; + + if ((regs.F & BIT_C) || ((regs.A & 0xf0) > 0x90)) + incr |= 0x60; + + if (regs.F & BIT_N) { /* not addition */ + sub_A_bytereg(incr); + } else { + if ((regs.A > 0x90) && ((regs.A & 0x0f) >9)) incr |= 0x60; + add_A_bytereg(incr); + } + + return(resGO); +} + +int +cl_z80::inst_cpl(t_mem code) +{ + regs.F |= (BIT_A | BIT_N); + regs.A = ~regs.A; + return(resGO); +} + +int +cl_z80::inst_scf(t_mem code) +{ + /* Set Carry Flag */ + regs.F |= BIT_C; + return(resGO); +} + +int +cl_z80::inst_ccf(t_mem code) +{ + /* Compliment Carry Flag */ + regs.F ^= BIT_C; + return(resGO); +} + +int +cl_z80::inst_halt(t_mem code) +{ + return(resHALT); +} + +int +cl_z80::inst_adc(t_mem code) +{ + switch(code) { + case 0x88: // ADC A,B + adc_A_bytereg(regs.bc.h); + break; + case 0x89: // ADC A,C + adc_A_bytereg(regs.bc.l); + break; + case 0x8A: // ADC A,D + adc_A_bytereg(regs.de.h); + break; + case 0x8B: // ADC A,E + adc_A_bytereg(regs.de.l); + break; + case 0x8C: // ADC A,H + adc_A_bytereg(regs.hl.h); + break; + case 0x8D: // ADC A,L + adc_A_bytereg(regs.hl.l); + break; + case 0x8E: // ADC A,(HL) + { unsigned char utmp; + utmp = get1(regs.HL); + adc_A_bytereg(utmp); + } + break; + case 0x8F: // ADC A,A + adc_A_bytereg(regs.A); + break; + + case 0xCE: // ADC A,nn + { unsigned char utmp; + utmp = fetch(); + adc_A_bytereg(utmp); + } + break; + + default: + return(resINV_INST); + break; + } + return(resGO); +} + +int +cl_z80::inst_sbc(t_mem code) +{ + switch(code) { + case 0x98: // SBC A,B + sbc_A_bytereg(regs.bc.h); + break; + case 0x99: // SBC A,C + sbc_A_bytereg(regs.bc.l); + break; + case 0x9A: // SBC A,D + sbc_A_bytereg(regs.de.h); + break; + case 0x9B: // SBC A,E + sbc_A_bytereg(regs.de.l); + break; + case 0x9C: // SBC A,H + sbc_A_bytereg(regs.hl.h); + break; + case 0x9D: // SBC A,L + sbc_A_bytereg(regs.hl.l); + break; + case 0x9E: // SBC A,(HL) + { unsigned char utmp; + utmp = get1(regs.HL); + sbc_A_bytereg(utmp); + } + break; + case 0x9F: // SBC A,A + sbc_A_bytereg(regs.A); + break; + case 0xDE: // SBC A,nn + { unsigned char utmp; + utmp = fetch(); + sbc_A_bytereg(utmp); + } + break; + default: + return(resINV_INST); + break; + } + return(resGO); +} + +int +cl_z80::inst_and(t_mem code) +{ + switch(code) { + case 0xA0: // AND B + and_A_bytereg(regs.bc.h); + break; + case 0xA1: // AND C + and_A_bytereg(regs.bc.l); + break; + case 0xA2: // AND D + and_A_bytereg(regs.de.h); + break; + case 0xA3: // AND E + and_A_bytereg(regs.de.l); + break; + case 0xA4: // AND H + and_A_bytereg(regs.hl.h); + break; + case 0xA5: // AND L + and_A_bytereg(regs.hl.l); + break; + case 0xA6: // AND (HL) + { unsigned char utmp; + utmp = get1(regs.HL); + and_A_bytereg(utmp); + } + break; + case 0xA7: // AND A + and_A_bytereg(regs.A); + break; + case 0xE6: // AND nn + and_A_bytereg(fetch()); + break; + + default: + return(resINV_INST); + break; + } + return(resGO); +} + +int +cl_z80::inst_xor(t_mem code) +{ + switch(code) { + case 0xA8: // XOR B + xor_A_bytereg(regs.bc.h); + break; + case 0xA9: // XOR C + xor_A_bytereg(regs.bc.l); + break; + case 0xAA: // XOR D + xor_A_bytereg(regs.de.h); + break; + case 0xAB: // XOR E + xor_A_bytereg(regs.de.l); + break; + case 0xAC: // XOR H + xor_A_bytereg(regs.hl.h); + break; + case 0xAD: // XOR L + xor_A_bytereg(regs.hl.l); + break; + case 0xAE: // XOR (HL) + { unsigned char utmp; + utmp = get1(regs.HL); + xor_A_bytereg(utmp); + } + break; + case 0xAF: // XOR A + xor_A_bytereg(regs.A); + break; + case 0xEE: // XOR nn + xor_A_bytereg(fetch()); + break; + + default: + return(resINV_INST); + break; + } + return(resGO); +} + +int +cl_z80::inst_or(t_mem code) +{ + switch(code) { + case 0xB0: // OR B + or_A_bytereg(regs.bc.h); + break; + case 0xB1: // OR C + or_A_bytereg(regs.bc.l); + break; + case 0xB2: // OR D + or_A_bytereg(regs.de.h); + break; + case 0xB3: // OR E + or_A_bytereg(regs.de.l); + break; + case 0xB4: // OR H + or_A_bytereg(regs.hl.h); + break; + case 0xB5: // OR L + or_A_bytereg(regs.hl.l); + break; + case 0xB6: // OR (HL) + { unsigned char utmp; + utmp = get1(regs.HL); + or_A_bytereg(utmp); + } + break; + case 0xB7: // OR A + or_A_bytereg(regs.A); + break; + case 0xF6: // OR nn + or_A_bytereg(fetch()); + break; + default: + return(resINV_INST); + break; + } + return(resGO); +} + +int +cl_z80::inst_cp(t_mem code) +{ + /* Compare with Accumulator - subtract and test, leave A unchanged */ + switch(code) { + case 0xB8: // CP B + cp_bytereg(regs.bc.h); + break; + case 0xB9: // CP C + cp_bytereg(regs.bc.l); + break; + case 0xBA: // CP D + cp_bytereg(regs.de.h); + break; + case 0xBB: // CP E + cp_bytereg(regs.de.l); + break; + case 0xBC: // CP H + cp_bytereg(regs.hl.h); + break; + case 0xBD: // CP L + cp_bytereg(regs.hl.l); + break; + case 0xBE: // CP (HL) + { unsigned char utmp; + utmp = get1(regs.HL); + cp_bytereg(utmp); + } + break; + case 0xBF: // CP A + cp_bytereg(regs.A); + break; + case 0xFE: // CP nn + { unsigned char utmp; + utmp = fetch(); + cp_bytereg(utmp); + } + break; + default: + return(resINV_INST); + break; + } + return(resGO); +} + +int +cl_z80::inst_rst(t_mem code) +{ + switch(code) { + case 0xC7: // RST 0 + push2(PC+2); + PC = 0x0; + break; + case 0xCF: // RST 8 + //PC = 0x08; + switch (regs.A) { + case 0: + ::exit(0); + break; + + case 1: + //printf("PUTCHAR-----> %xH\n", regs.hl.l); + putchar(regs.hl.l); + fflush(stdout); + break; + } + break; + case 0xD7: // RST 10H + push2(PC+2); + PC = 0x10; + break; + case 0xDF: // RST 18H + push2(PC+2); + PC = 0x18; + break; + case 0xE7: // RST 20H + push2(PC+2); + PC = 0x20; + break; + case 0xEF: // RST 28H + push2(PC+2); + PC = 0x28; + break; + case 0xF7: // RST 30H + push2(PC+2); + PC = 0x30; + break; + case 0xFF: // RST 38H + push2(PC+2); + PC = 0x38; + break; + default: + return(resINV_INST); + break; + } + return(resGO); +} + +int +cl_z80::inst_ret(t_mem code) +{ + switch(code) { + case 0xC0: // RET NZ + if (!(regs.F & BIT_Z)) { + pop2(PC); + } + break; + case 0xC8: // RET Z + if ((regs.F & BIT_Z)) { + pop2(PC); + } + break; + case 0xC9: // RET + pop2(PC); + break; + case 0xD0: // RET NC + if (!(regs.F & BIT_C)) { + pop2(PC); + } + break; + case 0xD8: // RET C + if ((regs.F & BIT_C)) { + pop2(PC); + } + break; + case 0xE0: // RET PO + if (!(regs.F & BIT_P)) { + pop2(PC); + } + break; + case 0xE8: // RET PE + if ((regs.F & BIT_P)) { + pop2(PC); + } + break; + case 0xF0: // RET P + if (!(regs.F & BIT_S)) { + pop2(PC); + } + break; + case 0xF8: // RET M + if ((regs.F & BIT_S)) { + pop2(PC); + } + break; + default: + return(resINV_INST); + break; + } + return(resGO); +} + +int +cl_z80::inst_call(t_mem code) +{ + int jnk; + + switch(code) { + case 0xC4: // CALL NZ,nnnn + if (!(regs.F & BIT_Z)) { + push2(PC+2); + PC = fetch2(); + } else { + jnk = fetch2(); + } + break; + case 0xCC: // CALL Z,nnnn + if (regs.F & BIT_Z) { + push2(PC+2); + PC = fetch2(); + } else { + jnk = fetch2(); + } + break; + case 0xCD: // CALL nnnn + push2(PC+2); + PC = fetch2(); + break; + case 0xD4: // CALL NC,nnnn + if (!(regs.F & BIT_C)) { + push2(PC+2); + PC = fetch2(); + } else { + jnk = fetch2(); + } + break; + case 0xDC: // CALL C,nnnn + if (regs.F & BIT_C) { + push2(PC+2); + PC = fetch2(); + } else { + jnk = fetch2(); + } + break; + case 0xE4: // CALL PO,nnnn + if (!(regs.F & BIT_P)) { + push2(PC+2); + PC = fetch2(); + } else { + jnk = fetch2(); + } + break; + case 0xEC: // CALL PE,nnnn + if (regs.F & BIT_P) { + push2(PC+2); + PC = fetch2(); + } else { + jnk = fetch2(); + } + break; + case 0xF4: // CALL P,nnnn + if (!(regs.F & BIT_S)) { + push2(PC+2); + PC = fetch2(); + } else { + jnk = fetch2(); + } + break; + case 0xFC: // CALL M,nnnn + if (regs.F & BIT_S) { + push2(PC+2); + PC = fetch2(); + } else { + jnk = fetch2(); + } + break; + default: + return(resINV_INST); + break; + } + + return(resGO); +} + +int +cl_z80::inst_out(t_mem code) +{ + return(resGO); +} + +int +cl_z80::inst_push(t_mem code) +{ + switch(code) { + case 0xC5: // PUSH BC + push2(regs.BC); + break; + case 0xD5: // PUSH DE + push2(regs.DE); + break; + case 0xE5: // PUSH HL + push2(regs.HL); + break; + case 0xF5: // PUSH AF + push1(regs.A); + push1(regs.F); + break; + default: + return(resINV_INST); + break; + } + return(resGO); +} + +int +cl_z80::inst_exx(t_mem code) +{ + /* case 0xD9: // EXX - swap BC,DE,HL with alternates */ + TYPE_UWORD tempw; + + tempw = regs.aBC; + regs.BC = regs.aBC; + regs.aBC = tempw; + + tempw = regs.aDE; + regs.DE = regs.aDE; + regs.aDE = tempw; + + tempw = regs.aDE; + regs.DE = regs.aDE; + regs.aDE = tempw; + + return(resGO); +} + +int +cl_z80::inst_in(t_mem code) +{ + return(resGO); +} + +int +cl_z80::inst_sub(t_mem code) +{ + switch(code) { + case 0x90: // SUB B + sub_A_bytereg(regs.bc.h); + break; + case 0x91: // SUB C + sub_A_bytereg(regs.bc.l); + break; + case 0x92: // SUB D + sub_A_bytereg(regs.de.h); + break; + case 0x93: // SUB E + sub_A_bytereg(regs.de.l); + break; + case 0x94: // SUB H + sub_A_bytereg(regs.hl.h); + break; + case 0x95: // SUB L + sub_A_bytereg(regs.hl.l); + break; + case 0x96: // SUB (HL) + { unsigned char tmp1; + tmp1 = get1(regs.HL); + sub_A_bytereg(tmp1); + } + break; + case 0x97: // SUB A + regs.A = 0; + break; + case 0xD6: // SUB nn + { unsigned char tmp1; + tmp1 = fetch(); + sub_A_bytereg(tmp1); + } + break; + default: + return(resINV_INST); + break; + } + return(resGO); +} + +int +cl_z80::inst_pop(t_mem code) { + switch (code) { + case 0xC1: // POP BC + regs.BC = get2(regs.SP); + regs.SP+=2; + break; + case 0xD1: // POP DE + regs.DE = get2(regs.SP); + regs.SP+=2; + break; + case 0xE1: // POP HL + regs.HL = get2(regs.SP); + regs.SP+=2; + break; + case 0xF1: // POP AF + regs.A = get1(regs.SP++); + regs.F = get1(regs.SP++); + break; + default: + return(resINV_INST); + break; + } return(resGO); } +int +cl_z80::inst_jp(t_mem code) +{ + int jnk; + + switch (code) { + case 0xC2: // JP NZ,nnnn + if (!(regs.F & BIT_Z)) { + PC = fetch2(); + } else { + jnk = fetch2(); + } + break; + + case 0xC3: // JP nnnn + PC = fetch2(); + break; + + case 0xCA: // JP Z,nnnn + if (regs.F & BIT_Z) { + PC = fetch2(); + } else { + jnk = fetch2(); + } + break; + + case 0xD2: // JP NC,nnnn + if (!(regs.F & BIT_C)) { + PC = fetch2(); + } else { + jnk = fetch2(); + } + break; + + case 0xDA: // JP C,nnnn + if (regs.F & BIT_C) { + PC = fetch2(); + } else { + jnk = fetch2(); + } + break; + + case 0xE2: // JP PO,nnnn + if (regs.F & BIT_P) { + PC = fetch2(); + } else { + jnk = fetch2(); + } + break; + + case 0xE9: // JP (HL) + PC = regs.HL; + break; + + case 0xea: // JP PO,nnnn + if (!(regs.F & BIT_P)) { + PC = fetch2(); + } else { + jnk = fetch2(); + } + break; + + case 0xF2: // JP P,nnnn (positive) + if (!(regs.F & BIT_S)) { + PC = fetch2(); + } else { + jnk = fetch2(); + } + break; + + case 0xfa: // JP M,nnnn (sign negative) + if (regs.F & BIT_S) { + PC = fetch2(); + } else { + jnk = fetch2(); + } + break; + default: + return(resINV_INST); + break; + } + return(resGO); +} + +int +cl_z80::inst_di(t_mem code) +{ + /* disable interrupts */ + return(resGO); +} + +int +cl_z80::inst_ei(t_mem code) +{ + /* enable interrupts */ + return(resGO); +} /* End of z80.src/inst.cc */ diff --git a/sim/ucsim/z80.src/inst_cb.cc b/sim/ucsim/z80.src/inst_cb.cc new file mode 100644 index 00000000..6c9aa410 --- /dev/null +++ b/sim/ucsim/z80.src/inst_cb.cc @@ -0,0 +1,704 @@ +/* + * Simulator of microcontrollers (inst.cc) + * + * Copyright (C) 1999,99 Drotos Daniel, Talker Bt. + * + * To contact author send email to drdani@mazsola.iit.uni-miskolc.hu + * + */ + +/* This file is part of microcontroller simulator: ucsim. + +UCSIM is free software; you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation; either version 2 of the License, or +(at your option) any later version. + +UCSIM is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU General Public License for more details. + +You should have received a copy of the GNU General Public License +along with UCSIM; see the file COPYING. If not, write to the Free +Software Foundation, 59 Temple Place - Suite 330, Boston, MA +02111-1307, USA. */ +/*@1@*/ + +#include "ddconfig.h" + +// local +#include "z80cl.h" +#include "regsz80.h" +#include "z80mac.h" + +int +cl_z80::inst_cb_rlc(t_mem code) +{ + switch(code) { + case 0x00: // RLC B + rlc_byte(regs.bc.h); + break; + case 0x01: // RLC C + rlc_byte(regs.bc.l); + break; + case 0x02: // RLC D + rlc_byte(regs.de.h); + break; + case 0x03: // RLC E + rlc_byte(regs.de.l); + break; + case 0x04: // RLC H + rlc_byte(regs.hl.h); + break; + case 0x05: // RLC L + rlc_byte(regs.hl.l); + break; + case 0x06: // RLC (HL) + { unsigned char tmp; + tmp = get1(regs.HL); + rlc_byte(tmp); + store1(regs.HL, tmp); + } + break; + case 0x07: // RLC A + rlc_byte(regs.A); + break; + } + return(resGO); +} + +int +cl_z80::inst_cb_rrc(t_mem code) +{ + switch(code) { + case 0x08: // RRC B + rrc_byte(regs.bc.h); + break; + case 0x09: // RRC C + rrc_byte(regs.bc.l); + break; + case 0x0A: // RRC D + rrc_byte(regs.de.h); + break; + case 0x0B: // RRC E + rrc_byte(regs.de.l); + break; + case 0x0C: // RRC H + rrc_byte(regs.hl.h); + break; + case 0x0D: // RRC L + rrc_byte(regs.hl.l); + break; + case 0x0E: // RRC (HL) + { unsigned char tmp; + tmp = get1(regs.HL); + rrc_byte(tmp); + store1(regs.HL, tmp); + } + break; + case 0x0F: // RRC A + rrc_byte(regs.A); + break; + } + return(resGO); +} + +int +cl_z80::inst_cb_rl(t_mem code) +{ + switch(code) { + case 0x10: // RL B + rl_byte(regs.bc.h); + break; + case 0x11: // RL C + rl_byte(regs.bc.l); + break; + case 0x12: // RL D + rl_byte(regs.de.h); + break; + case 0x13: // RL E + rl_byte(regs.de.l); + break; + case 0x14: // RL H + rl_byte(regs.hl.h); + break; + case 0x15: // RL L + rl_byte(regs.hl.l); + break; + case 0x16: // RL (HL) + { unsigned char tmp; + tmp = get1(regs.HL); + rl_byte(tmp); + store1(regs.HL, tmp); + } + break; + case 0x17: // RL A + rl_byte(regs.A); + break; + } + return(resGO); +} + +int +cl_z80::inst_cb_rr(t_mem code) +{ + switch(code) { + case 0x18: // RR B + rr_byte(regs.bc.h); + break; + case 0x19: // RR C + rr_byte(regs.bc.l); + break; + case 0x1A: // RR D + rr_byte(regs.de.h); + break; + case 0x1B: // RR E + rr_byte(regs.de.l); + break; + case 0x1C: // RR H + rr_byte(regs.hl.h); + break; + case 0x1D: // RR L + rr_byte(regs.hl.l); + break; + case 0x1E: // RR (HL) + { unsigned char tmp; + tmp = get1(regs.HL); + rr_byte(tmp); + store1(regs.HL, tmp); + } + break; + case 0x1F: // RR A + rr_byte(regs.A); + break; + } + return(resGO); +} + +int +cl_z80::inst_cb_sla(t_mem code) +{ + switch(code) { + case 0x20: // SLA B + sla_byte(regs.bc.h); + break; + case 0x21: // SLA C + sla_byte(regs.bc.l); + break; + case 0x22: // SLA D + sla_byte(regs.de.h); + break; + case 0x23: // SLA E + sla_byte(regs.de.l); + break; + case 0x24: // SLA H + sla_byte(regs.hl.h); + break; + case 0x25: // SLA L + sla_byte(regs.hl.l); + break; + case 0x26: // SLA (HL) + { unsigned char tmp; + tmp = get1(regs.HL); + sla_byte(tmp); + store1(regs.HL, tmp); + } + break; + case 0x27: // SLA A + sla_byte(regs.A); + break; + } + return(resGO); +} + +int +cl_z80::inst_cb_sra(t_mem code) +{ + switch(code) { + case 0x28: // SRA B + sra_byte(regs.bc.h); + break; + case 0x29: // SRA C + sra_byte(regs.bc.l); + break; + case 0x2A: // SRA D + sra_byte(regs.de.h); + break; + case 0x2B: // SRA E + sra_byte(regs.de.l); + break; + case 0x2C: // SRA H + sra_byte(regs.hl.h); + break; + case 0x2D: // SRA L + sra_byte(regs.hl.l); + break; + case 0x2E: // SRA (HL) + { unsigned char tmp; + tmp = get1(regs.HL); + sra_byte(tmp); + store1(regs.HL, tmp); + } + break; + case 0x2F: // SRA A + sra_byte(regs.A); + break; + } + return(resGO); +} + +int +cl_z80::inst_cb_slia(t_mem code) +{ + switch(code) { + case 0x30: // SLIA B (Shift Left Inverted Arithmetic) + slia_byte(regs.bc.h); + break; + case 0x31: // SLIA C like SLA, but shifts in a 1 bit + slia_byte(regs.bc.l); + break; + case 0x32: // SLIA D + slia_byte(regs.de.h); + break; + case 0x33: // SLIA E + slia_byte(regs.de.l); + break; + case 0x34: // SLIA H + slia_byte(regs.hl.h); + break; + case 0x35: // SLIA L + slia_byte(regs.hl.l); + break; + case 0x36: // SLIA (HL) + { unsigned char tmp; + tmp = get1(regs.HL); + slia_byte(tmp); + store1(regs.HL, tmp); + } + break; + case 0x37: // SLIA A + slia_byte(regs.A); + break; + } + return(resGO); +} + +int +cl_z80::inst_cb_srl(t_mem code) +{ + switch(code) { + case 0x38: // SRL B + srl_byte(regs.bc.h); + break; + case 0x39: // SRL C + srl_byte(regs.bc.l); + break; + case 0x3A: // SRL D + srl_byte(regs.de.h); + break; + case 0x3B: // SRL E + srl_byte(regs.de.l); + break; + case 0x3C: // SRL H + srl_byte(regs.hl.h); + break; + case 0x3D: // SRL L + srl_byte(regs.hl.l); + break; + case 0x3E: // SRL (HL) + { unsigned char tmp; + tmp = get1(regs.HL); + srl_byte(tmp); + store1(regs.HL, tmp); + } + break; + case 0x3F: // SRL A + srl_byte(regs.A); + break; + } + return(resGO); +} + + +int +cl_z80::inst_cb_bit(t_mem code) +{ +#define bit_bitnum ((code >> 3) & 7) + + switch(code & 7) { + case 0x0: // BIT x,B + bit_byte(regs.bc.h, bit_bitnum); break; + case 0x1: // BIT x,C + bit_byte(regs.bc.l, bit_bitnum); break; + case 0x2: // BIT x,D + bit_byte(regs.de.h, bit_bitnum); break; + case 0x3: // BIT x,E + bit_byte(regs.de.l, bit_bitnum); break; + case 0x4: // BIT x,H + bit_byte(regs.hl.h, bit_bitnum); break; + case 0x5: // BIT x,L + bit_byte(regs.hl.l, bit_bitnum); break; + case 0x6: // BIT x,(HL) + { unsigned char tmp; + tmp = get1(regs.HL); + bit_byte(tmp, bit_bitnum); + store1(regs.HL, tmp); + } + break; + case 0x7: // BIT x,A + bit_byte(regs.A, bit_bitnum); break; + break; + } + return(resGO); +} + +int +cl_z80::inst_cb_res(t_mem code) +{ +#define bit_bitnum ((code >> 3) & 7) + + switch(code & 0x7) { + case 0x0: // RES x,B + regs.bc.h &= ~(1 << bit_bitnum); break; + case 0x1: // RES x,C + regs.bc.l &= ~(1 << bit_bitnum); break; + case 0x2: // RES x,D + regs.de.h &= ~(1 << bit_bitnum); break; + case 0x3: // RES x,E + regs.de.l &= ~(1 << bit_bitnum); break; + case 0x4: // RES x,H + regs.hl.h &= ~(1 << bit_bitnum); break; + case 0x5: // RES x,L + regs.hl.l &= ~(1 << bit_bitnum); break; + case 0x6: // RES x,(HL) + { unsigned char tmp; + tmp = get1(regs.HL); + tmp &= ~(1 << bit_bitnum); + store1(regs.HL, tmp); + } + break; + case 0x7: // RES x,A + regs.A &= ~(bit_bitnum); break; + } + return(resGO); +} + +int +cl_z80::inst_cb_set(t_mem code) +{ +#define bit_bitnum ((code >> 3) & 7) + + switch(code) { + case 0x0: // SET x,B + regs.bc.h |= (1 << bit_bitnum); break; + case 0x1: // SET x,C + regs.bc.l |= (1 << bit_bitnum); break; + case 0x2: // SET x,D + regs.de.h |= (1 << bit_bitnum); break; + case 0x3: // SET x,E + regs.de.l |= (1 << bit_bitnum); break; + case 0x4: // SET x,H + regs.hl.h |= (1 << bit_bitnum); break; + case 0x5: // SET x,L + regs.hl.h |= (1 << bit_bitnum); break; + case 0x6: // SET x,(HL) + { unsigned char tmp; + tmp = get1(regs.HL); + tmp |= (1 << bit_bitnum); + store1(regs.HL, tmp); + } + break; + case 0x7: // SET x,A + regs.de.h |= (1 << bit_bitnum); break; + } + return(resGO); +} + +/******** start CB codes *****************/ +int +cl_z80::inst_cb(void) +{ + t_mem code; + + if (fetch(&code)) + return(resBREAKPOINT); + tick(1); + switch (code) + { + case 0x00: // RLC B + case 0x01: // RLC C + case 0x02: // RLC D + case 0x03: // RLC E + case 0x04: // RLC H + case 0x05: // RLC L + case 0x06: // RLC (HL) + case 0x07: // RLC A + return (inst_cb_rlc(code)); + case 0x08: // RRC B + case 0x09: // RRC C + case 0x0A: // RRC D + case 0x0B: // RRC E + case 0x0C: // RRC H + case 0x0D: // RRC L + case 0x0E: // RRC (HL) + case 0x0F: // RRC A + return (inst_cb_rrc(code)); + case 0x10: // RL B + case 0x11: // RL C + case 0x12: // RL D + case 0x13: // RL E + case 0x14: // RL H + case 0x15: // RL L + case 0x16: // RL (HL) + case 0x17: // RL A + return (inst_cb_rl(code)); + case 0x18: // RR B + case 0x19: // RR C + case 0x1A: // RR D + case 0x1B: // RR E + case 0x1C: // RR H + case 0x1D: // RR L + case 0x1E: // RR (HL) + case 0x1F: // RR A + return (inst_cb_rr(code)); + case 0x20: // SLA B + case 0x21: // SLA C + case 0x22: // SLA D + case 0x23: // SLA E + case 0x24: // SLA H + case 0x25: // SLA L + case 0x26: // SLA (HL) + case 0x27: // SLA A + return (inst_cb_sla(code)); + case 0x28: // SRA B + case 0x29: // SRA C + case 0x2A: // SRA D + case 0x2B: // SRA E + case 0x2C: // SRA H + case 0x2D: // SRA L + case 0x2E: // SRA (HL) + case 0x2F: // SRA A + return (inst_cb_sra(code)); + case 0x30: // SLIA B (Shift Left Inverted Arithmetic) + case 0x31: // SLIA C like SLA, but shifts in a 1 bit + case 0x32: // SLIA D + case 0x33: // SLIA E + case 0x34: // SLIA H + case 0x35: // SLIA L + case 0x36: // SLIA (HL) + case 0x37: // SLIA A + return (inst_cb_slia(code)); + case 0x38: // SRL B + case 0x39: // SRL C + case 0x3A: // SRL D + case 0x3B: // SRL E + case 0x3C: // SRL H + case 0x3D: // SRL L + case 0x3E: // SRL (HL) + case 0x3F: // SRL A + return (inst_cb_srl(code)); + case 0x40: // BIT 0,B + case 0x41: // BIT 0,C + case 0x42: // BIT 0,D + case 0x43: // BIT 0,E + case 0x44: // BIT 0,H + case 0x45: // BIT 0,L + case 0x46: // BIT 0,(HL) + case 0x47: // BIT 0,A + case 0x48: // BIT 1,B + case 0x49: // BIT 1,C + case 0x4A: // BIT 1,D + case 0x4B: // BIT 1,E + case 0x4C: // BIT 1,H + case 0x4D: // BIT 1,L + case 0x4E: // BIT 1,(HL) + case 0x4F: // BIT 1,A + case 0x50: // BIT 2,B + case 0x51: // BIT 2,C + case 0x52: // BIT 2,D + case 0x53: // BIT 2,E + case 0x54: // BIT 2,H + case 0x55: // BIT 2,L + case 0x56: // BIT 2,(HL) + case 0x57: // BIT 2,A + case 0x58: // BIT 3,B + case 0x59: // BIT 3,C + case 0x5A: // BIT 3,D + case 0x5B: // BIT 3,E + case 0x5C: // BIT 3,H + case 0x5D: // BIT 3,L + case 0x5E: // BIT 3,(HL) + case 0x5F: // BIT 3,A + case 0x60: // BIT 4,B + case 0x61: // BIT 4,C + case 0x62: // BIT 4,D + case 0x63: // BIT 4,E + case 0x64: // BIT 4,H + case 0x65: // BIT 4,L + case 0x66: // BIT 4,(HL) + case 0x67: // BIT 4,A + case 0x68: // BIT 5,B + case 0x69: // BIT 5,C + case 0x6A: // BIT 5,D + case 0x6B: // BIT 5,E + case 0x6C: // BIT 5,H + case 0x6D: // BIT 5,L + case 0x6E: // BIT 5,(HL) + case 0x6F: // BIT 5,A + case 0x70: // BIT 6,B + case 0x71: // BIT 6,C + case 0x72: // BIT 6,D + case 0x73: // BIT 6,E + case 0x74: // BIT 6,H + case 0x75: // BIT 6,L + case 0x76: // BIT 6,(HL) + case 0x77: // BIT 6,A + case 0x78: // BIT 7,B + case 0x79: // BIT 7,C + case 0x7A: // BIT 7,D + case 0x7B: // BIT 7,E + case 0x7C: // BIT 7,H + case 0x7D: // BIT 7,L + case 0x7E: // BIT 7,(HL) + case 0x7F: // BIT 7,A + return (inst_cb_bit(code)); + case 0x80: // RES 0,B + case 0x81: // RES 0,C + case 0x82: // RES 0,D + case 0x83: // RES 0,E + case 0x84: // RES 0,H + case 0x85: // RES 0,L + case 0x86: // RES 0,(HL) + case 0x87: // RES 0,A + case 0x88: // RES 1,B + case 0x89: // RES 1,C + case 0x8A: // RES 1,D + case 0x8B: // RES 1,E + case 0x8C: // RES 1,H + case 0x8D: // RES 1,L + case 0x8E: // RES 1,(HL) + case 0x8F: // RES 1,A + case 0x90: // RES 2,B + case 0x91: // RES 2,C + case 0x92: // RES 2,D + case 0x93: // RES 2,E + case 0x94: // RES 2,H + case 0x95: // RES 2,L + case 0x96: // RES 2,(HL) + case 0x97: // RES 2,A + case 0x98: // RES 3,B + case 0x99: // RES 3,C + case 0x9A: // RES 3,D + case 0x9B: // RES 3,E + case 0x9C: // RES 3,H + case 0x9D: // RES 3,L + case 0x9E: // RES 3,(HL) + case 0x9F: // RES 3,A + case 0xA0: // RES 4,B + case 0xA1: // RES 4,C + case 0xA2: // RES 4,D + case 0xA3: // RES 4,E + case 0xA4: // RES 4,H + case 0xA5: // RES 4,L + case 0xA6: // RES 4,(HL) + case 0xA7: // RES 4,A + case 0xA8: // RES 5,B + case 0xA9: // RES 5,C + case 0xAA: // RES 5,D + case 0xAB: // RES 5,E + case 0xAC: // RES 5,H + case 0xAD: // RES 5,L + case 0xAE: // RES 5,(HL) + case 0xAF: // RES 5,A + case 0xB0: // RES 6,B + case 0xB1: // RES 6,C + case 0xB2: // RES 6,D + case 0xB3: // RES 6,E + case 0xB4: // RES 6,H + case 0xB5: // RES 6,L + case 0xB6: // RES 6,(HL) + case 0xB7: // RES 6,A + case 0xB8: // RES 7,B + case 0xB9: // RES 7,C + case 0xBA: // RES 7,D + case 0xBB: // RES 7,E + case 0xBC: // RES 7,H + case 0xBD: // RES 7,L + case 0xBE: // RES 7,(HL) + case 0xBF: // RES 7,A + return (inst_cb_res(code)); + case 0xC0: // SET 0,B + case 0xC1: // SET 0,C + case 0xC2: // SET 0,D + case 0xC3: // SET 0,E + case 0xC4: // SET 0,H + case 0xC5: // SET 0,L + case 0xC6: // SET 0,(HL) + case 0xC7: // SET 0,A + case 0xC8: // SET 1,B + case 0xC9: // SET 1,C + case 0xCA: // SET 1,D + case 0xCB: // SET 1,E + case 0xCC: // SET 1,H + case 0xCD: // SET 1,L + case 0xCE: // SET 1,(HL) + case 0xCF: // SET 1,A + case 0xD0: // SET 2,B + case 0xD1: // SET 2,C + case 0xD2: // SET 2,D + case 0xD3: // SET 2,E + case 0xD4: // SET 2,H + case 0xD5: // SET 2,L + case 0xD6: // SET 2,(HL) + case 0xD7: // SET 2,A + case 0xD8: // SET 3,B + case 0xD9: // SET 3,C + case 0xDA: // SET 3,D + case 0xDB: // SET 3,E + case 0xDC: // SET 3,H + case 0xDD: // SET 3,L + case 0xDE: // SET 3,(HL) + case 0xDF: // SET 3,A + case 0xE0: // SET 4,B + case 0xE1: // SET 4,C + case 0xE2: // SET 4,D + case 0xE3: // SET 4,E + case 0xE4: // SET 4,H + case 0xE5: // SET 4,L + case 0xE6: // SET 4,(HL) + case 0xE7: // SET 4,A + case 0xE8: // SET 5,B + case 0xE9: // SET 5,C + case 0xEA: // SET 5,D + case 0xEB: // SET 5,E + case 0xEC: // SET 5,H + case 0xED: // SET 5,L + case 0xEE: // SET 5,(HL) + case 0xEF: // SET 5,A + case 0xF0: // SET 6,B + case 0xF1: // SET 6,C + case 0xF2: // SET 6,D + case 0xF3: // SET 6,E + case 0xF4: // SET 6,H + case 0xF5: // SET 6,L + case 0xF6: // SET 6,(HL) + case 0xF7: // SET 6,A + case 0xF8: // SET 7,B + case 0xF9: // SET 7,C + case 0xFA: // SET 7,D + case 0xFB: // SET 7,E + case 0xFC: // SET 7,H + case 0xFD: // SET 7,L + case 0xFE: // SET 7,(HL) + case 0xFF: // SET 7,A + return (inst_cb_set(code)); + } + if (PC) + PC--; + else + PC= get_mem_size(MEM_ROM)-1; + return(resINV_INST); +} + +/* End of z80.src/inst_cb.cc */ diff --git a/sim/ucsim/z80.src/inst_dd.cc b/sim/ucsim/z80.src/inst_dd.cc new file mode 100644 index 00000000..ba9cb83d --- /dev/null +++ b/sim/ucsim/z80.src/inst_dd.cc @@ -0,0 +1,52 @@ +/* + * Simulator of microcontrollers (inst_dd.cc) + * dd escaped multi-byte opcodes. + * + * some z80 code base from Karl Bongers karl@turbobit.com + * + * Copyright (C) 1999,99 Drotos Daniel, Talker Bt. + * + * To contact author send email to drdani@mazsola.iit.uni-miskolc.hu + * + */ + +/* This file is part of microcontroller simulator: ucsim. + +UCSIM is free software; you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation; either version 2 of the License, or +(at your option) any later version. + +UCSIM is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU General Public License for more details. + +You should have received a copy of the GNU General Public License +along with UCSIM; see the file COPYING. If not, write to the Free +Software Foundation, 59 Temple Place - Suite 330, Boston, MA +02111-1307, USA. */ +/*@1@*/ + +#include "ddconfig.h" + +// local +#include "z80cl.h" +#include "regsz80.h" +#include "z80mac.h" + +#define regs_iX_h regs.ix.h +#define regs_iX_l regs.ix.l +#define regs_IX_OR_IY regs.IX +#define inst_Xd_ld inst_dd_ld +#define inst_Xd_add inst_dd_add +#define inst_Xd_push inst_dd_push +#define inst_Xd_inc inst_dd_inc +#define inst_Xd_dec inst_dd_dec +#define inst_Xd_misc inst_dd_misc +#define inst_Xd inst_dd +#define inst_Xdcb inst_ddcb + +#include "inst_xd.cc" + +/* End of z80.src/inst_dd.cc */ diff --git a/sim/ucsim/z80.src/inst_ddcb.cc b/sim/ucsim/z80.src/inst_ddcb.cc new file mode 100644 index 00000000..4d04fb29 --- /dev/null +++ b/sim/ucsim/z80.src/inst_ddcb.cc @@ -0,0 +1,53 @@ +/* + * Simulator of microcontrollers (inst_ddcb.cc) + * DD CB escaped multi-byte opcodes for Z80. + * + * Copyright (C) 1999,99 Drotos Daniel, Talker Bt. + * + * To contact author send email to drdani@mazsola.iit.uni-miskolc.hu + * + */ + +/* This file is part of microcontroller simulator: ucsim. + +UCSIM is free software; you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation; either version 2 of the License, or +(at your option) any later version. + +UCSIM is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU General Public License for more details. + +You should have received a copy of the GNU General Public License +along with UCSIM; see the file COPYING. If not, write to the Free +Software Foundation, 59 Temple Place - Suite 330, Boston, MA +02111-1307, USA. */ +/*@1@*/ + +#include "ddconfig.h" + +// local +#include "z80cl.h" +#include "regsz80.h" +#include "z80mac.h" + + +#define regs_IX_OR_IY regs.IX +#define inst_XXcb_rlc inst_ddcb_rlc +#define inst_XXcb_rrc inst_ddcb_rrc +#define inst_XXcb_rl inst_ddcb_rl +#define inst_XXcb_rr inst_ddcb_rr +#define inst_XXcb_sla inst_ddcb_sla +#define inst_XXcb_sra inst_ddcb_sra +#define inst_XXcb_slia inst_ddcb_slia +#define inst_XXcb_srl inst_ddcb_srl +#define inst_XXcb_bit inst_ddcb_bit +#define inst_XXcb_res inst_ddcb_res +#define inst_XXcb_set inst_ddcb_set +#define inst_XXcb inst_ddcb + +#include "inst_xxcb.cc" + +/* End of z80.src/inst_ddcb.cc */ diff --git a/sim/ucsim/z80.src/inst_ed.cc b/sim/ucsim/z80.src/inst_ed.cc new file mode 100644 index 00000000..a91524f8 --- /dev/null +++ b/sim/ucsim/z80.src/inst_ed.cc @@ -0,0 +1,330 @@ +/* + * Simulator of microcontrollers (inst_ed.cc) + * ED escaped multi-byte opcodes for Z80. + * + * Copyright (C) 1999,99 Drotos Daniel, Talker Bt. + * + * To contact author send email to drdani@mazsola.iit.uni-miskolc.hu + * + */ + +/* This file is part of microcontroller simulator: ucsim. + +UCSIM is free software; you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation; either version 2 of the License, or +(at your option) any later version. + +UCSIM is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU General Public License for more details. + +You should have received a copy of the GNU General Public License +along with UCSIM; see the file COPYING. If not, write to the Free +Software Foundation, 59 Temple Place - Suite 330, Boston, MA +02111-1307, USA. */ +/*@1@*/ + +#include "ddconfig.h" + +// local +#include "z80cl.h" +#include "regsz80.h" +#include "z80mac.h" + + +int +cl_z80::inst_ed_(t_mem code) +{ + switch(code) { + } + return(resGO); +} + +/******** start CB codes *****************/ +int +cl_z80::inst_ed(void) +{ + t_mem code; + unsigned short tw; + + if (fetch(&code)) + return(resBREAKPOINT); + + switch (code) + { +#if 0 + case 0x40: // IN B,(C) + return(resGO); + case 0x41: // OUT (C),B + return(resGO); +#endif + case 0x42: // SBC HL,BC + sbc_HL_wordreg(regs.BC); + return(resGO); + case 0x43: // LD (nnnn),BC + tw = fetch2(); + store2(tw, regs.BC); + return(resGO); + case 0x44: // NEG + regs.F &= ~(BIT_ALL); /* clear these */ + regs.A -= regs.A; + regs.F |= BIT_N; /* not addition */ + if (regs.A == 0) regs.F |= BIT_Z; + if (regs.A & 0x80) regs.F |= BIT_S; + /* Skip BIT_A for now */ + return(resGO); + case 0x45: // RETN (return from non-maskable interrupt) + pop2(PC); + return(resGO); +#if 0 + case 0x46: // IM 0 + /* interrupt device puts opcode on data bus */ + return(resGO); +#endif + case 0x47: // LD IV,A + regs.iv = regs.A; + return(resGO); + + case 0x48: // IN C,(C) + return(resGO); + case 0x49: // OUT (C),C + return(resGO); + + case 0x4A: // ADC HL,BC + adc_HL_wordreg(regs.BC); + return(resGO); + case 0x4B: // LD BC,(nnnn) + tw = fetch2(); + regs.BC = get2(tw); + return(resGO); + case 0x4D: // RETI (return from interrupt) + pop2(PC); + return(resGO); + case 0x4F: // LD R,A + /* Load "refresh" register(whats that?) */ + return(resGO); + + case 0x50: // IN D,(C) + return(resGO); + case 0x51: // OUT (C),D + return(resGO); + + case 0x52: // SBC HL,DE + sbc_HL_wordreg(regs.DE); + return(resGO); + case 0x53: // LD (nnnn),DE + tw = fetch2(); + store2(tw, regs.DE); + return(resGO); +#if 0 + case 0x56: // IM 1 + return(resGO); +#endif + case 0x57: // LD A,IV + regs.A = regs.iv; + return(resGO); + + case 0x58: // IN E,(C) + return(resGO); + case 0x59: // OUT (C),E + return(resGO); + + case 0x5A: // ADC HL,DE + adc_HL_wordreg(regs.DE); + return(resGO); + case 0x5B: // LD DE,(nnnn) + tw = fetch2(); + regs.DE = get2(tw); + return(resGO); + +#if 0 + case 0x5E: // IM 2 + return(resGO); + case 0x5F: // LD A,R + return(resGO); + case 0x60: // IN H,(C) + return(resGO); + case 0x61: // OUT (C),H + return(resGO); +#endif + case 0x62: // SBC HL,HL + sbc_HL_wordreg(regs.HL); + return(resGO); + case 0x63: // LD (nnnn),HL opcode 22 does the same faster + tw = fetch2(); + store2(tw, regs.HL); + return(resGO); + +#if 0 + case 0x67: // RRD + return(resGO); +#endif + case 0x68: // IN L,(C) + return(resGO); + case 0x69: // OUT (C),L + return(resGO); + + case 0x6A: // ADC HL,HL + adc_HL_wordreg(regs.HL); + return(resGO); + case 0x6B: // LD HL,(nnnn) opcode 2A does the same faster + tw = fetch2(); + regs.HL = get2(tw); + return(resGO); + +#if 0 + case 0x6F: // RLD + /* rotate 1 bcd digit left between ACC and memory location */ + return(resGO); +#endif + + case 0x70: // IN (C) set flags only (TSTI) + return(resGO); + case 0x71: // OUT (C),0 + return(resGO); + + case 0x72: // SBC HL,SP + sbc_HL_wordreg(regs.SP); + return(resGO); + case 0x73: // LD (nnnn),SP + tw = fetch2(); + store2(tw, regs.SP); + return(resGO); + + case 0x78: // IN A,(C) + return(resGO); + case 0x79: // OUT (C),A + return(resGO); + + case 0x7A: // ADC HL,SP + adc_HL_wordreg(regs.SP); + return(resGO); + case 0x7B: // LD SP,(nnnn) + tw = fetch2(); + regs.SP = get2(tw); + return(resGO); + + case 0xA0: // LDI + // BC - count, sourc=HL, dest=DE. *DE++ = *HL++, --BC until zero + regs.F &= ~(BIT_P | BIT_N | BIT_A); /* clear these */ + store1(regs.DE, get1(regs.HL)); + ++regs.HL; + ++regs.DE; + --regs.BC; + if (regs.BC != 0) regs.F |= BIT_P; + return(resGO); + case 0xA1: // CPI + // compare acc with mem(HL), if ACC=0 set Z flag. Incr HL, decr BC. + { + unsigned char tmp; + tmp = get1(regs.HL); + cp_bytereg(tmp); + ++regs.HL; + --regs.BC; + if (regs.BC != 0) regs.F |= BIT_P; + } + return(resGO); + + case 0xA2: // INI + return(resGO); + case 0xA3: // OUTI + return(resGO); + + case 0xA8: // LDD + // BC - count, source=HL, dest=DE. *DE-- = *HL--, --BC until zero + regs.F &= ~(BIT_P | BIT_N | BIT_A); /* clear these */ + store1(regs.DE, get1(regs.HL)); + --regs.HL; + --regs.DE; + --regs.BC; + if (regs.BC != 0) regs.F |= BIT_P; + return(resGO); + case 0xA9: // CPD +/* fixme: checkme, compare to other emul. */ + + regs.F &= ~(BIT_ALL); /* clear these */ + if ((regs.A - get1(regs.HL)) == 0) { + regs.F |= (BIT_Z | BIT_P); + } + ++regs.HL; + --regs.BC; + if (regs.BC != 0) regs.F |= BIT_P; + + return(resGO); + + case 0xAA: // IND + return(resGO); + case 0xAB: // OUTD + return(resGO); + + case 0xB0: // LDIR + // BC - count, sourc=HL, dest=DE. *DE++ = *HL++, --BC until zero + regs.F &= ~(BIT_P | BIT_N | BIT_A); /* clear these */ + do { + store1(regs.DE, get1(regs.HL)); + ++regs.HL; + ++regs.DE; + --regs.BC; + } while (regs.BC != 0); + return(resGO); + + case 0xB1: // CPIR +/* fixme: checkme, compare to other emul. */ + // compare acc with mem(HL), if ACC=0 set Z flag. Incr HL, decr BC. + regs.F &= ~(BIT_ALL); /* clear these */ + regs.F |= BIT_N | BIT_P; + do { + if ((regs.A - get1(regs.HL)) == 0) { + regs.F |= (BIT_Z | BIT_P); + return(resGO); + } + ++regs.HL; + --regs.BC; + } while (regs.BC != 0); + + return(resGO); +#if 0 + case 0xB2: // INIR + return(resGO); + case 0xB3: // OTIR + return(resGO); +#endif + case 0xB8: // LDDR + // BC - count, source=HL, dest=DE. *DE-- = *HL--, --BC until zero + regs.F &= ~(BIT_P | BIT_N | BIT_A); /* clear these */ + do { + store1(regs.DE, get1(regs.HL)); + --regs.HL; + --regs.DE; + --regs.BC; + } while (regs.BC != 0); + return(resGO); + case 0xB9: // CPDR + // compare acc with mem(HL), if ACC=0 set Z flag. Incr HL, decr BC. + regs.F &= ~(BIT_ALL); /* clear these */ + do { + if ((regs.A - get1(regs.HL)) == 0) { + regs.F |= (BIT_Z | BIT_P); + break; + } + --regs.HL; + --regs.BC; + } while (regs.BC != 0); + return(resGO); +#if 0 + case 0xBA: // INDR + return(resGO); + case 0xBB: // OTDR + return(resGO); +#endif + + default: + return(resINV_INST); + } + + return(resINV_INST); +} + +/* End of z80.src/inst_ed.cc */ diff --git a/sim/ucsim/z80.src/inst_fd.cc b/sim/ucsim/z80.src/inst_fd.cc new file mode 100644 index 00000000..417f8edb --- /dev/null +++ b/sim/ucsim/z80.src/inst_fd.cc @@ -0,0 +1,52 @@ +/* + * Simulator of microcontrollers (inst_fd.cc) + * FD escaped multi-byte opcodes. + * + * + * Copyright (C) 1999,2001 Drotos Daniel, Talker Bt. + * + * To contact author send email to drdani@mazsola.iit.uni-miskolc.hu + * + * some z80 code base from Karl Bongers karl@turbobit.com + */ + +/* 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" + +// local +#include "z80cl.h" +#include "regsz80.h" +#include "z80mac.h" + +#define regs_iX_h regs.iy.h +#define regs_iX_l regs.iy.l +#define regs_IX_OR_IY regs.IY +#define inst_Xd_ld inst_fd_ld +#define inst_Xd_add inst_fd_add +#define inst_Xd_push inst_fd_push +#define inst_Xd_inc inst_fd_inc +#define inst_Xd_dec inst_fd_dec +#define inst_Xd_misc inst_fd_misc +#define inst_Xd inst_fd +#define inst_Xdcb inst_fdcb + +#include "inst_xd.cc" + +/* End of z80.src/inst_fd.cc */ diff --git a/sim/ucsim/z80.src/inst_fdcb.cc b/sim/ucsim/z80.src/inst_fdcb.cc new file mode 100644 index 00000000..cbd5e3d6 --- /dev/null +++ b/sim/ucsim/z80.src/inst_fdcb.cc @@ -0,0 +1,52 @@ +/* + * Simulator of microcontrollers (inst_fdcb.cc) + * FD CB escaped multi-byte opcodes for Z80. + * + * Copyright (C) 1999,99 Drotos Daniel, Talker Bt. + * + * To contact author send email to drdani@mazsola.iit.uni-miskolc.hu + * + */ + +/* This file is part of microcontroller simulator: ucsim. + +UCSIM is free software; you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation; either version 2 of the License, or +(at your option) any later version. + +UCSIM is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU General Public License for more details. + +You should have received a copy of the GNU General Public License +along with UCSIM; see the file COPYING. If not, write to the Free +Software Foundation, 59 Temple Place - Suite 330, Boston, MA +02111-1307, USA. */ +/*@1@*/ + +#include "ddconfig.h" + +// local +#include "z80cl.h" +#include "regsz80.h" +#include "z80mac.h" + +#define regs_IX_OR_IY regs.IY +#define inst_XXcb_rlc inst_fdcb_rlc +#define inst_XXcb_rrc inst_fdcb_rrc +#define inst_XXcb_rl inst_fdcb_rl +#define inst_XXcb_rr inst_fdcb_rr +#define inst_XXcb_sla inst_fdcb_sla +#define inst_XXcb_sra inst_fdcb_sra +#define inst_XXcb_slia inst_fdcb_slia +#define inst_XXcb_srl inst_fdcb_srl +#define inst_XXcb_bit inst_fdcb_bit +#define inst_XXcb_res inst_fdcb_res +#define inst_XXcb_set inst_fdcb_set +#define inst_XXcb inst_fdcb + +#include "inst_xxcb.cc" + +/* End of z80.src/inst_fdcb.cc */ diff --git a/sim/ucsim/z80.src/inst_xd.cc b/sim/ucsim/z80.src/inst_xd.cc new file mode 100644 index 00000000..d1b7a3a7 --- /dev/null +++ b/sim/ucsim/z80.src/inst_xd.cc @@ -0,0 +1,534 @@ +/* + * Simulator of microcontrollers (inst_xd.cc) + * dd or fd escaped multi-byte opcodes. + * + * This module gets pulled in and pre-processed to create + * two modules. DD prefixed opcodes reference + * IX register, while FD prefixes reference IY register. + * See inst_ddcb.cc and inst_fdcb.cc + * + * Copyright (C) 1999,2002 Drotos Daniel, Talker Bt. + * some z80 coding from Karl Bongers karl@turbobit.com + * + * 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@*/ + +int +cl_z80::inst_Xd_ld(t_mem code) +{ + unsigned short tw; + + switch (code) { + case 0x21: // LD IX,nnnn + regs_IX_OR_IY = fetch2(); + return(resGO); + case 0x22: // LD (nnnn),IX + tw = fetch2(); + store2(tw, regs_IX_OR_IY); + return(resGO); + case 0x26: // LD HX,nn + regs_iX_h = fetch1(); + return(resGO); + case 0x2A: // LD IX,(nnnn) + tw = fetch2(); + regs_IX_OR_IY = get2(tw); + return(resGO); + case 0x2E: // LD LX,nn + regs_iX_l = fetch1(); + return(resGO); + case 0x36: // LD (IX+dd),nn + tw = add_u16_disp(regs_IX_OR_IY, fetch()); + store1(tw, fetch()); + return(resGO); + case 0x44: // LD B,HX + regs.bc.h = regs_iX_h; + return(resGO); + case 0x45: // LD B,LX + regs.bc.h = regs_iX_l; + return(resGO); + case 0x46: // LD B,(IX+dd) + regs.bc.h = get1(add_u16_disp(regs_IX_OR_IY,fetch())); + return(resGO); + case 0x4C: // LD C,HX + regs.bc.l = regs_iX_h; + return(resGO); + case 0x4D: // LD C,LX + regs.bc.l = regs_iX_l; + return(resGO); + case 0x4E: // LD C,(IX+dd) + regs.bc.l = get1(add_u16_disp(regs_IX_OR_IY,fetch())); + return(resGO); + case 0x54: // LD D,HX + regs.de.h = regs_iX_h; + return(resGO); + case 0x55: // LD D,LX + regs.de.h = regs_iX_l; + return(resGO); + case 0x56: // LD D,(IX+dd) + regs.de.h = get1(add_u16_disp(regs_IX_OR_IY,fetch())); + return(resGO); + case 0x5C: // LD E,H + regs.de.l = regs.hl.h; + return(resGO); + case 0x5D: // LD E,L + regs.de.l = regs.hl.l; + return(resGO); + case 0x5E: // LD E,(IX+dd) + regs.de.l = get1(add_u16_disp(regs_IX_OR_IY,fetch())); + return(resGO); + case 0x60: // LD HX,B + regs_iX_h = regs.bc.h; + return(resGO); + case 0x61: // LD HX,C + regs_iX_h = regs.bc.l; + return(resGO); + case 0x62: // LD HX,D + regs_iX_h = regs.de.h; + return(resGO); + case 0x63: // LD HX,E + regs_iX_h = regs.de.l; + return(resGO); + case 0x64: // LD HX,HX + return(resGO); + case 0x65: // LD HX,LX + regs_iX_h = regs_iX_l; + return(resGO); + case 0x66: // LD H,(IX+dd) + regs.hl.h = get1(add_u16_disp(regs_IX_OR_IY,fetch())); + return(resGO); + case 0x67: // LD HX,A + regs_iX_h = regs.A; + return(resGO); + case 0x68: // LD LX,B + regs_iX_l = regs.bc.h; + return(resGO); + case 0x69: // LD LX,C + regs_iX_l = regs.bc.l; + return(resGO); + case 0x6A: // LD LX,D + regs_iX_l = regs.de.h; + return(resGO); + case 0x6B: // LD LX,E + regs_iX_l = regs.de.l; + return(resGO); + case 0x6C: // LD LX,HX + regs_iX_l = regs.hl.h; + return(resGO); + case 0x6D: // LD LX,LX + return(resGO); + case 0x6E: // LD L,(IX+dd) + regs.hl.l = get1(add_u16_disp(regs_IX_OR_IY,fetch())); + return(resGO); + case 0x6F: // LD LX,A + regs_iX_l = regs.A; + return(resGO); + case 0x70: // LD (IX+dd),B + store1(add_u16_disp(regs_IX_OR_IY,fetch()), regs.bc.h); + return(resGO); + case 0x71: // LD (IX+dd),C + store1(add_u16_disp(regs_IX_OR_IY,fetch()), regs.bc.l); + return(resGO); + case 0x72: // LD (IX+dd),D + store1(add_u16_disp(regs_IX_OR_IY,fetch()), regs.de.h); + return(resGO); + case 0x73: // LD (IX+dd),E + store1(add_u16_disp(regs_IX_OR_IY,fetch()), regs.de.l); + return(resGO); + case 0x74: // LD (IX+dd),H + store1(add_u16_disp(regs_IX_OR_IY,fetch()), regs.hl.h); + return(resGO); + case 0x75: // LD (IX+dd),L + store1(add_u16_disp(regs_IX_OR_IY,fetch()), regs.hl.l); + return(resGO); + case 0x77: // LD (IX+dd),A + store1(add_u16_disp(regs_IX_OR_IY,fetch()), regs.A); + return(resGO); + case 0x7C: // LD A,HX + regs.A = regs_iX_h; + return(resGO); + case 0x7D: // LD A,LX + regs.A = regs_iX_l; + return(resGO); + case 0x7E: // LD A,(IX+dd) + regs.A = get1(add_u16_disp(regs_IX_OR_IY,fetch())); + return(resGO); + case 0xF9: // LD SP,IX + regs.SP = regs_IX_OR_IY; + return(resGO); + } + return(resINV_INST); +} + +int +cl_z80::inst_Xd_add(t_mem code) +{ +#define add_IX_Word(wr) { \ + unsigned int tmp; \ + regs.F &= ~(BIT_A | BIT_N | BIT_C); /* clear these */ \ + tmp = (unsigned int)regs_IX_OR_IY + (unsigned int)(wr); \ + if (tmp > 0xffff) regs.F |= BIT_C; \ + regs_IX_OR_IY = (unsigned short) tmp; } + + switch (code) { + case 0x09: // ADD IX,BC + add_IX_Word(regs.BC); + return(resGO); + case 0x19: // ADD IX,DE + add_IX_Word(regs.DE); + return(resGO); + case 0x29: // ADD IX,IX + add_IX_Word(regs_IX_OR_IY); + return(resGO); + case 0x39: // ADD IX,SP + add_IX_Word(regs.SP); + return(resGO); + case 0x84: // ADD A,HX + add_A_bytereg(regs_iX_h); + return(resGO); + case 0x85: // ADD A,LX + add_A_bytereg(regs_iX_l); + return(resGO); + case 0x86: // ADD A,(IX+dd) + { unsigned char ourtmp; + t_addr addr; + addr = add_u16_disp(regs_IX_OR_IY, fetch()); + ourtmp = get1(addr); + add_A_bytereg(ourtmp); + } + return(resGO); + } + return(resINV_INST); +} + +int +cl_z80::inst_Xd_push(t_mem code) +{ + switch (code) { + case 0xe5: // PUSH IX + push2(regs_IX_OR_IY); + return(resGO); + } + return(resINV_INST); +} + +int +cl_z80::inst_Xd_inc(t_mem code) +{ + switch(code) { + case 0x23: // INC IX + ++regs_IX_OR_IY; + break; + case 0x24: // INC HX + inc(regs_iX_h); + break; + case 0x2C: // INC LX + inc(regs_iX_l); + break; + case 0x34: // INC (IX+dd) + { + t_addr addr; + unsigned char tmp; + addr = add_u16_disp(regs_IX_OR_IY,fetch()); + tmp = get1(addr); + inc(tmp); + store1(addr, tmp); + } + break; + default: + return(resINV_INST); + break; + } + return(resGO); +} + +int +cl_z80::inst_Xd_dec(t_mem code) +{ + switch(code) { + case 0x25: // DEC HX + dec(regs_iX_h); + break; + case 0x2B: // DEC IX + --regs.IX; + break; + case 0x2D: // DEC LX + dec(regs_iX_l); + break; + case 0x35: // DEC (IX+dd) + { + t_addr addr; + unsigned char tmp; + addr = add_u16_disp(regs_IX_OR_IY,fetch()); + tmp = get1(addr); + dec(tmp); + store1(addr, tmp); + } + break; + default: + return(resINV_INST); + break; + } + return(resGO); +} + + +/* need ADC, SUB, SBC, AND, XOR, OR, CP */ +int +cl_z80::inst_Xd_misc(t_mem code) +{ + switch(code) { + case 0x8C: // ADC A,HX + adc_A_bytereg(regs_iX_h); + return(resGO); + case 0x8D: // ADC A,LX + adc_A_bytereg(regs_iX_l); + return(resGO); + case 0x8E: // ADC A,(IX+dd) + { unsigned char utmp; + t_addr addr; + addr = add_u16_disp(regs_IX_OR_IY, fetch()); + utmp = get1(addr); + adc_A_bytereg(utmp); + } + return(resGO); + + case 0x94: // SUB HX + sub_A_bytereg(regs_iX_h); + return(resGO); + case 0x95: // SUB LX + sub_A_bytereg(regs_iX_l); + return(resGO); + case 0x96: // SUB (IX+dd) + { unsigned char tmp1; + tmp1 = get1(add_u16_disp(regs_IX_OR_IY, fetch())); + sub_A_bytereg(tmp1); + } + return(resGO); + + case 0x9C: // SBC A,HX + sbc_A_bytereg(regs_iX_h); + return(resGO); + case 0x9D: // SBC A,LX + sbc_A_bytereg(regs_iX_l); + return(resGO); + case 0x9E: // SBC A,(IX+dd) + { unsigned char utmp; + utmp = get1(add_u16_disp(regs_IX_OR_IY, fetch())); + sbc_A_bytereg(utmp); + } + return(resGO); + + case 0xA4: // AND HX + and_A_bytereg(regs_iX_h); + return(resGO); + case 0xA5: // AND LX + and_A_bytereg(regs_iX_l); + return(resGO); + case 0xA6: // AND (IX+dd) + { unsigned char utmp; + utmp = get1(add_u16_disp(regs_IX_OR_IY, fetch())); + and_A_bytereg(utmp); + } + return(resGO); + + case 0xAC: // XOR HX + xor_A_bytereg(regs_iX_h); + return(resGO); + case 0xAD: // XOR LX + xor_A_bytereg(regs_iX_l); + return(resGO); + case 0xAE: // XOR (IX+dd) + { unsigned char utmp; + utmp = get1(add_u16_disp(regs_IX_OR_IY, fetch())); + xor_A_bytereg(utmp); + } + return(resGO); + + case 0xB4: // OR HX + or_A_bytereg(regs_iX_h); + return(resGO); + case 0xB5: // OR LX + or_A_bytereg(regs_iX_l); + return(resGO); + case 0xB6: // OR (IX+dd) + { unsigned char utmp; + utmp = get1(add_u16_disp(regs_IX_OR_IY, fetch())); + or_A_bytereg(utmp); + } + return(resGO); + + case 0xBC: // CP HX + cp_bytereg(regs_iX_h); + return(resGO); + case 0xBD: // CP LX + cp_bytereg(regs_iX_l); + return(resGO); + case 0xBE: // CP (IX+dd) + { unsigned char utmp; + utmp = get1(add_u16_disp(regs_IX_OR_IY, fetch())); + cp_bytereg(utmp); + } + return(resGO); + } + return(resINV_INST); +} + +int +cl_z80::inst_Xd(void) +{ + t_mem code; + + if (fetch(&code)) + return(resBREAKPOINT); + + switch (code) + { + case 0x21: // LD IX,nnnn + case 0x22: // LD (nnnn),IX + case 0x26: // LD HX,nn + case 0x2A: // LD IX,(nnnn) + case 0x2E: // LD LX,nn + case 0x36: // LD (IX+dd),nn + case 0x44: // LD B,HX + case 0x45: // LD B,LX + case 0x46: // LD B,(IX+dd) + case 0x4C: // LD C,HX + case 0x4D: // LD C,LX + case 0x4E: // LD C,(IX+dd) + case 0x54: // LD D,HX + case 0x55: // LD D,LX + case 0x56: // LD D,(IX+dd) + case 0x5C: // LD E,H + case 0x5D: // LD E,L + case 0x5E: // LD E,(IX+dd) + case 0x60: // LD HX,B + case 0x61: // LD HX,C + case 0x62: // LD HX,D + case 0x63: // LD HX,E + case 0x64: // LD HX,HX + case 0x66: // LD H,(IX+dd) + case 0x67: // LD HX,A + case 0x68: // LD LX,B + case 0x69: // LD LX,C + case 0x6A: // LD LX,D + case 0x6B: // LD LX,E + case 0x6C: // LD LX,HX + case 0x6D: // LD LX,LX + case 0x6E: // LD L,(IX+dd) + case 0x6F: // LD LX,A + case 0x70: // LD (IX+dd),B + case 0x71: // LD (IX+dd),C + case 0x72: // LD (IX+dd),D + case 0x73: // LD (IX+dd),E + case 0x74: // LD (IX+dd),H + case 0x75: // LD (IX+dd),L + case 0x77: // LD (IX+dd),A + case 0x7C: // LD A,HX + case 0x7D: // LD A,LX + case 0x7E: // LD A,(IX+dd) + case 0xF9: // LD SP,IX + return(inst_Xd_ld(code)); + + case 0x23: // INC IX + case 0x24: // INC HX + case 0x2C: // INC LX + case 0x34: // INC (IX+dd) + return(inst_Xd_inc(code)); + { + t_addr addr; + addr = add_u16_disp(regs_IX_OR_IY,fetch()); + store1(addr, get1(addr)+1); + } + + case 0x09: // ADD IX,BC + case 0x19: // ADD IX,DE + case 0x29: // ADD IX,IX + case 0x39: // ADD IX,SP + case 0x84: // ADD A,HX + case 0x85: // ADD A,LX + case 0x86: // ADD A,(IX) + return(inst_Xd_add(code)); + + case 0x25: // DEC HX + case 0x2B: // DEC IX + case 0x2D: // DEC LX + case 0x35: // DEC (IX+dd) + return(inst_Xd_dec(code)); + + case 0x8C: // ADC A,HX + case 0x8D: // ADC A,LX + case 0x8E: // ADC A,(IX) + case 0x94: // SUB HX + case 0x95: // SUB LX + case 0x96: // SUB (IX+dd) + case 0x9C: // SBC A,HX + case 0x9D: // SBC A,LX + case 0x9E: // SBC A,(IX+dd) + case 0xA4: // AND HX + case 0xA5: // AND LX + case 0xA6: // AND (IX+dd) + case 0xAC: // XOR HX + case 0xAD: // XOR LX + case 0xAE: // XOR (IX+dd) + case 0xB4: // OR HX + case 0xB5: // OR LX + case 0xB6: // OR (IX+dd) + case 0xBC: // CP HX + case 0xBD: // CP LX + case 0xBE: // CP (IX+dd) + return(inst_Xd_misc(code)); + break; + + case 0xCB: // escape, IX prefix to CB commands + return(inst_Xdcb()); /* see inst_ddcb.cc */ + break; + + case 0xE1: // POP IX + regs_IX_OR_IY = get2(regs.SP); + regs.SP+=2; + return(resGO); + + case 0xE3: // EX (SP),IX + { + TYPE_UWORD tempw; + + tempw = regs_IX_OR_IY; + regs_IX_OR_IY = get2(regs.SP); + store2(regs.SP, tempw); + } + return(resGO); + + case 0xE5: // PUSH IX + push2(regs_IX_OR_IY); + return(resGO); + + case 0xE9: // JP (IX) + PC = get2(regs_IX_OR_IY); + return(resGO); + + default: + return(resINV_INST); + } + return(resINV_INST); +} + +/* End of z80.src/inst_xd.cc */ diff --git a/sim/ucsim/z80.src/inst_xxcb.cc b/sim/ucsim/z80.src/inst_xxcb.cc new file mode 100644 index 00000000..d696d302 --- /dev/null +++ b/sim/ucsim/z80.src/inst_xxcb.cc @@ -0,0 +1,694 @@ +/* + * Simulator of microcontrollers (inst_xxcb.cc) + * DD CB or FD CB escaped multi-byte opcodes for Z80. + * + * This module gets pulled in and pre-processed to create + * two modules. DD CB prefixed opcodes reference + * IX register, while FD CB prefixes reference IY register. + * See inst_ddcb.cc and inst_fdcb.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@*/ + +static unsigned char n_offset; + +int +cl_z80::inst_XXcb_rlc(t_mem code) +{ + unsigned char tmp; + unsigned short addr; + + addr = add_u16_disp(regs_IX_OR_IY, n_offset); + tmp = get1(addr); + rlc_byte(tmp); + + switch(code) { + case 0x00: // RLC B + regs.bc.h = tmp; + break; + case 0x01: // RLC C + regs.bc.l = tmp; + break; + case 0x02: // RLC D + regs.de.h = tmp; + break; + case 0x03: // RLC E + regs.de.l = tmp; + break; + case 0x04: // RLC H + regs.hl.h = tmp; + break; + case 0x05: // RLC L + regs.hl.l = tmp; + break; + case 0x06: // RLC (HL) + break; + case 0x07: // RLC A + regs.A = tmp; + break; + default: + return(resINV_INST); + break; + } + store1(addr, tmp); + + return(resGO); +} + +int +cl_z80::inst_XXcb_rrc(t_mem code) +{ + unsigned char tmp; + unsigned short addr; + addr = add_u16_disp(regs_IX_OR_IY, n_offset); + tmp = get1(addr); + rrc_byte(tmp); + + switch(code) { + case 0x08: // RRC B + regs.bc.h = tmp; + break; + case 0x09: // RRC C + regs.bc.l = tmp; + break; + case 0x0A: // RRC D + regs.de.h = tmp; + break; + case 0x0B: // RRC E + regs.de.l = tmp; + break; + case 0x0C: // RRC H + regs.hl.h = tmp; + break; + case 0x0D: // RRC L + regs.hl.l = tmp; + break; + case 0x0E: // RRC (HL) + break; + case 0x0F: // RRC A + regs.A = tmp; + break; + default: + return(resINV_INST); + break; + } + store1(addr, tmp); + + return(resGO); +} + +int +cl_z80::inst_XXcb_rl(t_mem code) +{ + unsigned char tmp; + unsigned short addr; + addr = add_u16_disp(regs_IX_OR_IY, n_offset); + tmp = get1(addr); + rl_byte(tmp); + + switch(code) { + case 0x10: // RL B + regs.bc.h = tmp; + break; + case 0x11: // RL C + regs.bc.l = tmp; + break; + case 0x12: // RL D + regs.de.h = tmp; + break; + case 0x13: // RL E + regs.de.l = tmp; + break; + case 0x14: // RL H + regs.hl.h = tmp; + break; + case 0x15: // RL L + regs.hl.l = tmp; + break; + case 0x16: // RL (HL) + break; + case 0x17: // RL A + regs.A = tmp; + break; + default: + return(resINV_INST); + break; + } + store1(addr, tmp); + + return(resGO); +} + +int +cl_z80::inst_XXcb_rr(t_mem code) +{ + unsigned char tmp; + unsigned short addr; + addr = add_u16_disp(regs_IX_OR_IY, n_offset); + tmp = get1(addr); + rr_byte(tmp); + + switch(code) { + case 0x18: // RR B + regs.bc.h = tmp; + break; + case 0x19: // RR C + regs.bc.l = tmp; + break; + case 0x1A: // RR D + regs.de.h = tmp; + break; + case 0x1B: // RR E + regs.de.l = tmp; + break; + case 0x1C: // RR H + regs.hl.h = tmp; + break; + case 0x1D: // RR L + regs.hl.l = tmp; + break; + case 0x1E: // RR (HL) + break; + case 0x1F: // RR A + regs.A = tmp; + break; + default: + return(resINV_INST); + break; + } + store1(addr, tmp); + + return(resGO); +} + +int +cl_z80::inst_XXcb_sla(t_mem code) +{ + unsigned char tmp; + unsigned short addr; + addr = add_u16_disp(regs_IX_OR_IY, n_offset); + tmp = get1(addr); + sla_byte(tmp); + + switch(code) { + case 0x20: // SLA B + regs.bc.h = tmp; + break; + case 0x21: // SLA C + regs.bc.l = tmp; + break; + case 0x22: // SLA D + regs.de.h = tmp; + break; + case 0x23: // SLA E + regs.de.l = tmp; + break; + case 0x24: // SLA H + regs.hl.h = tmp; + break; + case 0x25: // SLA L + regs.hl.l = tmp; + break; + case 0x26: // SLA (HL) + break; + case 0x27: // SLA A + regs.A = tmp; + break; + default: + return(resINV_INST); + break; + } + store1(addr, tmp); + return(resGO); +} + +int +cl_z80::inst_XXcb_sra(t_mem code) +{ + unsigned char tmp; + unsigned short addr; + addr = add_u16_disp(regs_IX_OR_IY, n_offset); + tmp = get1(addr); + sra_byte(tmp); + + switch(code) { + case 0x28: // SRA B + regs.bc.h = tmp; + break; + case 0x29: // SRA C + regs.bc.l = tmp; + break; + case 0x2A: // SRA D + regs.de.h = tmp; + break; + case 0x2B: // SRA E + regs.de.l = tmp; + break; + case 0x2C: // SRA H + regs.hl.h = tmp; + break; + case 0x2D: // SRA L + regs.hl.l = tmp; + break; + case 0x2E: // SRA (HL) + break; + case 0x2F: // SRA A + regs.A = tmp; + break; + default: + return(resINV_INST); + break; + } + store1(addr, tmp); + return(resGO); +} + +int +cl_z80::inst_XXcb_slia(t_mem code) +{ + unsigned char tmp; + unsigned short addr; + addr = add_u16_disp(regs_IX_OR_IY, n_offset); + tmp = get1(addr); + slia_byte(tmp); + + switch(code) { + case 0x30: // SLIA B (Shift Left Inverted Arithmetic) + regs.bc.h = tmp; + break; + case 0x31: // SLIA C like SLA, but shifts in a 1 bit + regs.bc.l = tmp; + break; + case 0x32: // SLIA D + regs.de.h = tmp; + break; + case 0x33: // SLIA E + regs.de.l = tmp; + break; + case 0x34: // SLIA H + regs.hl.h = tmp; + break; + case 0x35: // SLIA L + regs.hl.l = tmp; + break; + case 0x36: // SLIA (HL) + break; + case 0x37: // SLIA A + regs.A = tmp; + break; + default: + return(resINV_INST); + break; + } + store1(addr, tmp); + return(resGO); +} + +int +cl_z80::inst_XXcb_srl(t_mem code) +{ + unsigned char tmp; + unsigned short addr; + addr = add_u16_disp(regs_IX_OR_IY, n_offset); + tmp = get1(addr); + srl_byte(tmp); + + switch(code) { + case 0x38: // SRL B + regs.bc.h = tmp; + break; + case 0x39: // SRL C + regs.bc.l = tmp; + break; + case 0x3A: // SRL D + regs.de.h = tmp; + break; + case 0x3B: // SRL E + regs.de.l = tmp; + break; + case 0x3C: // SRL H + regs.hl.h = tmp; + break; + case 0x3D: // SRL L + regs.hl.l = tmp; + break; + case 0x3E: // SRL (HL) + break; + case 0x3F: // SRL A + regs.A = tmp; + break; + default: + return(resINV_INST); + break; + } + store1(addr, tmp); + return(resGO); +} + + +int +cl_z80::inst_XXcb_bit(t_mem code) +{ + unsigned char tmp; + unsigned short addr; + +#define bit_bitnum ((code >> 3) & 7) + + addr = add_u16_disp(regs_IX_OR_IY, n_offset); + tmp = get1(addr); + bit_byte(tmp, bit_bitnum); + + store1(addr, tmp); + + return(resGO); +} + +int +cl_z80::inst_XXcb_res(t_mem code) +{ + unsigned char tmp; + unsigned short addr; + +#define bit_bitnum ((code >> 3) & 7) + + addr = add_u16_disp(regs_IX_OR_IY, n_offset); + tmp = get1(addr); + tmp &= ~(1 << bit_bitnum); + + switch(code & 0x7) { + case 0x0: // RES x,B + regs.bc.h = tmp; break; + case 0x1: // RES x,C + regs.bc.l = tmp; break; + case 0x2: // RES x,D + regs.de.h = tmp; break; + case 0x3: // RES x,E + regs.de.l = tmp; break; + case 0x4: // RES x,H + regs.hl.h = tmp; break; + case 0x5: // RES x,L + regs.hl.l = tmp; break; + case 0x6: // RES x,(HL) + break; + case 0x7: // RES x,A + regs.A = tmp; + break; + } + store1(addr, tmp); + return(resGO); +} + +int +cl_z80::inst_XXcb_set(t_mem code) +{ + unsigned char tmp; + unsigned short addr; + +#define bit_bitnum ((code >> 3) & 7) + + addr = add_u16_disp(regs_IX_OR_IY, n_offset); + tmp = get1(addr); + tmp |= (1 << bit_bitnum); + + switch(code) { + case 0x0: // SET x,B + regs.bc.h = tmp; break; + case 0x1: // SET x,C + regs.bc.l = tmp; break; + case 0x2: // SET x,D + regs.de.h = tmp; break; + case 0x3: // SET x,E + regs.de.l = tmp; break; + case 0x4: // SET x,H + regs.de.h = tmp; break; + case 0x5: // SET x,L + regs.de.h = tmp; break; + case 0x6: // SET x,(IX+dd) + break; + case 0x7: // SET x,A + regs.de.h = tmp; break; + break; + default: + return(resINV_INST); + break; + } + store1(addr, tmp); + return(resGO); +} + +/******** start CB codes *****************/ +int +cl_z80::inst_XXcb(void) +{ + t_mem code; + + // all DD CB escaped opcodes have a 3rd byte which is a displacement, + // 4th byte is opcode extension. + n_offset = fetch(); + + if (fetch(&code)) + return(resBREAKPOINT); + tick(1); + switch (code) + { + case 0x00: // RLC B + case 0x01: // RLC C + case 0x02: // RLC D + case 0x03: // RLC E + case 0x04: // RLC H + case 0x05: // RLC L + case 0x06: // RLC (HL) + case 0x07: // RLC A + return (inst_XXcb_rlc(code)); + case 0x08: // RRC B + case 0x09: // RRC C + case 0x0A: // RRC D + case 0x0B: // RRC E + case 0x0C: // RRC H + case 0x0D: // RRC L + case 0x0E: // RRC (HL) + case 0x0F: // RRC A + return (inst_XXcb_rrc(code)); + case 0x10: // RL B + case 0x11: // RL C + case 0x12: // RL D + case 0x13: // RL E + case 0x14: // RL H + case 0x15: // RL L + case 0x16: // RL (HL) + case 0x17: // RL A + return (inst_XXcb_rl(code)); + case 0x18: // RR B + case 0x19: // RR C + case 0x1A: // RR D + case 0x1B: // RR E + case 0x1C: // RR H + case 0x1D: // RR L + case 0x1E: // RR (HL) + case 0x1F: // RR A + return (inst_XXcb_rr(code)); + case 0x20: // SLA B + case 0x21: // SLA C + case 0x22: // SLA D + case 0x23: // SLA E + case 0x24: // SLA H + case 0x25: // SLA L + case 0x26: // SLA (HL) + case 0x27: // SLA A + return (inst_XXcb_sla(code)); + case 0x28: // SRA B + case 0x29: // SRA C + case 0x2A: // SRA D + case 0x2B: // SRA E + case 0x2C: // SRA H + case 0x2D: // SRA L + case 0x2E: // SRA (HL) + case 0x2F: // SRA A + return (inst_XXcb_sra(code)); + case 0x30: // SLIA B (Shift Left Inverted Arithmetic) + case 0x31: // SLIA C like SLA, but shifts in a 1 bit + case 0x32: // SLIA D + case 0x33: // SLIA E + case 0x34: // SLIA H + case 0x35: // SLIA L + case 0x36: // SLIA (HL) + case 0x37: // SLIA A + return (inst_XXcb_slia(code)); + case 0x38: // SRL B + case 0x39: // SRL C + case 0x3A: // SRL D + case 0x3B: // SRL E + case 0x3C: // SRL H + case 0x3D: // SRL L + case 0x3E: // SRL (HL) + case 0x3F: // SRL A + return (inst_XXcb_srl(code)); + case 0x46: // BIT 0,(HL) + case 0x4E: // BIT 1,(HL) + case 0x56: // BIT 2,(HL) + case 0x5E: // BIT 3,(HL) + case 0x66: // BIT 4,(HL) + case 0x6E: // BIT 5,(HL) + case 0x76: // BIT 6,(HL) + case 0x7E: // BIT 7,(HL) + return (inst_XXcb_bit(code)); + case 0x80: // RES 0,B + case 0x81: // RES 0,C + case 0x82: // RES 0,D + case 0x83: // RES 0,E + case 0x84: // RES 0,H + case 0x85: // RES 0,L + case 0x86: // RES 0,(HL) + case 0x87: // RES 0,A + case 0x88: // RES 1,B + case 0x89: // RES 1,C + case 0x8A: // RES 1,D + case 0x8B: // RES 1,E + case 0x8C: // RES 1,H + case 0x8D: // RES 1,L + case 0x8E: // RES 1,(HL) + case 0x8F: // RES 1,A + case 0x90: // RES 2,B + case 0x91: // RES 2,C + case 0x92: // RES 2,D + case 0x93: // RES 2,E + case 0x94: // RES 2,H + case 0x95: // RES 2,L + case 0x96: // RES 2,(HL) + case 0x97: // RES 2,A + case 0x98: // RES 3,B + case 0x99: // RES 3,C + case 0x9A: // RES 3,D + case 0x9B: // RES 3,E + case 0x9C: // RES 3,H + case 0x9D: // RES 3,L + case 0x9E: // RES 3,(HL) + case 0x9F: // RES 3,A + case 0xA0: // RES 4,B + case 0xA1: // RES 4,C + case 0xA2: // RES 4,D + case 0xA3: // RES 4,E + case 0xA4: // RES 4,H + case 0xA5: // RES 4,L + case 0xA6: // RES 4,(HL) + case 0xA7: // RES 4,A + case 0xA8: // RES 5,B + case 0xA9: // RES 5,C + case 0xAA: // RES 5,D + case 0xAB: // RES 5,E + case 0xAC: // RES 5,H + case 0xAD: // RES 5,L + case 0xAE: // RES 5,(HL) + case 0xAF: // RES 5,A + case 0xB0: // RES 6,B + case 0xB1: // RES 6,C + case 0xB2: // RES 6,D + case 0xB3: // RES 6,E + case 0xB4: // RES 6,H + case 0xB5: // RES 6,L + case 0xB6: // RES 6,(HL) + case 0xB7: // RES 6,A + case 0xB8: // RES 7,B + case 0xB9: // RES 7,C + case 0xBA: // RES 7,D + case 0xBB: // RES 7,E + case 0xBC: // RES 7,H + case 0xBD: // RES 7,L + case 0xBE: // RES 7,(HL) + case 0xBF: // RES 7,A + return (inst_XXcb_res(code)); + case 0xC0: // SET 0,B + case 0xC1: // SET 0,C + case 0xC2: // SET 0,D + case 0xC3: // SET 0,E + case 0xC4: // SET 0,H + case 0xC5: // SET 0,L + case 0xC6: // SET 0,(HL) + case 0xC7: // SET 0,A + case 0xC8: // SET 1,B + case 0xC9: // SET 1,C + case 0xCA: // SET 1,D + case 0xCB: // SET 1,E + case 0xCC: // SET 1,H + case 0xCD: // SET 1,L + case 0xCE: // SET 1,(HL) + case 0xCF: // SET 1,A + case 0xD0: // SET 2,B + case 0xD1: // SET 2,C + case 0xD2: // SET 2,D + case 0xD3: // SET 2,E + case 0xD4: // SET 2,H + case 0xD5: // SET 2,L + case 0xD6: // SET 2,(HL) + case 0xD7: // SET 2,A + case 0xD8: // SET 3,B + case 0xD9: // SET 3,C + case 0xDA: // SET 3,D + case 0xDB: // SET 3,E + case 0xDC: // SET 3,H + case 0xDD: // SET 3,L + case 0xDE: // SET 3,(HL) + case 0xDF: // SET 3,A + case 0xE0: // SET 4,B + case 0xE1: // SET 4,C + case 0xE2: // SET 4,D + case 0xE3: // SET 4,E + case 0xE4: // SET 4,H + case 0xE5: // SET 4,L + case 0xE6: // SET 4,(HL) + case 0xE7: // SET 4,A + case 0xE8: // SET 5,B + case 0xE9: // SET 5,C + case 0xEA: // SET 5,D + case 0xEB: // SET 5,E + case 0xEC: // SET 5,H + case 0xED: // SET 5,L + case 0xEE: // SET 5,(HL) + case 0xEF: // SET 5,A + case 0xF0: // SET 6,B + case 0xF1: // SET 6,C + case 0xF2: // SET 6,D + case 0xF3: // SET 6,E + case 0xF4: // SET 6,H + case 0xF5: // SET 6,L + case 0xF6: // SET 6,(HL) + case 0xF7: // SET 6,A + case 0xF8: // SET 7,B + case 0xF9: // SET 7,C + case 0xFA: // SET 7,D + case 0xFB: // SET 7,E + case 0xFC: // SET 7,H + case 0xFD: // SET 7,L + case 0xFE: // SET 7,(HL) + case 0xFF: // SET 7,A + return (inst_XXcb_set(code)); + } + if (PC) + PC--; + else + PC= get_mem_size(MEM_ROM)-1; + return(resINV_INST); +} + +/* End of z80.src/inst_xxcb.cc */ diff --git a/sim/ucsim/z80.src/instcl.h b/sim/ucsim/z80.src/instcl.h index f000e94c..074ca41d 100644 --- a/sim/ucsim/z80.src/instcl.h +++ b/sim/ucsim/z80.src/instcl.h @@ -1,5 +1,97 @@ /* avr.src/instcl.h */ - virtual int nop(t_mem code); + virtual int inst_nop(t_mem code); + virtual int inst_ld(t_mem code); + virtual int inst_inc(t_mem code); + virtual int inst_dec(t_mem code); + virtual int inst_rlca(t_mem code); + virtual int inst_rrca(t_mem code); + virtual int inst_ex(t_mem code); + virtual int inst_add(t_mem code); + virtual int inst_djnz(t_mem code); + virtual int inst_jr(t_mem code); + virtual int inst_rla(t_mem code); + virtual int inst_rra(t_mem code); + virtual int inst_daa(t_mem code); + virtual int inst_cpl(t_mem code); + virtual int inst_scf(t_mem code); + virtual int inst_ccf(t_mem code); + virtual int inst_halt(t_mem code); + virtual int inst_adc(t_mem code); + virtual int inst_sbc(t_mem code); + virtual int inst_and(t_mem code); + virtual int inst_xor(t_mem code); + virtual int inst_or(t_mem code); + virtual int inst_cp(t_mem code); + virtual int inst_rst(t_mem code); + virtual int inst_ret(t_mem code); + virtual int inst_call(t_mem code); + virtual int inst_out(t_mem code); + virtual int inst_push(t_mem code); + virtual int inst_exx(t_mem code); + virtual int inst_in(t_mem code); + virtual int inst_sub(t_mem code); + virtual int inst_pop(t_mem code); + virtual int inst_jp(t_mem code); + virtual int inst_di(t_mem code); + virtual int inst_ei(t_mem code); + + virtual int inst_fd(void); + virtual int inst_fd_ld(t_mem code); + virtual int inst_fd_add(t_mem code); + virtual int inst_fd_push(t_mem code); + virtual int inst_fd_inc(t_mem code); + virtual int inst_fd_dec(t_mem code); + virtual int inst_fd_misc(t_mem code); + + virtual int inst_dd(void); + virtual int inst_dd_ld(t_mem code); + virtual int inst_dd_add(t_mem code); + virtual int inst_dd_push(t_mem code); + virtual int inst_dd_inc(t_mem code); + virtual int inst_dd_dec(t_mem code); + virtual int inst_dd_misc(t_mem code); + + virtual int inst_ed(void); + virtual int inst_ed_(t_mem code); + + virtual int inst_cb(void); + virtual int inst_cb_rlc(t_mem code); + virtual int inst_cb_rrc(t_mem code); + virtual int inst_cb_rl(t_mem code); + virtual int inst_cb_rr(t_mem code); + virtual int inst_cb_sla(t_mem code); + virtual int inst_cb_sra(t_mem code); + virtual int inst_cb_slia(t_mem code); + virtual int inst_cb_srl(t_mem code); + virtual int inst_cb_bit(t_mem code); + virtual int inst_cb_res(t_mem code); + virtual int inst_cb_set(t_mem code); + + virtual int inst_ddcb(void); + virtual int inst_ddcb_rlc(t_mem code); + virtual int inst_ddcb_rrc(t_mem code); + virtual int inst_ddcb_rl(t_mem code); + virtual int inst_ddcb_rr(t_mem code); + virtual int inst_ddcb_sla(t_mem code); + virtual int inst_ddcb_sra(t_mem code); + virtual int inst_ddcb_slia(t_mem code); + virtual int inst_ddcb_srl(t_mem code); + virtual int inst_ddcb_bit(t_mem code); + virtual int inst_ddcb_res(t_mem code); + virtual int inst_ddcb_set(t_mem code); + + virtual int inst_fdcb(void); + virtual int inst_fdcb_rlc(t_mem code); + virtual int inst_fdcb_rrc(t_mem code); + virtual int inst_fdcb_rl(t_mem code); + virtual int inst_fdcb_rr(t_mem code); + virtual int inst_fdcb_sla(t_mem code); + virtual int inst_fdcb_sra(t_mem code); + virtual int inst_fdcb_slia(t_mem code); + virtual int inst_fdcb_srl(t_mem code); + virtual int inst_fdcb_bit(t_mem code); + virtual int inst_fdcb_res(t_mem code); + virtual int inst_fdcb_set(t_mem code); /* End of avr.src/instcl.h */ diff --git a/sim/ucsim/z80.src/regsz80.h b/sim/ucsim/z80.src/regsz80.h index b176a016..7f85f83d 100644 --- a/sim/ucsim/z80.src/regsz80.h +++ b/sim/ucsim/z80.src/regsz80.h @@ -1,6 +1,8 @@ /* * Simulator of microcontrollers (regsz80.h) * + * some z80 code base from Karl Bongers karl@turbobit.com + * * Copyright (C) 1999,99 Drotos Daniel, Talker Bt. * * To contact author send email to drdani@mazsola.iit.uni-miskolc.hu @@ -25,8 +27,8 @@ Software Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ /*@1@*/ -#ifndef REGSAVR_HEADER -#define REGSAVR_HEADER +#ifndef REGSZ80_HEADER +#define REGSZ80_HEADER #include "ddconfig.h" @@ -55,17 +57,33 @@ struct t_regs DEF_REGPAIR(BC, bc); DEF_REGPAIR(DE, de); DEF_REGPAIR(HL, hl); - TYPE_UWORD IX; - TYPE_UWORD IY; + DEF_REGPAIR(IX, ix); + DEF_REGPAIR(IY, iy); TYPE_UWORD SP; + /* there are alternate AF,BC,DE,HL register sets, and a few instructions + that swap one for the other */ + TYPE_UBYTE aA; + TYPE_UBYTE aF; + DEF_REGPAIR(aBC, a_bc); + DEF_REGPAIR(aDE, a_de); + DEF_REGPAIR(aHL, a_hl); + TYPE_UBYTE iv; /* interrupt vector, see ed 47 ld A,IV.. */ }; -#define BIT_C 0x01 -#define BIT_P 0x04 -#define BIT_A 0x10 -#define BIT_Z 0x40 -#define BIT_S 0x80 +#define BIT_C 0x01 // carry status(out of bit 7) +#define BIT_N 0x02 // Not addition: subtract status(1 after subtract). +#define BIT_P 0x04 // parity/overflow, 1=even, 0=odd parity. arith:1=overflow +#define BIT_A 0x10 // aux carry status(out of bit 3) +#define BIT_Z 0x40 // zero status, 1=zero, 0=nonzero +#define BIT_S 0x80 // sign status(value of bit 7) +#define BIT_ALL (BIT_C |BIT_N |BIT_P |BIT_A |BIT_Z |BIT_S) // all bits +#define BITPOS_C 0 // 1 +#define BITPOS_SUB 1 // 2H +#define BITPOS_P 2 // 4H +#define BITPOS_A 4 // 10H +#define BITPOS_Z 6 // 40H +#define BITPOS_S 7 // 80H #endif diff --git a/sim/ucsim/z80.src/z80.cc b/sim/ucsim/z80.src/z80.cc index 3c7cc119..e0b1b123 100644 --- a/sim/ucsim/z80.src/z80.cc +++ b/sim/ucsim/z80.src/z80.cc @@ -1,6 +1,8 @@ /* * Simulator of microcontrollers (z80.cc) * + * some z80 code base from Karl Bongers karl@turbobit.com + * * Copyright (C) 1999,99 Drotos Daniel, Talker Bt. * * To contact author send email to drdani@mazsola.iit.uni-miskolc.hu @@ -27,6 +29,7 @@ Software Foundation, 59 Temple Place - Suite 330, Boston, MA #include "ddconfig.h" +#include /* for va_list */ #include #include #include @@ -43,6 +46,12 @@ Software Foundation, 59 Temple Place - Suite 330, Boston, MA #include "glob.h" #include "regsz80.h" +#define uint32 t_addr +#define uint8 unsigned char +#define int8 char + +/*******************************************************************/ + /* * Base type of Z80 controllers @@ -58,8 +67,16 @@ int cl_z80::init(void) { cl_uc::init(); /* Memories now exist */ - ram= mem(MEM_XRAM); + rom= mem(MEM_ROM); +// ram= mem(MEM_XRAM); + ram= rom; + + // zero out ram(this is assumed in regression tests) + for (int i=0x8000; i<0x10000; i++) { + ram->set((t_addr) i, 0); + } + return(0); } @@ -117,28 +134,178 @@ cl_z80::bit_tbl(void) return(0); }*/ +int +cl_z80::inst_length(t_addr addr) +{ + int len = 0; + char *s; + + s = get_disasm_info(addr, &len, NULL, NULL); + + return len; +} + +int +cl_z80::inst_branch(t_addr addr) +{ + int b; + char *s; + + s = get_disasm_info(addr, NULL, &b, NULL); + + return b; +} + +int +cl_z80::longest_inst(void) +{ + return 4; +} + + +char * +cl_z80::get_disasm_info(t_addr addr, + int *ret_len, + int *ret_branch, + int *immed_offset) +{ + char *b = NULL; + uint code; + int len = 0; + int immed_n = 0; + int i; + int start_addr = addr; + struct dis_entry *dis_e; + + code= get_mem(MEM_ROM, addr++); + dis_e = NULL; + + switch(code) { + case 0xcb: /* ESC code to lots of op-codes, all 2-byte */ + code= get_mem(MEM_ROM, addr++); + i= 0; + while ((code & disass_z80_cb[i].mask) != disass_z80_cb[i].code && + disass_z80_cb[i].mnemonic) + i++; + dis_e = &disass_z80_cb[i]; + b= disass_z80_cb[i].mnemonic; + if (b != NULL) + len += (disass_z80_cb[i].length + 1); + break; + + case 0xed: /* ESC code to about 80 opcodes of various lengths */ + code= get_mem(MEM_ROM, addr++); + i= 0; + while ((code & disass_z80_ed[i].mask) != disass_z80_ed[i].code && + disass_z80_ed[i].mnemonic) + i++; + dis_e = &disass_z80_ed[i]; + b= disass_z80_ed[i].mnemonic; + if (b != NULL) + len += (disass_z80_ed[i].length + 1); + break; + + case 0xdd: /* ESC codes,about 284, vary lengths, IX centric */ + code= get_mem(MEM_ROM, addr++); + if (code == 0xcb) { + immed_n = 2; + addr++; // pass up immed data + code= get_mem(MEM_ROM, addr++); + i= 0; + while ((code & disass_z80_ddcb[i].mask) != disass_z80_ddcb[i].code && + disass_z80_ddcb[i].mnemonic) + i++; + dis_e = &disass_z80_ddcb[i]; + b= disass_z80_ddcb[i].mnemonic; + if (b != NULL) + len += (disass_z80_ddcb[i].length + 2); + } else { + i= 0; + while ((code & disass_z80_dd[i].mask) != disass_z80_dd[i].code && + disass_z80_dd[i].mnemonic) + i++; + dis_e = &disass_z80_dd[i]; + b= disass_z80_dd[i].mnemonic; + if (b != NULL) + len += (disass_z80_dd[i].length + 1); + } + break; + + case 0xfd: /* ESC codes,sme as dd but IY centric */ + code= get_mem(MEM_ROM, addr++); + if (code == 0xcb) { + immed_n = 2; + addr++; // pass up immed data + code= get_mem(MEM_ROM, addr++); + i= 0; + while ((code & disass_z80_fdcb[i].mask) != disass_z80_fdcb[i].code && + disass_z80_fdcb[i].mnemonic) + i++; + dis_e = &disass_z80_fdcb[i]; + b= disass_z80_fdcb[i].mnemonic; + if (b != NULL) + len += (disass_z80_fdcb[i].length + 2); + } else { + i= 0; + while ((code & disass_z80_fd[i].mask) != disass_z80_fd[i].code && + disass_z80_fd[i].mnemonic) + i++; + dis_e = &disass_z80_fd[i]; + b= disass_z80_fd[i].mnemonic; + if (b != NULL) + len += (disass_z80_fd[i].length + 1); + } + break; + + default: + i= 0; + while ((code & disass_z80[i].mask) != disass_z80[i].code && + disass_z80[i].mnemonic) + i++; + dis_e = &disass_z80[i]; + b= disass_z80[i].mnemonic; + if (b != NULL) + len += (disass_z80[i].length); + break; + } + + + if (ret_branch) { + *ret_branch = dis_e->branch; + } + + if (immed_offset) { + if (immed_n > 0) + *immed_offset = immed_n; + else *immed_offset = (addr - start_addr); + } + + if (len == 0) + len = 1; + + if (ret_len) + *ret_len = len; + + return b; +} + char * cl_z80::disass(t_addr addr, char *sep) { char work[256], temp[20]; char *buf, *p, *b, *t; - uint code, data= 0; - int i; + int len = 0; + int immed_offset = 0; p= work; + + b = get_disasm_info(addr, &len, NULL, &immed_offset); - code= get_mem(MEM_ROM, addr); - i= 0; - while ((code & dis_tbl()[i].mask) != dis_tbl()[i].code && - dis_tbl()[i].mnemonic) - i++; - if (dis_tbl()[i].mnemonic == NULL) - { - buf= (char*)malloc(30); - strcpy(buf, "UNKNOWN/INVALID"); - return(buf); - } - b= dis_tbl()[i].mnemonic; + if (b == NULL) { + buf= (char*)malloc(30); + strcpy(buf, "UNKNOWN/INVALID"); + return(buf); + } while (*b) { @@ -147,76 +314,21 @@ cl_z80::disass(t_addr addr, char *sep) b++; switch (*(b++)) { - case 'd': // Rd .... ...d dddd .... 0<=d<=31 - if (!get_name(data= (code&0x01f0)>>4, sfr_tbl(), temp)) - sprintf(temp, "r%d", data); - break; - case 'D': // Rd .... .... dddd .... 16<=d<=31 - if (!get_name(data= 16+((code&0xf0)>>4), sfr_tbl(), temp)) - sprintf(temp, "r%d", data); - break; - case 'K': // K .... KKKK .... KKKK 0<=K<=255 - sprintf(temp, "%d", ((code&0xf00)>>4)|(code&0xf)); + case 'd': // d jump relative target, signed? byte immediate operand + sprintf(temp, "#%d", (char)get_mem(MEM_ROM, addr+immed_offset)); + ++immed_offset; break; - case 'r': // Rr .... ..r. .... rrrr 0<=r<=31 - if (!get_name(data= ((code&0x0200)>>5)|(code&0x000f), - sfr_tbl(), temp)) - sprintf(temp, "r%d", data); + case 'w': // w word immediate operand + sprintf(temp, "#0x%04x", + (uint)((get_mem(MEM_ROM, addr+immed_offset)) | + (get_mem(MEM_ROM, addr+immed_offset+1)<<8)) ); + ++immed_offset; + ++immed_offset; break; - case '2': // Rdl .... .... ..dd .... dl= {24,26,28,30} - if (!get_name(data= 24+(2*((code&0x0030)>>4)), - sfr_tbl(), temp)) - sprintf(temp, "r%d", data); + case 'b': // b byte immediate operand + sprintf(temp, "#0x%02x", (uint)get_mem(MEM_ROM, addr+immed_offset)); + ++immed_offset; break; - case '6': // K .... .... KK.. KKKK 0<=K<=63 - sprintf(temp, "%d", ((code&0xc0)>>2)|(code&0xf)); - break; - case 's': // s .... .... .sss .... 0<=s<=7 - sprintf(temp, "%d", (code&0x70)>>4); - break; - case 'b': // b .... .... .... .bbb 0<=b<=7 - sprintf(temp, "%d", code&0x7); - break; - case 'k': // k .... ..kk kkkk k... -64<=k<=+63 - { - int k= (code&0x3f8)>>3; - if (code&0x200) - k|= -128; - sprintf(temp, "0x%06x", k+1+(signed int)addr); - break; - } - case 'A': // k .... ...k kkkk ...k 0<=k<=64K - // kkkk kkkk kkkk kkkk 0<=k<=4M - sprintf(temp, "0x%06x", - (((code&0x1f0)>>3)|(code&1))*0x10000+ - (uint)get_mem(MEM_ROM, addr+1)); - break; - case 'P': // P .... .... pppp p... 0<=P<=31 - data= (code&0xf8)>>3; - if (!get_name(data+0x20, sfr_tbl(), temp)) - sprintf(temp, "%d", data); - break; - case 'p': // P .... .PP. .... PPPP 0<=P<=63 - data= ((code&0x600)>>5)|(code&0xf); - if (!get_name(data+0x20, sfr_tbl(), temp)) - sprintf(temp, "%d", data); - break; - case 'q': // q ..q. qq.. .... .qqq 0<=q<=63 - sprintf(temp, "%d", - ((code&0x2000)>>8)|((code&0xc00)>>7)|(code&7)); - break; - case 'R': // k SRAM address on second word 0<=k<=65535 - sprintf(temp, "0x%06x", (uint)get_mem(MEM_ROM, addr+1)); - break; - case 'a': // k .... kkkk kkkk kkkk -2k<=k<=2k - { - int k= code&0xfff; - if (code&0x800) - k|= -4096; - sprintf(temp, "0x%06lx", - (k+1+(signed int)addr) % rom->size); - break; - } default: strcpy(temp, "?"); break; @@ -291,7 +403,6 @@ cl_z80::print_regs(class cl_console *con) print_disass(PC, con); } - /* * Execution */ @@ -306,14 +417,187 @@ cl_z80::exec_inst(void) tick(1); switch (code) { - case 0x00: - return(nop(code)); + case 0x00: return(inst_nop(code)); + case 0x01: case 0x02: case 0x06: return(inst_ld(code)); + case 0x03: case 0x04: return(inst_inc(code)); + case 0x05: return(inst_dec(code)); + case 0x07: return(inst_rlca(code)); + + case 0x08: return(inst_ex(code)); + case 0x09: return(inst_add(code)); + case 0x0a: case 0x0e: return(inst_ld(code)); + case 0x0b: case 0x0d: return(inst_dec(code)); + case 0x0c: return(inst_inc(code)); + case 0x0f: return(inst_rrca(code)); + + + case 0x10: return(inst_djnz(code)); + case 0x11: case 0x12: case 0x16: return(inst_ld(code)); + case 0x13: case 0x14: return(inst_inc(code)); + case 0x15: return(inst_dec(code)); + case 0x17: return(inst_rla(code)); + + case 0x18: return(inst_jr(code)); + case 0x19: return(inst_add(code)); + case 0x1a: case 0x1e: return(inst_ld(code)); + case 0x1b: case 0x1d: return(inst_dec(code)); + case 0x1c: return(inst_inc(code)); + case 0x1f: return(inst_rra(code)); + + + case 0x20: return(inst_jr(code)); + case 0x21: case 0x22: case 0x26: return(inst_ld(code)); + case 0x23: case 0x24: return(inst_inc(code)); + case 0x25: return(inst_dec(code)); + case 0x27: return(inst_daa(code)); + + case 0x28: return(inst_jr(code)); + case 0x29: return(inst_add(code)); + case 0x2a: case 0x2e: return(inst_ld(code)); + case 0x2b: case 0x2d: return(inst_dec(code)); + case 0x2c: return(inst_inc(code)); + case 0x2f: return(inst_cpl(code)); + + + case 0x30: return(inst_jr(code)); + case 0x31: case 0x32: case 0x36: return(inst_ld(code)); + case 0x33: case 0x34: return(inst_inc(code)); + case 0x35: return(inst_dec(code)); + case 0x37: return(inst_scf(code)); + + case 0x38: return(inst_jr(code)); + case 0x39: return(inst_add(code)); + case 0x3a: case 0x3e: return(inst_ld(code)); + case 0x3b: case 0x3d: return(inst_dec(code)); + case 0x3c: return(inst_inc(code)); + case 0x3f: return(inst_ccf(code)); + + case 0x40: case 0x41: case 0x42: case 0x43: case 0x44: case 0x45: case 0x46: case 0x47: + case 0x48: case 0x49: case 0x4a: case 0x4b: case 0x4c: case 0x4d: case 0x4e: case 0x4f: + return(inst_ld(code)); + + case 0x50: case 0x51: case 0x52: case 0x53: case 0x54: case 0x55: case 0x56: case 0x57: + case 0x58: case 0x59: case 0x5a: case 0x5b: case 0x5c: case 0x5d: case 0x5e: case 0x5f: + return(inst_ld(code)); + + case 0x60: case 0x61: case 0x62: case 0x63: case 0x64: case 0x65: case 0x66: case 0x67: + case 0x68: case 0x69: case 0x6a: case 0x6b: case 0x6c: case 0x6d: case 0x6e: case 0x6f: + return(inst_ld(code)); + + case 0x70: case 0x71: case 0x72: case 0x73: case 0x74: case 0x75: case 0x77: + case 0x78: case 0x79: case 0x7a: case 0x7b: case 0x7c: case 0x7d: case 0x7e: case 0x7f: + return(inst_ld(code)); + case 0x76: + return(inst_halt(code)); + + case 0x80: case 0x81: case 0x82: case 0x83: case 0x84: case 0x85: case 0x86: case 0x87: + return(inst_add(code)); + case 0x88: case 0x89: case 0x8a: case 0x8b: case 0x8c: case 0x8d: case 0x8e: case 0x8f: + return(inst_adc(code)); + + case 0x90: case 0x91: case 0x92: case 0x93: case 0x94: case 0x95: case 0x96: case 0x97: + return(inst_sub(code)); + case 0x98: case 0x99: case 0x9a: case 0x9b: case 0x9c: case 0x9d: case 0x9e: case 0x9f: + return(inst_sbc(code)); + + case 0xa0: case 0xa1: case 0xa2: case 0xa3: case 0xa4: case 0xa5: case 0xa6: case 0xa7: + return(inst_and(code)); + case 0xa8: case 0xa9: case 0xaa: case 0xab: case 0xac: case 0xad: case 0xae: case 0xaf: + return(inst_xor(code)); + + case 0xb0: case 0xb1: case 0xb2: case 0xb3: case 0xb4: case 0xb5: case 0xb6: case 0xb7: + return(inst_or(code)); + case 0xb8: case 0xb9: case 0xba: case 0xbb: case 0xbc: case 0xbd: case 0xbe: case 0xbf: + return(inst_cp(code)); + + case 0xc0: return(inst_ret(code)); + case 0xc1: return(inst_pop(code)); + case 0xc2: case 0xc3: return(inst_jp(code)); + case 0xc4: return(inst_call(code)); + case 0xc5: return(inst_push(code)); + case 0xc6: return(inst_add(code)); + case 0xc7: return(inst_rst(code)); + + case 0xc8: case 0xc9: return(inst_ret(code)); + case 0xca: return(inst_jp(code)); + + /* CB escapes out to 2 byte opcodes(CB include), opcodes + to do register bit manipulations */ + case 0xcb: return(inst_cb()); + case 0xcc: case 0xcd: return(inst_call(code)); + case 0xce: return(inst_adc(code)); + case 0xcf: return(inst_rst(code)); + + + case 0xd0: return(inst_ret(code)); + case 0xd1: return(inst_pop(code)); + case 0xd2: return(inst_jp(code)); + case 0xd3: return(inst_out(code)); + case 0xd4: return(inst_call(code)); + case 0xd5: return(inst_push(code)); + case 0xd6: return(inst_sub(code)); + case 0xd7: return(inst_rst(code)); + + case 0xd8: return(inst_ret(code)); + case 0xd9: return(inst_exx(code)); + case 0xda: return(inst_jp(code)); + case 0xdb: return(inst_in(code)); + case 0xdc: return(inst_call(code)); + /* DD escapes out to 2 to 4 byte opcodes(DD included) + with a variety of uses. It can precede the CB escape + sequence to extend CB codes with IX+immed_byte */ + case 0xdd: return(inst_dd()); + case 0xde: return(inst_sbc(code)); + case 0xdf: return(inst_rst(code)); + + + case 0xe0: return(inst_ret(code)); + case 0xe1: return(inst_pop(code)); + case 0xe2: return(inst_jp(code)); + case 0xe3: return(inst_ex(code)); + case 0xe4: return(inst_call(code)); + case 0xe5: return(inst_push(code)); + case 0xe6: return(inst_and(code)); + case 0xe7: return(inst_rst(code)); + + case 0xe8: return(inst_ret(code)); + case 0xe9: return(inst_jp(code)); + case 0xea: return(inst_jp(code)); + case 0xeb: return(inst_ex(code)); + case 0xec: return(inst_call(code)); + /* ED escapes out to misc IN, OUT and other oddball opcodes */ + case 0xed: return(inst_ed()); + case 0xee: return(inst_xor(code)); + case 0xef: return(inst_rst(code)); + + + case 0xf0: return(inst_ret(code)); + case 0xf1: return(inst_pop(code)); + case 0xf2: return(inst_jp(code)); + case 0xf3: return(inst_di(code)); + case 0xf4: return(inst_call(code)); + case 0xf5: return(inst_push(code)); + case 0xf6: return(inst_or(code)); + case 0xf7: return(inst_rst(code)); + + case 0xf8: return(inst_ret(code)); + case 0xf9: return(inst_ld(code)); + case 0xfa: return(inst_jp(code)); + case 0xfb: return(inst_ei(code)); + case 0xfc: return(inst_call(code)); + /* DD escapes out to 2 to 4 byte opcodes(DD included) + with a variety of uses. It can precede the CB escape + sequence to extend CB codes with IX+immed_byte */ + case 0xfd: return(inst_fd()); + case 0xfe: return(inst_cp(code)); + case 0xff: return(inst_rst(code)); } + if (PC) PC--; else PC= get_mem_size(MEM_ROM)-1; - //tick(-clock_per_cycle()); + sim->stop(resINV_INST); return(resINV_INST); } diff --git a/sim/ucsim/z80.src/z80.txt b/sim/ucsim/z80.src/z80.txt new file mode 100644 index 00000000..4b1be260 --- /dev/null +++ b/sim/ucsim/z80.src/z80.txt @@ -0,0 +1,1402 @@ + +Last week somebody asked for a list of opcodes. +Well, here is mine. Have fun! + +| Herbert Oppmann | email: htoppman@cip.informatik.uni-erlangen.de | +| irc: mtx | mail: Drausnickstrasse 29, D-8520 Erlangen | + +------------ 8< ---------- 8< --------------- +8080/Z80/HD64180 opcodes + +Legend: +HX, LX highbyte/lowbyte of IX +HY, LY dito IY + + 8080 subset +* Z80 only +/ "illegal" Z80 ++ HD 64180 (reacts with a trap to illegal Z80 opcodes) + +Hex Instruction Comment (applies to Z80 only) +----------------------------------------------- +00 NOP +01 nnnn LD BC,nnnn +02 LD (BC),A +03 INC BC +04 INC B +05 DEC B +06 nn LD B,nn +07 RLCA +08 * EX AF,AF' +09 ADD HL,BC +0A LD A,(BC) +0B DEC BC +0C INC C +0D DEC C +0E nn LD C,nn +0F RRCA +10 dd * DJNZ dd +11 nnnn LD DE,nnnn +12 LD (DE),A +13 INC DE +14 INC D +15 DEC D +16 nn LD D,nn +17 RLA +18 dd * JR dd +19 ADD HL,DE +1A LD A,(DE) +1B DEC DE +1C INC E +1D DEC E +1E nn LD E,nn +1F RRA +20 dd * JR NZ,dd +21 nnnn LD HL,nnnn +22 nnnn LD (nnnn),HL +23 INC HL +24 INC H +25 DEC H +26 nn LD H,nn +27 DAA +28 dd * JR Z,dd +29 ADD HL,HL +2A nnnn LD HL,(nnnn) +2B DEC HL +2C INC L +2D DEC L +2E nn LD L,nn +2F CPL +30 dd * JR NC,dd +31 nnnn LD SP,nnnn +32 nnnn LD (nnnn),A +33 INC SP +34 INC (HL) +35 DEC (HL) +36 nn LD (HL),nn +37 SCF +38 dd * JR C,dd +39 ADD HL,SP +3A nnnn LD A,(nnnn) +3B DEC SP +3C INC A +3D DEC A +3E nn LD A,nn +3F CCF +40 LD B,B +41 LD B,C +42 LD B,D +43 LD B,E +44 LD B,H +45 LD B,L +46 LD B,(HL) +47 LD B,A +48 LD C,B +49 LD C,C +4A LD C,D +4B LD C,E +4C LD C,H +4D LD C,L +4E LD C,(HL) +4F LD C,A +50 LD D,B +51 LD D,C +52 LD D,D +53 LD D,E +54 LD D,H +55 LD D,L +56 LD D,(HL) +57 LD D,A +58 LD E,B +59 LD E,C +5A LD E,D +5B LD E,E +5C LD E,H +5D LD E,L +5E LD E,(HL) +5F LD E,A +60 LD H,B +61 LD H,C +62 LD H,D +63 LD H,E +64 LD H,H +65 LD H,L +66 LD H,(HL) +67 LD H,A +68 LD L,B +69 LD L,C +6A LD L,D +6B LD L,E +6C LD L,H +6D LD L,L +6E LD L,(HL) +6F LD L,A +70 LD (HL),B +71 LD (HL),C +72 LD (HL),D +73 LD (HL),E +74 LD (HL),H +75 LD (HL),L +76 HALT +77 LD (HL),A +78 LD A,B +79 LD A,C +7A LD A,D +7B LD A,E +7C LD A,H +7D LD A,L +7E LD A,(HL) +7F LD A,A +80 ADD A,B +81 ADD A,C +82 ADD A,D +83 ADD A,E +84 ADD A,H +85 ADD A,L +86 ADD A,(HL) +87 ADD A,A +88 ADC A,B +89 ADC A,C +8A ADC A,D +8B ADC A,E +8C ADC A,H +8D ADC A,L +8E ADC A,(HL) +8F ADC A,A +90 SUB B +91 SUB C +92 SUB D +93 SUB E +94 SUB H +95 SUB L +96 SUB (HL) +97 SUB A +98 SBC A,B +99 SBC A,C +9A SBC A,D +9B SBC A,E +9C SBC A,H +9D SBC A,L +9E SBC A,(HL) +9F SBC A,A +A0 AND B +A1 AND C +A2 AND D +A3 AND E +A4 AND H +A5 AND L +A6 AND (HL) +A7 AND A +A8 XOR B +A9 XOR C +AA XOR D +AB XOR E +AC XOR H +AD XOR L +AE XOR (HL) +AF XOR A +B0 OR B +B1 OR C +B2 OR D +B3 OR E +B4 OR H +B5 OR L +B6 OR (HL) +B7 OR A +B8 CP B +B9 CP C +BA CP D +BB CP E +BC CP H +BD CP L +BE CP (HL) +BF CP A +C0 RET NZ +C1 POP BC +C2 nnnn JP NZ,nnnn +C3 nnnn JP nnnn +C4 nnnn CALL NZ,nnnn +C5 PUSH BC +C6 nn ADD A,nn +C7 RST 0 +C8 RET Z +C9 RET +CA nnnn JP Z,nnnn +CB 00 * RLC B +CB 01 * RLC C +CB 02 * RLC D +CB 03 * RLC E +CB 04 * RLC H +CB 05 * RLC L +CB 06 * RLC (HL) +CB 07 * RLC A +CB 08 * RRC B +CB 09 * RRC C +CB 0A * RRC D +CB 0B * RRC E +CB 0C * RRC H +CB 0D * RRC L +CB 0E * RRC (HL) +CB 0F * RRC A +CB 10 * RL B +CB 11 * RL C +CB 12 * RL D +CB 13 * RL E +CB 14 * RL H +CB 15 * RL L +CB 16 * RL (HL) +CB 17 * RL A +CB 18 * RR B +CB 19 * RR C +CB 1A * RR D +CB 1B * RR E +CB 1C * RR H +CB 1D * RR L +CB 1E * RR (HL) +CB 1F * RR A +CB 20 * SLA B +CB 21 * SLA C +CB 22 * SLA D +CB 23 * SLA E +CB 24 * SLA H +CB 25 * SLA L +CB 26 * SLA (HL) +CB 27 * SLA A +CB 28 * SRA B +CB 29 * SRA C +CB 2A * SRA D +CB 2B * SRA E +CB 2C * SRA H +CB 2D * SRA L +CB 2E * SRA (HL) +CB 2F * SRA A +CB 30 / SLIA B (Shift Left Inverted Arithmetic) +CB 31 / SLIA C like SLA, but shifts in a 1 bit +CB 32 / SLIA D +CB 33 / SLIA E +CB 34 / SLIA H +CB 35 / SLIA L +CB 36 / SLIA (HL) +CB 37 / SLIA A +CB 38 * SRL B +CB 39 * SRL C +CB 3A * SRL D +CB 3B * SRL E +CB 3C * SRL H +CB 3D * SRL L +CB 3E * SRL (HL) +CB 3F * SRL A +CB 40 * BIT 0,B +CB 41 * BIT 0,C +CB 42 * BIT 0,D +CB 43 * BIT 0,E +CB 44 * BIT 0,H +CB 45 * BIT 0,L +CB 46 * BIT 0,(HL) +CB 47 * BIT 0,A +CB 48 * BIT 1,B +CB 49 * BIT 1,C +CB 4A * BIT 1,D +CB 4B * BIT 1,E +CB 4C * BIT 1,H +CB 4D * BIT 1,L +CB 4E * BIT 1,(HL) +CB 4F * BIT 1,A +CB 50 * BIT 2,B +CB 51 * BIT 2,C +CB 52 * BIT 2,D +CB 53 * BIT 2,E +CB 54 * BIT 2,H +CB 55 * BIT 2,L +CB 56 * BIT 2,(HL) +CB 57 * BIT 2,A +CB 58 * BIT 3,B +CB 59 * BIT 3,C +CB 5A * BIT 3,D +CB 5B * BIT 3,E +CB 5C * BIT 3,H +CB 5D * BIT 3,L +CB 5E * BIT 3,(HL) +CB 5F * BIT 3,A +CB 60 * BIT 4,B +CB 61 * BIT 4,C +CB 62 * BIT 4,D +CB 63 * BIT 4,E +CB 64 * BIT 4,H +CB 65 * BIT 4,L +CB 66 * BIT 4,(HL) +CB 67 * BIT 4,A +CB 68 * BIT 5,B +CB 69 * BIT 5,C +CB 6A * BIT 5,D +CB 6B * BIT 5,E +CB 6C * BIT 5,H +CB 6D * BIT 5,L +CB 6E * BIT 5,(HL) +CB 6F * BIT 5,A +CB 70 * BIT 6,B +CB 71 * BIT 6,C +CB 72 * BIT 6,D +CB 73 * BIT 6,E +CB 74 * BIT 6,H +CB 75 * BIT 6,L +CB 76 * BIT 6,(HL) +CB 77 * BIT 6,A +CB 78 * BIT 7,B +CB 79 * BIT 7,C +CB 7A * BIT 7,D +CB 7B * BIT 7,E +CB 7C * BIT 7,H +CB 7D * BIT 7,L +CB 7E * BIT 7,(HL) +CB 7F * BIT 7,A +CB 80 * RES 0,B +CB 81 * RES 0,C +CB 82 * RES 0,D +CB 83 * RES 0,E +CB 84 * RES 0,H +CB 85 * RES 0,L +CB 86 * RES 0,(HL) +CB 87 * RES 0,A +CB 88 * RES 1,B +CB 89 * RES 1,C +CB 8A * RES 1,D +CB 8B * RES 1,E +CB 8C * RES 1,H +CB 8D * RES 1,L +CB 8E * RES 1,(HL) +CB 8F * RES 1,A +CB 90 * RES 2,B +CB 91 * RES 2,C +CB 92 * RES 2,D +CB 93 * RES 2,E +CB 94 * RES 2,H +CB 95 * RES 2,L +CB 96 * RES 2,(HL) +CB 97 * RES 2,A +CB 98 * RES 3,B +CB 99 * RES 3,C +CB 9A * RES 3,D +CB 9B * RES 3,E +CB 9C * RES 3,H +CB 9D * RES 3,L +CB 9E * RES 3,(HL) +CB 9F * RES 3,A +CB A0 * RES 4,B +CB A1 * RES 4,C +CB A2 * RES 4,D +CB A3 * RES 4,E +CB A4 * RES 4,H +CB A5 * RES 4,L +CB A6 * RES 4,(HL) +CB A7 * RES 4,A +CB A8 * RES 5,B +CB A9 * RES 5,C +CB AA * RES 5,D +CB AB * RES 5,E +CB AC * RES 5,H +CB AD * RES 5,L +CB AE * RES 5,(HL) +CB AF * RES 5,A +CB B0 * RES 6,B +CB B1 * RES 6,C +CB B2 * RES 6,D +CB B3 * RES 6,E +CB B4 * RES 6,H +CB B5 * RES 6,L +CB B6 * RES 6,(HL) +CB B7 * RES 6,A +CB B8 * RES 7,B +CB B9 * RES 7,C +CB BA * RES 7,D +CB BB * RES 7,E +CB BC * RES 7,H +CB BD * RES 7,L +CB BE * RES 7,(HL) +CB BF * RES 7,A +CB C0 * SET 0,B +CB C1 * SET 0,C +CB C2 * SET 0,D +CB C3 * SET 0,E +CB C4 * SET 0,H +CB C5 * SET 0,L +CB C6 * SET 0,(HL) +CB C7 * SET 0,A +CB C8 * SET 1,B +CB C9 * SET 1,C +CB CA * SET 1,D +CB CB * SET 1,E +CB CC * SET 1,H +CB CD * SET 1,L +CB CE * SET 1,(HL) +CB CF * SET 1,A +CB D0 * SET 2,B +CB D1 * SET 2,C +CB D2 * SET 2,D +CB D3 * SET 2,E +CB D4 * SET 2,H +CB D5 * SET 2,L +CB D6 * SET 2,(HL) +CB D7 * SET 2,A +CB D8 * SET 3,B +CB D9 * SET 3,C +CB DA * SET 3,D +CB DB * SET 3,E +CB DC * SET 3,H +CB DD * SET 3,L +CB DE * SET 3,(HL) +CB DF * SET 3,A +CB E0 * SET 4,B +CB E1 * SET 4,C +CB E2 * SET 4,D +CB E3 * SET 4,E +CB E4 * SET 4,H +CB E5 * SET 4,L +CB E6 * SET 4,(HL) +CB E7 * SET 4,A +CB E8 * SET 5,B +CB E9 * SET 5,C +CB EA * SET 5,D +CB EB * SET 5,E +CB EC * SET 5,H +CB ED * SET 5,L +CB EE * SET 5,(HL) +CB EF * SET 5,A +CB F0 * SET 6,B +CB F1 * SET 6,C +CB F2 * SET 6,D +CB F3 * SET 6,E +CB F4 * SET 6,H +CB F5 * SET 6,L +CB F6 * SET 6,(HL) +CB F7 * SET 6,A +CB F8 * SET 7,B +CB F9 * SET 7,C +CB FA * SET 7,D +CB FB * SET 7,E +CB FC * SET 7,H +CB FD * SET 7,L +CB FE * SET 7,(HL) +CB FF * SET 7,A +CC nnnn CALL Z,nnnn +CD nnnn CALL nnnn +CE nn ADC A,nn +CF RST 8 +D0 RET NC +D1 POP DE +D2 nnnn JP NC,nnnn +D3 nn OUT (nn),A +D4 nnnn CALL NC,nnnn +D5 PUSH DE +D6 nn SUB nn +D7 RST 10H +D8 RET C +D9 * EXX +DA nnnn JP C,nnnn +DB nn IN A,(nn) +DC nnnn CALL C,nnnn +All other DD combinations not listed below: + DD is ignored, all following bytes are treated as instructions +DD 09 * ADD IX,BC +DD 19 * ADD IX,DE +DD 21 nnnn * LD IX,nnnn +DD 22 nnnn * LD (nnnn),IX +DD 23 * INC IX +DD 24 / INC HX +DD 25 / DEC HX +DD 26 nn / LD HX,nn +DD 29 * ADD IX,IX +DD 2A nnnn * LD IX,(nnnn) +DD 2B * DEC IX +DD 2C / INC LX +DD 2D / DEC LX +DD 2E nn / LD LX,nn +DD 34 dd * INC (IX+dd) +DD 35 dd * DEC (IX+dd) +DD 36 dd nn * LD (IX+dd),nn +DD 39 * ADD IX,SP +DD 44 / LD B,HX +DD 45 / LD B,LX +DD 46 dd * LD B,(IX+dd) +DD 4C / LD C,HX +DD 4D / LD C,LX +DD 4E dd * LD C,(IX+dd) +DD 54 / LD D,HX +DD 55 / LD D,LX +DD 56 dd * LD D,(IX+dd) +DD 5C / LD E,H +DD 5D / LD E,L +DD 5E dd * LD E,(IX+dd) +DD 60 / LD HX,B +DD 61 / LD HX,C +DD 62 / LD HX,D +DD 63 / LD HX,E +DD 64 / LD HX,HX +DD 65 / LD HX,LX +DD 66 dd * LD H,(IX+dd) +DD 67 / LD HX,A +DD 68 / LD LX,B +DD 69 / LD LX,C +DD 6A / LD LX,D +DD 6B / LD LX,E +DD 6C / LD LX,HX +DD 6D / LD LX,LX +DD 6E dd * LD L,(IX+dd) +DD 6F / LD LX,A +DD 70 dd * LD (IX+dd),B +DD 71 dd * LD (IX+dd),C +DD 72 dd * LD (IX+dd),D +DD 73 dd * LD (IX+dd),E +DD 74 dd * LD (IX+dd),H +DD 75 dd * LD (IX+dd),L +DD 77 dd * LD (IX+dd),A +DD 7C / LD A,HX +DD 7D / LD A,LX +DD 7E dd * LD A,(IX+dd) +DD 84 / ADD A,HX +DD 85 / ADD A,LX +DD 86 dd * ADD A,(IX+dd) /* add +dd, kpb */ +DD 8C / ADC A,HX +DD 8D / ADC A,LX +DD 8E dd * ADC A,(IX+dd) /* add +dd, kpb */ +DD 94 / SUB HX +DD 95 / SUB LX +DD 96 dd * SUB (IX+dd) +DD 9C / SBC A,HX +DD 9D / SBC A,LX +DD 9E dd * SBC A,(IX+dd) +DD A4 / AND HX +DD A5 / AND LX +DD A6 dd * AND (IX+dd) +DD AC / XOR HX +DD AD / XOR LX +DD AE dd * XOR (IX+dd) +DD B4 / OR HX +DD B5 / OR LX +DD B6 dd * OR (IX+dd) +DD BC / CP HX +DD BD / CP LX +DD BE dd * CP (IX+dd) +DD CB dd 00 / RLC (IX+dd)->B result is placed in a register +DD CB dd 01 / RLC (IX+dd)->C additionally +DD CB dd 02 / RLC (IX+dd)->D +DD CB dd 03 / RLC (IX+dd)->E +DD CB dd 04 / RLC (IX+dd)->H +DD CB dd 05 / RLC (IX+dd)->L +DD CB dd 06 * RLC (IX+dd) +DD CB dd 07 / RLC (IX+dd)->A +DD CB dd 08 / RRC (IX+dd)->B +DD CB dd 09 / RRC (IX+dd)->C +DD CB dd 0A / RRC (IX+dd)->D +DD CB dd 0B / RRC (IX+dd)->E +DD CB dd 0C / RRC (IX+dd)->H +DD CB dd 0D / RRC (IX+dd)->L +DD CB dd 0E * RRC (IX+dd) +DD CB dd 0F / RRC (IX+dd)->A +DD CB dd 10 / RL (IX+dd)->B +DD CB dd 11 / RL (IX+dd)->C +DD CB dd 12 / RL (IX+dd)->D +DD CB dd 13 / RL (IX+dd)->E +DD CB dd 14 / RL (IX+dd)->H +DD CB dd 15 / RL (IX+dd)->L +DD CB dd 16 * RL (IX+dd) +DD CB dd 17 / RL (IX+dd)->A +DD CB dd 18 / RR (IX+dd)->B +DD CB dd 19 / RR (IX+dd)->C +DD CB dd 1A / RR (IX+dd)->D +DD CB dd 1B / RR (IX+dd)->E +DD CB dd 1C / RR (IX+dd)->H +DD CB dd 1D / RR (IX+dd)->L +DD CB dd 1E * RR (IX+dd) +DD CB dd 1F / RR (IX+dd)->A +DD CB dd 20 / SLA (IX+dd)->B +DD CB dd 21 / SLA (IX+dd)->C +DD CB dd 22 / SLA (IX+dd)->D +DD CB dd 23 / SLA (IX+dd)->E +DD CB dd 24 / SLA (IX+dd)->H +DD CB dd 25 / SLA (IX+dd)->L +DD CB dd 26 * SLA (IX+dd) +DD CB dd 27 / SLA (IX+dd)->A +DD CB dd 28 / SRA (IX+dd)->B +DD CB dd 29 / SRA (IX+dd)->C +DD CB dd 2A / SRA (IX+dd)->D +DD CB dd 2B / SRA (IX+dd)->E +DD CB dd 2C / SRA (IX+dd)->H +DD CB dd 2D / SRA (IX+dd)->L +DD CB dd 2E * SRA (IX+dd) +DD CB dd 2F / SRA (IX+dd)->A +DD CB dd 30 / SLIA (IX+dd)->B +DD CB dd 31 / SLIA (IX+dd)->C +DD CB dd 32 / SLIA (IX+dd)->D +DD CB dd 33 / SLIA (IX+dd)->E +DD CB dd 34 / SLIA (IX+dd)->H +DD CB dd 35 / SLIA (IX+dd)->L +DD CB dd 36 / SLIA (IX+dd) +DD CB dd 37 / SLIA (IX+dd)->A +DD CB dd 38 / SRL (IX+dd)->B +DD CB dd 39 / SRL (IX+dd)->C +DD CB dd 3A / SRL (IX+dd)->D +DD CB dd 3B / SRL (IX+dd)->E +DD CB dd 3C / SRL (IX+dd)->H +DD CB dd 3D / SRL (IX+dd)->L +DD CB dd 3E * SRL (IX+dd) +DD CB dd 3F / SRL (IX+dd)->A +DD CB dd 46 * BIT 0,(IX+dd) all other BIT combinations +DD CB dd 4E * BIT 1,(IX+dd) react like the documented ones +DD CB dd 56 * BIT 2,(IX+dd) because there is no write +DD CB dd 5E * BIT 3,(IX+dd) +DD CB dd 66 * BIT 4,(IX+dd) +DD CB dd 6E * BIT 5,(IX+dd) +DD CB dd 76 * BIT 6,(IX+dd) +DD CB dd 7E * BIT 7,(IX+dd) +DD CB dd 80 / RES 0,(IX+dd)->B +DD CB dd 81 / RES 0,(IX+dd)->C +DD CB dd 82 / RES 0,(IX+dd)->D +DD CB dd 83 / RES 0,(IX+dd)->E +DD CB dd 84 / RES 0,(IX+dd)->H +DD CB dd 85 / RES 0,(IX+dd)->L +DD CB dd 86 * RES 0,(IX+dd) +DD CB dd 87 / RES 0,(IX+dd)->A +DD CB dd 88 / RES 1,(IX+dd)->B +DD CB dd 89 / RES 1,(IX+dd)->C +DD CB dd 8A / RES 1,(IX+dd)->D +DD CB dd 8B / RES 1,(IX+dd)->E +DD CB dd 8C / RES 1,(IX+dd)->H +DD CB dd 8D / RES 1,(IX+dd)->L +DD CB dd 8E * RES 1,(IX+dd) +DD CB dd 8F / RES 1,(IX+dd)->A +DD CB dd 90 / RES 2,(IX+dd)->B +DD CB dd 91 / RES 2,(IX+dd)->C +DD CB dd 92 / RES 2,(IX+dd)->D +DD CB dd 93 / RES 2,(IX+dd)->E +DD CB dd 94 / RES 2,(IX+dd)->H +DD CB dd 95 / RES 2,(IX+dd)->L +DD CB dd 96 * RES 2,(IX+dd) +DD CB dd 97 / RES 2,(IX+dd)->A +DD CB dd 98 / RES 3,(IX+dd)->B +DD CB dd 99 / RES 3,(IX+dd)->C +DD CB dd 9A / RES 3,(IX+dd)->D +DD CB dd 9B / RES 3,(IX+dd)->E +DD CB dd 9C / RES 3,(IX+dd)->H +DD CB dd 9D / RES 3,(IX+dd)->L +DD CB dd 9E * RES 3,(IX+dd) +DD CB dd 9F / RES 3,(IX+dd)->A +DD CB dd A0 / RES 4,(IX+dd)->B +DD CB dd A1 / RES 4,(IX+dd)->C +DD CB dd A2 / RES 4,(IX+dd)->D +DD CB dd A3 / RES 4,(IX+dd)->E +DD CB dd A4 / RES 4,(IX+dd)->H +DD CB dd A5 / RES 4,(IX+dd)->L +DD CB dd A6 * RES 4,(IX+dd) +DD CB dd A7 / RES 4,(IX+dd)->A +DD CB dd A8 / RES 5,(IX+dd)->B +DD CB dd A9 / RES 5,(IX+dd)->C +DD CB dd AA / RES 5,(IX+dd)->D +DD CB dd AB / RES 5,(IX+dd)->E +DD CB dd AC / RES 5,(IX+dd)->H +DD CB dd AD / RES 5,(IX+dd)->L +DD CB dd AE * RES 5,(IX+dd) +DD CB dd AF / RES 5,(IX+dd)->A +DD CB dd B0 / RES 6,(IX+dd)->B +DD CB dd B1 / RES 6,(IX+dd)->C +DD CB dd B2 / RES 6,(IX+dd)->D +DD CB dd B3 / RES 6,(IX+dd)->E +DD CB dd B4 / RES 6,(IX+dd)->H +DD CB dd B5 / RES 6,(IX+dd)->L +DD CB dd B6 * RES 6,(IX+dd) +DD CB dd B7 / RES 6,(IX+dd)->A +DD CB dd B8 / RES 7,(IX+dd)->B +DD CB dd B9 / RES 7,(IX+dd)->C +DD CB dd BA / RES 7,(IX+dd)->D +DD CB dd BB / RES 7,(IX+dd)->E +DD CB dd BC / RES 7,(IX+dd)->H +DD CB dd BD / RES 7,(IX+dd)->L +DD CB dd BE * RES 7,(IX+dd) +DD CB dd BF / RES 7,(IX+dd)->A +DD CB dd C0 / SET 0,(IX+dd)->B +DD CB dd C1 / SET 0,(IX+dd)->C +DD CB dd C2 / SET 0,(IX+dd)->D +DD CB dd C3 / SET 0,(IX+dd)->E +DD CB dd C4 / SET 0,(IX+dd)->H +DD CB dd C5 / SET 0,(IX+dd)->L +DD CB dd C6 * SET 0,(IX+dd) +DD CB dd C7 / SET 0,(IX+dd)->A +DD CB dd C8 / SET 1,(IX+dd)->B +DD CB dd C9 / SET 1,(IX+dd)->C +DD CB dd CA / SET 1,(IX+dd)->D +DD CB dd CB / SET 1,(IX+dd)->E +DD CB dd CC / SET 1,(IX+dd)->H +DD CB dd CD / SET 1,(IX+dd)->L +DD CB dd CE * SET 1,(IX+dd) +DD CB dd CF / SET 1,(IX+dd)->A +DD CB dd D0 / SET 2,(IX+dd)->B +DD CB dd D1 / SET 2,(IX+dd)->C +DD CB dd D2 / SET 2,(IX+dd)->D +DD CB dd D3 / SET 2,(IX+dd)->E +DD CB dd D4 / SET 2,(IX+dd)->H +DD CB dd D5 / SET 2,(IX+dd)->L +DD CB dd D6 * SET 2,(IX+dd) +DD CB dd D7 / SET 2,(IX+dd)->A +DD CB dd D8 / SET 3,(IX+dd)->B +DD CB dd D9 / SET 3,(IX+dd)->C +DD CB dd DA / SET 3,(IX+dd)->D +DD CB dd DB / SET 3,(IX+dd)->E +DD CB dd DC / SET 3,(IX+dd)->H +DD CB dd DD / SET 3,(IX+dd)->L +DD CB dd DE * SET 3,(IX+dd) +DD CB dd DF / SET 3,(IX+dd)->A +DD CB dd E0 / SET 4,(IX+dd)->B +DD CB dd E1 / SET 4,(IX+dd)->C +DD CB dd E2 / SET 4,(IX+dd)->D +DD CB dd E3 / SET 4,(IX+dd)->E +DD CB dd E4 / SET 4,(IX+dd)->H +DD CB dd E5 / SET 4,(IX+dd)->L +DD CB dd E6 * SET 4,(IX+dd) +DD CB dd E7 / SET 4,(IX+dd)->A +DD CB dd E8 / SET 5,(IX+dd)->B +DD CB dd E9 / SET 5,(IX+dd)->C +DD CB dd EA / SET 5,(IX+dd)->D +DD CB dd EB / SET 5,(IX+dd)->E +DD CB dd EC / SET 5,(IX+dd)->H +DD CB dd ED / SET 5,(IX+dd)->L +DD CB dd EE * SET 5,(IX+dd) +DD CB dd EF / SET 5,(IX+dd)->A +DD CB dd F0 / SET 6,(IX+dd)->B +DD CB dd F1 / SET 6,(IX+dd)->C +DD CB dd F2 / SET 6,(IX+dd)->D +DD CB dd F3 / SET 6,(IX+dd)->E +DD CB dd F4 / SET 6,(IX+dd)->H +DD CB dd F5 / SET 6,(IX+dd)->L +DD CB dd F6 * SET 6,(IX+dd) +DD CB dd F7 / SET 6,(IX+dd)->A +DD CB dd F8 / SET 7,(IX+dd)->B +DD CB dd F9 / SET 7,(IX+dd)->C +DD CB dd FA / SET 7,(IX+dd)->D +DD CB dd FB / SET 7,(IX+dd)->E +DD CB dd FC / SET 7,(IX+dd)->H +DD CB dd FD / SET 7,(IX+dd)->L +DD CB dd FE * SET 7,(IX+dd) +DD CB dd FF / SET 7,(IX+dd)->A +DD E1 * POP IX +DD E3 * EX (SP),IX +DD E5 * PUSH IX +DD E9 * JP (IX) +DD F9 * LD SP,IX +DE nn SBC A,nn +DF RST 18H +E0 RET PO +E1 POP HL +E2 nnnn JP PO,nnnn +E3 EX (SP),HL +E4 nnnn CALL PO,nnnn +E5 PUSH HL +E6 nn AND nn +E7 RST 20H +E8 RET PE +E9 JP (HL) +EA nnnn JP PE,nnnn +EB EX DE,HL +EC nnnn CALL PE,nnnn +All other ED combinations not listed below: + in the range ED40 - ED7F: valid opcodes are mirrored + elsewhere: ED and the next byte is ignored, + all following bytes treated as instructions +ED 00 nn + IN0 B,(nn) +ED 01 nn + OUT0 (nn),B +ED 04 + TST B +ED 08 nn + IN0 C,(nn) +ED 09 nn + OUT0 (nn),C +ED 0C + TST C +ED 10 nn + IN0 D,(nn) +ED 11 nn + OUT0 (nn),D +ED 14 + TST D +ED 18 nn + IN0 E,(nn) +ED 19 nn + OUT0 (nn),E +ED 1C + TST E +ED 20 nn + IN0 H,(nn) +ED 21 nn + OUT0 (nn),H +ED 24 + TST H +ED 28 nn + IN0 L,(nn) +ED 29 nn + OUT0 (nn),L +ED 2C + TST L +ED 30 nn + IN0 (nn) set flags only +ED 34 + TST (HL) +ED 38 nn + IN0 A,(nn) +ED 39 nn + OUT0 (nn),A +ED 3C + TST A +ED 40 * IN B,(C) +ED 41 * OUT (C),B +ED 42 * SBC HL,BC +ED 43 nnnn * LD (nnnn),BC +ED 44 * NEG +ED 45 * RETN +ED 46 * IM 0 +ED 47 * LD I,A +ED 48 * IN C,(C) +ED 49 * OUT (C),C +ED 4A * ADC HL,BC +ED 4B nnnn * LD BC,(nnnn) +ED 4C + MULT BC +ED 4D * RETI +ED 4F * LD R,A +ED 50 * IN D,(C) +ED 51 * OUT (C),D +ED 52 * SBC HL,DE +ED 53 nnnn * LD (nnnn),DE +ED 56 * IM 1 +ED 57 * LD A,I +ED 58 * IN E,(C) +ED 59 * OUT (C),E +ED 5A * ADC HL,DE +ED 5B nnnn * LD DE,(nnnn) +ED 5C + MULT DE +ED 5E * IM 2 +ED 5F * LD A,R +ED 60 * IN H,(C) +ED 61 * OUT (C),H +ED 62 * SBC HL,HL +ED 63 nnnn * LD (nnnn),HL opcode 22 does the same faster +ED 64 nn + TST nn +ED 67 * RRD +ED 68 * IN L,(C) +ED 69 * OUT (C),L +ED 6A * ADC HL,HL +ED 6B nnnn * LD HL,(nnnn) opcode 2A does the same faster +ED 6C + MULT HL +ED 6F * RLD +ED 70 / IN (C) set flags only (TSTI) + ^--- can be viewed as *, because SGS manual and HD64180 + manual list this instruction as valid Z80 +ED 71 / OUT (C),0 +ED 72 * SBC HL,SP +ED 73 nnnn * LD (nnnn),SP +ED 74 nn + TSTIO nn +ED 76 + SLP +ED 78 * IN A,(C) +ED 79 * OUT (C),A +ED 7A * ADC HL,SP +ED 7B nnnn * LD SP,(nnnn) +ED 7C + MULT SP +ED 83 + OTIM +ED 8B + OTDM +ED 93 + OTIMR +ED 9B + OTDMR +ED A0 * LDI +ED A1 * CPI +ED A2 * INI +ED A3 * OUTI +ED A8 * LDD +ED A9 * CPD +ED AA * IND +ED AB * OUTD +ED B0 * LDIR +ED B1 * CPIR +ED B2 * INIR +ED B3 * OTIR +ED B8 * LDDR +ED B9 * CPDR +ED BA * INDR +ED BB * OTDR +EE nn XOR nn +EF RST 28H +F0 RET P +F1 POP AF +F2 nnnn JP P,nnnn +F3 DI +F4 nnnn CALL P,nnnn +F5 PUSH AF +F6 nn OR nn +F7 RST 30H +F8 RET M +F9 LD SP,HL +FA nnnn JP M,nnnn +FB EI +FC nnnn CALL M,nnnn +FD ... * like DD ..., with IY instead of IX +FE nn CP nn +FF RST 38H + + +From: peterm@maths.grace.cri.nz (Peter McGavin) +Newsgroups: comp.sys.sinclair +Subject: Re: Undocumented Z80 opcodes +Date: 05 Jan 1994 20:44:15 GMT +Organization: Applied Maths, Industrial Research Ltd, NZ +NNTP-Posting-Host: kea.grace.cri.nz +In-reply-to: agulbra@tigern.nvg.unit.no's message of 5 Jan 1994 17:47:59 +0100 + +In article, <2geqvv$nlq@tigern.nvg.unit.no>, +agulbra@tigern.nvg.unit.no (Arnt Gulbrandsen) wrote: +>I believe that list originally was written by from David Librik +>. David (with someone else, I think) +>reverse-engineered the Z80 and wrote a list of what he found, a list +>which I think I sent to Peter. + +Actually I got it from Simon Owen (S.N.Owen@newcastle.ac.uk). + +Here it is: (sorry it's a bit wide) +------------------------------------------------------------------------------ + +Key: + + Instruction is unchanged by index prefix + * Instruction thought of as 'undocumented' + +Notes: + + IM * - is either IM 0 or IM 1 (more likely IM 0), hard to decide which + + IN X,(C) reads into nowhere (not even (HL)) but affects the flags. + OUT (C),X performs OUT (C),0 + + *NOP indicated instruction has no effect on anything [ 2M cycles delay ? ] + + instructions with an ED prefix cannot have a preceding DD prefix as well. + + Instructions like LD B,RL (IX+d) perform RL (IX+d) and load B with the result + AS WELL AS affecting the contents of (IX+d). 2 for price of 1 ! + +List: + ++-------------------------------+-------------------+------------------+------------------+-------------------------+ +| Hex | Dec | Normal | DD Prefix | CB Prefix | ED Prefix | DDCB prefix | ++-------------------------------+-------------------+------------------+------------------+-------------------------+ +|[ 00 | 000 ] | NOP | +NOP | RLC B | *NOP | *LD B,RLC (IX+d) | +|[ 01 | 001 ] | LD BC,nn | +LD BC,nn | RLC C | *NOP | *LD C,RLC (IX+d) | +|[ 02 | 002 ] | LD (BC),A | +LD (BC),A | RLC D | *NOP | *LD D,RLC (IX+d) | +|[ 03 | 003 ] | INC BC | +INC BC | RLC E | *NOP | *LD E,RLC (IX+d) | +|[ 04 | 004 ] | INC B | +INC B | RLC H | *NOP | *LD H,RLC (IX+d) | +|[ 05 | 005 ] | DEC B | +DEC B | RLC L | *NOP | *LD L,RLC (IX+d) | +|[ 06 | 006 ] | LD B,n | +LD B,n | RLC (HL) | *NOP | RLC (IX+d) | +|[ 07 | 007 ] | RLCA | +RLCA | RLC A | *NOP | *LD A,RLC (IX+d) | +|[ 08 | 008 ] | EX AF,AF' | +EX AF,AF' | RRC B | *NOP | *LD B,RRC (IX+d) | +|[ 09 | 009 ] | ADD HL,BC | ADD IX,BC | RRC C | *NOP | *LD C,RRC (IX+d) | +|[ 0a | 010 ] | LD A,(BC) | +LD A,(BC) | RRC D | *NOP | *LD D,RRC (IX+d) | +|[ 0b | 011 ] | DEC BC | +DEC BC | RRC E | *NOP | *LD E,RRC (IX+d) | +|[ 0c | 012 ] | INC C | +INC C | RRC H | *NOP | *LD H,RRC (IX+d) | +|[ 0d | 013 ] | DEC C | +DEC C | RRC L | *NOP | *LD L,RRC (IX+d) | +|[ 0e | 014 ] | LD C,n | +LD C,n | RRC (HL) | *NOP | RRC (IX+d) | +|[ 0f | 015 ] | RRCA | +RRCA | RRC A | *NOP | *LD A,RRC (IX+d) | +|[ 10 | 016 ] | DJNZ d | +DJNZ d | RL B | *NOP | *LD B,RL (IX+d) | +|[ 11 | 017 ] | LD DE,nn | +LD DE,nn | RL C | *NOP | *LD C,RL (IX+d) | +|[ 12 | 018 ] | LD (DE),A | +LD (DE),A | RL D | *NOP | *LD D,RL (IX+d) | +|[ 13 | 019 ] | INC DE | +INC DE | RL E | *NOP | *LD E,RL (IX+d) | +|[ 14 | 020 ] | INC D | +INC D | RL H | *NOP | *LD H,RL (IX+d) | +|[ 15 | 021 ] | DEC D | +DEC D | RL L | *NOP | *LD L,RL (IX+d) | +|[ 16 | 022 ] | LD D,n | +LD D,n | RL (HL) | *NOP | RL (IX+d) | +|[ 17 | 023 ] | RLA | +RLA | RL A | *NOP | *LD A,RL (IX+d) | +|[ 18 | 024 ] | JR d | +JR d | RR B | *NOP | *LD B,RR (IX+d) | +|[ 19 | 025 ] | ADD HL,DE | ADD IX,DE | RR C | *NOP | *LD C,RR (IX+d) | +|[ 1a | 026 ] | LD A,(DE) | +LD A,(DE) | RR D | *NOP | *LD D,RR (IX+d) | +|[ 1b | 027 ] | DEC DE | +DEC DE | RR E | *NOP | *LD E,RR (IX+d) | +|[ 1c | 028 ] | INC E | +INC E | RR H | *NOP | *LD H,RR (IX+d) | +|[ 1d | 029 ] | DEC E | +DEC E | RR L | *NOP | *LD L,RR (IX+d) | +|[ 1e | 030 ] | LD E,n | +LD E,n | RR (HL) | *NOP | RR (IX+d) | +|[ 1f | 031 ] | RRA | +RRA | RR A | *NOP | *LD A,RR (IX+d) | +|[ 20 | 032 ] | JR NZ,d | +JR NZ,d | SLA B | *NOP | *LD B,SLA (IX+d) | +|[ 21 | 033 ] | LD HL,nn | LD IX,nn | SLA C | *NOP | *LD C,SLA (IX+d) | +|[ 22 | 034 ] | LD (nn),HL | LD (nn),IX | SLA D | *NOP | *LD D,SLA (IX+d) | +|[ 23 | 035 ] | INC HL | INC IX | SLA E | *NOP | *LD E,SLA (IX+d) | +|[ 24 | 036 ] | INC H | *INC IXh | SLA H | *NOP | *LD H,SLA (IX+d) | +|[ 25 | 037 ] | DEC H | *DEC IXh | SLA L | *NOP | *LD L,SLA (IX+d) | +|[ 26 | 038 ] | LD H,n | *LD IXh,n | SLA (HL) | *NOP | SLA (IX+d) | +|[ 27 | 039 ] | DAA | +DAA | SLA A | *NOP | *LD A,SLA (IX+d) | +|[ 28 | 040 ] | JR Z,d | +JR Z,d | SRA B | *NOP | *LD B,SRA (IX+d) | +|[ 29 | 041 ] | ADD HL,HL | ADD IX,IX | SRA C | *NOP | *LD C,SRA (IX+d) | +|[ 2a | 042 ] | LD HL,(nn) | LD IX,(nn) | SRA D | *NOP | *LD D,SRA (IX+d) | +|[ 2b | 043 ] | DEC HL | DEC IX | SRA E | *NOP | *LD E,SRA (IX+d) | +|[ 2c | 044 ] | INC L | *INC IXl | SRA H | *NOP | *LD H,SRA (IX+d) | +|[ 2d | 045 ] | DEC L | *DEC IXl | SRA L | *NOP | *LD L,SRA (IX+d) | +|[ 2e | 046 ] | LD L,n | *LD IXl,n | SRA (HL) | *NOP | SRA (IX+d) | +|[ 2f | 047 ] | CPL | +CPL | SRA A | *NOP | *LD A,SRA (IX+d) | +|[ 30 | 048 ] | JR NC,d | +JR NC,d | SLL B | *NOP | *LD B,SLL (IX+d) | +|[ 31 | 049 ] | LD SP,nn | +LD SP,nn | SLL C | *NOP | *LD C,SLL (IX+d) | +|[ 32 | 050 ] | LD (nn),A | +LD (nn),A | SLL D | *NOP | *LD D,SLL (IX+d) | +|[ 33 | 051 ] | INC SP | +INC SP | SLL E | *NOP | *LD E,SLL (IX+d) | +|[ 34 | 052 ] | INC (HL) | INC (IX+d) | SLL H | *NOP | *LD H,SLL (IX+d) | +|[ 35 | 053 ] | DEC (HL) | DEC (IX+d) | SLL L | *NOP | *LD L,SLL (IX+d) | +|[ 36 | 054 ] | LD (HL),n | LD (IX+d),n | SLL (HL) | *NOP | SLL (IX+d) | +|[ 37 | 055 ] | SCF | +SCF | SLL A | *NOP | *LD A,SLL (IX+d) | +|[ 38 | 056 ] | JR C,d | +JR C,d | SRL B | *NOP | *LD B,SRL (IX+d) | +|[ 39 | 057 ] | ADD HL,SP | ADD IX,SP | SRL C | *NOP | *LD C,SRL (IX+d) | +|[ 3a | 058 ] | LD A,(nn) | +LD A,(nn) | SRL D | *NOP | *LD D,SRL (IX+d) | +|[ 3b | 059 ] | DEC SP | +DEC SP | SRL E | *NOP | *LD E,SRL (IX+d) | +|[ 3c | 060 ] | INC A | +INC A | SRL H | *NOP | *LD H,SRL (IX+d) | +|[ 3d | 061 ] | DEC A | +DEC A | SRL L | *NOP | *LD L,SRL (IX+d) | +|[ 3e | 062 ] | LD A,n | +LD A,n | SRL (HL) | *NOP | SRL (IX+d) | +|[ 3f | 063 ] | CCF | +CCF | SRL A | *NOP | *LD A,SRL (IX+d) | +|[ 40 | 064 ] | LD B,B | +LD B,B | BIT 0,B | IN B,(C) | *BIT 0,(IX+d) | +|[ 41 | 065 ] | LD B,C | +LD B,C | BIT 0,C | OUT (C),B | *BIT 0,(IX+d) | +|[ 42 | 066 ] | LD B,D | +LD B,D | BIT 0,D | SBC HL,BC | *BIT 0,(IX+d) | +|[ 43 | 067 ] | LD B,E | +LD B,E | BIT 0,E | LD (nn),BC | *BIT 0,(IX+d) | +|[ 44 | 068 ] | LD B,H | *LD B,IXh | BIT 0,H | NEG | *BIT 0,(IX+d) | +|[ 45 | 069 ] | LD B,L | *LD B,IXl | BIT 0,L | RETN | *BIT 0,(IX+d) | +|[ 46 | 070 ] | LD B,(HL) | LD B,(IX+d) | BIT 0,(HL) | IM 0 | BIT 0,(IX+d) | +|[ 47 | 071 ] | LD B,A | +LD B,A | BIT 0,A | LD I,A | *BIT 0,(IX+d) | +|[ 48 | 072 ] | LD C,B | +LD C,B | BIT 1,B | IN C,(C) | *BIT 1,(IX+d) | +|[ 49 | 073 ] | LD C,C | +LD C,C | BIT 1,C | OUT (C),C | *BIT 1,(IX+d) | +|[ 4a | 074 ] | LD C,D | +LD C,D | BIT 1,D | ADC HL,BC | *BIT 1,(IX+d) | +|[ 4b | 075 ] | LD C,E | +LD C,E | BIT 1,E | LD BC,(nn) | *BIT 1,(IX+d) | +|[ 4c | 076 ] | LD C,H | *LD C,IXh | BIT 1,H | *NEG | *BIT 1,(IX+d) | +|[ 4d | 077 ] | LD C,L | *LD C,IXl | BIT 1,L | RETI | *BIT 1,(IX+d) | +|[ 4e | 078 ] | LD C,(HL) | LD C,(IX+d) | BIT 1,(HL) | *IM * (0?) | BIT 1,(IX+d) | +|[ 4f | 079 ] | LD C,A | +LD C,A | BIT 1,A | LD R,A | *BIT 1,(IX+d) | +|[ 50 | 080 ] | LD D,B | +LD D,B | BIT 2,B | IN D,(C) | *BIT 2,(IX+d) | +|[ 51 | 081 ] | LD D,C | +LD D,C | BIT 2,C | OUT (C),D | *BIT 2,(IX+d) | +|[ 52 | 082 ] | LD D,D | +LD D,D | BIT 2,D | SBC HL,DE | *BIT 2,(IX+d) | +|[ 53 | 083 ] | LD D,E | +LD D,E | BIT 2,E | LD (nn),DE | *BIT 2,(IX+d) | +|[ 54 | 084 ] | LD D,H | *LD D,IXh | BIT 2,H | *NEG | *BIT 2,(IX+d) | +|[ 55 | 085 ] | LD D,L | *LD D,IXl | BIT 2,L | *RETN | *BIT 2,(IX+d) | +|[ 56 | 086 ] | LD D,(HL) | LD D,(IX+d) | BIT 2,(HL) | IM 1 | BIT 2,(IX+d) | +|[ 57 | 087 ] | LD D,A | +LD D,A | BIT 2,A | LD A,I | *BIT 2,(IX+d) | +|[ 58 | 088 ] | LD E,B | +LD E,B | BIT 3,B | IN E,(C) | *BIT 3,(IX+d) | +|[ 59 | 089 ] | LD E,C | +LD E,C | BIT 3,C | OUT (C),E | *BIT 3,(IX+d) | +|[ 5a | 090 ] | LD E,D | +LD E,D | BIT 3,D | ADC HL,DE | *BIT 3,(IX+d) | +|[ 5b | 091 ] | LD E,E | +LD E,E | BIT 3,E | LD DE,(nn) | *BIT 3,(IX+d) | +|[ 5c | 092 ] | LD E,H | *LD E,IXh | BIT 3,H | *NEG | *BIT 3,(IX+d) | +|[ 5d | 093 ] | LD E,L | *LD E,IXl | BIT 3,L | *RETI | *BIT 3,(IX+d) | +|[ 5e | 094 ] | LD E,(HL) | LD E,(IX+d) | BIT 3,(HL) | IM 2 | BIT 3,(IX+d) | +|[ 5f | 095 ] | LD E,A | +LD E,A | BIT 3,A | LD A,R | *BIT 3,(IX+d) | +|[ 60 | 096 ] | LD H,B | *LD IXh,B | BIT 4,B | IN H,(C) | *BIT 4,(IX+d) | +|[ 61 | 097 ] | LD H,C | *LD IXh,C | BIT 4,C | OUT (C),H | *BIT 4,(IX+d) | +|[ 62 | 098 ] | LD H,D | *LD IXh,D | BIT 4,D | SBC HL,HL | *BIT 4,(IX+d) | +|[ 63 | 099 ] | LD H,E | *LD IXh,E | BIT 4,E | LD (nn),HL | *BIT 4,(IX+d) | +|[ 64 | 100 ] | LD H,H | *LD IXh,IXh | BIT 4,H | *NEG | *BIT 4,(IX+d) | +|[ 65 | 101 ] | LD H,L | *LD IXh,IXl | BIT 4,L | *RETN | *BIT 4,(IX+d) | +|[ 66 | 102 ] | LD H,(HL) | LD H,(IX+d) | BIT 4,(HL) | *IM 0 | BIT 4,(IX+d) | +|[ 67 | 103 ] | LD H,A | *LD IXh,A | BIT 4,A | RRD | *BIT 4,(IX+d) | +|[ 68 | 104 ] | LD L,B | *LD IXl,B | BIT 5,B | IN L,(C) | *BIT 5,(IX+d) | +|[ 69 | 105 ] | LD L,C | *LD IXl,C | BIT 5,C | OUT (C),L | *BIT 5,(IX+d) | +|[ 6a | 106 ] | LD L,D | *LD IXl,D | BIT 5,D | ADC HL,HL | *BIT 5,(IX+d) | +|[ 6b | 107 ] | LD L,E | *LD IXl,E | BIT 5,E | LD HL,(nn) | *BIT 5,(IX+d) | +|[ 6c | 108 ] | LD L,H | *LD IXl,IXh | BIT 5,H | *NEG | *BIT 5,(IX+d) | +|[ 6d | 109 ] | LD L,L | *LD IXl,IXl | BIT 5,L | *RETI | *BIT 5,(IX+d) | +|[ 6e | 110 ] | LD L,(HL) | LD L,(IX+d) | BIT 5,(HL) | *IM * (0?) | BIT 5,(IX+d) | +|[ 6f | 111 ] | LD L,A | *LD IXl,A | BIT 5,A | RLD | *BIT 5,(IX+d) | +|[ 70 | 112 ] | LD (HL),B | LD (IX+d),B | BIT 6,B | *IN X,(C) | *BIT 6,(IX+d) | +|[ 71 | 113 ] | LD (HL),C | LD (IX+d),C | BIT 6,C | *OUT (C),X(0)| *BIT 6,(IX+d) | +|[ 72 | 114 ] | LD (HL),D | LD (IX+d),D | BIT 6,D | SBC HL,SP | *BIT 6,(IX+d) | +|[ 73 | 115 ] | LD (HL),E | LD (IX+d),E | BIT 6,E | LD (nn),SP | *BIT 6,(IX+d) | +|[ 74 | 116 ] | LD (HL),H | LD (IX+d),H | BIT 6,H | *NEG | *BIT 6,(IX+d) | +|[ 75 | 117 ] | LD (HL),L | LD (IX+d),L | BIT 6,L | *RETN | *BIT 6,(IX+d) | +|[ 76 | 118 ] | HALT | +HALT | BIT 6,(HL) | *IM 1 | BIT 6,(IX+d) | +|[ 77 | 119 ] | LD (HL),A | LD (IX+d),A | BIT 6,A | *NOP | *BIT 6,(IX+d) | +|[ 78 | 120 ] | LD A,B | +LD A,B | BIT 7,B | IN A,(C) | *BIT 7,(IX+d) | +|[ 79 | 121 ] | LD A,C | +LD A,C | BIT 7,C | OUT (C),A | *BIT 7,(IX+d) | +|[ 7a | 122 ] | LD A,D | +LD A,D | BIT 7,D | ADC HL,SP | *BIT 7,(IX+d) | +|[ 7b | 123 ] | LD A,E | +LD A,E | BIT 7,E | LD SP,(nn) | *BIT 7,(IX+d) | +|[ 7c | 124 ] | LD A,H | *LD A,IXh | BIT 7,H | *NEG | *BIT 7,(IX+d) | +|[ 7d | 125 ] | LD A,L | *LD A,IXl | BIT 7,L | *RETI | *BIT 7,(IX+d) | +|[ 7e | 126 ] | LD A,(HL) | LD A,(IX+d) | BIT 7,(HL) | *IM 2 | BIT 7,(IX+d) | +|[ 7f | 127 ] | LD A,A | +LD A,A | BIT 7,A | *NOP | *BIT 7,(IX+d) | +|[ 80 | 128 ] | ADD A,B | +ADD A,B | RES 0,B | *NOP | *LD B,RES 0,(IX+d) | +|[ 81 | 129 ] | ADD A,C | +ADD A,C | RES 0,C | *NOP | *LD C,RES 0,(IX+d) | +|[ 82 | 130 ] | ADD A,D | +ADD A,D | RES 0,D | *NOP | *LD D,RES 0,(IX+d) | +|[ 83 | 131 ] | ADD A,E | +ADD A,E | RES 0,E | *NOP | *LD E,RES 0,(IX+d) | +|[ 84 | 132 ] | ADD A,H | *ADD A,IXh | RES 0,H | *NOP | *LD H,RES 0,(IX+d) | +|[ 85 | 133 ] | ADD A,L | *ADD A,IXl | RES 0,L | *NOP | *LD L,RES 0,(IX+d) | +|[ 86 | 134 ] | ADD A,(HL) | ADD A,(IX+d) | RES 0,(HL) | *NOP | RES 0,(IX+d) | +|[ 87 | 135 ] | ADD A,A | +ADD A,A | RES 0,A | *NOP | *LD A,RES 0,(IX+d) | +|[ 88 | 136 ] | ADC A,B | +ADC A,B | RES 1,B | *NOP | *LD B,RES 1,(IX+d) | +|[ 89 | 137 ] | ADC A,C | +ADC A,C | RES 1,C | *NOP | *LD C,RES 1,(IX+d) | +|[ 8a | 138 ] | ADC A,D | +ADC A,D | RES 1,D | *NOP | *LD D,RES 1,(IX+d) | +|[ 8b | 139 ] | ADC A,E | +ADC A,E | RES 1,E | *NOP | *LD E,RES 1,(IX+d) | +|[ 8c | 140 ] | ADC A,H | *ADC A,IXh | RES 1,H | *NOP | *LD H,RES 1,(IX+d) | +|[ 8d | 141 ] | ADC A,L | *ADC A,IXl | RES 1,L | *NOP | *LD L,RES 1,(IX+d) | +|[ 8e | 142 ] | ADC A,(HL) | ADC A,(IX+d) | RES 1,(HL) | *NOP | RES 1,(IX+d) | +|[ 8f | 143 ] | ADC A,A | +ADC A,A | RES 1,A | *NOP | *LD A,RES 1,(IX+d) | +|[ 90 | 144 ] | SUB B | +SUB B | RES 2,B | *NOP | *LD B,RES 2,(IX+d) | +|[ 91 | 145 ] | SUB C | +SUB C | RES 2,C | *NOP | *LD C,RES 2,(IX+d) | +|[ 92 | 146 ] | SUB D | +SUB D | RES 2,D | *NOP | *LD D,RES 2,(IX+d) | +|[ 93 | 147 ] | SUB E | +SUB E | RES 2,E | *NOP | *LD E,RES 2,(IX+d) | +|[ 94 | 148 ] | SUB H | *SUB IXh | RES 2,H | *NOP | *LD H,RES 2,(IX+d) | +|[ 95 | 149 ] | SUB L | *SUB IXl | RES 2,L | *NOP | *LD L,RES 2,(IX+d) | +|[ 96 | 150 ] | SUB (HL) | SUB (IX+d) | RES 2,(HL) | *NOP | RES 2,(IX+d) | +|[ 97 | 151 ] | SUB A | +SUB A | RES 2,A | *NOP | *LD A,RES 2,(IX+d) | +|[ 98 | 152 ] | SBC A,B | +SBC A,B | RES 3,B | *NOP | *LD B,RES 3,(IX+d) | +|[ 99 | 153 ] | SBC A,C | +SBC A,C | RES 3,C | *NOP | *LD C,RES 3,(IX+d) | +|[ 9a | 154 ] | SBC A,D | +SBC A,D | RES 3,D | *NOP | *LD D,RES 3,(IX+d) | +|[ 9b | 155 ] | SBC A,E | +SBC A,E | RES 3,E | *NOP | *LD E,RES 3,(IX+d) | +|[ 9c | 156 ] | SBC A,H | *SBC A,IXh | RES 3,H | *NOP | *LD H,RES 3,(IX+d) | +|[ 9d | 157 ] | SBC A,L | *SBC A,IXl | RES 3,L | *NOP | *LD L,RES 3,(IX+d) | +|[ 9e | 158 ] | SBC A,(HL) | SBC A,(IX+d) | RES 3,(HL) | *NOP | RES 3,(IX+d) | +|[ 9f | 159 ] | SBC A,A | +SBC A,A | RES 3,A | *NOP | *LD A,RES 3,(IX+d) | +|[ a0 | 160 ] | AND B | +AND B | RES 4,B | LDI | *LD B,RES 4,(IX+d) | +|[ a1 | 161 ] | AND C | +AND C | RES 4,C | CPI | *LD C,RES 4,(IX+d) | +|[ a2 | 162 ] | AND D | +AND D | RES 4,D | INI | *LD D,RES 4,(IX+d) | +|[ a3 | 163 ] | AND E | +AND E | RES 4,E | OUTI | *LD E,RES 4,(IX+d) | +|[ a4 | 164 ] | AND H | *AND IXh | RES 4,H | *NOP | *LD H,RES 4,(IX+d) | +|[ a5 | 165 ] | AND L | *AND IXl | RES 4,L | *NOP | *LD L,RES 4,(IX+d) | +|[ a6 | 166 ] | AND (HL) | AND (IX+d) | RES 4,(HL) | *NOP | RES 4,(IX+d) | +|[ a7 | 167 ] | AND A | +AND A | RES 4,A | *NOP | *LD A,RES 4,(IX+d) | +|[ a8 | 168 ] | XOR B | +XOR B | RES 5,B | LDD | *LD B,RES 5,(IX+d) | +|[ a9 | 169 ] | XOR C | +XOR C | RES 5,C | CPD | *LD C,RES 5,(IX+d) | +|[ aa | 170 ] | XOR D | +XOR D | RES 5,D | IND | *LD D,RES 5,(IX+d) | +|[ ab | 171 ] | XOR E | +XOR E | RES 5,E | OUTD | *LD E,RES 5,(IX+d) | +|[ ac | 172 ] | XOR H | *XOR IXh | RES 5,H | *NOP | *LD H,RES 5,(IX+d) | +|[ ad | 173 ] | XOR L | *XOR IXl | RES 5,L | *NOP | *LD L,RES 5,(IX+d) | +|[ ae | 174 ] | XOR (HL) | XOR (IX+d) | RES 5,(HL) | *NOP | RES 5,(IX+d) | +|[ af | 175 ] | XOR A | +XOR A | RES 5,A | *NOP | *LD A,RES 5,(IX+d) | +|[ b0 | 176 ] | OR B | +OR B | RES 6,B | LDIR | *LD B,RES 6,(IX+d) | +|[ b1 | 177 ] | OR C | +OR C | RES 6,C | CPIR | *LD C,RES 6,(IX+d) | +|[ b2 | 178 ] | OR D | +OR D | RES 6,D | INIR | *LD D,RES 6,(IX+d) | +|[ b3 | 179 ] | OR E | +OR E | RES 6,E | OTIR | *LD E,RES 6,(IX+d) | +|[ b4 | 180 ] | OR H | *OR IXh | RES 6,H | *NOP | *LD H,RES 6,(IX+d) | +|[ b5 | 181 ] | OR L | *OR IXl | RES 6,L | *NOP | *LD L,RES 6,(IX+d) | +|[ b6 | 182 ] | OR (HL) | OR (IX+d) | RES 6,(HL) | *NOP | RES 6,(IX+d) | +|[ b7 | 183 ] | OR A | +OR A | RES 6,A | *NOP | *LD A,RES 6,(IX+d) | +|[ b8 | 184 ] | CP B | +CP B | RES 7,B | LDDR | *LD B,RES 7,(IX+d) | +|[ b9 | 185 ] | CP C | +CP C | RES 7,C | CPDR | *LD C,RES 7,(IX+d) | +|[ ba | 186 ] | CP D | +CP D | RES 7,D | INDR | *LD D,RES 7,(IX+d) | +|[ bb | 187 ] | CP E | +CP E | RES 7,E | OTDR | *LD E,RES 7,(IX+d) | +|[ bc | 188 ] | CP H | *CP IXh | RES 7,H | *NOP | *LD H,RES 7,(IX+d) | +|[ bd | 189 ] | CP L | *CP IXl | RES 7,L | *NOP | *LD L,RES 7,(IX+d) | +|[ be | 190 ] | CP (HL) | CP (IX+d) | RES 7,(HL) | *NOP | RES 7,(IX+d) | +|[ bf | 191 ] | CP A | +CP A | RES 7,A | *NOP | *LD A,RES 7,(IX+d) | +|[ c0 | 192 ] | RET NZ | +RET NZ | SET 0,B | *NOP | *LD B,SET 0,(IX+d) | +|[ c1 | 193 ] | POP BC | +POP BC | SET 0,C | *NOP | *LD C,SET 0,(IX+d) | +|[ c2 | 194 ] | JP NZ,nn | +JP NZ,nn | SET 0,D | *NOP | *LD D,SET 0,(IX+d) | +|[ c3 | 195 ] | JP nn | +JP nn | SET 0,E | *NOP | *LD E,SET 0,(IX+d) | +|[ c4 | 196 ] | CALL NZ,nn | +CALL NZ,nn | SET 0,H | *NOP | *LD H,SET 0,(IX+d) | +|[ c5 | 197 ] | PUSH BC | +PUSH BC | SET 0,L | *NOP | *LD L,SET 0,(IX+d) | +|[ c6 | 198 ] | ADD A,n | +ADD A,n | SET 0,(HL) | *NOP | SET 0,(IX+d) | +|[ c7 | 199 ] | RST 0 | +RST 0 | SET 0,A | *NOP | *LD A,SET 0,(IX+d) | +|[ c8 | 100 ] | RET Z | +RET Z | SET 1,B | *NOP | *LD B,SET 1,(IX+d) | +|[ c9 | 201 ] | RET | +RET | SET 1,C | *NOP | *LD C,SET 1,(IX+d) | +|[ ca | 202 ] | JP Z,nn | +JP Z,nn | SET 1,D | *NOP | *LD D,SET 1,(IX+d) | +|[ cb | 203 ] | [Prefix] | *[See DDCB info]| SET 1,E | *NOP | *LD E,SET 1,(IX+d) | +|[ cc | 204 ] | CALL Z,nn | +CALL Z,nn | SET 1,H | *NOP | *LD H,SET 1,(IX+d) | +|[ cd | 205 ] | CALL nn | +CALL nn | SET 1,L | *NOP | *LD L,SET 1,(IX+d) | +|[ ce | 206 ] | ADC A,n | +ADC A,n | SET 1,(HL) | *NOP | SET 1,(IX+d) | +|[ cf | 207 ] | RST 8 | +RST 8 | SET 1,A | *NOP | *LD A,SET 1,(IX+d) | +|[ d0 | 208 ] | RET NC | +RET NC | SET 2,B | *NOP | *LD B,SET 2,(IX+d) | +|[ d1 | 209 ] | POP DE | +POP DE | SET 2,C | *NOP | *LD C,SET 2,(IX+d) | +|[ d2 | 210 ] | JP NC,nn | +JP NC,nn | SET 2,D | *NOP | *LD D,SET 2,(IX+d) | +|[ d3 | 211 ] | OUT (n),A | +OUT (n),A | SET 2,E | *NOP | *LD E,SET 2,(IX+d) | +|[ d4 | 212 ] | CALL NC,nn | +CALL NC,nn | SET 2,H | *NOP | *LD H,SET 2,(IX+d) | +|[ d5 | 213 ] | PUSH DE | +PUSH DE | SET 2,L | *NOP | *LD L,SET 2,(IX+d) | +|[ d6 | 214 ] | SUB n | +SUB n | SET 2,(HL) | *NOP | SET 2,(IX+d) | +|[ d7 | 215 ] | RST 10H | +RST 10H | SET 2,A | *NOP | *LD A,SET 2,(IX+d) | +|[ d8 | 216 ] | RET C | +RET C | SET 3,B | *NOP | *LD B,SET 3,(IX+d) | +|[ d9 | 217 ] | EXX | +EXX | SET 3,C | *NOP | *LD C,SET 3,(IX+d) | +|[ da | 218 ] | JP C,nn | +JP C,nn | SET 3,D | *NOP | *LD D,SET 3,(IX+d) | +|[ db | 219 ] | IN A,(n) | +IN A,(n) | SET 3,E | *NOP | *LD E,SET 3,(IX+d) | +|[ dc | 220 ] | CALL C,nn | +CALL C,nn | SET 3,H | *NOP | *LD H,SET 3,(IX+d) | +|[ dd | 221 ] | [IX Prefix] | +[IX Prefix] | SET 3,L | *NOP | *LD L,SET 3,(IX+d) | +|[ de | 222 ] | SBC A,n | +SBC A,n | SET 3,(HL) | *NOP | SET 3,(IX+d) | +|[ df | 223 ] | RST 18H | +RST 18H | SET 3,A | *NOP | *LD A,SET 3,(IX+d) | +|[ e0 | 224 ] | RET PO | +RET PO | SET 4,B | *NOP | *LD B,SET 4,(IX+d) | +|[ e1 | 225 ] | POP HL | POP IX | SET 4,C | *NOP | *LD C,SET 4,(IX+d) | +|[ e2 | 226 ] | JP PO,nn | +JP PO,nn | SET 4,D | *NOP | *LD D,SET 4,(IX+d) | +|[ e3 | 227 ] | EX (SP),HL | EX (SP),IX | SET 4,E | *NOP | *LD E,SET 4,(IX+d) | +|[ e4 | 228 ] | CALL PO,nn | +CALL PO,nn | SET 4,H | *NOP | *LD H,SET 4,(IX+d) | +|[ e5 | 229 ] | PUSH HL | PUSH IX | SET 4,L | *NOP | *LD L,SET 4,(IX+d) | +|[ e6 | 230 ] | AND n | +AND n | SET 4,(HL) | *NOP | SET 4,(IX+d) | +|[ e7 | 231 ] | RST 20H | +RST 20H | SET 4,A | *NOP | *LD A,SET 4,(IX+d) | +|[ e8 | 232 ] | RET PE | +RET PE | SET 5,B | *NOP | *LD B,SET 5,(IX+d) | +|[ e9 | 233 ] | JP (HL) | JP (IX) | SET 5,C | *NOP | *LD C,SET 5,(IX+d) | +|[ ea | 234 ] | JP PE,nn | +JP PE,nn | SET 5,D | *NOP | *LD D,SET 5,(IX+d) | +|[ eb | 235 ] | EX DE,HL | +EX DE,HL | SET 5,E | *NOP | *LD E,SET 5,(IX+d) | +|[ ec | 236 ] | CALL PE,nn | +CALL PE,nn | SET 5,H | *NOP | *LD H,SET 5,(IX+d) | +|[ ed | 237 ] | [Prefix] | +[Prefix] | SET 5,L | *NOP | *LD L,SET 5,(IX+d) | +|[ ee | 238 ] | XOR n | +XOR n | SET 5,(HL) | *NOP | SET 5,(IX+d) | +|[ ef | 239 ] | RST 28H | +RST 28H | SET 5,A | *NOP | *LD A,SET 5,(IX+d) | +|[ f0 | 240 ] | RET P | +RET P | SET 6,B | *NOP | *LD B,SET 6,(IX+d) | +|[ f1 | 241 ] | POP AF | +POP AF | SET 6,C | *NOP | *LD C,SET 6,(IX+d) | +|[ f2 | 242 ] | JP P,nn | +JP P,nn | SET 6,D | *NOP | *LD D,SET 6,(IX+d) | +|[ f3 | 243 ] | DI | +DI | SET 6,E | *NOP | *LD E,SET 6,(IX+d) | +|[ f4 | 244 ] | CALL P,nn | +CALL P,nn | SET 6,H | *NOP | *LD H,SET 6,(IX+d) | +|[ f5 | 245 ] | PUSH AF | +PUSH AF | SET 6,L | *NOP | *LD L,SET 6,(IX+d) | +|[ f6 | 246 ] | OR n | +OR n | SET 6,(HL) | *NOP | SET 6,(IX+d) | +|[ f7 | 247 ] | RST 30H | +RST 30H | SET 6,A | *NOP | *LD A,SET 6,(IX+d) | +|[ f8 | 248 ] | RET M | +RET M | SET 7,B | *NOP | *LD B,SET 7,(IX+d) | +|[ f9 | 249 ] | LD SP,HL | LD SP,IX | SET 7,C | *NOP | *LD C,SET 7,(IX+d) | +|[ fa | 250 ] | JP M,nn | +JP M,nn | SET 7,D | *NOP | *LD D,SET 7,(IX+d) | +|[ fb | 251 ] | EI | +EI | SET 7,E | *NOP | *LD E,SET 7,(IX+d) | +|[ fc | 252 ] | CALL M,nn | +CALL M,nn | SET 7,H | *NOP | *LD H,SET 7,(IX+d) | +|[ fd | 253 ] | [IY Prefix] | +[IY Prefix] | SET 7,L | *NOP | *LD L,SET 7,(IX+d) | +|[ fe | 254 ] | CP n | +CP n | SET 7,(HL) | *NOP | SET 7,(IX+d) | +|[ ff | 255 ] | RST 38H | +RST 38H | SET 7,A | *NOP | *LD A,SET 7,(IX+d) | ++-------------+-----------------+-------------------+------------------+------------------+-------------------------+ +-- +Peter McGavin. (peterm@maths.grace.cri.nz) + +From: agulbra@tigern.nvg.unit.no (Arnt Gulbrandsen) +Newsgroups: comp.sys.sinclair +Subject: Re: Undocumented Z80 opcodes +Date: 6 Jan 1994 13:31:44 +0100 +Organization: University of Trondheim, Norway +NNTP-Posting-Host: tigern.nvg.unit.no + +In article , +Peter McGavin wrote: +>In article, <2geqvv$nlq@tigern.nvg.unit.no>, +>agulbra@tigern.nvg.unit.no (Arnt Gulbrandsen) wrote: +>>I believe that list originally was written by from David Librik +>>. David (with someone else, I think) +>>reverse-engineered the Z80 and wrote a list of what he found, a list +>>which I think I sent to Peter. +> +>Actually I got it from Simon Owen (S.N.Owen@newcastle.ac.uk). +> +>Here it is: (sorry it's a bit wide) + +Not the same. Here's the big one. + +--Arnt + +Date: Fri, 19 Nov 1993 00:40:23 -0800 +From: David Librik +Message-Id: <199311190840.AAA06896@cory.EECS.Berkeley.EDU> +Subject: Undocumented Z-80 Instructions + + +Here is my article on undocumented Z-80 instructions. Please go over +your data and add anything you can to this list, and send it back to me. +Thanks! + +- David Librik +librik@cs.Berkeley.edu + + ------------------ + +There's been some discussion about the so-called "undocumented" opcodes +of the Z-80 microprocessor. These are officially-undefined machine- +language instructions that often have powerful and useful effects; +they are so often used by Z-80 system programmers that they are de-facto +"documented". Here is an article I posted a few years ago on another +computer system. + +By the way, the reason these instructions exist even though they were +not part of the original CPU design: the Z-80 was the most complex +microprocessor ever to be completely hard-wired (no microcode). As a +result -- as anyone who's ever taken a logic design course can tell +you -- it's much easier to have "undefined states" do whatever-comes- +easiest. + +* 2/28/88 2:37 pm librik / pega / cerl * + +The undocumented Z80 opcodes. While Zilog claims that +these should not be "trusted", I have yet to hear of a +Z80 that does not support them; and at least one operating +system uses them. + +* HX and LX instructions. These instructions manipulate + the high- and low-order 8 bits of the sixteen bit IX and + IY registers. (Here, I give the opcodes for HX and LX, + to get HY and LY, use FD instead of DD in the opcodes.) + +* SLL. This instruction shifts an 8-bit quantity left + (logical), then inserts 1 into the low-order bit. + +* Shift/Bit Set/Bit Reset with autocopy. These instructions + perform bit shifts (RLC, RRC, RL, RR, SLA, SRA, SLL, SRL), + bit set (SET) and bit reset (RES) operations on (IX+jj) + [and (IY+jj)], but also automatically copy the result + into an 8-bit register. + +* Null port accesses. IN and OUT without data. + +dd24 inc hx dd62 ld hx,d dd8c adc a,hx +dd25 dec hx dd63 ld hx,e dd8d adc a,lx +dd26nn ld hx,nn dd64 ld hx,hx dd94 sub hx +dd2c inc lx dd65 ld hx,lx dd95 sub lx +dd2d dec lx dd67 ld hx,a dd9c sbc a,hx +dd2enn ld lx,nn dd68 ld lx,b dd9d sbc a,lx +dd44 ld b,hx dd69 ld lx,c dda4 and hx +dd45 ld b,lx dd6a ld lx,d dda5 and lx +dd4c ld c,hx dd6b ld lx,e ddac xor hx +dd4d ld c,lx dd6c ld lx,hx ddad xor lx +dd54 ld d,hx dd6d ld lx,lx ddb4 or hx +dd55 ld d,lx dd6f ld lx,a ddb5 or lx +dd5c ld e,hx dd7c ld a,hx ddbc cp hx +dd5d ld e,lx dd7d ld a,lx ddbd cp lx +dd60 ld hx,b dd84 add a,hx +dd61 ld hx,c dd85 add a,lx + +The corresponding instructions for HY and LY may be obtained +by using FD in place of DD. + +cb30 sll b cb34 sll h +cb31 sll c cb35 sll l +cb32 sll d cb36 sll (hl) +cb33 sll e cb37 sll a + +* The following instructions perform the indicated operation +* on (ix+jj) and copy results into register 'r' (see below). +ddcbjj00-ddcbjj07 rlc r,(ix+jj) +ddcbjj08-ddcbjj0f rrc r,(ix+jj) +ddcbjj10-ddcbjj17 rl r,(ix+jj) +ddcbjj18-ddcbjj1f rr r,(ix+jj) +ddcbjj20-ddcbjj27 sla r,(ix+jj) +ddcbjj28-ddcbjj2f sra r,(ix+jj) +ddcbjj30-ddcbjj37 sll r,(ix+jj) +ddcbjj38-ddcbjj3f srl r,(ix+jj) + +ddcbjj80-ddcbjj87 res r,0,(ix+jj) +ddcbjj88-ddcbjj8f res r,1,(ix+jj) +ddcbjj90-ddcbjj97 res r,2,(ix+jj) +ddcbjj98-ddcbjj9f res r,3,(ix+jj) +ddcbjja0-ddcbjja7 res r,4,(ix+jj) +ddcbjja8-ddcbjjaf res r,5,(ix+jj) +ddcbjjb0-ddcbjjb7 res r,6,(ix+jj) +ddcbjjb8-ddcbjjbf res r,7,(ix+jj) + +ddcbjjc0-ddcbjjc7 set r,0,(ix+jj) +ddcbjjc8-ddcbjjcf set r,1,(ix+jj) +ddcbjjd0-ddcbjjd7 set r,2,(ix+jj) +ddcbjjd8-ddcbjjdf set r,3,(ix+jj) +ddcbjje0-ddcbjje7 set r,4,(ix+jj) +ddcbjje8-ddcbjjef set r,5,(ix+jj) +ddcbjjf0-ddcbjjf7 set r,6,(ix+jj) +ddcbjjf8-ddcbjjff set r,7,(ix+jj) + +In the last 3 tables, the corresponding instructions for +(IY+jj) may be obtained by using FD in place of DD. + +The value for 'r' is determined as follows: + Last digit of opcode: register 'r': + 0 or 8 B + 1 or 9 C + 2 or A D + 3 or B E + 4 or C H + 5 or D L + 6 or E (no effect) + 7 or F A + +* +ed70 in --,(c) +* gets input from port stored in (c), but does not store it. +* another reference claims this is: in (hl),(c) but I see no +* evidence for that, other than symmetry. +* +ed71 out (c),-- +* seems to send a 00 to port stored in (c). +* the same reference as as above calls this: out (hl),(c). + +A full article on this material is available upon request. +This information from NORTHERN BYTES, volume 5 number 8. + + -------- + +In addition to the information in the above article, I should mention +for completeness' sake all the other undefined opcodes and their +(generally redundant) effects. I shall list the ordinary Z-80 +instructions which they mimic. + +ed63nnnn ld (nnnn),hl +ed6bnnnn ld hl,(nnnn) +ed4c, ed54, ed5c, ed64, ed6c, ed74, ed7c neg + ed55, ed5d, ed65, ed6d, ed75, ed7d retn + +The following are no-ops: + +ed80-9f, eda4-a7, edac-af, edb4-b7, edbc-bf, ed00-3f, edc0-ff, +ed4e, ed66, ed6e, ed76, ed77, ed7e, ed7f + +Additional information from NANOS' Reference Card for the Z-80 microprocessor. + +David Librik +librik/pega/nova (on PLATO/NovaNET) + + diff --git a/sim/ucsim/z80.src/z80cl.h b/sim/ucsim/z80.src/z80cl.h index 470b999a..53e9e331 100644 --- a/sim/ucsim/z80.src/z80cl.h +++ b/sim/ucsim/z80.src/z80cl.h @@ -52,12 +52,19 @@ public: virtual void mk_hw_elements(void); virtual struct dis_entry *dis_tbl(void); - //virtual struct name_entry *sfr_tbl(void); - //virtual struct name_entry *bit_tbl(void); + virtual int inst_length(t_addr addr); + virtual int inst_branch(t_addr addr); + virtual int longest_inst(void); virtual char *disass(t_addr addr, char *sep); virtual void print_regs(class cl_console *con); virtual int exec_inst(void); + + virtual char * get_disasm_info(t_addr addr, + int *ret_len, + int *ret_branch, + int *immed_offset); + #include "instcl.h" }; diff --git a/sim/ucsim/z80.src/z80mac.h b/sim/ucsim/z80.src/z80mac.h new file mode 100644 index 00000000..7b1a743a --- /dev/null +++ b/sim/ucsim/z80.src/z80mac.h @@ -0,0 +1,266 @@ +/* + * Simulator of microcontrollers (z80mac.h) + * + * some z80 code base from Karl Bongers karl@turbobit.com + * + * Copyright (C) 1999,99 Drotos Daniel, Talker Bt. + * + * To contact author send email to drdani@mazsola.iit.uni-miskolc.hu + * + */ + +// shift positions +#define BITPOS_C 0 // 1 +#define BITPOS_P 2 // 4H +#define BITPOS_A 4 // 10H +#define BITPOS_Z 6 // 40H +#define BITPOS_S 7 // 80H + +#define store2(addr, val) { ram->set((t_addr) (addr), val & 0xff); \ + ram->set((t_addr) (addr+1), (val >> 8) & 0xff); } +#define store1(addr, val) ram->set((t_addr) (addr), val) +#define get1(addr) ram->get((t_addr) (addr)) +#define get2(addr) (ram->get((t_addr) (addr)) | (ram->get((t_addr) (addr+1)) << 8) ) +#define fetch2() (fetch() | (fetch() << 8)) +#define fetch1() fetch() +#define push2(val) {regs.SP-=2; store2(regs.SP,(val));} +#define push1(val) {regs.SP-=1; store1(regs.SP,(val));} +#define pop2(var) {var=get2(regs.SP),regs.SP+=2;} +//#define pop1(var) {var=get1(regs.SP),regs.SP+=1;} +#define add_u16_disp(_w, _d) (( (unsigned short)(_w) + (char)(_d) ) & 0xffff) + +#define sub_A_bytereg(br) { \ + regs.F &= ~(BIT_ALL); /* clear these */ \ + if (regs.A < br) regs.F |= (BIT_C | BIT_P); \ + regs.A -= (br); \ + regs.F |= BIT_N; /* not addition */ \ + if (regs.A == 0) regs.F |= BIT_Z; \ + if (regs.A & 0x80) regs.F |= BIT_S; \ + /* Skip BIT_A for now */ \ + } + + +#define rr_byte(reg) { \ + if (regs.F & BIT_C) { \ + regs.F &= ~(BIT_ALL); /* clear these */ \ + if (reg & 0x01) \ + regs.F |= BIT_C; \ + reg = (reg >> 1) | 0x80; \ + } else { \ + regs.F &= ~(BIT_ALL); /* clear these */ \ + if (reg & 0x01) \ + regs.F |= BIT_C; \ + reg >>= 1; \ + } \ + if (reg == 0) regs.F |= BIT_Z; \ + if (reg & 0x80) regs.F |= BIT_S; \ + /* fixme: BIT_P(lookup table?) */ \ +} + +#define rl_byte(reg) { \ + if (regs.F & BIT_C) { \ + regs.F &= ~(BIT_ALL); /* clear these */ \ + if (reg & 0x80) \ + regs.F |= BIT_C; \ + reg = (reg << 1) | 0x01; \ + } else { \ + regs.F &= ~(BIT_ALL); /* clear these */ \ + if (reg & 0x80) \ + regs.F |= BIT_C; \ + reg = (reg << 1); \ + } \ + if (reg == 0) regs.F |= BIT_Z; \ + if (reg & 0x80) regs.F |= BIT_S; \ + /* fixme: BIT_P(lookup table?) */ \ +} + +#define rrc_byte(reg) { \ + regs.F &= ~(BIT_ALL); /* clear these */ \ + if (reg & 0x01) { \ + regs.F |= BIT_C; \ + reg = (reg >> 1) | 0x80; \ + } \ + else \ + reg = (reg >> 1); \ + if (reg == 0) regs.F |= BIT_Z; \ + if (reg & 0x80) regs.F |= BIT_S; \ + /* fixme: BIT_P(lookup table?) */ \ +} + +#define rlc_byte(reg) { \ + regs.F &= ~(BIT_ALL); /* clear these */ \ + if (reg & 0x80) { \ + regs.F |= BIT_C; \ + reg = (reg << 1) | 0x01; \ + } else \ + reg <<= 1; \ + if (reg == 0) regs.F |= BIT_Z; \ + if (reg & 0x80) regs.F |= BIT_S; \ + /* fixme: BIT_P(lookup table?) */ \ +} + +#define sla_byte(reg) { \ + regs.F &= ~(BIT_ALL); /* clear these */ \ + if (reg & 0x80) \ + regs.F |= BIT_C; \ + reg <<= 1; \ + if (reg == 0) regs.F |= BIT_Z; \ + if (reg & 0x80) regs.F |= BIT_S; \ + /* fixme: BIT_P(lookup table?) */ \ +} + +#define sra_byte(reg) { \ + regs.F &= ~(BIT_ALL); /* clear these */ \ + if (reg & 0x80) { \ + if (reg & 0x01) \ + regs.F |= BIT_C; \ + reg = (reg >> 1) | 0x80; \ + } else { \ + if (reg & 0x01) \ + regs.F |= BIT_C; \ + reg >>= 1; \ + } \ + if (reg == 0) regs.F |= BIT_Z; \ + if (reg & 0x80) regs.F |= BIT_S; \ + /* fixme: BIT_P(lookup table?) */ \ +} + +#define srl_byte(reg) { \ + regs.F &= ~(BIT_ALL); /* clear these */ \ + if (reg & 0x01) \ + regs.F |= BIT_C; \ + reg >>= 1; \ + if (reg == 0) regs.F |= BIT_Z; \ + if (reg & 0x80) regs.F |= BIT_S; \ + /* fixme: BIT_P(lookup table?) */ \ +} + +/* following not in my book, best guess based on z80.txt comments */ +#define slia_byte(reg) { \ + regs.F &= ~(BIT_ALL); /* clear these */ \ + if (reg & 0x80) \ + regs.F |= BIT_C; \ + reg = (reg << 1) | 1; \ + if (reg == 0) regs.F |= BIT_Z; \ + if (reg & 0x80) regs.F |= BIT_S; \ + /* fixme: BIT_P(lookup table?) */ \ +} + +#define bit_byte(reg, _bitnum) { \ + regs.F &= ~(BIT_ALL); /* clear these */ \ + regs.F |= BIT_A; \ + if (!(reg & (1 << (_bitnum)))) \ + regs.F |= BIT_Z; \ + /* book shows BIT_S & BIT_P as unknown state */ \ +} + +#define add_A_bytereg(br) { \ + unsigned int tmp; \ + regs.F &= ~(BIT_ALL); /* clear these */ \ + tmp = (unsigned short)regs.A + (unsigned short)(br); \ + regs.A = (unsigned short) tmp; \ + /* C Z S A */ \ + if (tmp > 0xff) regs.F |= (BIT_C | BIT_P); \ + if (regs.A == 0) regs.F |= BIT_Z; \ + if (regs.A & 0x80) regs.F |= BIT_S; \ + /* Skip BIT_A for now */ \ + } + +#define adc_A_bytereg(br) { \ + unsigned int tmp; \ + tmp = (unsigned short)regs.A + (unsigned short)(br); \ + if (regs.F & BIT_C) ++tmp; \ + regs.F &= ~(BIT_ALL); /* clear these */ \ + regs.A = (unsigned char) tmp; \ + if (tmp > 0xff) regs.F |= (BIT_C | BIT_P); \ + if (regs.A == 0) regs.F |= BIT_Z; \ + if (regs.A & 0x80) regs.F |= BIT_S; \ + /* Skip BIT_A for now */ \ + } + +#define adc_HL_wordreg(reg) { \ + unsigned int tmp; \ + tmp = (unsigned int)regs.HL + (unsigned int)(reg); \ + if (regs.F & BIT_C) ++tmp; \ + regs.F &= ~(BIT_ALL); /* clear these */ \ + regs.HL = (unsigned short) tmp; \ + if (tmp > 0xffff) regs.F |= (BIT_C | BIT_P); \ + if (regs.HL == 0) regs.F |= BIT_Z; \ + if (regs.HL & 0x8000) regs.F |= BIT_S; \ + /* Skip BIT_A for now */ \ + } + +#define sbc_A_bytereg(br) { \ + unsigned int tmp; \ + tmp = (unsigned short)regs.A - (unsigned short)(br); \ + if (regs.F & BIT_C) --tmp; \ + regs.F &= ~(BIT_ALL); /* clear these */ \ + regs.A = (unsigned char) tmp; \ + if (tmp > 0xff) regs.F |= (BIT_C | BIT_P); \ + if (regs.A == 0) regs.F |= BIT_Z; \ + if (regs.A & 0x80) regs.F |= BIT_S; \ + regs.F |= BIT_N; \ + /* Skip BIT_A for now */ \ + } + +#define sbc_HL_wordreg(reg) { \ + unsigned int tmp; \ + tmp = (unsigned int)regs.HL - (unsigned int)(reg); \ + if (regs.F & BIT_C) --tmp; \ + regs.F &= ~(BIT_ALL); /* clear these */ \ + regs.HL = (unsigned short) tmp; \ + if (tmp > 0xffff) regs.F |= (BIT_C | BIT_P); \ + if (regs.HL == 0) regs.F |= BIT_Z; \ + if (regs.HL & 0x8000) regs.F |= BIT_S; \ + regs.F |= BIT_N; \ + /* Skip BIT_A for now */ \ + } + +#define and_A_bytereg(br) { \ + regs.A &= (br); \ + regs.F &= ~(BIT_ALL); /* clear these */ \ + if (regs.A == 0) regs.F |= BIT_Z; \ + if (regs.A & 0x80) regs.F |= BIT_S; \ + } + +#define xor_A_bytereg(br) { \ + regs.A ^= (br); \ + regs.F &= ~(BIT_ALL); /* clear these */ \ + if (regs.A == 0) regs.F |= BIT_Z; \ + if (regs.A & 0x80) regs.F |= BIT_S; \ + } + +#define or_A_bytereg(br) { \ + regs.A |= (br); \ + regs.F &= ~(BIT_ALL); /* clear these */ \ + if (regs.A == 0) regs.F |= BIT_Z; \ + if (regs.A & 0x80) regs.F |= BIT_S; \ + } + +#define cp_bytereg(br) { unsigned char _tmp1; \ + regs.F &= ~(BIT_ALL); /* clear these */ \ + if (regs.A < br) regs.F |= BIT_C; \ + _tmp1 = regs.A - (br); \ + regs.F |= BIT_N; /* not addition */ \ + if (_tmp1 == 0) regs.F |= BIT_Z; \ + if (_tmp1 & 0x80) regs.F |= BIT_S; \ + /* Skip BIT_A for now */ \ + } + +#define inc(var) /* 8-bit increment */ { var++; \ + regs.F &= ~(BIT_N |BIT_P |BIT_A |BIT_Z |BIT_S); /* clear these */ \ + if (var == 0) regs.F |= BIT_Z; \ + if (var & 0x80) regs.F |= BIT_S; \ + if ((var & 0x0f) == 0) regs.F |= BIT_A; \ + } + +#define dec(var) { \ + --var; \ + regs.F &= ~(BIT_N |BIT_P |BIT_A |BIT_Z |BIT_S); /* clear these */ \ + regs.F |= BIT_N; /* Not add */ \ + if (var == 0) regs.F |= BIT_Z; \ + if (var & 0x80) regs.F |= BIT_S; \ + if ((var & 0x0f) == 0) regs.F |= BIT_A; \ + } + + -- 2.30.2