# HG changeset patch # User nkeynes # Date 1093068949 0 # Node ID 42349f6ea216daf939cc4f232ac5c1798f9c9364 # Parent eea311cfd33ee72dc7ac2090e6ea8b2ce4fdd162 Commit changes into cvs --- a/src/Makefile.am Sat Mar 13 00:03:32 2004 +0000 +++ b/src/Makefile.am Sat Aug 21 06:15:49 2004 +0000 @@ -13,11 +13,15 @@ support.c support.h \ interface.c interface.h \ callbacks.c callbacks.h \ - gui.c gui.h gui_mmr.c \ - asic.c asic.h pvr2.c pvr2.h \ - video.c machine.c aica.c aica.h\ + gui.c gui.h mmr_win.c debug_win.c dump_win.c \ + asic.c asic.h pvr2.c pvr2.h ide.c ide.h \ + video.c dreamcast.c dreamcast.h aica.c aica.h\ + maple.c maple.h maple/controller.c maple/controller.h \ + sh4/intc.c sh4/intc.h sh4/mem.c sh4/mem.h sh4/mmio.h \ + sh4/sh4core.c sh4/sh4core.h sh4/sh4dasm.c sh4/sh4dasm.h \ + sh4/sh4mmio.c sh4/sh4mmio.h sh4/watch.c \ fileio.c ipbin.c -dream_LDADD = @PACKAGE_LIBS@ $(INTLLIBS) sh4/libsh4.a +dream_LDADD = @PACKAGE_LIBS@ $(INTLLIBS) AM_CFLAGS = -D_ISOC99_SOURCE -D_BSD_SOURCE --- a/src/Makefile.in Sat Mar 13 00:03:32 2004 +0000 +++ b/src/Makefile.in Sat Aug 21 06:15:49 2004 +0000 @@ -140,13 +140,17 @@ support.c support.h \ interface.c interface.h \ callbacks.c callbacks.h \ - gui.c gui.h gui_mmr.c \ - asic.c asic.h pvr2.c pvr2.h \ - video.c machine.c aica.c aica.h\ + gui.c gui.h mmr_win.c debug_win.c dump_win.c \ + asic.c asic.h pvr2.c pvr2.h ide.c ide.h \ + video.c dreamcast.c dreamcast.h aica.c aica.h\ + maple.c maple.h maple/controller.c maple/controller.h \ + sh4/intc.c sh4/intc.h sh4/mem.c sh4/mem.h sh4/mmio.h \ + sh4/sh4core.c sh4/sh4core.h sh4/sh4dasm.c sh4/sh4dasm.h \ + sh4/sh4mmio.c sh4/sh4mmio.h sh4/watch.c \ fileio.c ipbin.c -dream_LDADD = @PACKAGE_LIBS@ $(INTLLIBS) sh4/libsh4.a +dream_LDADD = @PACKAGE_LIBS@ $(INTLLIBS) AM_CFLAGS = -D_ISOC99_SOURCE -D_BSD_SOURCE subdir = src @@ -158,23 +162,32 @@ PROGRAMS = $(bin_PROGRAMS) am_dream_OBJECTS = main.$(OBJEXT) support.$(OBJEXT) interface.$(OBJEXT) \ - callbacks.$(OBJEXT) gui.$(OBJEXT) gui_mmr.$(OBJEXT) \ - asic.$(OBJEXT) pvr2.$(OBJEXT) video.$(OBJEXT) machine.$(OBJEXT) \ - aica.$(OBJEXT) fileio.$(OBJEXT) ipbin.$(OBJEXT) + callbacks.$(OBJEXT) gui.$(OBJEXT) mmr_win.$(OBJEXT) \ + debug_win.$(OBJEXT) dump_win.$(OBJEXT) asic.$(OBJEXT) \ + pvr2.$(OBJEXT) ide.$(OBJEXT) video.$(OBJEXT) \ + dreamcast.$(OBJEXT) aica.$(OBJEXT) maple.$(OBJEXT) \ + controller.$(OBJEXT) intc.$(OBJEXT) mem.$(OBJEXT) \ + sh4core.$(OBJEXT) sh4dasm.$(OBJEXT) sh4mmio.$(OBJEXT) \ + watch.$(OBJEXT) fileio.$(OBJEXT) ipbin.$(OBJEXT) dream_OBJECTS = $(am_dream_OBJECTS) -dream_DEPENDENCIES = sh4/libsh4.a +dream_DEPENDENCIES = dream_LDFLAGS = DEFAULT_INCLUDES = -I. -I$(srcdir) -I$(top_builddir) depcomp = $(SHELL) $(top_srcdir)/depcomp am__depfiles_maybe = depfiles @AMDEP_TRUE@DEP_FILES = ./$(DEPDIR)/aica.Po ./$(DEPDIR)/asic.Po \ -@AMDEP_TRUE@ ./$(DEPDIR)/callbacks.Po ./$(DEPDIR)/fileio.Po \ -@AMDEP_TRUE@ ./$(DEPDIR)/gui.Po ./$(DEPDIR)/gui_mmr.Po \ -@AMDEP_TRUE@ ./$(DEPDIR)/interface.Po ./$(DEPDIR)/ipbin.Po \ -@AMDEP_TRUE@ ./$(DEPDIR)/machine.Po ./$(DEPDIR)/main.Po \ -@AMDEP_TRUE@ ./$(DEPDIR)/pvr2.Po ./$(DEPDIR)/support.Po \ -@AMDEP_TRUE@ ./$(DEPDIR)/video.Po +@AMDEP_TRUE@ ./$(DEPDIR)/callbacks.Po ./$(DEPDIR)/controller.Po \ +@AMDEP_TRUE@ ./$(DEPDIR)/debug_win.Po ./$(DEPDIR)/dreamcast.Po \ +@AMDEP_TRUE@ ./$(DEPDIR)/dump_win.Po ./$(DEPDIR)/fileio.Po \ +@AMDEP_TRUE@ ./$(DEPDIR)/gui.Po ./$(DEPDIR)/ide.Po \ +@AMDEP_TRUE@ ./$(DEPDIR)/intc.Po ./$(DEPDIR)/interface.Po \ +@AMDEP_TRUE@ ./$(DEPDIR)/ipbin.Po ./$(DEPDIR)/main.Po \ +@AMDEP_TRUE@ ./$(DEPDIR)/maple.Po ./$(DEPDIR)/mem.Po \ +@AMDEP_TRUE@ ./$(DEPDIR)/mmr_win.Po ./$(DEPDIR)/pvr2.Po \ +@AMDEP_TRUE@ ./$(DEPDIR)/sh4core.Po ./$(DEPDIR)/sh4dasm.Po \ +@AMDEP_TRUE@ ./$(DEPDIR)/sh4mmio.Po ./$(DEPDIR)/support.Po \ +@AMDEP_TRUE@ ./$(DEPDIR)/video.Po ./$(DEPDIR)/watch.Po COMPILE = $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) \ $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) CCLD = $(CC) @@ -229,16 +242,27 @@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/aica.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/asic.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/callbacks.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/controller.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/debug_win.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/dreamcast.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/dump_win.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/fileio.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/gui.Po@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/gui_mmr.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/ide.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/intc.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/interface.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/ipbin.Po@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/machine.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/main.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/maple.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/mem.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/mmr_win.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pvr2.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/sh4core.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/sh4dasm.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/sh4mmio.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/support.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/video.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/watch.Po@am__quote@ .c.o: @am__fastdepCC_TRUE@ if $(COMPILE) -MT $@ -MD -MP -MF "$(DEPDIR)/$*.Tpo" \ @@ -261,6 +285,160 @@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ depfile='$(DEPDIR)/$*.Po' tmpdepfile='$(DEPDIR)/$*.TPo' @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(COMPILE) -c `if test -f '$<'; then $(CYGPATH_W) '$<'; else $(CYGPATH_W) '$(srcdir)/$<'; fi` + +controller.o: maple/controller.c +@am__fastdepCC_TRUE@ if $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT controller.o -MD -MP -MF "$(DEPDIR)/controller.Tpo" \ +@am__fastdepCC_TRUE@ -c -o controller.o `test -f 'maple/controller.c' || echo '$(srcdir)/'`maple/controller.c; \ +@am__fastdepCC_TRUE@ then mv -f "$(DEPDIR)/controller.Tpo" "$(DEPDIR)/controller.Po"; \ +@am__fastdepCC_TRUE@ else rm -f "$(DEPDIR)/controller.Tpo"; exit 1; \ +@am__fastdepCC_TRUE@ fi +@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='maple/controller.c' object='controller.o' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ depfile='$(DEPDIR)/controller.Po' tmpdepfile='$(DEPDIR)/controller.TPo' @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o controller.o `test -f 'maple/controller.c' || echo '$(srcdir)/'`maple/controller.c + +controller.obj: maple/controller.c +@am__fastdepCC_TRUE@ if $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT controller.obj -MD -MP -MF "$(DEPDIR)/controller.Tpo" \ +@am__fastdepCC_TRUE@ -c -o controller.obj `if test -f 'maple/controller.c'; then $(CYGPATH_W) 'maple/controller.c'; else $(CYGPATH_W) '$(srcdir)/maple/controller.c'; fi`; \ +@am__fastdepCC_TRUE@ then mv -f "$(DEPDIR)/controller.Tpo" "$(DEPDIR)/controller.Po"; \ +@am__fastdepCC_TRUE@ else rm -f "$(DEPDIR)/controller.Tpo"; exit 1; \ +@am__fastdepCC_TRUE@ fi +@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='maple/controller.c' object='controller.obj' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ depfile='$(DEPDIR)/controller.Po' tmpdepfile='$(DEPDIR)/controller.TPo' @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o controller.obj `if test -f 'maple/controller.c'; then $(CYGPATH_W) 'maple/controller.c'; else $(CYGPATH_W) '$(srcdir)/maple/controller.c'; fi` + +intc.o: sh4/intc.c +@am__fastdepCC_TRUE@ if $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT intc.o -MD -MP -MF "$(DEPDIR)/intc.Tpo" \ +@am__fastdepCC_TRUE@ -c -o intc.o `test -f 'sh4/intc.c' || echo '$(srcdir)/'`sh4/intc.c; \ +@am__fastdepCC_TRUE@ then mv -f "$(DEPDIR)/intc.Tpo" "$(DEPDIR)/intc.Po"; \ +@am__fastdepCC_TRUE@ else rm -f "$(DEPDIR)/intc.Tpo"; exit 1; \ +@am__fastdepCC_TRUE@ fi +@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='sh4/intc.c' object='intc.o' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ depfile='$(DEPDIR)/intc.Po' tmpdepfile='$(DEPDIR)/intc.TPo' @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o intc.o `test -f 'sh4/intc.c' || echo '$(srcdir)/'`sh4/intc.c + +intc.obj: sh4/intc.c +@am__fastdepCC_TRUE@ if $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT intc.obj -MD -MP -MF "$(DEPDIR)/intc.Tpo" \ +@am__fastdepCC_TRUE@ -c -o intc.obj `if test -f 'sh4/intc.c'; then $(CYGPATH_W) 'sh4/intc.c'; else $(CYGPATH_W) '$(srcdir)/sh4/intc.c'; fi`; \ +@am__fastdepCC_TRUE@ then mv -f "$(DEPDIR)/intc.Tpo" "$(DEPDIR)/intc.Po"; \ +@am__fastdepCC_TRUE@ else rm -f "$(DEPDIR)/intc.Tpo"; exit 1; \ +@am__fastdepCC_TRUE@ fi +@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='sh4/intc.c' object='intc.obj' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ depfile='$(DEPDIR)/intc.Po' tmpdepfile='$(DEPDIR)/intc.TPo' @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o intc.obj `if test -f 'sh4/intc.c'; then $(CYGPATH_W) 'sh4/intc.c'; else $(CYGPATH_W) '$(srcdir)/sh4/intc.c'; fi` + +mem.o: sh4/mem.c +@am__fastdepCC_TRUE@ if $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT mem.o -MD -MP -MF "$(DEPDIR)/mem.Tpo" \ +@am__fastdepCC_TRUE@ -c -o mem.o `test -f 'sh4/mem.c' || echo '$(srcdir)/'`sh4/mem.c; \ +@am__fastdepCC_TRUE@ then mv -f "$(DEPDIR)/mem.Tpo" "$(DEPDIR)/mem.Po"; \ +@am__fastdepCC_TRUE@ else rm -f "$(DEPDIR)/mem.Tpo"; exit 1; \ +@am__fastdepCC_TRUE@ fi +@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='sh4/mem.c' object='mem.o' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ depfile='$(DEPDIR)/mem.Po' tmpdepfile='$(DEPDIR)/mem.TPo' @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o mem.o `test -f 'sh4/mem.c' || echo '$(srcdir)/'`sh4/mem.c + +mem.obj: sh4/mem.c +@am__fastdepCC_TRUE@ if $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT mem.obj -MD -MP -MF "$(DEPDIR)/mem.Tpo" \ +@am__fastdepCC_TRUE@ -c -o mem.obj `if test -f 'sh4/mem.c'; then $(CYGPATH_W) 'sh4/mem.c'; else $(CYGPATH_W) '$(srcdir)/sh4/mem.c'; fi`; \ +@am__fastdepCC_TRUE@ then mv -f "$(DEPDIR)/mem.Tpo" "$(DEPDIR)/mem.Po"; \ +@am__fastdepCC_TRUE@ else rm -f "$(DEPDIR)/mem.Tpo"; exit 1; \ +@am__fastdepCC_TRUE@ fi +@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='sh4/mem.c' object='mem.obj' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ depfile='$(DEPDIR)/mem.Po' tmpdepfile='$(DEPDIR)/mem.TPo' @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o mem.obj `if test -f 'sh4/mem.c'; then $(CYGPATH_W) 'sh4/mem.c'; else $(CYGPATH_W) '$(srcdir)/sh4/mem.c'; fi` + +sh4core.o: sh4/sh4core.c +@am__fastdepCC_TRUE@ if $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT sh4core.o -MD -MP -MF "$(DEPDIR)/sh4core.Tpo" \ +@am__fastdepCC_TRUE@ -c -o sh4core.o `test -f 'sh4/sh4core.c' || echo '$(srcdir)/'`sh4/sh4core.c; \ +@am__fastdepCC_TRUE@ then mv -f "$(DEPDIR)/sh4core.Tpo" "$(DEPDIR)/sh4core.Po"; \ +@am__fastdepCC_TRUE@ else rm -f "$(DEPDIR)/sh4core.Tpo"; exit 1; \ +@am__fastdepCC_TRUE@ fi +@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='sh4/sh4core.c' object='sh4core.o' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ depfile='$(DEPDIR)/sh4core.Po' tmpdepfile='$(DEPDIR)/sh4core.TPo' @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o sh4core.o `test -f 'sh4/sh4core.c' || echo '$(srcdir)/'`sh4/sh4core.c + +sh4core.obj: sh4/sh4core.c +@am__fastdepCC_TRUE@ if $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT sh4core.obj -MD -MP -MF "$(DEPDIR)/sh4core.Tpo" \ +@am__fastdepCC_TRUE@ -c -o sh4core.obj `if test -f 'sh4/sh4core.c'; then $(CYGPATH_W) 'sh4/sh4core.c'; else $(CYGPATH_W) '$(srcdir)/sh4/sh4core.c'; fi`; \ +@am__fastdepCC_TRUE@ then mv -f "$(DEPDIR)/sh4core.Tpo" "$(DEPDIR)/sh4core.Po"; \ +@am__fastdepCC_TRUE@ else rm -f "$(DEPDIR)/sh4core.Tpo"; exit 1; \ +@am__fastdepCC_TRUE@ fi +@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='sh4/sh4core.c' object='sh4core.obj' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ depfile='$(DEPDIR)/sh4core.Po' tmpdepfile='$(DEPDIR)/sh4core.TPo' @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o sh4core.obj `if test -f 'sh4/sh4core.c'; then $(CYGPATH_W) 'sh4/sh4core.c'; else $(CYGPATH_W) '$(srcdir)/sh4/sh4core.c'; fi` + +sh4dasm.o: sh4/sh4dasm.c +@am__fastdepCC_TRUE@ if $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT sh4dasm.o -MD -MP -MF "$(DEPDIR)/sh4dasm.Tpo" \ +@am__fastdepCC_TRUE@ -c -o sh4dasm.o `test -f 'sh4/sh4dasm.c' || echo '$(srcdir)/'`sh4/sh4dasm.c; \ +@am__fastdepCC_TRUE@ then mv -f "$(DEPDIR)/sh4dasm.Tpo" "$(DEPDIR)/sh4dasm.Po"; \ +@am__fastdepCC_TRUE@ else rm -f "$(DEPDIR)/sh4dasm.Tpo"; exit 1; \ +@am__fastdepCC_TRUE@ fi +@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='sh4/sh4dasm.c' object='sh4dasm.o' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ depfile='$(DEPDIR)/sh4dasm.Po' tmpdepfile='$(DEPDIR)/sh4dasm.TPo' @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o sh4dasm.o `test -f 'sh4/sh4dasm.c' || echo '$(srcdir)/'`sh4/sh4dasm.c + +sh4dasm.obj: sh4/sh4dasm.c +@am__fastdepCC_TRUE@ if $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT sh4dasm.obj -MD -MP -MF "$(DEPDIR)/sh4dasm.Tpo" \ +@am__fastdepCC_TRUE@ -c -o sh4dasm.obj `if test -f 'sh4/sh4dasm.c'; then $(CYGPATH_W) 'sh4/sh4dasm.c'; else $(CYGPATH_W) '$(srcdir)/sh4/sh4dasm.c'; fi`; \ +@am__fastdepCC_TRUE@ then mv -f "$(DEPDIR)/sh4dasm.Tpo" "$(DEPDIR)/sh4dasm.Po"; \ +@am__fastdepCC_TRUE@ else rm -f "$(DEPDIR)/sh4dasm.Tpo"; exit 1; \ +@am__fastdepCC_TRUE@ fi +@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='sh4/sh4dasm.c' object='sh4dasm.obj' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ depfile='$(DEPDIR)/sh4dasm.Po' tmpdepfile='$(DEPDIR)/sh4dasm.TPo' @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o sh4dasm.obj `if test -f 'sh4/sh4dasm.c'; then $(CYGPATH_W) 'sh4/sh4dasm.c'; else $(CYGPATH_W) '$(srcdir)/sh4/sh4dasm.c'; fi` + +sh4mmio.o: sh4/sh4mmio.c +@am__fastdepCC_TRUE@ if $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT sh4mmio.o -MD -MP -MF "$(DEPDIR)/sh4mmio.Tpo" \ +@am__fastdepCC_TRUE@ -c -o sh4mmio.o `test -f 'sh4/sh4mmio.c' || echo '$(srcdir)/'`sh4/sh4mmio.c; \ +@am__fastdepCC_TRUE@ then mv -f "$(DEPDIR)/sh4mmio.Tpo" "$(DEPDIR)/sh4mmio.Po"; \ +@am__fastdepCC_TRUE@ else rm -f "$(DEPDIR)/sh4mmio.Tpo"; exit 1; \ +@am__fastdepCC_TRUE@ fi +@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='sh4/sh4mmio.c' object='sh4mmio.o' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ depfile='$(DEPDIR)/sh4mmio.Po' tmpdepfile='$(DEPDIR)/sh4mmio.TPo' @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o sh4mmio.o `test -f 'sh4/sh4mmio.c' || echo '$(srcdir)/'`sh4/sh4mmio.c + +sh4mmio.obj: sh4/sh4mmio.c +@am__fastdepCC_TRUE@ if $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT sh4mmio.obj -MD -MP -MF "$(DEPDIR)/sh4mmio.Tpo" \ +@am__fastdepCC_TRUE@ -c -o sh4mmio.obj `if test -f 'sh4/sh4mmio.c'; then $(CYGPATH_W) 'sh4/sh4mmio.c'; else $(CYGPATH_W) '$(srcdir)/sh4/sh4mmio.c'; fi`; \ +@am__fastdepCC_TRUE@ then mv -f "$(DEPDIR)/sh4mmio.Tpo" "$(DEPDIR)/sh4mmio.Po"; \ +@am__fastdepCC_TRUE@ else rm -f "$(DEPDIR)/sh4mmio.Tpo"; exit 1; \ +@am__fastdepCC_TRUE@ fi +@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='sh4/sh4mmio.c' object='sh4mmio.obj' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ depfile='$(DEPDIR)/sh4mmio.Po' tmpdepfile='$(DEPDIR)/sh4mmio.TPo' @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o sh4mmio.obj `if test -f 'sh4/sh4mmio.c'; then $(CYGPATH_W) 'sh4/sh4mmio.c'; else $(CYGPATH_W) '$(srcdir)/sh4/sh4mmio.c'; fi` + +watch.o: sh4/watch.c +@am__fastdepCC_TRUE@ if $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT watch.o -MD -MP -MF "$(DEPDIR)/watch.Tpo" \ +@am__fastdepCC_TRUE@ -c -o watch.o `test -f 'sh4/watch.c' || echo '$(srcdir)/'`sh4/watch.c; \ +@am__fastdepCC_TRUE@ then mv -f "$(DEPDIR)/watch.Tpo" "$(DEPDIR)/watch.Po"; \ +@am__fastdepCC_TRUE@ else rm -f "$(DEPDIR)/watch.Tpo"; exit 1; \ +@am__fastdepCC_TRUE@ fi +@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='sh4/watch.c' object='watch.o' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ depfile='$(DEPDIR)/watch.Po' tmpdepfile='$(DEPDIR)/watch.TPo' @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o watch.o `test -f 'sh4/watch.c' || echo '$(srcdir)/'`sh4/watch.c + +watch.obj: sh4/watch.c +@am__fastdepCC_TRUE@ if $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT watch.obj -MD -MP -MF "$(DEPDIR)/watch.Tpo" \ +@am__fastdepCC_TRUE@ -c -o watch.obj `if test -f 'sh4/watch.c'; then $(CYGPATH_W) 'sh4/watch.c'; else $(CYGPATH_W) '$(srcdir)/sh4/watch.c'; fi`; \ +@am__fastdepCC_TRUE@ then mv -f "$(DEPDIR)/watch.Tpo" "$(DEPDIR)/watch.Po"; \ +@am__fastdepCC_TRUE@ else rm -f "$(DEPDIR)/watch.Tpo"; exit 1; \ +@am__fastdepCC_TRUE@ fi +@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='sh4/watch.c' object='watch.obj' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ depfile='$(DEPDIR)/watch.Po' tmpdepfile='$(DEPDIR)/watch.TPo' @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o watch.obj `if test -f 'sh4/watch.c'; then $(CYGPATH_W) 'sh4/watch.c'; else $(CYGPATH_W) '$(srcdir)/sh4/watch.c'; fi` uninstall-info-am: ETAGS = etags --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/aica/armcore.c Sat Aug 21 06:15:49 2004 +0000 @@ -0,0 +1,31 @@ + +#include "armcore.h" + +struct arm_registers armr; + +/* NB: The arm (one assumes) has a different memory map, but for the meantime... */ + +#define MEM_READ_BYTE( addr ) mem_read_byte(addr) +#define MEM_READ_WORD( addr ) mem_read_word(addr) +#define MEM_READ_LONG( addr ) mem_read_long(addr) +#define MEM_WRITE_BYTE( addr, val ) mem_write_byte(addr, val) +#define MEM_WRITE_WORD( addr, val ) mem_write_word(addr, val) +#define MEM_WRITE_LONG( addr, val ) mem_write_long(addr, val) + +#define PC armr.r[15]; + +void arm_execute_instruction( void ) +{ + uint32_t ir = MEM_READ_LONG(PC); + +#define COND(ir) (ir>>28) + + +} + +void arm_execute_thumb_instruction( void ) +{ + + + +} --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/aica/armcore.h Sat Aug 21 06:15:49 2004 +0000 @@ -0,0 +1,47 @@ + +#ifndef dream_armcore_H +#define dream_armcore_H 1 + +#include "dream.h" +#include + + + +struct arm_registers { + uint32_t r[16]; /* Current register bank */ + + uint32_t cpsr; + uint32_t spsr; + + /* Various banked versions of the registers. */ + uint32_t fiq_r[7]; /* FIQ bank 8..14 */ + uint32_t irq_r[2]; /* IRQ bank 13..14 */ + uint32_t und_r[2]; /* UND bank 13..14 */ + uint32_t abt_r[2]; /* ABT bank 13..14 */ + uint32_t svc_r[2]; /* SVC bank 13..14 */ + uint32_t user_r[7]; /* User/System bank 8..14 */ + +}; + +#define CPSR_N 0x80000000 /* Negative flag */ +#define CPSR_Z 0x40000000 /* Zero flag */ +#define CPSR_C 0x20000000 /* Carry flag */ +#define CPSR_V 0x10000000 /* Overflow flag */ +#define CPSR_I 0x00000080 /* Interrupt disable bit */ +#define CPSR_F 0x00000040 /* Fast interrupt disable bit */ +#define CPSR_T 0x00000020 /* Thumb mode */ +#define CPSR_MODE 0x0000001F /* Current execution mode */ + +#define MODE_USER 0x00 /* User mode */ +#define MODE_FIQ 0x01 /* Fast IRQ mode */ +#define MODE_IRQ 0x02 /* IRQ mode */ +#define MODE_SV 0x03 /* Supervisor mode */ +#define MODE_ABT 0x07 /* Abort mode */ +#define MODE_UND 0x0B /* Undefined mode */ +#define MODE_SYS 0x0F /* System mode */ + +extern struct arm_registers armr; + + + +#endif /* !dream_armcore_H */ --- a/src/asic.c Sat Mar 13 00:03:32 2004 +0000 +++ b/src/asic.c Sat Aug 21 06:15:49 2004 +0000 @@ -3,7 +3,9 @@ #include "mem.h" #include "sh4/intc.h" #include "asic.h" +#include "dreamcast.h" #include "maple.h" +#include "ide.h" #define MMIO_IMPL #include "asic.h" /* @@ -39,10 +41,10 @@ MMIO_WRITE( ASIC, reg, val ); if( val & 1 ) { uint32_t maple_addr = MMIO_READ( ASIC, MAPLE_DMA) &0x1FFFFFE0; -// maple_handle_buffer( maple_addr ); - WARN( "Maple request initiated, halting" ); + WARN( "Maple request initiated at %08X, halting", maple_addr ); + maple_handle_buffer( maple_addr ); MMIO_WRITE( ASIC, reg, 0 ); - sh4_stop(); +// dreamcast_stop(); } break; default: @@ -56,6 +58,11 @@ { int32_t val; switch( reg ) { + /* + case 0x89C: + sh4_stop(); + return 0x000000B; + */ case PIRQ0: case PIRQ1: case PIRQ2: @@ -91,13 +98,63 @@ MMIO_REGION_WRITE_FN( EXTDMA, reg, val ) { - MMIO_WRITE( EXTDMA, reg, val ); + switch( reg ) { + case IDEALTSTATUS: /* Device control */ + ide_write_control( val ); + break; + case IDEDATA: + ide_write_data_pio( val ); + break; + case IDEFEAT: + if( ide_can_write_regs() ) + idereg.feature = (uint8_t)val; + break; + case IDECOUNT: + if( ide_can_write_regs() ) + idereg.count = (uint8_t)val; + break; + case IDELBA0: + if( ide_can_write_regs() ) + idereg.lba0 = (uint8_t)val; + break; + case IDELBA1: + if( ide_can_write_regs() ) + idereg.lba1 = (uint8_t)val; + break; + case IDELBA2: + if( ide_can_write_regs() ) + idereg.lba2 = (uint8_t)val; + break; + case IDEDEV: + if( ide_can_write_regs() ) + idereg.device = (uint8_t)val; + break; + case IDECMD: + if( ide_can_write_regs() ) { + ide_clear_interrupt(); + ide_write_command( (uint8_t)val ); + } + break; + + default: + MMIO_WRITE( EXTDMA, reg, val ); + } } MMIO_REGION_READ_FN( EXTDMA, reg ) { switch( reg ) { - case GDBUSY: return 0; + case IDEALTSTATUS: return idereg.status; + case IDEDATA: return ide_read_data_pio( ); + case IDEFEAT: return idereg.error; + case IDECOUNT:return idereg.count; + case IDELBA0: return idereg.disc; + case IDELBA1: return idereg.lba1; + case IDELBA2: return idereg.lba2; + case IDEDEV: return idereg.device; + case IDECMD: + ide_clear_interrupt(); + return idereg.status; default: return MMIO_READ( EXTDMA, reg ); } --- a/src/asic.h Sat Mar 13 00:03:32 2004 +0000 +++ b/src/asic.h Sat Aug 21 06:15:49 2004 +0000 @@ -9,6 +9,7 @@ LONG_PORT( 0x884, ASICUNK1, PORT_MRW, 0, "ASIC " ) LONG_PORT( 0x888, ASICUNK2, PORT_MRW, 0, "ASIC " ) LONG_PORT( 0x88C, G2STATUS, PORT_MR, 0, "G2 Bus status" ) + LONG_PORT( 0x89C, ASICUNK3, PORT_MRW, 0xB, "Unknown, always 0xB?" ) LONG_PORT( 0x900, PIRQ0, PORT_MRW, 0, "Pending interrupts 0" ) LONG_PORT( 0x904, PIRQ1, PORT_MRW, 0, "Pending interrupts 1" ) LONG_PORT( 0x908, PIRQ2, PORT_MRW, 0, "Pending interrupts 2" ) @@ -21,24 +22,48 @@ LONG_PORT( 0x930, IRQC0, PORT_MRW, 0, "IRQ C event map 0" ) LONG_PORT( 0x934, IRQC1, PORT_MRW, 0, "IRQ C event map 1" ) LONG_PORT( 0x938, IRQC2, PORT_MRW, 0, "IRQ C event map 2" ) + LONG_PORT( 0x940, ASIC9UNK1, PORT_MRW, 0, "Unknown 1" ) + LONG_PORT( 0x944, ASIC9UNK2, PORT_MRW, 0, "Unknown 2" ) + LONG_PORT( 0x950, ASIC9UNK3, PORT_MRW, 0, "Unknown 3" ) + LONG_PORT( 0x954, ASIC9UNK4, PORT_MRW, 0, "Unknown 4" ) +/* ASIC events repeats at 0x980..0x9FF, then the whole region 800..9ff + * repeats at 000..1ff, 200..3ff, 400..5ff, 600..7ff, a00..bff. + * The whole region 800..8ff is long-readable, but since I so far have no idea + * what any of it means (nor have I seen any of it accessed), they're not + * listed above. + */ + LONG_PORT( 0xC04, MAPLE_DMA, PORT_MRW, UNDEFINED, "Maple DMA Address" ) LONG_PORT( 0xC10, MAPLE_RESET2, PORT_MRW, UNDEFINED, "Maple Reset 2" ) LONG_PORT( 0xC14, MAPLE_ENABLE, PORT_MRW, UNDEFINED, "Maple Enable" ) LONG_PORT( 0xC18, MAPLE_STATE, PORT_MRW, 0, "Maple State" ) + LONG_PORT( 0xC70, MAPLE_UNK1, PORT_MRW, 0, "Maple unknown 1" ) + LONG_PORT( 0xC74, MAPLE_UNK2, PORT_MRW, 0, "Maple unknown 2" ) + LONG_PORT( 0xC78, MAPLE_UNK3, PORT_MRW, 0, "Maple unknown 3" ) + LONG_PORT( 0xC7C, MAPLE_UNK4, PORT_MRW, 0, "Maple unknown 4" ) LONG_PORT( 0xC80, MAPLE_SPEED, PORT_MRW, UNDEFINED, "Maple Speed" ) + LONG_PORT( 0xC84, MAPLE_UNK5, PORT_MRW, 0, "Maple unknown 5" ) LONG_PORT( 0xC8C, MAPLE_RESET1, PORT_MRW, UNDEFINED, "Maple Reset 1" ) + LONG_PORT( 0xCE8, MAPLE_UNK6, PORT_MRW, 0, "Maple unknown 6" ) + LONG_PORT( 0xCF4, MAPLE_SRC, PORT_MRW, 0, "Maple current source" ) + LONG_PORT( 0xCF8, MAPLE_DEST1, PORT_MRW, 0, "Maple current destination" ) + LONG_PORT( 0xCFC, MAPLE_DEST2, PORT_MRW, 0, "Maple current destination 2?" ) +/* Note: Maple registers repeat at 0xD00..0xDFF, + * 0xE00..0xEFF and 0xF00..0xFFF */ MMIO_REGION_END MMIO_REGION_BEGIN( 0x005F7000, EXTDMA, "ASIC External DMA" ) - BYTE_PORT( 0x018, GDBUSY, PORT_MRW, 0, "GD-Rom Busy" ) - WORD_PORT( 0x080, GDDATA, PORT_MRW, 0, "GD-Rom Data" ) - BYTE_PORT( 0x084, GDFEAT, PORT_MRW, 0, "GD-Rom Feature" ) - BYTE_PORT( 0x088, GDSECTOR, PORT_MRW, 0, "GD-Rom Sector Count" ) - BYTE_PORT( 0x08C, GDNSECTOR, PORT_MRW, 0, "GD-Rom Sector" ) - BYTE_PORT( 0x090, GDCMDLENLO, PORT_MRW, 0, "GD-Rom Command length low" ) - BYTE_PORT( 0x094, GDCMDLENHI, PORT_MRW, 0, "GD-Rom Command length hi" ) - BYTE_PORT( 0x09C, GDSTATUS, PORT_MRW, 0, "GD-Rom Status" ) + BYTE_PORT( 0x018, IDEALTSTATUS, PORT_RW, 0, "IDE Device Control / Alt-status" ) /* 10110 */ + BYTE_PORT( 0x01C, IDEUNK1, PORT_MRW, 0, "IDE Unknown" ) + WORD_PORT( 0x080, IDEDATA, PORT_RW, 0, "IDE Data" ) + BYTE_PORT( 0x084, IDEFEAT, PORT_RW, 0, "IDE Feature / Error" ) + BYTE_PORT( 0x088, IDECOUNT, PORT_RW, 0, "IDE Sector Count" ) + BYTE_PORT( 0x08C, IDELBA0, PORT_RW, 0, "IDE LBA lo" ) /* AKA sector */ + BYTE_PORT( 0x090, IDELBA1, PORT_RW, 0, "IDE LBA mid" ) /* AKA Cyl lo */ + BYTE_PORT( 0x094, IDELBA2, PORT_RW, 0, "IDE LBA hi" ) /* AKA Cyl hi */ + BYTE_PORT( 0x098, IDEDEV, PORT_RW, 0, "IDE Device" ) + BYTE_PORT( 0x09C, IDECMD, PORT_RW, 0, "IDE Command/Status" ) LONG_PORT( 0x404, EXTDMASH4, PORT_MRW, 0, "Ext DMA SH4 address" ) LONG_PORT( 0x408, EXTDMASIZ, PORT_MRW, 0, "Ext DMA Size" ) LONG_PORT( 0x40C, EXTDMADIR, PORT_MRW, 0, "Ext DMA Direction" ) @@ -54,7 +79,7 @@ LONG_PORT( 0x4A4, EXTDMAUNK7, PORT_MRW, 0, "Ext DMA " ) LONG_PORT( 0x4B4, EXTDMAUNK8, PORT_MRW, 0, "Ext DMA " ) LONG_PORT( 0x4B8, EXTDMAUNK9, PORT_MRW, 0, "Ext DMA " ) - LONG_PORT( 0x4E4, GDACTIVATE, PORT_MRW, 0, "GD-Rom activate" ) + LONG_PORT( 0x4E4, IDEACTIVATE, PORT_MRW, 0, "IDE activate" ) LONG_PORT( 0x800, SPUDMA0EXT, PORT_MRW, 0, "SPU DMA0 External address" ) LONG_PORT( 0x804, SPUDMA0SH4, PORT_MRW, 0, "SPU DMA0 SH4-based address" ) LONG_PORT( 0x808, SPUDMA0SIZ, PORT_MRW, 0, "SPU DMA0 Size" ) --- a/src/dream.h Sat Mar 13 00:03:32 2004 +0000 +++ b/src/dream.h Sat Aug 21 06:15:49 2004 +0000 @@ -4,6 +4,8 @@ #ifndef dream_H #define dream_H 1 +#include + #ifdef __cplusplus extern "C" { #if 0 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/dreamcast.c Sat Aug 21 06:15:49 2004 +0000 @@ -0,0 +1,37 @@ +#include "dream.h" +#include "mem.h" +#include "aica.h" +#include "asic.h" +#include "ide.h" +#include "dreamcast.h" +/* Central switchboard for the system */ + +void dreamcast_init( void ) +{ + mem_init(); + sh4_init(); + asic_init(); + pvr2_init(); + aica_init(); + ide_reset(); + + mem_create_ram_region( 0x0C000000, 16 MB, MEM_REGION_MAIN ); + mem_create_ram_region( 0x05000000, 8 MB, MEM_REGION_VIDEO ); + mem_create_ram_region( 0x00800000, 2 MB, MEM_REGION_AUDIO ); + mem_create_ram_region( 0x00703000, 8 KB, MEM_REGION_AUDIO_SCRATCH ); /*???*/ + mem_load_rom( "dcboot.rom", 0x00000000, 0x00200000, 0x89f2b1a1 ); + mem_load_rom( "dcflash.rom",0x00200000, 0x00020000, 0x357c3568 ); +} + +void dreamcast_reset( void ) +{ + sh4_reset(); + mem_reset(); +// pvr2_reset(); + aica_reset(); +} + +void dreamcast_stop( void ) +{ + sh4_stop(); +} --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/dreamcast.h Sat Aug 21 06:15:49 2004 +0000 @@ -0,0 +1,9 @@ + +#ifndef dreamcast_H +#define dreamcast_H 1 + +void dreamcast_init(void); +void dreamcast_reset(void); +void dreamcast_stop(void); + +#endif /* !dream_machine_H */ --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/gdrom/ide.c Sat Aug 21 06:15:49 2004 +0000 @@ -0,0 +1,127 @@ +/* + * ide.c 31 Mar 2004 - IDE Interface implementation + * + * Copyright (c) 2004 Nathan Keynes. Distribution and modification permitted + * under the terms of the GNU General Public License version 2 or later. + */ +#include +#include "ide.h" + +#define MAX_WRITE_BUF 4096; + +struct ide_registers idereg; + +static char command_buffer[12]; + +/* "\0\0\0\0\xb4\x19\0\0\x08SE REV 6.42990316" */ +char gdrom_ident[] = { 0x00, 0x00, 0x00, 0x00, 0x00, 0xb4, 0x19, 0x00, + 0x00, 0x08, 0x53, 0x45, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x52, 0x65, 0x76, 0x20, 0x36, 0x2e, + 0x34, 0x32, 0x39, 0x39, 0x30, 0x33, 0x31, 0x36 }; + + +void set_write_buffer( char *buf, int len ) +{ + idereg.status |= IDE_ST_DATA; + idereg.data = buf; + idereg.datalen = len; + idereg.writeptr = (uint16_t *)buf; + idereg.readptr = NULL; +} + +void set_read_buffer( char *buf, int len ) +{ + idereg.status |= IDE_ST_DATA; + idereg.data = buf; + idereg.datalen = len; + idereg.readptr = (uint16_t *)buf; + idereg.writeptr = NULL; + idereg.lba1 = len&0xFF; + idereg.lba2 = len>>8; +} + +void ide_clear_interrupt( void ) +{ + /* TODO */ +} + +void ide_reset( void ) +{ + ide_clear_interrupt(); + idereg.error = 0x01; + idereg.count = 0x01; + idereg.lba0 = 0x21; + idereg.lba1 = 0x14; + idereg.lba2 = 0xeb; + idereg.feature = 0; /* Indeterminate really */ + idereg.status = 0x00; + idereg.device = 0x00; + idereg.disc = IDE_DISC_GDROM | IDE_DISC_READY; +} + +uint16_t ide_read_data_pio( void ) { + if( idereg.readptr == NULL ) + return 0xFFFF; + uint16_t rv = *idereg.readptr++; + idereg.datalen-=2; + if( idereg.datalen <=0 ) { + idereg.readptr = NULL; + idereg.status &= ~IDE_ST_DATA; + } + return rv; +} + +void ide_write_data_pio( uint16_t val ) { + if( idereg.writeptr == NULL ) + return; + *idereg.writeptr++ = val; + idereg.datalen-=2; + if( idereg.datalen <= 0 ) { + idereg.writeptr = NULL; + idereg.status &= ~IDE_ST_DATA; + ide_write_buffer( idereg.data ); + } +} + +void ide_write_control( uint8_t val ) { + /* TODO: In theory we can cause a soft-reset here, but the DC doesn't + * appear to support it. + */ +} + +void ide_write_command( uint8_t val ) { + idereg.command = val; + switch( val ) { + case IDE_CMD_RESET_DEVICE: + ide_reset(); + break; + case IDE_CMD_PACKET: + set_write_buffer(command_buffer,12); + break; + default: + WARN( "IDE: Unimplemented command: %02X", val ); + } + idereg.status |= IDE_ST_READY | IDE_ST_SERV; +} + +void ide_write_buffer( char *data ) { + uint16_t length; + switch( idereg.command ) { + case IDE_CMD_PACKET: + /* Okay we have the packet in the command buffer */ + WARN( "ATAPI: Received Packet command: %02X", data[0] ); + + switch( command_buffer[0] ) { + case PKT_CMD_IDENTIFY: + /* NB: Bios sets data[4] = 0x08, no idea what this is for; + * different values here appear to have no effect. + */ + length = *((uint16_t*)(data+2)); + if( length > sizeof(gdrom_ident) ) + length = sizeof(gdrom_ident); + set_read_buffer(gdrom_ident, length); + break; + } + break; + } +} --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/gdrom/ide.h Sat Aug 21 06:15:49 2004 +0000 @@ -0,0 +1,91 @@ +/* + * ide.h 31 Mar 2004 - IDE Interface definitions + * + * Copyright (c) 2004 Nathan Keynes. Distribution and modification permitted + * under the terms of the GNU General Public License version 2 or later. + * + * This file defines the interface and structures of the dreamcast's IDE port. + * Note that the register definitions are in asic.h, as the registers fall into + * the general ASIC ranges (and I don't want to use smaller pages at this + * stage). The registers here are exactly as per the ATA specifications, which + * makes things a little easier. + */ +#ifndef dream_ide_H +#define dream_ide_H 1 + +#include "dream.h" + +struct ide_registers { + uint8_t status; /* A05F709C + A05F7018 Read-only */ + uint8_t control; /* A05F7018 Write-only 01110 */ + uint8_t error; /* A05F7084 Read-only 10001 */ + uint8_t feature; /* A05F7084 Write-only 10001 */ + uint8_t count; /* A05F7088 Read/Write 10010 */ + uint8_t disc; /* A05F708C Read-only 10011 */ + uint8_t lba0; /* A05F708C Write-only 10011 (NB: Presumed, TBV */ + uint8_t lba1; /* A05F7090 Read/Write 10100 */ + uint8_t lba2; /* A05F7094 Read/Write 10101 */ + uint8_t device; /* A05F7098 Read/Write 10110 */ + uint8_t command; /* A05F709C Write-only 10111 */ + + /* We don't keep the data register per se, rather the currently pending + * data is kept here and read out a byte at a time (in PIO mode) or all at + * once (in DMA mode). The IDE routines are responsible for managing this + * memory. If dataptr == NULL, there is no data available. + */ + char *data; + uint16_t *readptr, *writeptr; + int datalen; +}; + +#define IDE_ST_BUSY 0x80 +#define IDE_ST_READY 0x40 +#define IDE_ST_SERV 0x10 +#define IDE_ST_DATA 0x08 +#define IDE_ST_ERROR 0x01 + +#define IDE_CTL_RESET 0x04 +#define IDE_CTL_IRQEN 0x02 /* IRQ enabled when == 0 */ + +#define IDE_CMD_RESET_DEVICE 0x08 +#define IDE_CMD_PACKET 0xA0 +#define IDE_CMD_IDENTIFY_PACKET_DEVICE 0xA1 +#define IDE_CMD_SERVICE 0xA2 +#define IDE_CMD_SET_FEATURE 0xEF + +/* The disc register indicates the current contents of the drive. When open + * contains 0x06. + */ +#define IDE_DISC_AUDIO 0x00 +#define IDE_DISC_NONE 0x06 +#define IDE_DISC_CDROM 0x20 +#define IDE_DISC_GDROM 0x80 +#define IDE_DISC_READY 0x01 /* ored with above */ +#define IDE_DISC_IDLE 0x02 /* ie spun-down */ + +#define PKT_CMD_RESET 0x00 /* Wild-ass guess */ +#define PKT_CMD_IDENTIFY 0x11 + +extern struct ide_registers idereg; + +/* Note: control can be written at any time - all other registers are writable + * only when ide_can_write_regs() is true + */ +#define ide_can_write_regs() ((idereg.status&0x88)==0) + +/* Called upon: + * a) Writing the command register + * b) Reading the status (but not altstatus) register + * (whether this actually has any effect an the ASIC event is TBD) + */ +void ide_clear_interrupt(void); + +void ide_reset(void); + +uint16_t ide_read_data_pio(void); +void ide_write_data_pio( uint16_t value ); +void ide_write_buffer( char * ); + +void ide_write_command( uint8_t command ); +void ide_write_control( uint8_t value ); +#endif --- a/src/gui/callbacks.c Sat Mar 13 00:03:32 2004 +0000 +++ b/src/gui/callbacks.c Sat Aug 21 06:15:49 2004 +0000 @@ -84,7 +84,7 @@ { sh4_reset(); mem_reset(); - update_registers(); + update_gui(); } @@ -103,7 +103,7 @@ gpointer user_data) { sh4_execute_instruction(); - update_registers(); + update_gui(); } @@ -120,7 +120,7 @@ gtk_main_iteration(); pvr2_next_frame(); } while( sh4_isrunning() ); - update_registers(); + update_gui(); } } void @@ -273,3 +273,35 @@ jump_to_disassembly( sh4r.pc, TRUE ); } + +void +on_button_add_watch_clicked (GtkButton *button, + gpointer user_data) +{ + +} + + +void +on_button_clear_all_clicked (GtkButton *button, + gpointer user_data) +{ + +} + + +void +on_button_close_clicked (GtkButton *button, + gpointer user_data) +{ + +} + + +void +on_view_memory_activate (GtkMenuItem *menuitem, + gpointer user_data) +{ + dump_window_new(); +} + --- a/src/gui/callbacks.h Sat Mar 13 00:03:32 2004 +0000 +++ b/src/gui/callbacks.h Sat Aug 21 06:15:49 2004 +0000 @@ -141,3 +141,37 @@ void on_jump_pc_btn_clicked (GtkButton *button, gpointer user_data); + +void +on_memory1_activate (GtkMenuItem *menuitem, + gpointer user_data); + +gboolean +on_memory_win_delete_event (GtkWidget *widget, + GdkEvent *event, + gpointer user_data); + +void +button_view_clicked (GtkButton *button, + gpointer user_data); + +void +on_button_add_watch_clicked (GtkButton *button, + gpointer user_data); + +void +on_button_clear_all_clicked (GtkButton *button, + gpointer user_data); + +void +on_button_close_clicked (GtkButton *button, + gpointer user_data); + +gboolean +on_dump_win_delete_event (GtkWidget *widget, + GdkEvent *event, + gpointer user_data); + +void +on_view_memory_activate (GtkMenuItem *menuitem, + gpointer user_data); --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/gui/debug_win.c Sat Aug 21 06:15:49 2004 +0000 @@ -0,0 +1,217 @@ + +#include +#include +#include +#include +#include "gui.h" +#include "mem.h" +#include "sh4dasm.h" +#include "sh4core.h" + +GdkColor *msg_colors[] = { &clrError, &clrError, &clrWarn, &clrNormal, + &clrDebug, &clrTrace }; + +#define REG_INT 0 +#define REG_FLT 1 +#define REG_SPECIAL 2 + +struct reg_map_struct { + char *name; + int type; + void *value; +} reg_map[] = { {"R0", REG_INT, &sh4r.r[0]}, {"R1", REG_INT, &sh4r.r[1]}, + {"R2", REG_INT, &sh4r.r[2]}, {"R3", REG_INT, &sh4r.r[3]}, + {"R4", REG_INT, &sh4r.r[4]}, {"R5", REG_INT, &sh4r.r[5]}, + {"R6", REG_INT, &sh4r.r[6]}, {"R7", REG_INT, &sh4r.r[7]}, + {"R8", REG_INT, &sh4r.r[8]}, {"R9", REG_INT, &sh4r.r[9]}, + {"R10",REG_INT, &sh4r.r[10]}, {"R11",REG_INT, &sh4r.r[11]}, + {"R12",REG_INT, &sh4r.r[12]}, {"R13",REG_INT, &sh4r.r[13]}, + {"R14",REG_INT, &sh4r.r[14]}, {"R15",REG_INT, &sh4r.r[15]}, + {"SR", REG_INT, &sh4r.sr}, {"GBR", REG_INT, &sh4r.gbr}, + {"SSR",REG_INT, &sh4r.ssr}, {"SPC", REG_INT, &sh4r.spc}, + {"SGR",REG_INT, &sh4r.sgr}, {"DBR", REG_INT, &sh4r.dbr}, + {"VBR",REG_INT, &sh4r.vbr}, + {"PC", REG_INT, &sh4r.pc}, {"PR", REG_INT, &sh4r.pr}, + {"MACL",REG_INT, &sh4r.mac},{"MACH",REG_INT, ((uint32_t *)&sh4r.mac)+1}, + {"FPUL", REG_INT, &sh4r.fpul}, {"FPSCR", REG_INT, &sh4r.fpscr}, + {NULL, 0, NULL} }; + +GtkCList *msgs, *regs, *disasm; +GtkEntry *page_field; +GtkProgressBar *icounter; +char icounter_text[16]; + +struct sh4_registers sh4r_s; +int disasm_from = -1, disasm_to = -1; +int disasm_pc = -1; + + +void init_debug_win(GtkWidget *win) +{ + int i; + char buf[20]; + char *arr[2]; + GnomeAppBar *appbar; + + regs = gtk_object_get_data(GTK_OBJECT(win), "reg_list"); + arr[1] = buf; + for( i=0; reg_map[i].name != NULL; i++ ) { + arr[0] = reg_map[i].name; + if( reg_map[i].type == REG_INT ) + sprintf( buf, "%08X", *((uint32_t *)reg_map[i].value) ); + else + sprintf( buf, "%f", *((float *)reg_map[i].value) ); + gtk_clist_append( regs, arr ); + } + gtk_widget_modify_font( GTK_WIDGET(regs), fixed_list_font ); + + msgs = gtk_object_get_data(GTK_OBJECT(win), "output_list"); + disasm = gtk_object_get_data(GTK_OBJECT(win), "disasm_list"); + gtk_clist_set_column_width( disasm, 1, 16 ); + page_field = gtk_object_get_data(GTK_OBJECT(win), "page_field"); + + appbar = gtk_object_get_data(GTK_OBJECT(win), "debug_appbar"); + icounter = gnome_appbar_get_progress( appbar ); + gtk_progress_bar_set_text(icounter, "1"); +} + +/* + * Check for changed registers and update the display + */ +void update_registers( void ) +{ + int i; + for( i=0; reg_map[i].name != NULL; i++ ) { + if( reg_map[i].type == REG_INT ) { + /* Yes this _is_ probably fairly evil */ + if( *((uint32_t *)reg_map[i].value) != + *((uint32_t *)((char *)&sh4r_s + ((char *)reg_map[i].value - (char *)&sh4r))) ) { + char buf[20]; + sprintf( buf, "%08X", *((uint32_t *)reg_map[i].value) ); + gtk_clist_set_text( regs, i, 1, buf ); + gtk_clist_set_foreground( regs, i, &clrChanged ); + } else { + gtk_clist_set_foreground( regs, i, &clrNormal ); + } + } else { + if( *((float *)reg_map[i].value) != + *((float *)((char *)&sh4r_s + ((char *)reg_map[i].value - (char *)&sh4r))) ) { + char buf[20]; + sprintf( buf, "%f", *((float *)reg_map[i].value) ); + gtk_clist_set_text( regs, i, 1, buf ); + gtk_clist_set_foreground( regs, i, &clrChanged ); + } else { + gtk_clist_set_foreground( regs, i, &clrNormal ); + } + } + } + if( sh4r.pc != sh4r_s.pc ) + set_disassembly_pc( sh4r.pc, FALSE ); + memcpy( &sh4r_s, &sh4r, sizeof(sh4r) ); +} + +void update_icount( void ) +{ + sprintf( icounter_text, "%d", sh4r.icount ); + gtk_progress_bar_set_text( icounter, icounter_text ); +} + +void set_disassembly_region( unsigned int page ) +{ + uint32_t i, posn; + uint16_t op; + char buf[80]; + char addr[10]; + char opcode[6] = ""; + char *arr[4] = { addr, " ", opcode, buf }; + unsigned int from = page & 0xFFFFF000; + unsigned int to = from + 4096; + + gtk_clist_clear(disasm); + + sprintf( addr, "%08X", from ); + gtk_entry_set_text( page_field, addr ); + + if( !mem_has_page( from ) ) { + arr[3] = "This page is currently unmapped"; + gtk_clist_append( disasm, arr ); + gtk_clist_set_foreground( disasm, 0, &clrError ); + } else { + for( i=from; i>8 ); + posn = gtk_clist_append( disasm, arr ); + if( buf[0] == '?' ) + gtk_clist_set_foreground( disasm, posn, &clrWarn ); + } + if( disasm_pc != -1 && disasm_pc >= from && disasm_pc < to ) + gtk_clist_set_foreground( disasm, (disasm_pc - from)>>1, + &clrPC ); + } + + if( page != from ) { /* not a page boundary */ + gtk_clist_moveto( disasm, (page-from)>>1, 0, 0.5, 0.0 ); + } + disasm_from = from; + disasm_to = to; +} + +void jump_to_disassembly( unsigned int addr, gboolean select ) +{ + int row; + + if( addr < disasm_from || addr >= disasm_to ) + set_disassembly_region(addr); + + row = (addr-disasm_from)>>1; + if(select) { + gtk_clist_select_row( disasm, row, 0 ); + } + if( gtk_clist_row_is_visible( disasm, row ) != GTK_VISIBILITY_FULL ){ + gtk_clist_moveto( disasm, row, 0, 0.5, 0.0 ); + } +} + +void set_disassembly_pc( unsigned int pc, gboolean select ) +{ + int row; + + jump_to_disassembly( pc, select ); + if( disasm_pc != -1 && disasm_pc >= disasm_from && disasm_pc < disasm_to ) + gtk_clist_set_foreground( disasm, (disasm_pc - disasm_from)>>1, + &clrNormal ); + row = (pc - disasm_from)>>1; + gtk_clist_set_foreground( disasm, row, &clrPC ); + disasm_pc = pc; +} + + +void emit( int level, int source, char *msg, ... ) +{ + char buf[20], addr[10] = "", *p; + char *arr[3] = {buf, addr}; + int posn; + time_t tm = time(NULL); + va_list ap; + + va_start(ap, msg); + p = g_strdup_vprintf( msg, ap ); + strftime( buf, sizeof(buf), "%H:%M:%S", localtime(&tm) ); + if( source != -1 ) + sprintf( addr, "%08X", sh4r.pc ); + arr[2] = p; + posn = gtk_clist_append(msgs, arr); + free(p); + va_end(ap); + + gtk_clist_set_foreground( msgs, posn, msg_colors[level] ); + gtk_clist_moveto( msgs, posn, 0, 1.0, 0.0 ); + + /* emit _really_ slows down the emu, to the point where the gui can be + * completely unresponsive if I don't include this: + */ + while( gtk_events_pending() ) + gtk_main_iteration(); +} --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/gui/dump_win.c Sat Aug 21 06:15:49 2004 +0000 @@ -0,0 +1,194 @@ +/** + * Implements the memory dump window. + */ +#include +#include +#include +#include "gui.h" +#include "interface.h" +#include "mem.h" + +#define MAX_DUMP_SIZE 4096 + +#define DUMP_DATA_TAG 0xD4B9DA7A + +typedef struct dump_data { + uint32_t _tag; + uint32_t start; + uint32_t end; + int flags; + char *data; + + GtkEntry *fromInput, *toInput; + GtkTextView *textArea; + GtkTextTag *changedTag; + GtkTextBuffer *textBuffer; + struct dump_data *next; +} *dump_data_t; + +static dump_data_t dump_list_head = NULL; + +gboolean on_dump_win_delete_event( GtkWidget *widget, GdkEvent *event, + gpointer user_data ); +void on_dump_win_button_view_clicked( GtkWidget *widget, gpointer user_data ); +void dump_win_set_text( dump_data_t data, char *old_data, char *new_data ); + + +void dump_window_new( void ) { + GtkWidget *win = create_dump_win(); + GtkWidget *dump_view_button = (GtkWidget *)g_object_get_data(G_OBJECT(win), "dump_view_button"); + dump_data_t data = malloc( sizeof(struct dump_data) ); + data->_tag = DUMP_DATA_TAG; + data->fromInput = (GtkEntry *)g_object_get_data(G_OBJECT(win), "dump_from"); + data->toInput = (GtkEntry *)g_object_get_data(G_OBJECT(win), "dump_to"); + data->textArea = (GtkTextView *)g_object_get_data(G_OBJECT(win), "dump_text"); + data->next = dump_list_head; + dump_list_head = data; + data->data = NULL; + data->start = 0; + data->end = 0; + gtk_entry_set_text( data->fromInput, "" ); + gtk_entry_set_text( data->toInput, "" ); + data->textBuffer = gtk_text_buffer_new(NULL); + data->changedTag = gtk_text_buffer_create_tag(data->textBuffer, "changed", + "foreground", "blue", + NULL); + gtk_text_view_set_buffer(data->textArea, data->textBuffer); + gtk_text_view_set_editable(data->textArea, FALSE); + gtk_widget_modify_font(GTK_WIDGET(data->textArea),fixed_list_font); + + g_signal_connect ((gpointer) win, "delete_event", + G_CALLBACK (on_dump_win_delete_event), + data); + g_signal_connect ((gpointer) dump_view_button, "clicked", + G_CALLBACK (on_dump_win_button_view_clicked), + data); + gtk_widget_show( GTK_WIDGET(win) ); +} + + + +gboolean on_dump_win_delete_event( GtkWidget *widget, GdkEvent *event, + gpointer user_data ) +{ + dump_data_t data = (dump_data_t)user_data; + if( data->data != NULL ) + free( data->data ); + dump_data_t node = dump_list_head; + if( node == data ) + dump_list_head = data->next; + else { + while( node->next != data ) { + node = node->next; + assert( node != NULL ); + } + node->next = data->next; + } + free( data ); + return FALSE; +} + +void on_dump_win_button_view_clicked( GtkWidget *widget, gpointer user_data ) +{ + dump_data_t data = (dump_data_t)user_data; + uint32_t startVal, endVal; + + assert( data != NULL ); + assert( data->_tag == DUMP_DATA_TAG ); + + startVal = gtk_entry_get_hex_value(data->fromInput, data->start); + endVal = gtk_entry_get_hex_value(data->toInput, data->end); + if( startVal != data->start || endVal != data->end ) { + if( startVal > endVal ) { + int tmp = endVal; + endVal = startVal; + startVal = tmp; + } + if( endVal > startVal + MAX_DUMP_SIZE ) + endVal = startVal + MAX_DUMP_SIZE; + + gtk_entry_set_hex_value(data->fromInput,startVal); + gtk_entry_set_hex_value(data->toInput,endVal); + data->start = startVal; + data->end = endVal; + + if( data->data != NULL ) { + free( data->data ); + data->data = NULL; + } + if( startVal != endVal ) { + data->data = malloc( endVal - startVal ); + mem_copy_from_sh4( data->data, startVal, endVal-startVal ); + dump_win_set_text( data, data->data, data->data ); + } + } +} + +void dump_win_update( dump_data_t data ) +{ + if( data->data == NULL ) + return; + char tmp[data->end-data->start]; + int length = data->end-data->start; + memcpy( tmp, data->data, length ); + mem_copy_from_sh4( data->data, data->start, length ); + dump_win_set_text( data, tmp, data->data ); +} + +void dump_win_update_all( ) +{ + dump_data_t node = dump_list_head; + while( node != NULL ) { + dump_win_update(node); + node = node->next; + } +} + +void dump_win_set_text( dump_data_t data, char *old_data, char *new_data ) +{ + GtkTextBuffer *buf = data->textBuffer; + GtkTextTag *changedTag = data->changedTag; + GtkTextIter iter, endIter; + int i, j, offset; + /* Clear out the buffer */ + gtk_text_buffer_get_start_iter(buf,&iter); + gtk_text_buffer_get_end_iter(buf,&endIter); + gtk_text_buffer_delete(buf,&iter,&endIter); + gtk_text_buffer_get_start_iter(buf,&iter); + + for( offset = 0, i=data->start; iend; i+=16, offset+=16 ) { + char text[80]; + sprintf(text, "%08X:", i ); + gtk_text_buffer_insert( buf, &iter, text, 9 ); + for( j=0; j<16; j++ ) { + if( j%4 == 0 ) + gtk_text_buffer_insert( buf, &iter, " ", 1 ); + if( i+j < data->end ) { + int oldVal = ((int)old_data[offset+j])&0xFF; + int newVal = ((int)new_data[offset+j])&0xFF; + sprintf(text, "%02X ", newVal); + if( oldVal == newVal ) + gtk_text_buffer_insert( buf, &iter, text, 3 ); + else + gtk_text_buffer_insert_with_tags( buf, &iter, text, 3, + changedTag, NULL ); + } else { + gtk_text_buffer_insert( buf, &iter, " ", 3 ); + } + } + gtk_text_buffer_insert( buf, &iter, " ", 2 ); + for( j=0; j<16 && i+j < data->end; j++ ) { + int oldVal = ((int)old_data[offset+j])&0xFF; + int newVal = ((int)new_data[offset+j])&0xFF; + if( isprint(newVal) ) + sprintf( text, "%c", newVal ); + else strcpy( text, "." ); + if( oldVal == newVal ) + gtk_text_buffer_insert( buf, &iter, text, 1 ); + else + gtk_text_buffer_insert_with_tags( buf, &iter, text, 1, + changedTag, NULL ); + } + gtk_text_buffer_insert( buf, &iter, "\n", 1 ); + } +} --- a/src/gui/gui.c Sat Mar 13 00:03:32 2004 +0000 +++ b/src/gui/gui.c Sat Aug 21 06:15:49 2004 +0000 @@ -9,164 +9,48 @@ #define REGISTER_FONT "-*-fixed-medium-r-normal--12-*-*-*-*-*-iso8859-1" -#define REG_INT 0 -#define REG_FLT 1 -#define REG_SPECIAL 2 - -struct reg_map_struct { - char *name; - int type; - void *value; -} reg_map[] = { {"R0", REG_INT, &sh4r.r[0]}, {"R1", REG_INT, &sh4r.r[1]}, - {"R2", REG_INT, &sh4r.r[2]}, {"R3", REG_INT, &sh4r.r[3]}, - {"R4", REG_INT, &sh4r.r[4]}, {"R5", REG_INT, &sh4r.r[5]}, - {"R6", REG_INT, &sh4r.r[6]}, {"R7", REG_INT, &sh4r.r[7]}, - {"R8", REG_INT, &sh4r.r[8]}, {"R9", REG_INT, &sh4r.r[9]}, - {"R10",REG_INT, &sh4r.r[10]}, {"R11",REG_INT, &sh4r.r[11]}, - {"R12",REG_INT, &sh4r.r[12]}, {"R13",REG_INT, &sh4r.r[13]}, - {"R14",REG_INT, &sh4r.r[14]}, {"R15",REG_INT, &sh4r.r[15]}, - {"SR", REG_INT, &sh4r.sr}, {"GBR", REG_INT, &sh4r.gbr}, - {"SSR",REG_INT, &sh4r.ssr}, {"SPC", REG_INT, &sh4r.spc}, - {"SGR",REG_INT, &sh4r.sgr}, {"DBR", REG_INT, &sh4r.dbr}, - {"VBR",REG_INT, &sh4r.vbr}, - {"PC", REG_INT, &sh4r.pc}, {"PR", REG_INT, &sh4r.pr}, - {"MACL",REG_INT, &sh4r.mac},{"MACH",REG_INT, ((uint32_t *)&sh4r.mac)+1}, - {"FPUL", REG_INT, &sh4r.fpul}, {"FPSCR", REG_INT, &sh4r.fpscr}, - {NULL, 0, NULL} }; - -GtkCList *msgs, *regs, *disasm; GdkColor clrNormal, clrChanged, clrError, clrWarn, clrPC, clrDebug, clrTrace; -GtkEntry *page_field; -GnomeAppBar *appbar; -GtkProgressBar *icounter; -char icounter_text[16]; -GtkStyle *fixed_list_style; PangoFontDescription *fixed_list_font; -GdkColor *msg_colors[] = { &clrError, &clrError, &clrWarn, &clrNormal, - &clrDebug, &clrTrace }; - -struct sh4_registers sh4r_s; -int disasm_from = -1, disasm_to = -1; -int disasm_pc = -1; void open_file_callback(GtkWidget *btn, gpointer user_data); void open_file_canceled(GtkWidget *btn, gpointer user_data); void open_file( char *filename ); -/* - * Check for changed registers and update the display - */ -void update_registers( void ) -{ - int i; - for( i=0; reg_map[i].name != NULL; i++ ) { - if( reg_map[i].type == REG_INT ) { - /* Yes this _is_ probably fairly evil */ - if( *((uint32_t *)reg_map[i].value) != - *((uint32_t *)((char *)&sh4r_s + ((char *)reg_map[i].value - (char *)&sh4r))) ) { - char buf[20]; - sprintf( buf, "%08X", *((uint32_t *)reg_map[i].value) ); - gtk_clist_set_text( regs, i, 1, buf ); - gtk_clist_set_foreground( regs, i, &clrChanged ); - } else { - gtk_clist_set_foreground( regs, i, &clrNormal ); - } - } else { - if( *((float *)reg_map[i].value) != - *((float *)((char *)&sh4r_s + ((char *)reg_map[i].value - (char *)&sh4r))) ) { - char buf[20]; - sprintf( buf, "%f", *((float *)reg_map[i].value) ); - gtk_clist_set_text( regs, i, 1, buf ); - gtk_clist_set_foreground( regs, i, &clrChanged ); - } else { - gtk_clist_set_foreground( regs, i, &clrNormal ); - } - } - } - if( sh4r.pc != sh4r_s.pc ) - set_disassembly_pc( sh4r.pc, FALSE ); - memcpy( &sh4r_s, &sh4r, sizeof(sh4r) ); +void init_gui() { + GdkColormap *map; + + clrNormal.red = clrNormal.green = clrNormal.blue = 0; + clrChanged.red = clrChanged.green = 64*256; + clrChanged.blue = 154*256; + clrError.red = 65535; + clrError.green = clrError.blue = 64*256; + clrPC.red = 32*256; + clrPC.green = 170*256; + clrPC.blue = 52*256; + clrWarn = clrChanged; + clrTrace.red = 156*256; + clrTrace.green = 78*256; + clrTrace.blue = 201*256; + clrDebug = clrPC; + map = gdk_colormap_new(gdk_visual_get_best(), TRUE); + gdk_colormap_alloc_color(map, &clrNormal, TRUE, TRUE); + gdk_colormap_alloc_color(map, &clrChanged, TRUE, TRUE); + gdk_colormap_alloc_color(map, &clrError, TRUE, TRUE); + gdk_colormap_alloc_color(map, &clrWarn, TRUE, TRUE); + gdk_colormap_alloc_color(map, &clrPC, TRUE, TRUE); + gdk_colormap_alloc_color(map, &clrDebug, TRUE, TRUE); + gdk_colormap_alloc_color(map, &clrTrace, TRUE, TRUE); + fixed_list_font = pango_font_description_from_string("Courier 10"); +} + +void update_gui(void) { + update_registers(); update_icount(); update_mmr_win(); + dump_win_update_all(); } -void update_icount( void ) -{ - sprintf( icounter_text, "%d", sh4r.icount ); - gtk_progress_bar_set_text( icounter, icounter_text ); -} - -void set_disassembly_region( unsigned int page ) -{ - uint32_t i, posn; - uint16_t op; - char buf[80]; - char addr[10]; - char opcode[6] = ""; - char *arr[4] = { addr, " ", opcode, buf }; - unsigned int from = page & 0xFFFFF000; - unsigned int to = from + 4096; - - gtk_clist_clear(disasm); - - sprintf( addr, "%08X", from ); - gtk_entry_set_text( page_field, addr ); - - if( !mem_has_page( from ) ) { - arr[3] = "This page is currently unmapped"; - gtk_clist_append( disasm, arr ); - gtk_clist_set_foreground( disasm, 0, &clrError ); - } else { - for( i=from; i>8 ); - posn = gtk_clist_append( disasm, arr ); - if( buf[0] == '?' ) - gtk_clist_set_foreground( disasm, posn, &clrWarn ); - } - if( disasm_pc != -1 && disasm_pc >= from && disasm_pc < to ) - gtk_clist_set_foreground( disasm, (disasm_pc - from)>>1, - &clrPC ); - } - - if( page != from ) { /* not a page boundary */ - gtk_clist_moveto( disasm, (page-from)>>1, 0, 0.5, 0.0 ); - } - disasm_from = from; - disasm_to = to; -} - -void jump_to_disassembly( unsigned int addr, gboolean select ) -{ - int row; - - if( addr < disasm_from || addr >= disasm_to ) - set_disassembly_region(addr); - - row = (addr-disasm_from)>>1; - if(select) { - gtk_clist_select_row( disasm, row, 0 ); - } - if( gtk_clist_row_is_visible( disasm, row ) != GTK_VISIBILITY_FULL ){ - gtk_clist_moveto( disasm, row, 0, 0.5, 0.0 ); - } -} - -void set_disassembly_pc( unsigned int pc, gboolean select ) -{ - int row; - - jump_to_disassembly( pc, select ); - if( disasm_pc != -1 && disasm_pc >= disasm_from && disasm_pc < disasm_to ) - gtk_clist_set_foreground( disasm, (disasm_pc - disasm_from)>>1, - &clrNormal ); - row = (pc - disasm_from)>>1; - gtk_clist_set_foreground( disasm, row, &clrPC ); - disasm_pc = pc; -} void open_file_callback(GtkWidget *btn, gpointer user_data) { GtkFileSelection *file = GTK_FILE_SELECTION(user_data); @@ -193,90 +77,23 @@ gtk_widget_show( file ); } -void emit( int level, int source, char *msg, ... ) +uint32_t gtk_entry_get_hex_value( GtkEntry *entry, uint32_t defaultValue ) { - char buf[20], addr[10] = "", *p; - char *arr[3] = {buf, addr}; - int posn; - time_t tm = time(NULL); - va_list ap; - - va_start(ap, msg); - p = g_strdup_vprintf( msg, ap ); - strftime( buf, sizeof(buf), "%H:%M:%S", localtime(&tm) ); - if( source != -1 ) - sprintf( addr, "%08X", sh4r.pc ); - arr[2] = p; - posn = gtk_clist_append(msgs, arr); - free(p); - va_end(ap); - - gtk_clist_set_foreground( msgs, posn, msg_colors[level] ); - gtk_clist_moveto( msgs, posn, 0, 1.0, 0.0 ); - - /* emit _really_ slows down the emu, to the point where the gui can be - * completely unresponsive if I don't include this: - */ - while( gtk_events_pending() ) - gtk_main_iteration(); + gchar *text = gtk_entry_get_text(entry); + if( text == NULL ) + return defaultValue; + gchar *endptr; + uint32_t value = strtoul( text, &endptr, 16 ); + if( text == endptr ) { /* invalid input */ + value = defaultValue; + gtk_entry_set_hex_value( entry, value ); + } + return value; } -void init_debug_win(GtkWidget *win) +void gtk_entry_set_hex_value( GtkEntry *entry, uint32_t value ) { - GdkColormap *map; - GdkFont *regfont; - GtkAdjustment *adj; - int i; - char buf[20]; - char *arr[2]; - - clrNormal.red = clrNormal.green = clrNormal.blue = 0; - clrChanged.red = clrChanged.green = 64*256; - clrChanged.blue = 154*256; - clrError.red = 65535; - clrError.green = clrError.blue = 64*256; - clrPC.red = 32*256; - clrPC.green = 170*256; - clrPC.blue = 52*256; - clrWarn = clrChanged; - clrTrace.red = 156*256; - clrTrace.green = 78*256; - clrTrace.blue = 201*256; - clrDebug = clrPC; - - map = gdk_colormap_new(gdk_visual_get_best(), TRUE); - gdk_colormap_alloc_color(map, &clrNormal, TRUE, TRUE); - gdk_colormap_alloc_color(map, &clrChanged, TRUE, TRUE); - gdk_colormap_alloc_color(map, &clrError, TRUE, TRUE); - gdk_colormap_alloc_color(map, &clrWarn, TRUE, TRUE); - gdk_colormap_alloc_color(map, &clrPC, TRUE, TRUE); - gdk_colormap_alloc_color(map, &clrDebug, TRUE, TRUE); - gdk_colormap_alloc_color(map, &clrTrace, TRUE, TRUE); - - fixed_list_font = pango_font_description_from_string("Courier 10"); - regs = gtk_object_get_data(GTK_OBJECT(win), "reg_list"); - arr[1] = buf; - for( i=0; reg_map[i].name != NULL; i++ ) { - arr[0] = reg_map[i].name; - if( reg_map[i].type == REG_INT ) - sprintf( buf, "%08X", *((uint32_t *)reg_map[i].value) ); - else - sprintf( buf, "%f", *((float *)reg_map[i].value) ); - gtk_clist_append( regs, arr ); - } - - fixed_list_style = gtk_style_copy( gtk_rc_get_style( GTK_WIDGET(regs) ) ); - if( fixed_list_style != NULL ) { - fixed_list_style->font_desc = fixed_list_font; - gtk_widget_set_style( GTK_WIDGET(regs), fixed_list_style ); - } - - msgs = gtk_object_get_data(GTK_OBJECT(win), "output_list"); - disasm = gtk_object_get_data(GTK_OBJECT(win), "disasm_list"); - gtk_clist_set_column_width( disasm, 1, 16 ); - page_field = gtk_object_get_data(GTK_OBJECT(win), "page_field"); - - appbar = gtk_object_get_data(GTK_OBJECT(win), "debug_appbar"); - icounter = gnome_appbar_get_progress( appbar ); - gtk_progress_bar_set_text(icounter, "1"); + char buf[10]; + sprintf( buf, "%08X", value ); + gtk_entry_set_text( entry, buf ); } --- a/src/gui/gui.h Sat Mar 13 00:03:32 2004 +0000 +++ b/src/gui/gui.h Sat Aug 21 06:15:49 2004 +0000 @@ -14,21 +14,28 @@ #endif #endif +void init_gui(void); +void update_gui(void); + void init_debug_win(GtkWidget *); void open_file_dialog( void ); void update_mmr_win( void ); void init_mmr_win( void ); void update_registers( void ); void update_icount( void ); +void dump_win_update_all( void ); void set_disassembly_region( unsigned int page ); void set_disassembly_pc( unsigned int pc, gboolean select ); void jump_to_disassembly( unsigned int addr, gboolean select ); -extern GtkStyle *fixed_list_style; -extern GdkColor clrNormal, clrChanged, clrError, clrWarn, clrPC; +extern PangoFontDescription *fixed_list_font; +extern GdkColor clrNormal, clrChanged, clrError, clrWarn, + clrPC, clrDebug, clrTrace; void mmr_open_win( void ); void mmr_close_win( void ); +uint32_t gtk_entry_get_hex_value( GtkEntry *entry, uint32_t defaultValue ); +void gtk_entry_set_hex_value( GtkEntry *entry, uint32_t value ); #ifdef __cplusplus } --- a/src/gui/interface.c Sat Mar 13 00:03:32 2004 +0000 +++ b/src/gui/interface.c Sat Aug 21 06:15:49 2004 +0000 @@ -28,49 +28,26 @@ static GnomeUIInfo file1_menu_uiinfo[] = { - { - GNOME_APP_UI_ITEM, N_("gtk-new"), - NULL, - (gpointer) on_new_file1_activate, NULL, NULL, - GNOME_APP_PIXMAP_NONE, NULL, - 0, (GdkModifierType) 0, NULL - }, - { - GNOME_APP_UI_ITEM, N_("gtk-open"), - NULL, - (gpointer) on_open1_activate, NULL, NULL, - GNOME_APP_PIXMAP_NONE, NULL, - 0, (GdkModifierType) 0, NULL - }, - { - GNOME_APP_UI_ITEM, N_("gtk-save"), - NULL, - (gpointer) on_save1_activate, NULL, NULL, - GNOME_APP_PIXMAP_NONE, NULL, - 0, (GdkModifierType) 0, NULL - }, - { - GNOME_APP_UI_ITEM, N_("gtk-save-as"), - NULL, - (gpointer) on_save_as1_activate, NULL, NULL, - GNOME_APP_PIXMAP_NONE, NULL, - 0, (GdkModifierType) 0, NULL - }, + GNOMEUIINFO_MENU_NEW_ITEM (N_("_New"), NULL, on_new_file1_activate, NULL), + GNOMEUIINFO_MENU_OPEN_ITEM (on_open1_activate, NULL), + GNOMEUIINFO_MENU_SAVE_ITEM (on_save1_activate, NULL), + GNOMEUIINFO_MENU_SAVE_AS_ITEM (on_save_as1_activate, NULL), GNOMEUIINFO_SEPARATOR, - { - GNOME_APP_UI_ITEM, N_("gtk-quit"), - NULL, - (gpointer) on_exit1_activate, NULL, NULL, - GNOME_APP_PIXMAP_NONE, NULL, - 0, (GdkModifierType) 0, NULL - }, + GNOMEUIINFO_MENU_EXIT_ITEM (on_exit1_activate, NULL), GNOMEUIINFO_END }; static GnomeUIInfo view1_menu_uiinfo[] = { { - GNOME_APP_UI_ITEM, N_("Mem mapped Regs"), + GNOME_APP_UI_ITEM, N_("Memory..."), + NULL, + (gpointer) on_view_memory_activate, NULL, NULL, + GNOME_APP_PIXMAP_NONE, NULL, + 0, (GdkModifierType) 0, NULL + }, + { + GNOME_APP_UI_ITEM, N_("Mem mapped Regs..."), NULL, (gpointer) on_mem_mapped_regs1_activate, NULL, NULL, GNOME_APP_PIXMAP_NONE, NULL, @@ -81,25 +58,13 @@ static GnomeUIInfo settings1_menu_uiinfo[] = { - { - GNOME_APP_UI_ITEM, N_("gtk-preferences"), - NULL, - (gpointer) on_preferences1_activate, NULL, NULL, - GNOME_APP_PIXMAP_NONE, NULL, - 0, (GdkModifierType) 0, NULL - }, + GNOMEUIINFO_MENU_PREFERENCES_ITEM (on_preferences1_activate, NULL), GNOMEUIINFO_END }; static GnomeUIInfo help1_menu_uiinfo[] = { - { - GNOME_APP_UI_ITEM, N_("gnome-stock-about"), - NULL, - (gpointer) on_about1_activate, NULL, NULL, - GNOME_APP_PIXMAP_NONE, NULL, - 0, (GdkModifierType) 0, NULL - }, + GNOMEUIINFO_MENU_ABOUT_ITEM (on_about1_activate, NULL), GNOMEUIINFO_END }; @@ -466,7 +431,8 @@ GLADE_HOOKUP_OBJECT (debug_win, file1_menu_uiinfo[4].widget, "separator1"); GLADE_HOOKUP_OBJECT (debug_win, file1_menu_uiinfo[5].widget, "exit1"); GLADE_HOOKUP_OBJECT (debug_win, menubar1_uiinfo[1].widget, "view1"); - GLADE_HOOKUP_OBJECT (debug_win, view1_menu_uiinfo[0].widget, "mem_mapped_regs1"); + GLADE_HOOKUP_OBJECT (debug_win, view1_menu_uiinfo[0].widget, "view_memory"); + GLADE_HOOKUP_OBJECT (debug_win, view1_menu_uiinfo[1].widget, "mem_mapped_regs1"); GLADE_HOOKUP_OBJECT (debug_win, menubar1_uiinfo[2].widget, "settings1"); GLADE_HOOKUP_OBJECT (debug_win, settings1_menu_uiinfo[0].widget, "preferences1"); GLADE_HOOKUP_OBJECT (debug_win, menubar1_uiinfo[3].widget, "help1"); @@ -603,3 +569,200 @@ return about_win; } +GtkWidget* +create_dump_win (void) +{ + GtkWidget *dump_win; + GtkWidget *vbox3; + GtkWidget *hbox2; + GtkWidget *label34; + GtkWidget *dump_from; + GtkWidget *label35; + GtkWidget *dump_to; + GtkWidget *dump_view_button; + GtkWidget *label36; + GtkWidget *scrolledwindow9; + GtkWidget *dump_text; + + dump_win = gtk_window_new (GTK_WINDOW_TOPLEVEL); + gtk_window_set_title (GTK_WINDOW (dump_win), _("Memory dump")); + + vbox3 = gtk_vbox_new (FALSE, 0); + gtk_widget_show (vbox3); + gtk_container_add (GTK_CONTAINER (dump_win), vbox3); + + hbox2 = gtk_hbox_new (FALSE, 0); + gtk_widget_show (hbox2); + gtk_box_pack_start (GTK_BOX (vbox3), hbox2, FALSE, TRUE, 3); + + label34 = gtk_label_new (_(" From ")); + gtk_widget_show (label34); + gtk_box_pack_start (GTK_BOX (hbox2), label34, FALSE, FALSE, 0); + + dump_from = gtk_entry_new (); + gtk_widget_show (dump_from); + gtk_box_pack_start (GTK_BOX (hbox2), dump_from, FALSE, TRUE, 0); + + label35 = gtk_label_new (_(" To ")); + gtk_widget_show (label35); + gtk_box_pack_start (GTK_BOX (hbox2), label35, FALSE, FALSE, 0); + + dump_to = gtk_entry_new (); + gtk_widget_show (dump_to); + gtk_box_pack_start (GTK_BOX (hbox2), dump_to, FALSE, TRUE, 0); + + dump_view_button = gtk_button_new_with_mnemonic (_("View")); + gtk_widget_show (dump_view_button); + gtk_box_pack_start (GTK_BOX (hbox2), dump_view_button, FALSE, FALSE, 0); + + label36 = gtk_label_new (_(" ")); + gtk_widget_show (label36); + gtk_box_pack_start (GTK_BOX (hbox2), label36, TRUE, TRUE, 0); + + scrolledwindow9 = gtk_scrolled_window_new (NULL, NULL); + gtk_widget_show (scrolledwindow9); + gtk_box_pack_start (GTK_BOX (vbox3), scrolledwindow9, TRUE, TRUE, 0); + gtk_scrolled_window_set_shadow_type (GTK_SCROLLED_WINDOW (scrolledwindow9), GTK_SHADOW_IN); + + dump_text = gtk_text_view_new (); + gtk_widget_show (dump_text); + gtk_container_add (GTK_CONTAINER (scrolledwindow9), dump_text); + + /* Store pointers to all widgets, for use by lookup_widget(). */ + GLADE_HOOKUP_OBJECT_NO_REF (dump_win, dump_win, "dump_win"); + GLADE_HOOKUP_OBJECT (dump_win, vbox3, "vbox3"); + GLADE_HOOKUP_OBJECT (dump_win, hbox2, "hbox2"); + GLADE_HOOKUP_OBJECT (dump_win, label34, "label34"); + GLADE_HOOKUP_OBJECT (dump_win, dump_from, "dump_from"); + GLADE_HOOKUP_OBJECT (dump_win, label35, "label35"); + GLADE_HOOKUP_OBJECT (dump_win, dump_to, "dump_to"); + GLADE_HOOKUP_OBJECT (dump_win, dump_view_button, "dump_view_button"); + GLADE_HOOKUP_OBJECT (dump_win, label36, "label36"); + GLADE_HOOKUP_OBJECT (dump_win, scrolledwindow9, "scrolledwindow9"); + GLADE_HOOKUP_OBJECT (dump_win, dump_text, "dump_text"); + + return dump_win; +} + +GtkWidget* +create_watch_win (void) +{ + GtkWidget *watch_win; + GtkWidget *vbox4; + GtkWidget *hbox4; + GtkWidget *label37; + GtkWidget *watch_start_addr; + GtkWidget *label38; + GtkWidget *watch_end_addr; + GtkWidget *label39; + GtkWidget *combo1; + GtkWidget *watch_type; + GtkWidget *button_add_watch; + GtkWidget *scrolledwindow10; + GtkWidget *treeview1; + GtkWidget *hbox5; + GtkWidget *label40; + GtkWidget *button_clear_all; + GtkWidget *button_close; + + watch_win = gtk_window_new (GTK_WINDOW_TOPLEVEL); + gtk_window_set_title (GTK_WINDOW (watch_win), _("Watchpoints")); + + vbox4 = gtk_vbox_new (FALSE, 0); + gtk_widget_show (vbox4); + gtk_container_add (GTK_CONTAINER (watch_win), vbox4); + + hbox4 = gtk_hbox_new (FALSE, 0); + gtk_widget_show (hbox4); + gtk_box_pack_start (GTK_BOX (vbox4), hbox4, FALSE, TRUE, 3); + + label37 = gtk_label_new (_("Start addr ")); + gtk_widget_show (label37); + gtk_box_pack_start (GTK_BOX (hbox4), label37, FALSE, FALSE, 3); + + watch_start_addr = gtk_entry_new (); + gtk_widget_show (watch_start_addr); + gtk_box_pack_start (GTK_BOX (hbox4), watch_start_addr, FALSE, TRUE, 0); + + label38 = gtk_label_new (_("End addr")); + gtk_widget_show (label38); + gtk_box_pack_start (GTK_BOX (hbox4), label38, FALSE, FALSE, 3); + + watch_end_addr = gtk_entry_new (); + gtk_widget_show (watch_end_addr); + gtk_box_pack_start (GTK_BOX (hbox4), watch_end_addr, FALSE, TRUE, 0); + + label39 = gtk_label_new (_("Type")); + gtk_widget_show (label39); + gtk_box_pack_start (GTK_BOX (hbox4), label39, FALSE, FALSE, 3); + + combo1 = gtk_combo_new (); + g_object_set_data (G_OBJECT (GTK_COMBO (combo1)->popwin), + "GladeParentKey", combo1); + gtk_widget_show (combo1); + gtk_box_pack_start (GTK_BOX (hbox4), combo1, TRUE, TRUE, 0); + + watch_type = GTK_COMBO (combo1)->entry; + gtk_widget_show (watch_type); + + button_add_watch = gtk_button_new_with_mnemonic (_("Add Watch")); + gtk_widget_show (button_add_watch); + gtk_box_pack_start (GTK_BOX (hbox4), button_add_watch, FALSE, FALSE, 3); + + scrolledwindow10 = gtk_scrolled_window_new (NULL, NULL); + gtk_widget_show (scrolledwindow10); + gtk_box_pack_start (GTK_BOX (vbox4), scrolledwindow10, TRUE, TRUE, 0); + + treeview1 = gtk_tree_view_new (); + gtk_widget_show (treeview1); + gtk_container_add (GTK_CONTAINER (scrolledwindow10), treeview1); + gtk_tree_view_set_enable_search (GTK_TREE_VIEW (treeview1), FALSE); + + hbox5 = gtk_hbox_new (FALSE, 0); + gtk_widget_show (hbox5); + gtk_box_pack_start (GTK_BOX (vbox4), hbox5, FALSE, TRUE, 3); + + label40 = gtk_label_new (""); + gtk_widget_show (label40); + gtk_box_pack_start (GTK_BOX (hbox5), label40, TRUE, TRUE, 0); + + button_clear_all = gtk_button_new_with_mnemonic (_("Clear all")); + gtk_widget_show (button_clear_all); + gtk_box_pack_start (GTK_BOX (hbox5), button_clear_all, FALSE, FALSE, 3); + + button_close = gtk_button_new_with_mnemonic (_("Close")); + gtk_widget_show (button_close); + gtk_box_pack_start (GTK_BOX (hbox5), button_close, FALSE, FALSE, 5); + + g_signal_connect ((gpointer) button_add_watch, "clicked", + G_CALLBACK (on_button_add_watch_clicked), + NULL); + g_signal_connect ((gpointer) button_clear_all, "clicked", + G_CALLBACK (on_button_clear_all_clicked), + NULL); + g_signal_connect ((gpointer) button_close, "clicked", + G_CALLBACK (on_button_close_clicked), + NULL); + + /* Store pointers to all widgets, for use by lookup_widget(). */ + GLADE_HOOKUP_OBJECT_NO_REF (watch_win, watch_win, "watch_win"); + GLADE_HOOKUP_OBJECT (watch_win, vbox4, "vbox4"); + GLADE_HOOKUP_OBJECT (watch_win, hbox4, "hbox4"); + GLADE_HOOKUP_OBJECT (watch_win, label37, "label37"); + GLADE_HOOKUP_OBJECT (watch_win, watch_start_addr, "watch_start_addr"); + GLADE_HOOKUP_OBJECT (watch_win, label38, "label38"); + GLADE_HOOKUP_OBJECT (watch_win, watch_end_addr, "watch_end_addr"); + GLADE_HOOKUP_OBJECT (watch_win, label39, "label39"); + GLADE_HOOKUP_OBJECT (watch_win, combo1, "combo1"); + GLADE_HOOKUP_OBJECT (watch_win, watch_type, "watch_type"); + GLADE_HOOKUP_OBJECT (watch_win, button_add_watch, "button_add_watch"); + GLADE_HOOKUP_OBJECT (watch_win, scrolledwindow10, "scrolledwindow10"); + GLADE_HOOKUP_OBJECT (watch_win, treeview1, "treeview1"); + GLADE_HOOKUP_OBJECT (watch_win, hbox5, "hbox5"); + GLADE_HOOKUP_OBJECT (watch_win, label40, "label40"); + GLADE_HOOKUP_OBJECT (watch_win, button_clear_all, "button_clear_all"); + GLADE_HOOKUP_OBJECT (watch_win, button_close, "button_close"); + + return watch_win; +} + --- a/src/gui/interface.h Sat Mar 13 00:03:32 2004 +0000 +++ b/src/gui/interface.h Sat Aug 21 06:15:49 2004 +0000 @@ -5,3 +5,5 @@ GtkWidget* create_debug_win (void); GtkWidget* create_mmr_win (void); GtkWidget* create_about_win (void); +GtkWidget* create_dump_win (void); +GtkWidget* create_watch_win (void); --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/gui/mmio_win.c Sat Aug 21 06:15:49 2004 +0000 @@ -0,0 +1,151 @@ +#include +#include +#include "interface.h" +#include "gui.h" +#include "mem.h" +#include "mmio.h" + +GtkWidget *mmr_win; +GtkNotebook *mmr_book; + +static void printbits( char *out, int nbits, uint32_t value ) +{ + if( nbits < 32 ) { + int i; + for( i=32; i>nbits; i-- ) { + if( !(i % 8) ) *out++ = ' '; + *out++ = ' '; + } + } + while( nbits > 0 ) { + *out++ = (value&(1<<--nbits) ? '1' : '0'); + if( !(nbits % 8) ) *out++ = ' '; + } + *out = '\0'; +} + +static void printhex( char *out, int nbits, uint32_t value ) +{ + char tmp[10], *p = tmp; + int i; + + sprintf( tmp, "%08X", value ); + for( i=32; i>0; i-=4, p++ ) { + if( i <= nbits ) *out++ = *p; + else *out++ = ' '; + } + *out = '\0'; +} + + +static GtkCList *create_mmr_page( char *name ) +{ + GtkCList *list; + GtkWidget *scroll; + GtkWidget *tab; + + scroll = gtk_scrolled_window_new(NULL, NULL); + gtk_widget_show( scroll ); + gtk_scrolled_window_set_policy( GTK_SCROLLED_WINDOW(scroll), + GTK_POLICY_AUTOMATIC, GTK_POLICY_ALWAYS ); + list = GTK_CLIST(gtk_clist_new(5)); + gtk_clist_set_column_width(list, 0, 60); + gtk_clist_set_column_width(list, 1, 50); + gtk_clist_set_column_width(list, 2, 60); + gtk_clist_set_column_width(list, 3, 220); + gtk_clist_set_column_width(list, 4, 160); + gtk_clist_set_column_justification(list, 0, GTK_JUSTIFY_CENTER ); + gtk_clist_set_column_justification(list, 2, GTK_JUSTIFY_CENTER ); + gtk_clist_set_column_justification(list, 3, GTK_JUSTIFY_CENTER ); + gtk_clist_set_column_title(list, 0, "Address"); + gtk_clist_set_column_title(list, 1, "Register"); + gtk_clist_set_column_title(list, 2, "Value"); + gtk_clist_set_column_title(list, 3, "Bit Pattern"); + gtk_clist_set_column_title(list, 4, "Description"); + gtk_clist_column_titles_show(list); + gtk_widget_modify_font( GTK_WIDGET(list), fixed_list_font ); + gtk_widget_show( GTK_WIDGET(list) ); + tab = gtk_label_new(_(name)); + gtk_widget_show( tab ); + gtk_container_add( GTK_CONTAINER(scroll), GTK_WIDGET(list) ); + gtk_notebook_append_page( mmr_book, scroll, tab ); + gtk_object_set_data( GTK_OBJECT(mmr_win), name, list ); + return list; +} + +void update_mmr_win( void ) +{ + int i,j, count = 0; + GtkCList *page, *all_page; + char data[10], bits[40]; + + all_page = GTK_CLIST(gtk_object_get_data( GTK_OBJECT(mmr_win), "All" )); + + for( i=1; i < num_io_rgns; i++ ) { + page = GTK_CLIST(gtk_object_get_data( GTK_OBJECT(mmr_win), + io_rgn[i]->id )); + for( j=0; io_rgn[i]->ports[j].id != NULL; j++ ) { + if( *io_rgn[i]->ports[j].val != + *(uint32_t *)(io_rgn[i]->save_mem+io_rgn[i]->ports[j].offset)){ + int sz = io_rgn[i]->ports[j].width; + /* Changed */ + printhex( data, sz, *io_rgn[i]->ports[j].val ); + printbits( bits, sz, *io_rgn[i]->ports[j].val ); + + gtk_clist_set_text( page, j, 2, data ); + gtk_clist_set_text( page, j, 3, bits ); + gtk_clist_set_foreground( page, j, &clrChanged ); + + gtk_clist_set_text( all_page, count, 2, data ); + gtk_clist_set_text( all_page, count, 3, bits ); + gtk_clist_set_foreground( all_page, count, &clrChanged ); + + } else { + gtk_clist_set_foreground( page, j, &clrNormal ); + gtk_clist_set_foreground( all_page, count, &clrNormal ); + } + count++; + } + memcpy( io_rgn[i]->save_mem, io_rgn[i]->mem, PAGE_SIZE ); + } +} + +void init_mmr_win( void ) +{ + int i, j; + GtkCList *all_list; + mmr_win = create_mmr_win(); + mmr_book = GTK_NOTEBOOK( gtk_object_get_data( GTK_OBJECT(mmr_win), "mmr_notebook" )); + + /* kill the dummy page glade insists on adding */ + gtk_notebook_remove_page( mmr_book, 0 ); + + all_list = create_mmr_page( "All" ); + for( i=1; i < num_io_rgns; i++ ) { + GtkCList *list = create_mmr_page( io_rgn[i]->id ); + + for( j=0; io_rgn[i]->ports[j].id != NULL; j++ ) { + int sz = io_rgn[i]->ports[j].width; + char addr[10], data[10], bits[40]; + char *arr[] = { addr, io_rgn[i]->ports[j].id, data, bits, + io_rgn[i]->ports[j].desc }; + sprintf( addr, "%08X", + io_rgn[i]->base + io_rgn[i]->ports[j].offset ); + printhex( data, sz, *io_rgn[i]->ports[j].val ); + printbits( bits, io_rgn[i]->ports[j].width, + *io_rgn[i]->ports[j].val ); + gtk_clist_append( list, arr ); + gtk_clist_append( all_list, arr ); + } + } +} + +void mmr_open_win( void ) +{ + gtk_widget_show( mmr_win ); +} + +void mmr_close_win( void ) +{ + gtk_widget_hide( mmr_win ); +} --- a/src/loader.c Sat Mar 13 00:03:32 2004 +0000 +++ b/src/loader.c Sat Aug 21 06:15:49 2004 +0000 @@ -59,7 +59,7 @@ sh4_set_pc( BOOTSTRAP_LOAD_ADDR + 0x300 ); set_disassembly_region( BOOTSTRAP_LOAD_ADDR ); set_disassembly_pc( sh4r.pc, TRUE ); - update_registers(); + update_gui(); } else { /* look for a valid ISO9660 header */ lseek( fd, 32768, SEEK_SET ); --- a/src/machine.c Sat Mar 13 00:03:32 2004 +0000 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,29 +0,0 @@ -#include "dream.h" -#include "mem.h" -#include "aica.h" -#include "asic.h" -/* Central switchboard for the system */ - -void machine_init( void ) -{ - mem_init(); - sh4_init(); - asic_init(); - pvr2_init(); - aica_init(); - - mem_create_ram_region( 0x0C000000, 16 MB, MEM_REGION_MAIN ); - mem_create_ram_region( 0x05000000, 8 MB, MEM_REGION_VIDEO ); - mem_create_ram_region( 0x00800000, 2 MB, MEM_REGION_AUDIO ); - mem_create_ram_region( 0x00703000, 8 KB, MEM_REGION_AUDIO_SCRATCH ); /*???*/ - mem_load_rom( "dcboot.rom", 0x00000000, 0x00200000, 0x89f2b1a1 ); - mem_load_rom( "dcflash.rom",0x00200000, 0x00020000, 0x357c3568 ); -} - -void machine_reset( void ) -{ - sh4_reset(); - mem_reset(); -// pvr2_reset(); - aica_reset(); -} --- a/src/main.c Sat Mar 13 00:03:32 2004 +0000 +++ b/src/main.c Sat Aug 21 06:15:49 2004 +0000 @@ -12,6 +12,7 @@ #include "interface.h" #include "gui.h" #include "sh4core.h" +#include "mem.h" int @@ -24,16 +25,18 @@ textdomain (PACKAGE); #endif gnome_init ("dreamon", VERSION, argc, argv); - + init_gui(); debug_win = create_debug_win (); init_debug_win(debug_win); video_open(); - machine_init(); + dreamcast_init(); init_mmr_win(); /* Note: must be done after sh4_init */ sh4_reset(); - update_registers(); + update_gui(); gtk_widget_show (debug_win); set_disassembly_region( 0xA0000000 ); + // mem_new_watch( 0x0C204818, 0x0C204830, WATCH_WRITE ); + emit( EMIT_INFO, -1, "DreamOn! ready..." ); gtk_main (); --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/maple/controller.c Sat Aug 21 06:15:49 2004 +0000 @@ -0,0 +1,56 @@ +#include +#include "dream.h" +#include "maple.h" +#include "maple/controller.h" + +void controller_attach( maple_device_t dev ); +void controller_detach( maple_device_t dev ); +int controller_get_cond( maple_device_t dev, int function, char *outbuf, + int *outlen ); + +static struct maple_device base_controller = { + MAPLE_DEVICE_TAG, CONTROLLER_IDENT, CONTROLLER_VERSION, NULL, NULL, + controller_get_cond, NULL, NULL, NULL, + controller_attach, controller_detach }; + +typedef struct controller_device { + struct maple_device dev; + uint32_t condition[2]; +} *controller_device_t; + + + +maple_device_t controller_new( ) +{ + controller_device_t dev = malloc( sizeof(struct controller_device) ); + memcpy( dev, &base_controller, sizeof(base_controller) ); + memset( dev->condition, 0, 8 ); + dev->condition[0] = 0x0000FFFF; + return MAPLE_DEVICE(dev); +} + + +void controller_attach( maple_device_t dev ) +{ + +} + +void controller_detach( maple_device_t dev ) +{ + +} + + +int controller_get_cond( maple_device_t mdev, int function, char *outbuf, + int *outlen ) +{ + controller_device_t dev = (controller_device_t)mdev; + if( function == MAPLE_FUNC_CONTROLLER ) { + *outlen = 2; + memcpy( outbuf, dev->condition, 8 ); + return 0; + } else { + return MAPLE_ERR_FUNC_UNSUP; + } +} + --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/maple/controller.h Sat Aug 21 06:15:49 2004 +0000 @@ -0,0 +1,37 @@ +/* First word of controller condition */ +#define BUTTON_C 0x00000001 /* not on standard controller */ +#define BUTTON_B 0x00000002 +#define BUTTON_A 0x00000004 +#define BUTTON_START 0x00000008 +#define BUTTON_DPAD_UP 0x00000010 +#define BUTTON_DPAD_DOWN 0x00000020 +#define BUTTON_DPAD_LEFT 0x00000040 +#define BUTTON_DPAD_RIGHT 0x00000080 +#define BUTTON_Z 0x00000100 /* not on standard controller */ +#define BUTTON_Y 0x00000200 +#define BUTTON_X 0x00000400 +#define BUTTON_D 0x00000800 /* not on standard controller */ +#define BUTTON_LEFT_TRIGGER 0xFF000000 /* Bitmask */ +#define BUTTON_RIGHT_TRIGGER 0x00FF0000 /* Bitmask */ + +/* Second word of controller condition (bitmasks) */ +#define JOY_X_AXIS 0x000000FF +#define JOY_Y_AXIS 0x0000FF00 +#define JOY2_X_AXIS 0x00FF0000 /* not on standard controller */ +#define JOY2_Y_AXIS 0xFF000000 /* not on standard controller */ + +/* Standard controller ID */ +#define CONTROLLER_IDENT {0x00, 0x00, 0x00, 0x01, 0x00, 0x0f, 0x06, 0xfe, 0x00, 0x00, 0x00, 0x00, \ +0x00, 0x00, 0x00, 0x00, 0xff, 0x00, 0x44, 0x72, 0x65, 0x61, 0x6d, 0x63, 0x61, 0x73, 0x74, 0x20, \ + 0x43, 0x6f, 0x6e, 0x74, 0x72, 0x6f, 0x6c, 0x6c, 0x65, 0x72, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, \ + 0x20, 0x20, 0x20, 0x20, 0x50, 0x72, 0x6f, 0x64, 0x75, 0x63, 0x65, 0x64, 0x20, 0x42, 0x79, 0x20, \ + 0x6f, 0x72, 0x20, 0x55, 0x6e, 0x64, 0x65, 0x72, 0x20, 0x4c, 0x69, 0x63, 0x65, 0x6e, 0x73, 0x65, \ + 0x20, 0x46, 0x72, 0x6f, 0x6d, 0x20, 0x53, 0x45, 0x47, 0x41, 0x20, 0x45, 0x4e, 0x54, 0x45, 0x52, \ + 0x50, 0x52, 0x49, 0x53, 0x45, 0x53, 0x2c, 0x4c, 0x54, 0x44, 0x2e, 0x20, 0x20, 0x20, 0x20, 0x20, \ + 0xae, 0x01, 0xf4, 0x01} +#define CONTROLLER_VERSION {0x56, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x20, 0x31, 0x2e, 0x30, 0x31, \ + 0x30, 0x2c, 0x31, 0x39, 0x39, 0x38, 0x2f, 0x30, 0x39, 0x2f, 0x32, 0x38, 0x2c, 0x33, 0x31, 0x35, \ + 0x2d, 0x36, 0x32, 0x31, 0x31, 0x2d, 0x41, 0x42, 0x20, 0x20, 0x20, 0x2c, 0x41, 0x6e, 0x61, 0x6c, \ + 0x6f, 0x67, 0x20, 0x4d, 0x6f, 0x64, 0x75, 0x6c, 0x65, 0x20, 0x3a, 0x20, 0x54, 0x68, 0x65, 0x20, \ + 0x34, 0x74, 0x68, 0x20, 0x45, 0x64, 0x69, 0x74, 0x69, 0x6f, 0x6e, 0x2e, 0x35, 0x2f, 0x38, 0x20, \ + 0x20, 0x2b, 0x44, 0x46 } --- a/src/maple/maple.c Sat Mar 13 00:03:32 2004 +0000 +++ b/src/maple/maple.c Sat Aug 21 06:15:49 2004 +0000 @@ -4,24 +4,213 @@ #include "asic.h" #include "maple.h" +/** + * Input data looks like this: + * 0: transfer control word + * 0: length of data in words (not including 3 word header) + * 1: low bit = lightgun mode + * 2: low 2 bits = port # (0..3) + * 3: 0x80 = last packet, 0x00 = normal packet + * 4: output buffer address + * 8: Command word + * 8: command code + * 9: destination address + * 10: source address + * 11: length of data in words (not including 3 word header) + * 12: command-specific data + */ + +/** + * array is [port][subperipheral], so [0][0] is main peripheral on port A, + * [1][2] is the second subperipheral on port B and so on. + */ +maple_device_t maple_devices[4][6]; +int maple_periph_mask[4]; +#define GETBYTE(n) ((uint32_t)(buf[n])) +#define GETWORD(n) (*((uint32_t *)(buf+(n)))) +#define PUTBYTE(n,x) (buf[n] = (char)x) +#define PUTWORD(n,x) (*((uint32_t *)(return_buf+(n))) = (x)) + void maple_handle_buffer( uint32_t address ) { - uint32_t *buf = (uint32_t *)mem_get_region(address); + unsigned char *buf = (unsigned char *)mem_get_region(address); if( buf == NULL ) { ERROR( "Invalid or unmapped buffer passed to maple (0x%08X)", address ); } else { - int last, port, length, cmd, recv_addr, send_addr, add_length; - int i = 0; - do { - last = buf[i]>>31; /* indicates last packet */ - port = (buf[i]>>16)&0x03; - length = buf[i]&0x0F; - uint32_t return_address = buf[i+1]; - cmd = buf[i+2]&0xFF; - recv_addr = (buf[i+2]>>8)&0xFF; - send_addr = (buf[i+2]>>16)&0xFF; - add_length = (buf[i+2]>>24)&0xFF; - char *return_buf = mem_get_region(return_address); + unsigned int last = 0; + int i = 0, count; + for( count=0; !last; count++ ) { + unsigned int port, length, gun, periph, periph_id, out_length; + unsigned int cmd, recv_addr, send_addr; + uint32_t return_addr; + unsigned char *return_buf; - } while( !last ); + last = GETBYTE(3) & 0x80; /* indicates last packet */ + port = GETBYTE(2) & 0x03; + gun = GETBYTE(1) & 0x01; + length = GETBYTE(0) & 0xFF; + return_addr = GETWORD(4); + if( return_addr == 0 ) { + /* ERROR */ + } + return_buf = mem_get_region(return_addr); + cmd = GETBYTE(8); + recv_addr = GETBYTE(9); + send_addr = GETBYTE(10); + /* Sanity checks */ + if( GETBYTE(11) != length || + send_addr != (port<<6) || + recv_addr >> 6 != port || + return_buf == NULL ) { + /* ERROR */ + } + periph = 0; + periph_id = recv_addr & 0x3F; + if( periph_id != 0x20 ) { + for( i=0;i<5;i++ ) { + if( periph_id == (1<ident, 112 ); + out_length = 0x1C; + break; + case MAPLE_CMD_EXT_INFO: + status = MAPLE_RESP_EXT_INFO; + memcpy( return_buf+4, dev->ident, 192 ); + out_length = 0x30; + break; + case MAPLE_CMD_RESET: + if( dev->reset == NULL ) + status = MAPLE_RESP_ACK; + else status = dev->reset(dev); + break; + case MAPLE_CMD_SHUTDOWN: + if( dev->shutdown == NULL ) + status = MAPLE_RESP_ACK; + else status = dev->shutdown(dev); + break; + case MAPLE_CMD_GET_COND: + func = GETWORD(12); + if( dev->get_condition == NULL ) + status = MAPLE_ERR_CMD_UNKNOWN; + else status = dev->get_condition(dev, func, + return_buf+8, + &out_length ); + if( status == 0 ) { + status = MAPLE_RESP_DATA; + PUTWORD(4,func); + } + break; + case MAPLE_CMD_SET_COND: + func = GETWORD(12); + if( dev->set_condition == NULL ) + status = MAPLE_ERR_CMD_UNKNOWN; + else status = dev->set_condition(dev, func, + buf+16, + length); + if( status == 0 ) + status = MAPLE_RESP_ACK; + break; + case MAPLE_CMD_READ_BLOCK: + func = GETWORD(12); + block = GETWORD(16); + if( dev->read_block == NULL ) + status = MAPLE_ERR_CMD_UNKNOWN; + else status = dev->read_block(dev, func, block, + return_buf+12, + &out_length ); + if( status == 0 ) { + status = MAPLE_RESP_DATA; + PUTWORD(4,func); + PUTWORD(8,block); + } + break; + case MAPLE_CMD_WRITE_BLOCK: + func = GETWORD(12); + block = GETWORD(16); + if( dev->write_block == NULL ) + status = MAPLE_ERR_CMD_UNKNOWN; + else { + status = dev->write_block(dev, func, block, + buf+20, length); + if( status == 0 ) + status = MAPLE_RESP_ACK; + } + break; + default: + status = MAPLE_ERR_CMD_UNKNOWN; + } + return_buf[0] = status; + return_buf[1] = send_addr; + return_buf[2] = recv_addr; + if( periph == 0 ) + return_buf[2] |= maple_periph_mask[port]; + return_buf[3] = out_length; + } + buf += 12 + (length<<2); + } + asic_event( EVENT_MAPLE_DMA ); } } + +void maple_attach_device( maple_device_t dev, unsigned int port, + unsigned int periph ) { + assert( port < 4 ); + assert( periph < 6 ); + + if( maple_devices[port][periph] != NULL ) { + /* Detach existing peripheral first */ + maple_detach_device( port, periph ); + } + + maple_devices[port][periph] = dev; + if( periph != 0 ) + maple_periph_mask[port] |= (1<<(periph-1)); + else maple_periph_mask[port] |= 0x20; + if( dev->attach != NULL ) { + dev->attach( dev ); + } +} + +void maple_detach_device( unsigned int port, unsigned int periph ) { + assert( port < 4 ); + assert( periph < 6 ); + + maple_device_t dev = maple_devices[port][periph]; + if( dev == NULL ) /* already detached */ + return; + maple_devices[port][periph] = NULL; + if( dev->detach != NULL ) { + dev->detach(dev); + } + if( periph == 0 ) { + /* If we detach the main peripheral, we also have to detach all the + * subperipherals, or the system could get quite confused + */ + int i; + maple_periph_mask[port] = 0; + for( i=1; i<6; i++ ) { + maple_detach_device(port,i); + } + } else { + maple_periph_mask[port] &= (~(1<<(periph-1))); + } + +} --- a/src/maple/maple.h Sat Mar 13 00:03:32 2004 +0000 +++ b/src/maple/maple.h Sat Aug 21 06:15:49 2004 +0000 @@ -10,8 +10,8 @@ #define MAPLE_CMD_SHUTDOWN 4 /* Shutdown device */ #define MAPLE_CMD_GET_COND 9 /* Get condition */ #define MAPLE_CMD_MEM_INFO 10 /* Get memory information */ -#define MAPLE_CMD_BLOCK_READ 11 /* Block read */ -#define MAPLE_CMD_BLOCK_WRITE 12 /* Block write */ +#define MAPLE_CMD_READ_BLOCK 11 /* Block read */ +#define MAPLE_CMD_WRITE_BLOCK 12 /* Block write */ #define MAPLE_CMD_SET_COND 14 /* Set condition */ #define MAPLE_RESP_INFO 5 /* Device information response */ #define MAPLE_RESP_EXT_INFO 6 /* Extended device information response */ @@ -23,24 +23,42 @@ #define MAPLE_ERR_RETRY -4 /* Retry command */ #define MAPLE_ERR_FILE -5 /* File error? */ -#define MAPLE_FUNC_CONTROLLER 0x001 -#define MAPLE_FUNC_MEMORY 0x002 -#define MAPLE_FUNC_LCD 0x004 -#define MAPLE_FUNC_CLOCK 0x008 -#define MAPLE_FUNC_MICROPHONE 0x010 -#define MAPLE_FUNC_AR_GUN 0x020 -#define MAPLE_FUNC_KEYBOARD 0x040 -#define MAPLE_FUNC_LIGHT_GUN 0x080 -#define MAPLE_FUNC_PURU_PURU 0x100 -#define MAPLE_FUNC_MOUSE 0x200 +#define MAPLE_FUNC_CONTROLLER 0x01000000 +#define MAPLE_FUNC_MEMORY 0x02000000 +#define MAPLE_FUNC_LCD 0x04000000 +#define MAPLE_FUNC_CLOCK 0x08000000 +#define MAPLE_FUNC_MICROPHONE 0x10000000 +#define MAPLE_FUNC_AR_GUN 0x20000000 +#define MAPLE_FUNC_KEYBOARD 0x40000000 +#define MAPLE_FUNC_LIGHT_GUN 0x80000000 +#define MAPLE_FUNC_PURU_PURU 0x00010000 +#define MAPLE_FUNC_MOUSE 0x00020000 + +#define MAPLE_DEVICE_TAG 0x4D41504C +#define MAPLE_DEVICE(x) ((maple_device_t)x) + +typedef struct maple_device { + uint32_t _tag; + unsigned char ident[112]; + unsigned char version[80]; + int (*reset)(struct maple_device *dev); + int (*shutdown)(struct maple_device *dev); + int (*get_condition)(struct maple_device *dev, + int function, char *outbuf, int *buflen); + int (*set_condition)(struct maple_device *dev, + int function, char *inbuf, int buflen); + int (*read_block)(struct maple_device *dev, + int function, uint32_t block, char *outbuf, int *buflen); + int (*write_block)(struct maple_device *dev, + int function, uint32_t block, char *inbuf, int buflen); + void (*attach)(struct maple_device *dev); + void (*detach)(struct maple_device *dev); +} *maple_device_t; + +maple_device_t controller_new(void); void maple_handle_buffer( uint32_t buffer ); - - -struct maple_device_t { - - -}; - +void maple_attach_device( maple_device_t dev, unsigned int port, unsigned int periph ); +void maple_detach_device( unsigned int port, unsigned int periph ); #endif /* !dream_maple_H */ --- a/src/pvr2/pvr2.c Sat Mar 13 00:03:32 2004 +0000 +++ b/src/pvr2/pvr2.c Sat Aug 21 06:15:49 2004 +0000 @@ -89,7 +89,7 @@ { switch( reg ) { case BEAMPOS: - return sh4r.icount&0x20 ? 0x2000 : 0; + return sh4r.icount&0x20 ? 0x2000 : 1; default: return MMIO_READ( PVR2, reg ); } --- a/src/sh4/mem.c Sat Mar 13 00:03:32 2004 +0000 +++ b/src/sh4/mem.c Sat Aug 21 06:15:49 2004 +0000 @@ -11,10 +11,29 @@ #include "dream.h" #include "sh4core.h" #include "mem.h" +#include "dreamcast.h" #define OC_BASE 0x1C000000 #define OC_TOP 0x20000000 +#ifdef ENABLE_WATCH +#define CHECK_READ_WATCH( addr, size ) \ + if( mem_is_watched(addr,size,WATCH_READ) != NULL ) { \ + WARN( "Watch triggered at %08X by %d byte read", addr, size ); \ + dreamcast_stop(); \ + } +#define CHECK_WRITE_WATCH( addr, size, val ) \ + if( mem_is_watched(addr,size,WATCH_WRITE) != NULL ) { \ + WARN( "Watch triggered at %08X by %d byte write <= %0*X", addr, size, size*2, val ); \ + dreamcast_stop(); \ + } +#else +#define CHECK_READ_WATCH( addr, size ) +#define CHECK_WRITE_WATCH( addr, size ) +#endif + +#define TRANSLATE_VIDEO_64BIT_ADDRESS(a) ( (((a)&0x00FFFFF8)>>1)|(((a)&0x00000004)<<20)|((a)&0x03)|0x05000000 ); + static char **page_map = NULL; static char *cache = NULL; @@ -209,7 +228,12 @@ { struct mmio_region *io = P4_io[(addr&0x1FFFFFFF)>>19]; if( !io ) { - ERROR( "Attempted write to unknown P4 region: %08X", addr ); + if( (addr & 0xFC000000) == 0xE0000000 ) { + /* Store queue */ + SH4_WRITE_STORE_QUEUE( addr, val ); + } else { + ERROR( "Attempted write to unknown P4 region: %08X", addr ); + } } else { io->io_write( addr&0xFFF, val ); } @@ -227,6 +251,10 @@ if( addr > 0xE0000000 ) /* P4 Area, handled specially */ return SIGNEXT16(mem_read_p4( addr )); + if( (addr&0x1F800000) == 0x04000000 ) { + addr = TRANSLATE_VIDEO_64BIT_ADDRESS(addr); + } + page = page_map[ (addr & 0x1FFFFFFF) >> 12 ]; if( ((uint32_t)page) < MAX_IO_REGIONS ) { /* IO Region */ if( page == NULL ) { @@ -243,9 +271,16 @@ int32_t mem_read_long( uint32_t addr ) { char *page; + + CHECK_READ_WATCH(addr,4); + if( addr > 0xE0000000 ) /* P4 Area, handled specially */ return mem_read_p4( addr ); + if( (addr&0x1F800000) == 0x04000000 ) { + addr = TRANSLATE_VIDEO_64BIT_ADDRESS(addr); + } + if( IS_MMU_ENABLED() ) { ERROR( "user-mode & mmu translation not implemented, aborting", NULL ); sh4_stop(); @@ -270,9 +305,16 @@ int32_t mem_read_word( uint32_t addr ) { char *page; + + CHECK_READ_WATCH(addr,2); + if( addr > 0xE0000000 ) /* P4 Area, handled specially */ return SIGNEXT16(mem_read_p4( addr )); + if( (addr&0x1F800000) == 0x04000000 ) { + addr = TRANSLATE_VIDEO_64BIT_ADDRESS(addr); + } + if( IS_MMU_ENABLED() ) { ERROR( "user-mode & mmu translation not implemented, aborting", NULL ); sh4_stop(); @@ -297,8 +339,14 @@ int32_t mem_read_byte( uint32_t addr ) { char *page; + + CHECK_READ_WATCH(addr,1); + if( addr > 0xE0000000 ) /* P4 Area, handled specially */ return SIGNEXT8(mem_read_p4( addr )); + if( (addr&0x1F800000) == 0x04000000 ) { + addr = TRANSLATE_VIDEO_64BIT_ADDRESS(addr); + } if( IS_MMU_ENABLED() ) { ERROR( "user-mode & mmu translation not implemented, aborting", NULL ); @@ -325,14 +373,14 @@ { char *page; + CHECK_WRITE_WATCH(addr,4,val); + if( addr > 0xE0000000 ) { mem_write_p4( addr, val ); return; } - - if( addr & 0xFFFFF000 == 0x0CFF0000 || - addr & 0x0FFFF000 == 0x0C374000 ) { - TRACE( "Long write to watched page: %08X => %08X", val, addr ); + if( (addr&0x1F800000) == 0x04000000 ) { + addr = TRANSLATE_VIDEO_64BIT_ADDRESS(addr); } if( IS_MMU_ENABLED() ) { @@ -340,6 +388,11 @@ sh4_stop(); return; } + if( (addr&0x1FFFFFFF) < 0x200000 ) { + ERROR( "Attempted write to read-only memory: %08X => %08X", val, addr); + sh4_stop(); + return; + } page = page_map[ (addr & 0x1FFFFFFF) >> 12 ]; if( ((uint32_t)page) < MAX_IO_REGIONS ) { /* IO Region */ if( page == NULL ) { @@ -357,10 +410,15 @@ { char *page; + CHECK_WRITE_WATCH(addr,2,val); + if( addr > 0xE0000000 ) { mem_write_p4( addr, (int16_t)val ); return; } + if( (addr&0x1F800000) == 0x04000000 ) { + addr = TRANSLATE_VIDEO_64BIT_ADDRESS(addr); + } if( IS_MMU_ENABLED() ) { ERROR( "user-mode & mmu translation not implemented, aborting", NULL ); sh4_stop(); @@ -383,10 +441,16 @@ { char *page; + CHECK_WRITE_WATCH(addr,1,val); + if( addr > 0xE0000000 ) { mem_write_p4( addr, (int8_t)val ); return; } + if( (addr&0x1F800000) == 0x04000000 ) { + addr = TRANSLATE_VIDEO_64BIT_ADDRESS(addr); + } + if( IS_MMU_ENABLED() ) { ERROR( "user-mode & mmu translation not implemented, aborting", NULL ); sh4_stop(); @@ -414,3 +478,17 @@ return page+(addr&0xFFF); } } + +/* FIXME: Handle all the many special cases when the range doesn't fall cleanly + * into the same memory black + */ + +void mem_copy_from_sh4( char *dest, uint32_t srcaddr, size_t count ) { + char *src = mem_get_region(srcaddr); + memcpy( dest, src, count ); +} + +void mem_copy_to_sh4( uint32_t destaddr, char *src, size_t count ) { + char *dest = mem_get_region(destaddr); + memcpy( dest, src, count ); +} --- a/src/sh4/mem.h Sat Mar 13 00:03:32 2004 +0000 +++ b/src/sh4/mem.h Sat Aug 21 06:15:49 2004 +0000 @@ -11,13 +11,13 @@ #endif #endif -struct mem_region { +typedef struct mem_region { uint32_t base; uint32_t size; char *name; char *mem; int flags; -}; +} *mem_region_t; #define MAX_IO_REGIONS 24 #define MAX_MEM_REGIONS 8 @@ -48,6 +48,17 @@ void mem_init( void ); void mem_reset( void ); +#define ENABLE_WATCH 1 + +#define WATCH_WRITE 1 +#define WATCH_READ 2 +#define WATCH_EXEC 3 /* AKA Breakpoint :) */ + +typedef struct watch_point *watch_point_t; + +watch_point_t mem_new_watch( uint32_t start, uint32_t end, int flags ); +void mem_delete_watch( watch_point_t watch ); +watch_point_t mem_is_watched( uint32_t addr, int size, int op ); /* mmucr register bits */ #define MMUCR_AT 0x00000001 /* Address Translation enabled */ --- a/src/sh4/sh4core.c Sat Mar 13 00:03:32 2004 +0000 +++ b/src/sh4/sh4core.c Sat Aug 21 06:15:49 2004 +0000 @@ -49,7 +49,14 @@ { running = 1; while( running && count--) { + int pc = sh4r.pc; sh4_execute_instruction(); + /* + if( sh4r.pc == 0x8C0C1636 || + sh4r.pc == 0x8C0C1634 ) { + WARN( "Branching to %08X from %08X", sh4r.pc, pc ); + sh4_stop(); + }*/ } } @@ -61,11 +68,13 @@ void sh4_runto( uint32_t target_pc, uint32_t count ) { running = 1; - do { + while( running && count--) { sh4_execute_instruction(); - } while( running && sh4r.pc != target_pc && count-- ); - if( count == 0 ) - running = 0; + if( sh4r.pc == target_pc ) { + running = 0; + break; + } + } } #define UNDEF(ir) do{ ERROR( "Raising exception on undefined instruction at %08x, opcode = %04x", sh4r.pc, ir ); sh4_stop(); RAISE( EXC_ILLEGAL, EXV_ILLEGAL ); }while(0) @@ -107,6 +116,7 @@ #define EXC_POWER_RESET 0x000 /* vector special */ #define EXC_MANUAL_RESET 0x020 +#define EXC_SLOT_ILLEGAL 0x1A0 #define EXC_ILLEGAL 0x180 #define EXV_ILLEGAL 0x100 #define EXC_TRAP 0x160 @@ -118,6 +128,7 @@ #define CHECKPRIV() CHECK( IS_SH4_PRIVMODE(), EXC_ILLEGAL, EXV_ILLEGAL ) #define CHECKFPUEN() CHECK( IS_FPU_ENABLED(), EXC_FPDISABLE, EXV_FPDISABLE ) #define CHECKDEST(p) if( (p) == 0 ) { ERROR( "%08X: Branch/jump to NULL, CPU halted", sh4r.pc ); sh4_stop(); return; } +#define CHECKSLOTILLEGAL() if(sh4r.in_delay_slot) { RAISE(EXC_SLOT_ILLEGAL,EXV_ILLEGAL); } static void sh4_switch_banks( ) { @@ -159,7 +170,6 @@ static void sh4_accept_interrupt( void ) { uint32_t code = intc_accept_interrupt(); - sh4r.ssr = sh4_read_sr(); sh4r.spc = sh4r.pc; sh4r.sgr = sh4r.r[15]; @@ -167,12 +177,13 @@ MMIO_WRITE( MMU, INTEVT, code ); sh4r.pc = sh4r.vbr + 0x600; sh4r.new_pc = sh4r.pc + 2; + WARN( "Accepting interrupt %03X, from %08X => %08X", code, sh4r.spc, sh4r.pc ); } void sh4_execute_instruction( void ) { - int pc = sh4r.pc; - unsigned short ir = MEM_READ_WORD(pc); + int pc; + unsigned short ir; uint32_t tmp; uint64_t tmpl; @@ -187,8 +198,8 @@ #define IMM8(ir) SIGNEXT8(ir&0x00FF) #define UIMM8(ir) (ir&0x00FF) /* Unsigned immmediate */ #define DISP12(ir) SIGNEXT12(ir&0x0FFF) -#define FVN(ir) ((ir&0x0C00) -#define FVM(ir) ((ir&0x0300)>>8) +#define FVN(ir) ((ir&0x0C00)>>8) +#define FVM(ir) ((ir&0x0300)>>6) #define FRN(ir) (FR[(ir&0x0F00)>>8]) #define FRM(ir) (FR[(ir&0x00F0)>>4]) #define FRNi(ir) (((uint32_t *)FR)[(ir&0x0F00)>>8]) @@ -202,8 +213,11 @@ #define FPULf *((float *)&sh4r.fpul) #define FPULi (sh4r.fpul) - if( SH4_INT_PENDING() ) sh4_accept_interrupt(); + if( SH4_INT_PENDING() ) + sh4_accept_interrupt(); + pc = sh4r.pc; + ir = MEM_READ_WORD(pc); sh4r.icount++; switch( (ir&0xF000)>>12 ) { @@ -242,16 +256,32 @@ switch( (ir&0x00F0)>>4 ) { case 0: /* BSRF Rn */ CHECKDEST( pc + 4 + RN(ir) ); + CHECKSLOTILLEGAL(); + sh4r.in_delay_slot = 1; sh4r.pr = sh4r.pc + 4; sh4r.pc = sh4r.new_pc; sh4r.new_pc = pc + 4 + RN(ir); return; case 2: /* BRAF Rn */ CHECKDEST( pc + 4 + RN(ir) ); + CHECKSLOTILLEGAL(); + sh4r.in_delay_slot = 1; sh4r.pc = sh4r.new_pc; sh4r.new_pc = pc + 4 + RN(ir); return; case 8: /* PREF [Rn] */ + tmp = RN(ir); + if( (tmp & 0xFC000000) == 0xE0000000 ) { + /* Store queue operation */ + int queue = (tmp&0x20)>>2; + int32_t *src = &sh4r.store_queue[queue]; + uint32_t hi = (MMIO_READ( MMU, (queue == 0 ? QACR0 : QACR1) ) & 0x1C) << 24; + uint32_t target = tmp&0x03FFFFE0 | hi; + mem_copy_to_sh4( target, src, 32 ); + WARN( "Executed SQ%c => %08X", + (queue == 0 ? '0' : '1'), target ); + } + break; case 9: /* OCBI [Rn] */ case 10:/* OCBP [Rn] */ case 11:/* OCBWB [Rn] */ @@ -272,7 +302,7 @@ MEM_WRITE_LONG( R0 + RN(ir), RM(ir) ); break; case 7: /* MUL.L Rm, Rn */ - sh4r.mac = (sh4r.mac&0xFFFFFFFF00000000) | + sh4r.mac = (sh4r.mac&0xFFFFFFFF00000000LL) | (RM(ir) * RN(ir)); break; case 8: @@ -338,6 +368,8 @@ switch( (ir&0x0FF0)>>4 ) { case 0: /* RTS */ CHECKDEST( sh4r.pr ); + CHECKSLOTILLEGAL(); + sh4r.in_delay_slot = 1; sh4r.pc = sh4r.new_pc; sh4r.new_pc = sh4r.pr; return; @@ -347,9 +379,12 @@ case 2: /* RTE */ CHECKPRIV(); CHECKDEST( sh4r.spc ); + CHECKSLOTILLEGAL(); + sh4r.in_delay_slot = 1; sh4r.pc = sh4r.new_pc; sh4r.new_pc = sh4r.spc; sh4_load_sr( sh4r.ssr ); + WARN( "RTE => %08X", sh4r.new_pc ); return; default:UNDEF(ir); } @@ -369,12 +404,12 @@ if( sh4r.s ) { /* 48-bit Saturation. Yuch */ tmpl += SIGNEXT48(sh4r.mac); - if( tmpl < 0xFFFF800000000000 ) - tmpl = 0xFFFF800000000000; - else if( tmpl > 0x00007FFFFFFFFFFF ) - tmpl = 0x00007FFFFFFFFFFF; - sh4r.mac = (sh4r.mac&0xFFFF000000000000) | - (tmpl&0x0000FFFFFFFFFFFF); + if( tmpl < 0xFFFF800000000000LL ) + tmpl = 0xFFFF800000000000LL; + else if( tmpl > 0x00007FFFFFFFFFFFLL ) + tmpl = 0x00007FFFFFFFFFFFLL; + sh4r.mac = (sh4r.mac&0xFFFF000000000000LL) | + (tmpl&0x0000FFFFFFFFFFFFLL); } else sh4r.mac = tmpl; RM(ir) += 4; @@ -440,11 +475,11 @@ RN(ir) = (RN(ir)>>16) | (RM(ir)<<16); break; case 14:/* MULU.W Rm, Rn */ - sh4r.mac = (sh4r.mac&0xFFFFFFFF00000000) | + sh4r.mac = (sh4r.mac&0xFFFFFFFF00000000LL) | (uint32_t)((RM(ir)&0xFFFF) * (RN(ir)&0xFFFF)); break; case 15:/* MULS.W Rm, Rn */ - sh4r.mac = (sh4r.mac&0xFFFFFFFF00000000) | + sh4r.mac = (sh4r.mac&0xFFFFFFFF00000000LL) | (uint32_t)(SIGNEXT32(RM(ir)&0xFFFF) * SIGNEXT32(RN(ir)&0xFFFF)); break; } @@ -571,6 +606,8 @@ break; case 0x0B: /* JSR [Rn] */ CHECKDEST( RN(ir) ); + CHECKSLOTILLEGAL(); + sh4r.in_delay_slot = 1; sh4r.pc = sh4r.new_pc; sh4r.new_pc = RN(ir); sh4r.pr = pc + 4; @@ -598,7 +635,7 @@ sh4r.t = ( ((int32_t)RN(ir)) > 0 ? 1 : 0 ); break; case 0x16: /* LDS.L [Rn++], MACL */ - sh4r.mac = (sh4r.mac & 0xFFFFFFFF00000000) | + sh4r.mac = (sh4r.mac & 0xFFFFFFFF00000000LL) | (uint64_t)((uint32_t)MEM_READ_LONG(RN(ir))); RN(ir) += 4; break; @@ -613,7 +650,7 @@ RN(ir) >>= 8; break; case 0x1A: /* LDS Rn, MACL */ - sh4r.mac = (sh4r.mac & 0xFFFFFFFF00000000) | + sh4r.mac = (sh4r.mac & 0xFFFFFFFF00000000LL) | (uint64_t)((uint32_t)(RN(ir))); break; case 0x1B: /* TAS.B [Rn] */ @@ -639,7 +676,7 @@ case 0x23: /* STC.L VBR, [--Rn] */ CHECKPRIV(); RN(ir) -= 4; - MEM_WRITE_LONG( RN(ir), sh4r.pr ); + MEM_WRITE_LONG( RN(ir), sh4r.vbr ); break; case 0x24: /* ROTCL Rn */ tmp = RN(ir) >> 31; @@ -673,6 +710,8 @@ break; case 0x2B: /* JMP [Rn] */ CHECKDEST( RN(ir) ); + CHECKSLOTILLEGAL(); + sh4r.in_delay_slot = 1; sh4r.pc = sh4r.new_pc; sh4r.new_pc = RN(ir); return; @@ -876,6 +915,7 @@ sh4r.t = ( R0 == IMM8(ir) ? 1 : 0 ); break; case 9: /* BT disp8 */ + CHECKSLOTILLEGAL() if( sh4r.t ) { CHECKDEST( sh4r.pc + (PCDISP8(ir)<<1) + 4 ) sh4r.pc += (PCDISP8(ir)<<1) + 4; @@ -884,6 +924,7 @@ } break; case 11:/* BF disp8 */ + CHECKSLOTILLEGAL() if( !sh4r.t ) { CHECKDEST( sh4r.pc + (PCDISP8(ir)<<1) + 4 ) sh4r.pc += (PCDISP8(ir)<<1) + 4; @@ -892,16 +933,21 @@ } break; case 13:/* BT/S disp8 */ + CHECKSLOTILLEGAL() if( sh4r.t ) { CHECKDEST( sh4r.pc + (PCDISP8(ir)<<1) + 4 ) + sh4r.in_delay_slot = 1; sh4r.pc = sh4r.new_pc; sh4r.new_pc = pc + (PCDISP8(ir)<<1) + 4; + sh4r.in_delay_slot = 1; return; } break; case 15:/* BF/S disp8 */ + CHECKSLOTILLEGAL() if( !sh4r.t ) { CHECKDEST( sh4r.pc + (PCDISP8(ir)<<1) + 4 ) + sh4r.in_delay_slot = 1; sh4r.pc = sh4r.new_pc; sh4r.new_pc = pc + (PCDISP8(ir)<<1) + 4; return; @@ -916,13 +962,17 @@ break; case 10:/* 1010dddddddddddd */ /* BRA disp12 */ - CHECKDEST( sh4r.pc + (DISP12(ir)<<1) + 4 ); + CHECKDEST( sh4r.pc + (DISP12(ir)<<1) + 4 ) + CHECKSLOTILLEGAL() + sh4r.in_delay_slot = 1; sh4r.pc = sh4r.new_pc; sh4r.new_pc = pc + 4 + (DISP12(ir)<<1); return; case 11:/* 1011dddddddddddd */ /* BSR disp12 */ CHECKDEST( sh4r.pc + (DISP12(ir)<<1) + 4 ) + CHECKSLOTILLEGAL() + sh4r.in_delay_slot = 1; sh4r.pr = pc + 4; sh4r.pc = sh4r.new_pc; sh4r.new_pc = pc + 4 + (DISP12(ir)<<1); @@ -939,6 +989,8 @@ MEM_WRITE_LONG( sh4r.gbr + (DISP8(ir)<<2), R0 ); break; case 3: /* TRAPA imm8 */ + CHECKSLOTILLEGAL() + sh4r.in_delay_slot = 1; MMIO_WRITE( MMU, TRA, UIMM8(ir) ); sh4r.pc = sh4r.new_pc; /* RAISE ends the instruction */ sh4r.new_pc += 2; @@ -1065,6 +1117,9 @@ case 6: /* FSQRT FRn */ FRN(ir) = sqrtf(FRN(ir)); break; + case 7: /* FSRRA FRn */ + FRN(ir) = 1.0/sqrtf(FRN(ir)); + break; case 8: /* FLDI0 FRn */ FRN(ir) = 0.0; break; @@ -1081,20 +1136,55 @@ FPULf = (float)DRN(ir); else UNDEF(ir); break; - case 14:/* FIPR FVn, FVn */ - UNIMP(ir); + case 14:/* FIPR FVm, FVn */ + /* FIXME: This is not going to be entirely accurate + * as the SH4 instruction is less precise. Also + * need to check for 0s and infinities. + */ + { + float *fr_bank = FR; + int tmp2 = FVN(ir); + tmp = FVM(ir); + fr_bank[tmp2+3] = fr_bank[tmp]*fr_bank[tmp2] + + fr_bank[tmp+1]*fr_bank[tmp2+1] + + fr_bank[tmp+2]*fr_bank[tmp2+2] + + fr_bank[tmp+3]*fr_bank[tmp2+3]; break; + } case 15: - if( FVM(ir) == 1 ) - /* FTRV XMTRX,FVn */ - UNIMP(ir); - else if( ir == 0xFBFD ) - /* FRCHG */ + if( (ir&0x0300) == 0x0100 ) { /* FTRV XMTRX,FVn */ + float *fvout = FR+FVN(ir); + float *xm = XF; + float fv[4] = { fvout[0], fvout[1], fvout[2], fvout[3] }; + fvout[0] = xm[0] * fv[0] + xm[4]*fv[1] + + xm[8]*fv[2] + xm[12]*fv[3]; + fvout[1] = xm[1] * fv[0] + xm[5]*fv[1] + + xm[9]*fv[2] + xm[13]*fv[3]; + fvout[2] = xm[2] * fv[0] + xm[6]*fv[1] + + xm[10]*fv[2] + xm[14]*fv[3]; + fvout[3] = xm[3] * fv[0] + xm[7]*fv[1] + + xm[11]*fv[2] + xm[15]*fv[3]; + break; + } + else if( (ir&0x0100) == 0 ) { /* FSCA FPUL, DRn */ + float angle = (((float)(short)(FPULi>>16)) + + ((float)(FPULi&16)/65536.0)) * + 2 * M_PI; + int reg = FRNn(ir); + FR[reg] = sinf(angle); + FR[reg+1] = cosf(angle); + break; + } + else if( ir == 0xFBFD ) { + /* FRCHG */ sh4r.fpscr ^= FPSCR_FR; - else if( ir == 0xF3FD ) + break; + } + else if( ir == 0xF3FD ) { + /* FSCHG */ sh4r.fpscr ^= FPSCR_SZ; - /* FSCHG */ - break; + break; + } default: UNDEF(ir); } break; @@ -1107,4 +1197,5 @@ } sh4r.pc = sh4r.new_pc; sh4r.new_pc += 2; + sh4r.in_delay_slot = 0; } --- a/src/sh4/sh4core.h Sat Mar 13 00:03:32 2004 +0000 +++ b/src/sh4/sh4core.h Sat Aug 21 06:15:49 2004 +0000 @@ -22,9 +22,13 @@ uint32_t m, q, s, t; /* really boolean - 0 or 1 */ float fr[2][16]; + int32_t store_queue[16]; /* technically 2 banks of 32 bytes */ + uint32_t new_pc; /* Not a real register, but used to handle delay slots */ uint32_t icount; /* Also not a real register, instruction counter */ uint32_t int_pending; /* flag set by the INTC = pending priority level */ + int in_delay_slot; /* flag to indicate the current instruction is in + * a delay slot (certain rules apply) */ }; extern struct sh4_registers sh4r; @@ -66,7 +70,7 @@ #define IS_SH4_PRIVMODE() (sh4r.sr&SR_MD) #define SH4_INTMASK() ((sh4r.sr&SR_IMASK)>>4) -#define SH4_INT_PENDING() (sh4r.int_pending) +#define SH4_INT_PENDING() (sh4r.int_pending && !sh4r.in_delay_slot) #define FPSCR_FR 0x00200000 /* FPU register bank */ #define FPSCR_SZ 0x00100000 /* FPU transfer size (0=32 bits, 1=64 bits) */ @@ -82,6 +86,7 @@ #define IS_FPU_ENABLED() ((sh4r.sr&SR_FD)==0) #define FR sh4r.fr[(sh4r.fpscr&FPSCR_FR)>>21] +#define XF sh4r.fr[((~sh4r.fpscr)&FPSCR_FR)>>21] /* Exceptions (for use with sh4_raise_exception) */ @@ -100,7 +105,7 @@ #define EX_FPU_DISABLED 0x800, 0x100 #define EX_SLOT_FPU_DISABLED 0x820, 0x100 - +#define SH4_WRITE_STORE_QUEUE(addr,val) sh4r.store_queue[(addr>>2)&0xF] = val; #ifdef __cplusplus } --- a/src/sh4/sh4dasm.c Sat Mar 13 00:03:32 2004 +0000 +++ b/src/sh4/sh4dasm.c Sat Aug 21 06:15:49 2004 +0000 @@ -305,18 +305,22 @@ case 4: snprintf( buf, len, "FNEG FR%d", RN(ir) ); break; case 5: snprintf( buf, len, "FABS FR%d", RN(ir) ); break; case 6: snprintf( buf, len, "FSQRT FR%d", RN(ir) ); break; + case 7: snprintf( buf, len, "FSRRA FR%d", RN(ir) ); break; case 8: snprintf( buf, len, "FLDI0 FR%d", RN(ir) ); break; case 9: snprintf( buf, len, "FLDI1 FR%d", RN(ir) ); break; case 10:snprintf( buf, len, "FCNVSD FPUL, DR%d", RN(ir)>>1 ); break; case 11:snprintf( buf, len, "FCNVDS DR%d, FPUL", RN(ir)>>1 ); break; case 14:snprintf( buf, len, "FIPR FV%d, FV%d", FVM(ir), FVN(ir) ); break; case 15: - if( FVM(ir) == 1 ) + if( (ir & 0x0300) == 0x0100 ) snprintf( buf, len, "FTRV XMTRX,FV%d", FVN(ir) ); + else if( (ir & 0x0100) == 0 ) + snprintf( buf, len, "FSCA FPUL, DR%d", RN(ir) ); else if( ir == 0xFBFD ) snprintf( buf, len, "FRCHG " ); else if( ir == 0xF3FD ) snprintf( buf, len, "FSCHG " ); + else UNIMP(ir); break; default: UNIMP(ir); } --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/watch.c Sat Aug 21 06:15:49 2004 +0000 @@ -0,0 +1,71 @@ +#include +#include "mem.h" + +struct watch_point { + uint32_t start; + uint32_t end; + int flags; +}; + +struct watch_point *watch_arr = NULL; +int watch_count = 0, watch_capacity = 0; + + +watch_point_t mem_new_watch( uint32_t start, uint32_t end, int flags ) +{ + int num; + if( watch_arr == NULL ) { + watch_capacity = 10; + watch_arr = calloc( sizeof(struct watch_point), watch_capacity ); + num = 0; + } else if( watch_count == watch_capacity ) { + struct watch_point *tmp = realloc( watch_arr, sizeof(struct watch_point) * watch_capacity * 2 ); + if( tmp == NULL ) + return NULL; + watch_arr = tmp; + memset( &watch_arr[watch_capacity], 0, sizeof( struct watch_point ) * watch_capacity ); + num = watch_capacity; + watch_capacity *= 2; + } else { + for( num=0; num= watch_capacity ) + return NULL; + watch->start = watch->end = 0; + watch->flags = 0; + watch_count--; +} + + +watch_point_t mem_is_watched( uint32_t addr, int size, int op ) +{ + int i, count; + addr &= 0x1FFFFFFF; + for( i=0, count=0; count< watch_count; i++ ) { + if( watch_arr[i].flags == 0 ) + continue; + count++; + if( watch_arr[i].flags & op && + watch_arr[i].start < addr+size && + watch_arr[i].end >= addr ) { + return &watch_arr[i]; + } + } + return NULL; +} +