revision 998:1754a8c6a9cf
summary |
tree |
shortlog |
changelog |
graph |
changeset |
raw | bz2 | zip | gz changeset | 998:1754a8c6a9cf |
parent | 997:3f7b28afc4f9 |
child | 999:3d19e3597d9b |
author | nkeynes |
date | Tue Mar 24 11:15:57 2009 +0000 (15 years ago) |
Add preliminary implementation of the GDB remote debugging server - attaches to
either or both the SH4 and ARM
either or both the SH4 and ARM
src/Makefile.am | view | annotate | diff | log | ||
src/Makefile.in | view | annotate | diff | log | ||
src/aica/armcore.h | view | annotate | diff | log | ||
src/aica/armdasm.c | view | annotate | diff | log | ||
src/aica/armmem.c | view | annotate | diff | log | ||
src/cpu.h | view | annotate | diff | log | ||
src/drivers/net_glib.c | view | annotate | diff | log | ||
src/drivers/net_osx.m | view | annotate | diff | log | ||
src/gdbserver.c | view | annotate | diff | log | ||
src/gtkui/gtk_debug.c | view | annotate | diff | log | ||
src/main.c | view | annotate | diff | log | ||
src/netutil.c | view | annotate | diff | log | ||
src/netutil.h | view | annotate | diff | log | ||
src/sh4/sh4.c | view | annotate | diff | log | ||
src/sh4/sh4.h | view | annotate | diff | log | ||
src/sh4/sh4dasm.h | view | annotate | diff | log | ||
src/sh4/sh4dasm.in | view | annotate | diff | log |
1.1 --- a/src/Makefile.am Tue Mar 24 11:04:51 2009 +00001.2 +++ b/src/Makefile.am Tue Mar 24 11:15:57 2009 +00001.3 @@ -3,6 +3,7 @@1.4 INCLUDES = \1.5 -DPACKAGE_DATA_DIR=\""$(datadir)"\" \1.6 -DPACKAGE_LOCALE_DIR=\""$(prefix)/$(DATADIRNAME)/locale"\" \1.7 + -DPACKAGE_PLUGIN_DIR=\""$(pkglibdir)"\" \1.8 -DPACKAGE_CONF_DIR=\""$(sysconfdir)"\" \1.9 -Ish4 \1.10 @GLIB_CFLAGS@ @GTK_CFLAGS@ @LIBPNG_CFLAGS@ @PULSE_CFLAGS@ @ESOUND_CFLAGS@ @ALSA_CFLAGS@ @SDL_CFLAGS@1.11 @@ -36,7 +37,8 @@1.12 main.c version.c config.c config.h lxdream.h dream.h gui.h cpu.h hook.h \1.13 gettext.h mem.c mem.h sdram.c mmio.h watch.c \1.14 asic.c asic.h clock.h serial.h \1.15 - syscall.c syscall.h bios.c dcload.c \1.16 + syscall.c syscall.h bios.c dcload.c gdbserver.c \1.17 + netutil.c netutil.h \1.18 gdrom/ide.c gdrom/ide.h gdrom/packet.h gdrom/gdimage.c \1.19 gdrom/gdrom.c gdrom/gdrom.h gdrom/nrg.c gdrom/cdi.c gdrom/gdi.c \1.20 gdrom/edc_ecc.c gdrom/ecc.h gdrom/edc_crctable.h gdrom/edc_encoder.h \1.21 @@ -87,14 +89,15 @@1.22 gtkui/gtk_win.c gtkui/gtkcb.c \1.23 gtkui/gtk_mmio.c gtkui/gtk_debug.c gtkui/gtk_dump.c \1.24 gtkui/gtk_ctrl.c gtkui/gtk_path.c gtkui/gtk_gd.c \1.25 - drivers/video_gtk.c1.26 + drivers/net_glib.c drivers/video_gtk.c1.27 endif1.29 if GUI_COCOA1.30 lxdream_SOURCES += cocoaui/cocoaui.m cocoaui/cocoaui.h \1.31 cocoaui/cocoa_win.m cocoaui/cocoa_gd.m cocoaui/cocoa_prefs.m \1.32 cocoaui/cocoa_path.m cocoaui/cocoa_ctrl.m cocoaui/paths_osx.m \1.33 - drivers/video_osx.m drivers/mac_keymap.h drivers/mac_keymap.txt1.34 + drivers/net_osx.m drivers/video_osx.m \1.35 + drivers/mac_keymap.h drivers/mac_keymap.txt1.36 else1.37 lxdream_SOURCES += paths_unix.c1.38 endif
2.1 --- a/src/Makefile.in Tue Mar 24 11:04:51 2009 +00002.2 +++ b/src/Makefile.in Tue Mar 24 11:15:57 2009 +00002.3 @@ -52,12 +52,13 @@2.4 @GUI_GTK_TRUE@ gtkui/gtk_win.c gtkui/gtkcb.c \2.5 @GUI_GTK_TRUE@ gtkui/gtk_mmio.c gtkui/gtk_debug.c gtkui/gtk_dump.c \2.6 @GUI_GTK_TRUE@ gtkui/gtk_ctrl.c gtkui/gtk_path.c gtkui/gtk_gd.c \2.7 -@GUI_GTK_TRUE@ drivers/video_gtk.c2.8 +@GUI_GTK_TRUE@ drivers/net_glib.c drivers/video_gtk.c2.10 @GUI_COCOA_TRUE@am__append_4 = cocoaui/cocoaui.m cocoaui/cocoaui.h \2.11 @GUI_COCOA_TRUE@ cocoaui/cocoa_win.m cocoaui/cocoa_gd.m cocoaui/cocoa_prefs.m \2.12 @GUI_COCOA_TRUE@ cocoaui/cocoa_path.m cocoaui/cocoa_ctrl.m cocoaui/paths_osx.m \2.13 -@GUI_COCOA_TRUE@ drivers/video_osx.m drivers/mac_keymap.h drivers/mac_keymap.txt2.14 +@GUI_COCOA_TRUE@ drivers/net_osx.m drivers/video_osx.m \2.15 +@GUI_COCOA_TRUE@ drivers/mac_keymap.h drivers/mac_keymap.txt2.17 @GUI_COCOA_FALSE@am__append_5 = paths_unix.c2.18 @VIDEO_OSMESA_TRUE@am__append_6 = drivers/video_gdk.c2.19 @@ -97,42 +98,43 @@2.20 am__lxdream_SOURCES_DIST = main.c version.c config.c config.h \2.21 lxdream.h dream.h gui.h cpu.h hook.h gettext.h mem.c mem.h \2.22 sdram.c mmio.h watch.c asic.c asic.h clock.h serial.h \2.23 - syscall.c syscall.h bios.c dcload.c gdrom/ide.c gdrom/ide.h \2.24 - gdrom/packet.h gdrom/gdimage.c gdrom/gdrom.c gdrom/gdrom.h \2.25 - gdrom/nrg.c gdrom/cdi.c gdrom/gdi.c gdrom/edc_ecc.c \2.26 - gdrom/ecc.h gdrom/edc_crctable.h gdrom/edc_encoder.h \2.27 - gdrom/edc_l2sq.h gdrom/edc_scramble.h gdrom/mmc.c \2.28 - gdrom/gddriver.h dreamcast.c dreamcast.h eventq.c eventq.h \2.29 - sh4/sh4.c sh4/intc.c sh4/intc.h sh4/sh4mem.c sh4/timer.c \2.30 - sh4/dmac.c sh4/mmu.c sh4/sh4core.c sh4/sh4core.h sh4/sh4dasm.c \2.31 - sh4/sh4dasm.h sh4/sh4mmio.c sh4/sh4mmio.h sh4/scif.c \2.32 - sh4/sh4stat.c sh4/sh4stat.h xlat/xltcache.c xlat/xltcache.h \2.33 - sh4/sh4.h sh4/dmac.h sh4/pmm.c sh4/cache.c sh4/mmu.h \2.34 - aica/armcore.c aica/armcore.h aica/armdasm.c aica/armdasm.h \2.35 - aica/armmem.c aica/aica.c aica/aica.h aica/audio.c \2.36 - aica/audio.h pvr2/pvr2.c pvr2/pvr2.h pvr2/pvr2mem.c \2.37 - pvr2/pvr2mmio.h pvr2/tacore.c pvr2/rendsort.c pvr2/texcache.c \2.38 - pvr2/yuv.c pvr2/rendsave.c pvr2/scene.c pvr2/scene.h \2.39 - pvr2/gl_sl.c pvr2/gl_slsrc.c pvr2/glutil.c pvr2/glutil.h \2.40 - pvr2/glrender.c pvr2/vertex.glsl pvr2/fragment.glsl \2.41 - maple/maple.c maple/maple.h maple/controller.c maple/kbd.c \2.42 - maple/mouse.c maple/lightgun.c loader.c loader.h elf.h \2.43 - bootstrap.c bootstrap.h util.c gdlist.c gdlist.h display.c \2.44 - display.h dckeysyms.h drivers/audio_null.c \2.45 - drivers/video_null.c drivers/video_gl.c drivers/video_gl.h \2.46 - drivers/gl_fbo.c sh4/sh4.def sh4/sh4core.in sh4/sh4x86.in \2.47 - sh4/sh4dasm.in sh4/sh4stat.in sh4/sh4x86.c xlat/x86/x86op.h \2.48 - xlat/x86/ia32abi.h xlat/x86/amd64abi.h sh4/sh4trans.c \2.49 - sh4/sh4trans.h sh4/mmux86.c x86dasm/x86dasm.c \2.50 + syscall.c syscall.h bios.c dcload.c gdbserver.c netutil.c \2.51 + netutil.h gdrom/ide.c gdrom/ide.h gdrom/packet.h \2.52 + gdrom/gdimage.c gdrom/gdrom.c gdrom/gdrom.h gdrom/nrg.c \2.53 + gdrom/cdi.c gdrom/gdi.c gdrom/edc_ecc.c gdrom/ecc.h \2.54 + gdrom/edc_crctable.h gdrom/edc_encoder.h gdrom/edc_l2sq.h \2.55 + gdrom/edc_scramble.h gdrom/mmc.c gdrom/gddriver.h dreamcast.c \2.56 + dreamcast.h eventq.c eventq.h sh4/sh4.c sh4/intc.c sh4/intc.h \2.57 + sh4/sh4mem.c sh4/timer.c sh4/dmac.c sh4/mmu.c sh4/sh4core.c \2.58 + sh4/sh4core.h sh4/sh4dasm.c sh4/sh4dasm.h sh4/sh4mmio.c \2.59 + sh4/sh4mmio.h sh4/scif.c sh4/sh4stat.c sh4/sh4stat.h \2.60 + xlat/xltcache.c xlat/xltcache.h sh4/sh4.h sh4/dmac.h sh4/pmm.c \2.61 + sh4/cache.c sh4/mmu.h aica/armcore.c aica/armcore.h \2.62 + aica/armdasm.c aica/armdasm.h aica/armmem.c aica/aica.c \2.63 + aica/aica.h aica/audio.c aica/audio.h pvr2/pvr2.c pvr2/pvr2.h \2.64 + pvr2/pvr2mem.c pvr2/pvr2mmio.h pvr2/tacore.c pvr2/rendsort.c \2.65 + pvr2/texcache.c pvr2/yuv.c pvr2/rendsave.c pvr2/scene.c \2.66 + pvr2/scene.h pvr2/gl_sl.c pvr2/gl_slsrc.c pvr2/glutil.c \2.67 + pvr2/glutil.h pvr2/glrender.c pvr2/vertex.glsl \2.68 + pvr2/fragment.glsl maple/maple.c maple/maple.h \2.69 + maple/controller.c maple/kbd.c maple/mouse.c maple/lightgun.c \2.70 + loader.c loader.h elf.h bootstrap.c bootstrap.h util.c \2.71 + gdlist.c gdlist.h display.c display.h dckeysyms.h \2.72 + drivers/audio_null.c drivers/video_null.c drivers/video_gl.c \2.73 + drivers/video_gl.h drivers/gl_fbo.c sh4/sh4.def sh4/sh4core.in \2.74 + sh4/sh4x86.in sh4/sh4dasm.in sh4/sh4stat.in sh4/sh4x86.c \2.75 + xlat/x86/x86op.h xlat/x86/ia32abi.h xlat/x86/amd64abi.h \2.76 + sh4/sh4trans.c sh4/sh4trans.h sh4/mmux86.c x86dasm/x86dasm.c \2.77 x86dasm/x86dasm.h x86dasm/i386-dis.c x86dasm/dis-init.c \2.78 x86dasm/dis-buf.c x86dasm/ansidecl.h x86dasm/bfd.h \2.79 x86dasm/dis-asm.h x86dasm/symcat.h x86dasm/sysdep.h \2.80 gtkui/gtkui.c gtkui/gtkui.h gtkui/gtk_win.c gtkui/gtkcb.c \2.81 gtkui/gtk_mmio.c gtkui/gtk_debug.c gtkui/gtk_dump.c \2.82 gtkui/gtk_ctrl.c gtkui/gtk_path.c gtkui/gtk_gd.c \2.83 - drivers/video_gtk.c cocoaui/cocoaui.m cocoaui/cocoaui.h \2.84 - cocoaui/cocoa_win.m cocoaui/cocoa_gd.m cocoaui/cocoa_prefs.m \2.85 - cocoaui/cocoa_path.m cocoaui/cocoa_ctrl.m cocoaui/paths_osx.m \2.86 + drivers/net_glib.c drivers/video_gtk.c cocoaui/cocoaui.m \2.87 + cocoaui/cocoaui.h cocoaui/cocoa_win.m cocoaui/cocoa_gd.m \2.88 + cocoaui/cocoa_prefs.m cocoaui/cocoa_path.m \2.89 + cocoaui/cocoa_ctrl.m cocoaui/paths_osx.m drivers/net_osx.m \2.90 drivers/video_osx.m drivers/mac_keymap.h \2.91 drivers/mac_keymap.txt paths_unix.c drivers/video_gdk.c \2.92 drivers/video_glx.c drivers/video_glx.h drivers/video_nsgl.m \2.93 @@ -149,11 +151,13 @@2.94 @GUI_GTK_TRUE@ gtkcb.$(OBJEXT) gtk_mmio.$(OBJEXT) \2.95 @GUI_GTK_TRUE@ gtk_debug.$(OBJEXT) gtk_dump.$(OBJEXT) \2.96 @GUI_GTK_TRUE@ gtk_ctrl.$(OBJEXT) gtk_path.$(OBJEXT) \2.97 -@GUI_GTK_TRUE@ gtk_gd.$(OBJEXT) video_gtk.$(OBJEXT)2.98 +@GUI_GTK_TRUE@ gtk_gd.$(OBJEXT) net_glib.$(OBJEXT) \2.99 +@GUI_GTK_TRUE@ video_gtk.$(OBJEXT)2.100 @GUI_COCOA_TRUE@am__objects_3 = cocoaui.$(OBJEXT) cocoa_win.$(OBJEXT) \2.101 @GUI_COCOA_TRUE@ cocoa_gd.$(OBJEXT) cocoa_prefs.$(OBJEXT) \2.102 @GUI_COCOA_TRUE@ cocoa_path.$(OBJEXT) cocoa_ctrl.$(OBJEXT) \2.103 -@GUI_COCOA_TRUE@ paths_osx.$(OBJEXT) video_osx.$(OBJEXT)2.104 +@GUI_COCOA_TRUE@ paths_osx.$(OBJEXT) net_osx.$(OBJEXT) \2.105 +@GUI_COCOA_TRUE@ video_osx.$(OBJEXT)2.106 @GUI_COCOA_FALSE@am__objects_4 = paths_unix.$(OBJEXT)2.107 @VIDEO_OSMESA_TRUE@am__objects_5 = video_gdk.$(OBJEXT)2.108 @VIDEO_GLX_TRUE@am__objects_6 = video_glx.$(OBJEXT)2.109 @@ -170,8 +174,9 @@2.110 am_lxdream_OBJECTS = main.$(OBJEXT) version.$(OBJEXT) config.$(OBJEXT) \2.111 mem.$(OBJEXT) sdram.$(OBJEXT) watch.$(OBJEXT) asic.$(OBJEXT) \2.112 syscall.$(OBJEXT) bios.$(OBJEXT) dcload.$(OBJEXT) \2.113 - ide.$(OBJEXT) gdimage.$(OBJEXT) gdrom.$(OBJEXT) nrg.$(OBJEXT) \2.114 - cdi.$(OBJEXT) gdi.$(OBJEXT) edc_ecc.$(OBJEXT) mmc.$(OBJEXT) \2.115 + gdbserver.$(OBJEXT) netutil.$(OBJEXT) ide.$(OBJEXT) \2.116 + gdimage.$(OBJEXT) gdrom.$(OBJEXT) nrg.$(OBJEXT) cdi.$(OBJEXT) \2.117 + gdi.$(OBJEXT) edc_ecc.$(OBJEXT) mmc.$(OBJEXT) \2.118 dreamcast.$(OBJEXT) eventq.$(OBJEXT) sh4.$(OBJEXT) \2.119 intc.$(OBJEXT) sh4mem.$(OBJEXT) timer.$(OBJEXT) dmac.$(OBJEXT) \2.120 mmu.$(OBJEXT) sh4core.$(OBJEXT) sh4dasm.$(OBJEXT) \2.121 @@ -407,6 +412,7 @@2.122 INCLUDES = \2.123 -DPACKAGE_DATA_DIR=\""$(datadir)"\" \2.124 -DPACKAGE_LOCALE_DIR=\""$(prefix)/$(DATADIRNAME)/locale"\" \2.125 + -DPACKAGE_PLUGIN_DIR=\""$(pkglibdir)"\" \2.126 -DPACKAGE_CONF_DIR=\""$(sysconfdir)"\" \2.127 -Ish4 \2.128 @GLIB_CFLAGS@ @GTK_CFLAGS@ @LIBPNG_CFLAGS@ @PULSE_CFLAGS@ @ESOUND_CFLAGS@ @ALSA_CFLAGS@ @SDL_CFLAGS@2.129 @@ -428,19 +434,20 @@2.130 lxdream_SOURCES = main.c version.c config.c config.h lxdream.h dream.h \2.131 gui.h cpu.h hook.h gettext.h mem.c mem.h sdram.c mmio.h \2.132 watch.c asic.c asic.h clock.h serial.h syscall.c syscall.h \2.133 - bios.c dcload.c gdrom/ide.c gdrom/ide.h gdrom/packet.h \2.134 - gdrom/gdimage.c gdrom/gdrom.c gdrom/gdrom.h gdrom/nrg.c \2.135 - gdrom/cdi.c gdrom/gdi.c gdrom/edc_ecc.c gdrom/ecc.h \2.136 - gdrom/edc_crctable.h gdrom/edc_encoder.h gdrom/edc_l2sq.h \2.137 - gdrom/edc_scramble.h gdrom/mmc.c gdrom/gddriver.h dreamcast.c \2.138 - dreamcast.h eventq.c eventq.h sh4/sh4.c sh4/intc.c sh4/intc.h \2.139 - sh4/sh4mem.c sh4/timer.c sh4/dmac.c sh4/mmu.c sh4/sh4core.c \2.140 - sh4/sh4core.h sh4/sh4dasm.c sh4/sh4dasm.h sh4/sh4mmio.c \2.141 - sh4/sh4mmio.h sh4/scif.c sh4/sh4stat.c sh4/sh4stat.h \2.142 - xlat/xltcache.c xlat/xltcache.h sh4/sh4.h sh4/dmac.h sh4/pmm.c \2.143 - sh4/cache.c sh4/mmu.h aica/armcore.c aica/armcore.h \2.144 - aica/armdasm.c aica/armdasm.h aica/armmem.c aica/aica.c \2.145 - aica/aica.h aica/audio.c aica/audio.h pvr2/pvr2.c pvr2/pvr2.h \2.146 + bios.c dcload.c gdbserver.c netutil.c netutil.h gdrom/ide.c \2.147 + gdrom/ide.h gdrom/packet.h gdrom/gdimage.c gdrom/gdrom.c \2.148 + gdrom/gdrom.h gdrom/nrg.c gdrom/cdi.c gdrom/gdi.c \2.149 + gdrom/edc_ecc.c gdrom/ecc.h gdrom/edc_crctable.h \2.150 + gdrom/edc_encoder.h gdrom/edc_l2sq.h gdrom/edc_scramble.h \2.151 + gdrom/mmc.c gdrom/gddriver.h dreamcast.c dreamcast.h eventq.c \2.152 + eventq.h sh4/sh4.c sh4/intc.c sh4/intc.h sh4/sh4mem.c \2.153 + sh4/timer.c sh4/dmac.c sh4/mmu.c sh4/sh4core.c sh4/sh4core.h \2.154 + sh4/sh4dasm.c sh4/sh4dasm.h sh4/sh4mmio.c sh4/sh4mmio.h \2.155 + sh4/scif.c sh4/sh4stat.c sh4/sh4stat.h xlat/xltcache.c \2.156 + xlat/xltcache.h sh4/sh4.h sh4/dmac.h sh4/pmm.c sh4/cache.c \2.157 + sh4/mmu.h aica/armcore.c aica/armcore.h aica/armdasm.c \2.158 + aica/armdasm.h aica/armmem.c aica/aica.c aica/aica.h \2.159 + aica/audio.c aica/audio.h pvr2/pvr2.c pvr2/pvr2.h \2.160 pvr2/pvr2mem.c pvr2/pvr2mmio.h pvr2/tacore.c pvr2/rendsort.c \2.161 pvr2/texcache.c pvr2/yuv.c pvr2/rendsave.c pvr2/scene.c \2.162 pvr2/scene.h pvr2/gl_sl.c pvr2/gl_slsrc.c pvr2/glutil.c \2.163 @@ -592,6 +599,7 @@2.164 @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/dreamcast.Po@am__quote@2.165 @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/edc_ecc.Po@am__quote@2.166 @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/eventq.Po@am__quote@2.167 +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/gdbserver.Po@am__quote@2.168 @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/gdi.Po@am__quote@2.169 @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/gdimage.Po@am__quote@2.170 @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/gdlist.Po@am__quote@2.171 @@ -627,6 +635,9 @@2.172 @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/mmu.Po@am__quote@2.173 @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/mmux86.Po@am__quote@2.174 @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/mouse.Po@am__quote@2.175 +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/net_glib.Po@am__quote@2.176 +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/net_osx.Po@am__quote@2.177 +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/netutil.Po@am__quote@2.178 @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/nrg.Po@am__quote@2.179 @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/osx_iokit.Po@am__quote@2.180 @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/paths_osx.Po@am__quote@2.181 @@ -1633,6 +1644,20 @@2.182 @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@2.183 @am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o gtk_gd.obj `if test -f 'gtkui/gtk_gd.c'; then $(CYGPATH_W) 'gtkui/gtk_gd.c'; else $(CYGPATH_W) '$(srcdir)/gtkui/gtk_gd.c'; fi`2.185 +net_glib.o: drivers/net_glib.c2.186 +@am__fastdepCC_TRUE@ if $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT net_glib.o -MD -MP -MF "$(DEPDIR)/net_glib.Tpo" -c -o net_glib.o `test -f 'drivers/net_glib.c' || echo '$(srcdir)/'`drivers/net_glib.c; \2.187 +@am__fastdepCC_TRUE@ then mv -f "$(DEPDIR)/net_glib.Tpo" "$(DEPDIR)/net_glib.Po"; else rm -f "$(DEPDIR)/net_glib.Tpo"; exit 1; fi2.188 +@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='drivers/net_glib.c' object='net_glib.o' libtool=no @AMDEPBACKSLASH@2.189 +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@2.190 +@am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o net_glib.o `test -f 'drivers/net_glib.c' || echo '$(srcdir)/'`drivers/net_glib.c2.191 +2.192 +net_glib.obj: drivers/net_glib.c2.193 +@am__fastdepCC_TRUE@ if $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT net_glib.obj -MD -MP -MF "$(DEPDIR)/net_glib.Tpo" -c -o net_glib.obj `if test -f 'drivers/net_glib.c'; then $(CYGPATH_W) 'drivers/net_glib.c'; else $(CYGPATH_W) '$(srcdir)/drivers/net_glib.c'; fi`; \2.194 +@am__fastdepCC_TRUE@ then mv -f "$(DEPDIR)/net_glib.Tpo" "$(DEPDIR)/net_glib.Po"; else rm -f "$(DEPDIR)/net_glib.Tpo"; exit 1; fi2.195 +@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='drivers/net_glib.c' object='net_glib.obj' libtool=no @AMDEPBACKSLASH@2.196 +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@2.197 +@am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o net_glib.obj `if test -f 'drivers/net_glib.c'; then $(CYGPATH_W) 'drivers/net_glib.c'; else $(CYGPATH_W) '$(srcdir)/drivers/net_glib.c'; fi`2.198 +2.199 video_gtk.o: drivers/video_gtk.c2.200 @am__fastdepCC_TRUE@ if $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT video_gtk.o -MD -MP -MF "$(DEPDIR)/video_gtk.Tpo" -c -o video_gtk.o `test -f 'drivers/video_gtk.c' || echo '$(srcdir)/'`drivers/video_gtk.c; \2.201 @am__fastdepCC_TRUE@ then mv -f "$(DEPDIR)/video_gtk.Tpo" "$(DEPDIR)/video_gtk.Po"; else rm -f "$(DEPDIR)/video_gtk.Tpo"; exit 1; fi2.202 @@ -1927,6 +1952,20 @@2.203 @AMDEP_TRUE@@am__fastdepOBJC_FALSE@ DEPDIR=$(DEPDIR) $(OBJCDEPMODE) $(depcomp) @AMDEPBACKSLASH@2.204 @am__fastdepOBJC_FALSE@ $(OBJC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_OBJCFLAGS) $(OBJCFLAGS) -c -o paths_osx.obj `if test -f 'cocoaui/paths_osx.m'; then $(CYGPATH_W) 'cocoaui/paths_osx.m'; else $(CYGPATH_W) '$(srcdir)/cocoaui/paths_osx.m'; fi`2.206 +net_osx.o: drivers/net_osx.m2.207 +@am__fastdepOBJC_TRUE@ if $(OBJC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_OBJCFLAGS) $(OBJCFLAGS) -MT net_osx.o -MD -MP -MF "$(DEPDIR)/net_osx.Tpo" -c -o net_osx.o `test -f 'drivers/net_osx.m' || echo '$(srcdir)/'`drivers/net_osx.m; \2.208 +@am__fastdepOBJC_TRUE@ then mv -f "$(DEPDIR)/net_osx.Tpo" "$(DEPDIR)/net_osx.Po"; else rm -f "$(DEPDIR)/net_osx.Tpo"; exit 1; fi2.209 +@AMDEP_TRUE@@am__fastdepOBJC_FALSE@ source='drivers/net_osx.m' object='net_osx.o' libtool=no @AMDEPBACKSLASH@2.210 +@AMDEP_TRUE@@am__fastdepOBJC_FALSE@ DEPDIR=$(DEPDIR) $(OBJCDEPMODE) $(depcomp) @AMDEPBACKSLASH@2.211 +@am__fastdepOBJC_FALSE@ $(OBJC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_OBJCFLAGS) $(OBJCFLAGS) -c -o net_osx.o `test -f 'drivers/net_osx.m' || echo '$(srcdir)/'`drivers/net_osx.m2.212 +2.213 +net_osx.obj: drivers/net_osx.m2.214 +@am__fastdepOBJC_TRUE@ if $(OBJC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_OBJCFLAGS) $(OBJCFLAGS) -MT net_osx.obj -MD -MP -MF "$(DEPDIR)/net_osx.Tpo" -c -o net_osx.obj `if test -f 'drivers/net_osx.m'; then $(CYGPATH_W) 'drivers/net_osx.m'; else $(CYGPATH_W) '$(srcdir)/drivers/net_osx.m'; fi`; \2.215 +@am__fastdepOBJC_TRUE@ then mv -f "$(DEPDIR)/net_osx.Tpo" "$(DEPDIR)/net_osx.Po"; else rm -f "$(DEPDIR)/net_osx.Tpo"; exit 1; fi2.216 +@AMDEP_TRUE@@am__fastdepOBJC_FALSE@ source='drivers/net_osx.m' object='net_osx.obj' libtool=no @AMDEPBACKSLASH@2.217 +@AMDEP_TRUE@@am__fastdepOBJC_FALSE@ DEPDIR=$(DEPDIR) $(OBJCDEPMODE) $(depcomp) @AMDEPBACKSLASH@2.218 +@am__fastdepOBJC_FALSE@ $(OBJC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_OBJCFLAGS) $(OBJCFLAGS) -c -o net_osx.obj `if test -f 'drivers/net_osx.m'; then $(CYGPATH_W) 'drivers/net_osx.m'; else $(CYGPATH_W) '$(srcdir)/drivers/net_osx.m'; fi`2.219 +2.220 video_osx.o: drivers/video_osx.m2.221 @am__fastdepOBJC_TRUE@ if $(OBJC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_OBJCFLAGS) $(OBJCFLAGS) -MT video_osx.o -MD -MP -MF "$(DEPDIR)/video_osx.Tpo" -c -o video_osx.o `test -f 'drivers/video_osx.m' || echo '$(srcdir)/'`drivers/video_osx.m; \2.222 @am__fastdepOBJC_TRUE@ then mv -f "$(DEPDIR)/video_osx.Tpo" "$(DEPDIR)/video_osx.Po"; else rm -f "$(DEPDIR)/video_osx.Tpo"; exit 1; fi
3.1 --- a/src/aica/armcore.h Tue Mar 24 11:04:51 2009 +00003.2 +++ b/src/aica/armcore.h Tue Mar 24 11:15:57 2009 +00003.3 @@ -109,6 +109,8 @@3.4 void arm_write_byte_user( uint32_t addr, uint32_t val );3.5 int32_t arm_read_phys_word( uint32_t addr );3.6 int arm_has_page( uint32_t addr );3.7 +size_t arm_read_phys( unsigned char *buf, uint32_t addr, size_t len );3.8 +size_t arm_write_phys( uint32_t addr, unsigned char *buf, size_t len );3.10 #ifdef __cplusplus3.11 }
4.1 --- a/src/aica/armdasm.c Tue Mar 24 11:04:51 2009 +00004.2 +++ b/src/aica/armdasm.c Tue Mar 24 11:15:57 2009 +00004.3 @@ -57,19 +57,40 @@4.4 {"R10",REG_INT, &armr.r[10]}, {"R11",REG_INT, &armr.r[11]},4.5 {"R12",REG_INT, &armr.r[12]}, {"R13",REG_INT, &armr.r[13]},4.6 {"R14",REG_INT, &armr.r[14]}, {"R15",REG_INT, &armr.r[15]},4.7 +4.8 + /* Block of FPA registers (arm-elf-gdb seems to expect these).4.9 + * Oddly enough the ARM7TDMI doesn't have them */4.10 + {"F0",REG_NONE, NULL}, {"F1",REG_NONE, NULL},4.11 + {"F2",REG_NONE, NULL}, {"F3",REG_NONE, NULL},4.12 + {"F4",REG_NONE, NULL}, {"F5",REG_NONE, NULL},4.13 + {"F6",REG_NONE, NULL}, {"F7",REG_NONE, NULL},4.14 + {"FPS",REG_NONE, NULL},4.15 +4.16 + /* System registers */4.17 {"CPSR", REG_INT, &armr.cpsr}, {"SPSR", REG_INT, &armr.spsr},4.18 {NULL, 0, NULL} };4.20 +/* Implementation of get_register - ARM has no pseudo registers so this4.21 + * is pretty simple4.22 + */4.23 +void *arm_get_register( int reg )4.24 +{4.25 + if( reg < 0 || reg >= 27 )4.26 + return NULL;4.27 + return arm_reg_map[reg].value;4.28 +}4.30 const struct cpu_desc_struct arm_cpu_desc =4.31 -{ "ARM7", arm_disasm_instruction, arm_execute_instruction, arm_has_page,4.32 - arm_set_breakpoint, arm_clear_breakpoint, arm_get_breakpoint, 4,4.33 - (char *)&armr, sizeof(armr), arm_reg_map,4.34 +{ "ARM7", arm_disasm_instruction, arm_get_register, arm_has_page,4.35 + arm_read_phys, arm_write_phys, arm_read_phys, arm_write_phys,4.36 + arm_execute_instruction, arm_set_breakpoint, arm_clear_breakpoint,4.37 + arm_get_breakpoint, 4, (char *)&armr, sizeof(armr), arm_reg_map, 26, 26,4.38 &armr.r[15] };4.39 const struct cpu_desc_struct armt_cpu_desc =4.40 -{ "ARM7T", armt_disasm_instruction, arm_execute_instruction, arm_has_page,4.41 - arm_set_breakpoint, arm_clear_breakpoint, arm_get_breakpoint, 2,4.42 - (char*)&armr, sizeof(armr), arm_reg_map,4.43 +{ "ARM7T", armt_disasm_instruction, arm_get_register, arm_has_page,4.44 + arm_read_phys, arm_write_phys, arm_read_phys, arm_write_phys,4.45 + arm_execute_instruction, arm_set_breakpoint, arm_clear_breakpoint,4.46 + arm_get_breakpoint, 2, (char*)&armr, sizeof(armr), arm_reg_map, 26, 26,4.47 &armr.r[15] };
5.1 --- a/src/aica/armmem.c Tue Mar 24 11:04:51 2009 +00005.2 +++ b/src/aica/armmem.c Tue Mar 24 11:15:57 2009 +00005.3 @@ -264,3 +264,27 @@5.4 {5.5 arm_write_byte( addr, val );5.6 }5.7 +5.8 +size_t arm_read_phys( unsigned char *buf, uint32_t addr, size_t length ) {5.9 + if( addr < sizeof(aica_main_ram) ) {5.10 + if( addr+length > sizeof(aica_main_ram) ) {5.11 + length = sizeof(aica_main_ram) - addr;5.12 + }5.13 + memcpy( buf, &aica_main_ram[addr], length );5.14 + return length;5.15 + } else {5.16 + return 0;5.17 + }5.18 +}5.19 +5.20 +size_t arm_write_phys( uint32_t addr, unsigned char *buf, size_t length ) {5.21 + if( addr < sizeof(aica_main_ram) ) {5.22 + if( addr+length > sizeof(aica_main_ram) ) {5.23 + length = sizeof(aica_main_ram) - addr;5.24 + }5.25 + memcpy( &aica_main_ram[addr], buf, length );5.26 + return length;5.27 + } else {5.28 + return 0;5.29 + }5.30 +}5.31 \ No newline at end of file
6.1 --- a/src/cpu.h Tue Mar 24 11:04:51 2009 +00006.2 +++ b/src/cpu.h Tue Mar 24 11:15:57 2009 +00006.3 @@ -37,8 +37,9 @@6.4 typedef uint32_t (*disasm_func_t)(uint32_t pc, char *buffer, int buflen, char *opcode );6.6 #define REG_INT 06.7 -#define REG_FLT 16.8 -#define REG_SPECIAL 26.9 +#define REG_FLOAT 16.10 +#define REG_DOUBLE 26.11 +#define REG_NONE 3 /* Used for empty/separator field */6.13 /**6.14 * Structure that defines a single register in a CPU for display purposes.6.15 @@ -50,13 +51,32 @@6.16 } reg_desc_t;6.18 /**6.19 - * CPU definition structure - basic information and support functions.6.20 + * CPU definition structure - basic information and support functions. Most6.21 + * of this is for debugger use.6.22 */6.23 typedef struct cpu_desc_struct {6.24 char *name; /* CPU Name */6.25 - disasm_func_t disasm_func; /* Disassembly function */6.26 + /**6.27 + * Single instruction disassembly6.28 + **/6.29 + disasm_func_t disasm_func;6.30 +6.31 + /**6.32 + * Return a pointer to a register (indexed per the reg_desc table)6.33 + */6.34 + void * (*get_register)( int reg );6.35 + gboolean (*is_valid_page_func)(uint32_t); /* Test for valid memory page */6.36 + /* Access to memory addressed by the CPU - physical and virtual versions.6.37 + * Virtual access should account for the current CPU mode, privilege level,6.38 + * etc.6.39 + * All functions return the number of bytes copied, which may be 0 if the6.40 + * address is unmapped.6.41 + */6.42 + size_t (*read_mem_phys)(unsigned char *buf, uint32_t addr, size_t length);6.43 + size_t (*write_mem_phys)(uint32_t addr, unsigned char *buf, size_t length);6.44 + size_t (*read_mem_vma)(unsigned char *buf, uint32_t addr, size_t length);6.45 + size_t (*write_mem_vma)(uint32_t addr, unsigned char *buf, size_t length);6.46 gboolean (*step_func)(); /* Single step function */6.47 - int (*is_valid_page_func)(uint32_t); /* Test for valid memory page */6.48 void (*set_breakpoint)(uint32_t, breakpoint_type_t);6.49 gboolean (*clear_breakpoint)(uint32_t, breakpoint_type_t);6.50 int (*get_breakpoint)(uint32_t);6.51 @@ -64,6 +84,8 @@6.52 char *regs; /* Pointer to start of registers */6.53 size_t regs_size; /* Size of register structure in bytes */6.54 const struct reg_desc_struct *regs_info; /* Description of all registers */6.55 + unsigned int num_gpr_regs; /* Number of general purpose registers */6.56 + unsigned int num_gdb_regs; /* Total number of registers visible to gdb */6.57 uint32_t *pc; /* Pointer to PC register */6.58 } const *cpu_desc_t;6.60 @@ -71,4 +93,6 @@6.61 }6.62 #endif6.64 +gboolean gdb_init_server( const char *interface, int port, cpu_desc_t cpu, gboolean mmu );6.65 +6.66 #endif /* !lxdream_cpu_H */
7.1 --- /dev/null Thu Jan 01 00:00:00 1970 +00007.2 +++ b/src/drivers/net_glib.c Tue Mar 24 11:15:57 2009 +00007.3 @@ -0,0 +1,72 @@7.4 +/**7.5 + * $Id: net_glib.c 1018 2009-03-19 12:29:06Z nkeynes $7.6 + *7.7 + * Glib-based networking support functions. Currently this is just for activity callbacks.7.8 + *7.9 + * Copyright (c) 2009 Nathan Keynes.7.10 + *7.11 + * This program is free software; you can redistribute it and/or modify7.12 + * it under the terms of the GNU General Public License as published by7.13 + * the Free Software Foundation; either version 2 of the License, or7.14 + * (at your option) any later version.7.15 + *7.16 + * This program is distributed in the hope that it will be useful,7.17 + * but WITHOUT ANY WARRANTY; without even the implied warranty of7.18 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the7.19 + * GNU General Public License for more details.7.20 + */7.21 +7.22 +#include <assert.h>7.23 +#include <glib.h>7.24 +#include <stdlib.h>7.25 +#include "netutil.h"7.26 +7.27 +struct net_glib_cbinfo {7.28 + net_callback_t callback;7.29 + void * cbdata;7.30 + void (*cbdealloc)(void *);7.31 +};7.32 +7.33 +static gboolean net_glib_callback( GIOChannel *source, GIOCondition cond, gpointer data )7.34 +{7.35 + struct net_glib_cbinfo *cbinfo = (struct net_glib_cbinfo *)data;7.36 + return cbinfo->callback( g_io_channel_unix_get_fd(source), cbinfo->cbdata);7.37 +}7.38 +7.39 +static void net_glib_release( void *data )7.40 +{7.41 + struct net_glib_cbinfo *cbinfo = (struct net_glib_cbinfo *)data;7.42 + if( cbinfo->cbdealloc ) {7.43 + cbinfo->cbdealloc( cbinfo->cbdata );7.44 + }7.45 + free(cbinfo);7.46 +}7.47 +7.48 +/**7.49 + * Register a TCP server socket listener on an already open (and listening)7.50 + * socket. The socket must not have been previously registered.7.51 + * @return TRUE on success, FALSE on failure.7.52 + *7.53 + * Defined in netutil.h7.54 + */7.55 +gboolean net_register_tcp_listener( int fd, net_callback_t callback, void *data, void (*dealloc)(void*) )7.56 +{7.57 + struct net_glib_cbinfo *cbinfo = malloc( sizeof(struct net_glib_cbinfo) );7.58 + assert(cbinfo != NULL);7.59 +7.60 + cbinfo->callback = callback;7.61 + cbinfo->cbdata = data;7.62 + cbinfo->cbdealloc = dealloc;7.63 +7.64 + /**7.65 + * Note magic here: the watch creates an event source which holds a7.66 + * reference to the channel. We unref the channel so that the channel then7.67 + * is automatically released when the event source goes away.7.68 + */7.69 + GIOChannel *chan = g_io_channel_unix_new(fd);7.70 + g_io_channel_set_encoding( chan, NULL, NULL );7.71 + g_io_channel_set_buffered(chan, FALSE);7.72 + g_io_add_watch_full( chan, 0, G_IO_IN, net_glib_callback, cbinfo, net_glib_release );7.73 + g_io_channel_unref( chan );7.74 + return TRUE;7.75 +}
8.1 --- /dev/null Thu Jan 01 00:00:00 1970 +00008.2 +++ b/src/drivers/net_osx.m Tue Mar 24 11:15:57 2009 +00008.3 @@ -0,0 +1,76 @@8.4 +/**8.5 + * $Id: net_osx.m 1018 2009-03-19 12:29:06Z nkeynes $8.6 + *8.7 + * OS X networking support functions. Currently this is just for activity callbacks.8.8 + *8.9 + * Copyright (c) 2009 Nathan Keynes.8.10 + *8.11 + * This program is free software; you can redistribute it and/or modify8.12 + * it under the terms of the GNU General Public License as published by8.13 + * the Free Software Foundation; either version 2 of the License, or8.14 + * (at your option) any later version.8.15 + *8.16 + * This program is distributed in the hope that it will be useful,8.17 + * but WITHOUT ANY WARRANTY; without even the implied warranty of8.18 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the8.19 + * GNU General Public License for more details.8.20 + */8.21 +8.22 +#include <CoreFoundation/CoreFoundation.h>8.23 +#include "netutil.h"8.24 +8.25 +struct net_osx_cbinfo {8.26 + net_callback_t callback;8.27 + void * cbdata;8.28 + void (*cbdealloc)(void *);8.29 + CFSocketRef sockRef;8.30 + CFRunLoopSourceRef sourceRef;8.31 +};8.32 +8.33 +static void net_osx_callback( CFSocketRef s, CFSocketCallBackType type, CFDataRef address, const void *unused, void *data )8.34 +{8.35 + struct net_osx_cbinfo *cbinfo = (struct net_osx_cbinfo *)data;8.36 + if(!cbinfo->callback( CFSocketGetNative(s), cbinfo->cbdata) ) {8.37 + CFRunLoopRemoveSource( CFRunLoopGetCurrent(), cbinfo->sourceRef, kCFRunLoopCommonModes );8.38 + CFRelease(cbinfo->sourceRef);8.39 + cbinfo->sourceRef = NULL;8.40 + CFRelease(cbinfo->sockRef);8.41 + }8.42 +}8.43 +8.44 +static void net_osx_release( const void *data )8.45 +{8.46 + struct net_osx_cbinfo *cbinfo = (struct net_osx_cbinfo *)data;8.47 + if( cbinfo->cbdealloc != NULL ) {8.48 + cbinfo->cbdealloc(cbinfo->cbdata);8.49 + }8.50 + free( cbinfo );8.51 +}8.52 +8.53 +/**8.54 + * Register a TCP server socket listener on an already open (and listening)8.55 + * socket. The socket must not have been previously registered.8.56 + * @return TRUE on success, FALSE on failure.8.57 + *8.58 + * Defined in netutil.h8.59 + */8.60 +gboolean net_register_tcp_listener( int fd, net_callback_t callback, void *data, void (*dealloc)(void*) )8.61 +{8.62 + CFSocketContext socketContext;8.63 + struct net_osx_cbinfo *cbinfo = malloc( sizeof(struct net_osx_cbinfo) );8.64 + assert(cbinfo != NULL);8.65 +8.66 + cbinfo->callback = callback;8.67 + cbinfo->cbdata = data;8.68 + cbinfo->cbdealloc = dealloc;8.69 + socketContext.version = 0;8.70 + socketContext.info = cbinfo;8.71 + socketContext.retain = NULL;8.72 + socketContext.release = net_osx_release;8.73 + socketContext.copyDescription = NULL;8.74 +8.75 + cbinfo->sockRef = CFSocketCreateWithNative( kCFAllocatorDefault, fd, kCFSocketReadCallBack,8.76 + net_osx_callback, &socketContext );8.77 + cbinfo->sourceRef = CFSocketCreateRunLoopSource( kCFAllocatorDefault, cbinfo->sockRef, 0 );8.78 + CFRunLoopAddSource( CFRunLoopGetCurrent(), cbinfo->sourceRef, kCFRunLoopCommonModes );8.79 +}
9.1 --- /dev/null Thu Jan 01 00:00:00 1970 +00009.2 +++ b/src/gdbserver.c Tue Mar 24 11:15:57 2009 +00009.3 @@ -0,0 +1,523 @@9.4 +/**9.5 + * $Id: gdbserver.c 1018 2009-03-19 12:29:06Z nkeynes $9.6 + *9.7 + * GDB RDP server stub - SH4 + ARM9.8 + *9.9 + * Copyright (c) 2009 Nathan Keynes.9.10 + *9.11 + * This program is free software; you can redistribute it and/or modify9.12 + * it under the terms of the GNU General Public License as published by9.13 + * the Free Software Foundation; either version 2 of the License, or9.14 + * (at your option) any later version.9.15 + *9.16 + * This program is distributed in the hope that it will be useful,9.17 + * but WITHOUT ANY WARRANTY; without even the implied warranty of9.18 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the9.19 + * GNU General Public License for more details.9.20 + */9.21 +9.22 +9.23 +#include <errno.h>9.24 +#include <stdio.h>9.25 +#include <stdlib.h>9.26 +#include <stdarg.h>9.27 +#include <string.h>9.28 +#include <unistd.h>9.29 +#include <glib.h>9.30 +#include <arpa/inet.h>9.31 +#include "lxdream.h"9.32 +#include "dreamcast.h"9.33 +#include "netutil.h"9.34 +#include "cpu.h"9.35 +9.36 +#define DEFAULT_BUFFER_SIZE 10249.37 +#define BUFFER_SIZE_MARGIN 329.38 +#define MAX_BUFFER_SIZE 655369.39 +9.40 +/* These are just local interpretations - they're not interpreted by GDB9.41 + * in any way shape or form.9.42 + */9.43 +#define GDB_ERROR_FORMAT 1 /* Badly formatted command */9.44 +#define GDB_ERROR_INVAL 2 /* Invalid data */9.45 +#define GDB_ERROR_FAIL 3 /* Command failed */9.46 +struct gdb_server {9.47 + cpu_desc_t cpu;9.48 + gboolean mmu;9.49 + int fd;9.50 + const gchar *peer_name;9.51 + char *buf;9.52 + int buf_size;9.53 + int buf_posn;9.54 +};9.55 +9.56 +void gdb_server_free( gpointer data )9.57 +{9.58 + struct gdb_server *server = (struct gdb_server *)data;9.59 + free((char *)server->peer_name);9.60 + free(server->buf);9.61 + free(data);9.62 +}9.63 +9.64 +int gdb_checksum( char *data, int length )9.65 +{9.66 + int i;9.67 + int result = 0;9.68 + for( i=0; i<length; i++ )9.69 + result += data[i];9.70 + result &= 0xFF;9.71 + return result;9.72 +}9.73 +9.74 +void gdb_send_frame( struct gdb_server *server, char *data, int length )9.75 +{9.76 + char out[length+5];9.77 + snprintf( out, length+5, "$%.*s#%02x", length, data, gdb_checksum(data,length) );9.78 + write( server->fd, out, length+4 );9.79 +}9.80 +9.81 +/**9.82 + * Send bulk data (ie memory dump) as hex, with optional string prefix.9.83 + * Saves double copying when going through gdb_send_frame.9.84 + */9.85 +void gdb_send_hex_data( struct gdb_server *server, char *prefix, unsigned char *data, int datalen )9.86 +{9.87 + int prefixlen = 0;9.88 + if( prefix != NULL )9.89 + prefixlen = strlen(prefix);9.90 + int totallen = datalen*2 + prefixlen + 4;9.91 + char out[totallen+1];9.92 + char *p = &out[1];9.93 + int i;9.94 +9.95 + out[0] = '$';9.96 + if( prefix != NULL ) {9.97 + p += sprintf( p, "%s", prefix );9.98 + }9.99 + for( i=0; i<datalen; i++ ) {9.100 + p += sprintf( p, "%02x", data[i] );9.101 + }9.102 + *p++ = '#';9.103 + sprintf( p, "%02x", gdb_checksum(out+1, datalen*2 + prefixlen) );9.104 + write( server->fd, out, totallen );9.105 +}9.106 +9.107 +/**9.108 + * Parse bulk hex data - buffer should be at least datalen/2 bytes long9.109 + */9.110 +size_t gdb_read_hex_data( struct gdb_server *server, unsigned char *buf, unsigned char *data, int datalen )9.111 +{9.112 + char *p = data;9.113 + for( int i=0; i<datalen/2; i++ ) {9.114 + int v;9.115 + sscanf( p, "%02x", &v );9.116 + buf[i] = v;9.117 + p += 2;9.118 + }9.119 + return datalen/2;9.120 +}9.121 +9.122 +/**9.123 + * Parse bulk binary-encoded data - $, #, 0x7D are encoded as 0x7d, char ^ 0x20.9.124 + * Buffer should be at least datalen bytes longs.9.125 + */9.126 +size_t gdb_read_binary_data( struct gdb_server *server, unsigned char *buf, unsigned char *data, int datalen )9.127 +{9.128 + unsigned char *q = buf;9.129 + for( int i=0, j=0; i<datalen; i++ ) {9.130 + if( data[i] == 0x7D ) {9.131 + if( i == datalen-1 ) {9.132 + return -1;9.133 + } else {9.134 + *q++ = data[++i] ^ 0x20;9.135 + }9.136 + } else {9.137 + *q++ = data[i];9.138 + }9.139 + }9.140 + return q - buf;9.141 +}9.142 +9.143 +void gdb_printf_frame( struct gdb_server *server, char *msg, ... )9.144 +{9.145 + va_list va;9.146 +9.147 + va_start(va,msg);9.148 + int len = vsnprintf( NULL, 0, msg, va );9.149 + char buf[len+1];9.150 + vsnprintf( buf, len+1, msg, va);9.151 + va_end(va);9.152 + gdb_send_frame( server, buf, len );9.153 +}9.154 +9.155 +int gdb_print_registers( struct gdb_server *server, char *buf, int buflen, int firstreg, int regcount )9.156 +{9.157 + int i;9.158 + char *p = buf;9.159 + char *endp = buf + (buflen-8);9.160 + for( i=firstreg; i < firstreg + regcount && p < endp; i++ ) {9.161 + uint8_t *val = server->cpu->get_register(i);9.162 + if( val == NULL ) {9.163 + sprintf( p, "00000000" );9.164 + } else {9.165 + sprintf( p, "%02x%02x%02x%02x", val[0], val[1], val[2], val[3] );9.166 + }9.167 + p += 8;9.168 + }9.169 +9.170 + return i - firstreg;9.171 +}9.172 +9.173 +void gdb_set_registers( struct gdb_server *server, char *buf, int firstreg, int regcount )9.174 +{9.175 + int i;9.176 + char *p = buf;9.177 + for( i=firstreg; i < firstreg + regcount; i++ ) {9.178 + uint8_t *val = server->cpu->get_register(i);9.179 + if( val != NULL ) {9.180 + sscanf( p, "%02x%02x%02x%02x", val, val+1, val+2, val+3 );9.181 + }9.182 + p += 8;9.183 + }9.184 +}9.185 +9.186 +/**9.187 + * Send a 2-digit error code. There's no actual definition for any of the codes9.188 + * so they're more for our own amusement really.9.189 + */9.190 +void gdb_send_error( struct gdb_server *server, int error )9.191 +{9.192 + char out[4];9.193 + snprintf( out, 4, "E%02X", (error&0xFF) );9.194 + gdb_send_frame( server, out, 3 );9.195 +}9.196 +9.197 +void gdb_server_handle_frame( struct gdb_server *server, int command, char *data, int length )9.198 +{9.199 + unsigned int tmp, tmp2, tmp3;9.200 + char buf[512];9.201 +9.202 + switch( command ) {9.203 + case '!': /* Enable extended mode */9.204 + gdb_send_frame( server, "OK", 2 );9.205 + break;9.206 + case '?': /* Get stop reason - always return 5 (TRAP) */9.207 + gdb_send_frame( server, "S05", 3 );9.208 + break;9.209 + case 'c': /* Continue */9.210 + dreamcast_run();9.211 + gdb_send_frame( server, "S05", 3 );9.212 + break;9.213 + case 'g': /* Read all general registers */9.214 + gdb_print_registers( server, buf, sizeof(buf), 0, server->cpu->num_gpr_regs );9.215 + gdb_send_frame( server, buf, strlen(buf) );9.216 + break;9.217 + case 'G': /* Write all general registers */9.218 + if( length != server->cpu->num_gpr_regs*8 ) {9.219 + gdb_send_error( server, GDB_ERROR_FORMAT );9.220 + } else {9.221 + gdb_set_registers( server, data, 0, server->cpu->num_gpr_regs );9.222 + gdb_send_frame( server, "OK", 2 );9.223 + }9.224 + break;9.225 + case 'H': /* Set thread - only thread 1 is supported here */9.226 + if( length < 2 ) {9.227 + gdb_send_error( server, GDB_ERROR_FORMAT );9.228 + } else {9.229 + int thread;9.230 + sscanf( data+1, "%d", &thread );9.231 + if( thread >= -1 && thread <= 1 ) {9.232 + gdb_send_frame( server, "OK", 2 );9.233 + } else {9.234 + gdb_send_error( server, GDB_ERROR_INVAL );9.235 + }9.236 + }9.237 + break;9.238 + case 'k': /* kill - do nothing */9.239 + gdb_send_frame( server, "", 0 );9.240 + break;9.241 + case 'm': /* Read memory */9.242 + if( sscanf( data, "%x,%x", &tmp, &tmp2 ) != 2 ) {9.243 + gdb_send_error( server, GDB_ERROR_FORMAT );9.244 + } else {9.245 + size_t datalen;9.246 + char mem[tmp2];9.247 + if( server->mmu ) {9.248 + datalen = server->cpu->read_mem_vma(mem, tmp, tmp2);9.249 + } else {9.250 + datalen = server->cpu->read_mem_phys(mem, tmp, tmp2);9.251 + }9.252 + if( datalen == 0 ) {9.253 + gdb_send_error( server, GDB_ERROR_INVAL );9.254 + } else {9.255 + gdb_send_hex_data( server, NULL, mem, datalen );9.256 + }9.257 + }9.258 + break;9.259 + case 'M': /* Write memory */9.260 + if( sscanf( data, "%x,%x:%n", &tmp, &tmp2, &tmp3 ) != 2 ||9.261 + length-tmp3 != tmp2*2 ) {9.262 + gdb_send_error( server, GDB_ERROR_FORMAT );9.263 + } else {9.264 + size_t len;9.265 + char mem[tmp2];9.266 + len = gdb_read_hex_data( server, mem, data+tmp3, length-tmp3 );9.267 + if( len != tmp2 ) {9.268 + gdb_send_error( server, GDB_ERROR_FORMAT );9.269 + } else {9.270 + if( server->mmu ) {9.271 + len = server->cpu->write_mem_vma(tmp, mem, tmp2);9.272 + } else {9.273 + len = server->cpu->write_mem_phys(tmp, mem, tmp2);9.274 + }9.275 + if( len != tmp2 ) {9.276 + gdb_send_error( server, GDB_ERROR_INVAL );9.277 + } else {9.278 + gdb_send_frame( server, "OK", 2 );9.279 + }9.280 + }9.281 + }9.282 + break;9.283 + case 'p': /* Read single register */9.284 + if( sscanf( data, "%x", &tmp ) != 1 ) {9.285 + gdb_send_error( server, GDB_ERROR_FORMAT );9.286 + } else if( tmp >= server->cpu->num_gdb_regs ) {9.287 + gdb_send_error( server, GDB_ERROR_INVAL );9.288 + } else {9.289 + gdb_print_registers( server, buf, sizeof(buf), tmp, 1 );9.290 + gdb_send_frame( server, buf, 8 );9.291 + }9.292 + break;9.293 + case 'P': /* Write single register. */9.294 + if( sscanf( data, "%x=%n", &tmp, &tmp2 ) != 1 ||9.295 + length-tmp2 != 8) {9.296 + gdb_send_error( server, GDB_ERROR_FORMAT );9.297 + } else if( tmp >= server->cpu->num_gdb_regs ) {9.298 + gdb_send_error( server, GDB_ERROR_INVAL );9.299 + } else {9.300 + gdb_set_registers( server, data+tmp2, tmp, 1 );9.301 + gdb_send_frame( server, "OK", 2 );9.302 + }9.303 + break;9.304 + case 'q': /* Query data */9.305 + if( strcmp( data, "C" ) == 0 ) {9.306 + gdb_send_frame( server, "QC1", 3 );9.307 + } else if( strcmp( data, "fThreadInfo" ) == 0 ) {9.308 + gdb_send_frame( server, "m1", 2 );9.309 + } else if( strcmp( data, "sThreadInfo" ) == 0 ) {9.310 + gdb_send_frame( server, "l", 1 );9.311 + } else if( strncmp( data, "Supported", 9 ) == 0 ) {9.312 + gdb_send_frame( server, "PacketSize=4000", 15 );9.313 + } else if( strcmp( data, "Symbol::" ) == 0 ) {9.314 + gdb_send_frame( server, "OK", 2 );9.315 + } else {9.316 + gdb_send_frame( server, "", 0 );9.317 + }9.318 + break;9.319 + case 's': /* Single-step */9.320 + if( length != 0 ) {9.321 + if( sscanf( data, "%x", &tmp ) != 1 ) {9.322 + gdb_send_error( server, GDB_ERROR_FORMAT );9.323 + } else {9.324 + *server->cpu->pc = tmp;9.325 + }9.326 + }9.327 + server->cpu->step_func();9.328 + gdb_send_frame( server, "S05", 3 );9.329 + break;9.330 + case 'T': /* Thread alive */9.331 + if( sscanf( data, "%x", &tmp ) != 1 ) {9.332 + gdb_send_error( server, GDB_ERROR_FORMAT );9.333 + } else if( tmp != 1 ) {9.334 + gdb_send_error( server, GDB_ERROR_INVAL );9.335 + } else {9.336 + gdb_send_frame( server, "OK", 2 );9.337 + }9.338 + break;9.339 + case 'v': /* Verbose */9.340 + /* Only current one is vCont, which we don't bother supporting9.341 + * at the moment, but don't warn about it either */9.342 + gdb_send_frame( server, "", 0 );9.343 + break;9.344 + case 'X': /* Write memory binary */9.345 + if( sscanf( data, "%x,%x:%n", &tmp, &tmp2, &tmp3 ) != 2 ) {9.346 + gdb_send_error( server, GDB_ERROR_FORMAT );9.347 + } else {9.348 + char mem[length - tmp3];9.349 + size_t len = gdb_read_binary_data( server, mem, data + tmp3, length-tmp3 );9.350 + if( len != tmp2 ) {9.351 + gdb_send_error( server, GDB_ERROR_FORMAT );9.352 + } else {9.353 + if( server->mmu ) {9.354 + len = server->cpu->write_mem_vma(tmp, mem, tmp2);9.355 + } else {9.356 + len = server->cpu->write_mem_phys(tmp, mem, tmp2);9.357 + }9.358 + if( len != tmp2 ) {9.359 + gdb_send_error( server, GDB_ERROR_INVAL );9.360 + } else {9.361 + gdb_send_frame( server, "OK", 2 );9.362 + }9.363 + }9.364 + }9.365 + break;9.366 + case 'z': /* Remove Break/watchpoint */9.367 + if( sscanf( data, "%d,%x,%x", &tmp, &tmp2, &tmp3 ) != 3 ) {9.368 + gdb_send_error( server, GDB_ERROR_FORMAT );9.369 + } else {9.370 + if( tmp == 0 || tmp == 1 ) { /* soft break or hard break */9.371 + server->cpu->clear_breakpoint( tmp2, BREAK_KEEP );9.372 + gdb_send_frame( server, "OK", 2 );9.373 + } else {9.374 + gdb_send_frame( server, "", 0 );9.375 + }9.376 + }9.377 + break;9.378 + case 'Z': /* Insert Break/watchpoint */9.379 + if( sscanf( data, "%d,%x,%x", &tmp, &tmp2, &tmp3 ) != 3 ) {9.380 + gdb_send_error( server, GDB_ERROR_FORMAT );9.381 + } else {9.382 + if( tmp == 0 || tmp == 1 ) { /* soft break or hard break */9.383 + server->cpu->set_breakpoint( tmp2, BREAK_KEEP );9.384 + gdb_send_frame( server, "OK", 2 );9.385 + } else {9.386 + gdb_send_frame( server, "", 0 );9.387 + }9.388 + }9.389 + break;9.390 + default:9.391 + /* Command unsupported */9.392 + WARN( "Received unknown GDB command '%c%s'", command, data );9.393 + gdb_send_frame( server, "", 0 );9.394 + break;9.395 + }9.396 +9.397 +}9.398 +9.399 +/**9.400 + * Decode out frames from the raw data stream. A frame takes the form of9.401 + * $<data>#<checksum>9.402 + * where data may not contain a '#' character, and checksum is a simple9.403 + * 8-bit modulo sum of all bytes in data, encoded as a 2-char hex number.9.404 + *9.405 + * The only other legal wire forms are9.406 + * +9.407 + * indicating successful reception of the last message (ignored here), and9.408 + * -9.409 + * indicating failed reception of the last message - need to resend.9.410 + */9.411 +void gdb_server_process_buffer( struct gdb_server *server )9.412 +{9.413 + int i, frame_start = -1, frame_len = -1;9.414 + for( i=0; i<server->buf_posn; i++ ) {9.415 + if( frame_start == -1 ) {9.416 + if( server->buf[i] == '$' ) {9.417 + frame_start = i;9.418 + } else if( server->buf[i] == '+' ) {9.419 + /* Success */9.420 + continue;9.421 + } else if( server->buf[i] == '-' ) {9.422 + /* Request retransmit */9.423 + } /* Anything else is noise */9.424 + } else if( server->buf[i] == '#' ) {9.425 + frame_len = i - frame_start - 1;9.426 + if( i+2 < server->buf_posn ) {9.427 + int calc_checksum = gdb_checksum( &server->buf[frame_start+1], frame_len );9.428 + int frame_checksum = 0;9.429 + sscanf( &server->buf[i+1], "%02x", &frame_checksum );9.430 +9.431 + if( calc_checksum != frame_checksum ) {9.432 + WARN( "GDB frame checksum failure (expected %02X but was %02X)",9.433 + calc_checksum, frame_checksum );9.434 + write( server->fd, "-", 1 );9.435 + } else if( frame_len == 0 ) {9.436 + /* Empty frame - should never occur as a request */9.437 + WARN( "Empty GDB frame received" );9.438 + write( server->fd, "-", 1 );9.439 + } else {9.440 + /* We have a good frame */9.441 + write( server->fd, "+", 1 );9.442 + server->buf[i] = '\0';9.443 + gdb_server_handle_frame( server, server->buf[frame_start+1], &server->buf[frame_start+2], frame_len-1 );9.444 + }9.445 + i+=2;9.446 + frame_start = -1;9.447 + }9.448 + }9.449 + }9.450 + if( frame_start == -1 ) {9.451 + server->buf_posn = 0; /* Consumed whole buffer */9.452 + } else if( frame_start > 0 ) {9.453 + memmove(&server->buf[0], &server->buf[frame_start], server->buf_posn - frame_start);9.454 + server->buf_posn -= frame_start;9.455 + }9.456 +}9.457 +9.458 +gboolean gdb_server_data_callback( int fd, void *data )9.459 +{9.460 + struct gdb_server *server = (struct gdb_server *)data;9.461 +9.462 + size_t len = read( fd, &server->buf[server->buf_posn], server->buf_size - server->buf_posn );9.463 + if( len > 0 ) {9.464 + server->buf_posn += len;9.465 + gdb_server_process_buffer( server );9.466 +9.467 + /* If we have an oversized packet, extend the buffer */9.468 + if( server->buf_posn > server->buf_size - BUFFER_SIZE_MARGIN &&9.469 + server->buf_size < MAX_BUFFER_SIZE ) {9.470 + server->buf_size <<= 1;9.471 + server->buf = realloc( server->buf, server->buf_size );9.472 + assert( server->buf != NULL );9.473 + }9.474 + return TRUE;9.475 + } else {9.476 + INFO( "GDB disconnected" );9.477 + return FALSE;9.478 + }9.479 +}9.480 +9.481 +gboolean gdb_server_connect_callback( int fd, gpointer data )9.482 +{9.483 + struct sockaddr_in sin;9.484 + socklen_t sinlen;9.485 + struct gdb_server *server = (struct gdb_server *)data;9.486 + int conn_fd = accept( fd, (struct sockaddr *)&sin, &sinlen);9.487 + if( conn_fd != -1 ) {9.488 + struct gdb_server *chan_serv = calloc( sizeof(struct gdb_server), 1 );9.489 + chan_serv->cpu = server->cpu;9.490 + chan_serv->mmu = server->mmu;9.491 + chan_serv->fd = conn_fd;9.492 + chan_serv->peer_name = g_strdup_printf("%s:%d", inet_ntoa(sin.sin_addr), ntohs(sin.sin_port));9.493 + chan_serv->buf = malloc(1024);9.494 + chan_serv->buf_size = 1024;9.495 + chan_serv->buf_posn = 0;9.496 + net_register_tcp_listener( conn_fd, gdb_server_data_callback, chan_serv, gdb_server_free );9.497 + INFO( "GDB connected from %s", chan_serv->peer_name );9.498 + }9.499 + return TRUE;9.500 +}9.501 +9.502 +/**9.503 + * Bind a network port for a GDB remote server for the specified cpu. The9.504 + * port is registered for the system network callback.9.505 + *9.506 + * @param interface network interface to bind to, or null for the default (all) interface9.507 + * @param port9.508 + * @param cpu CPU to make available over the network port..9.509 + * @param mmu if TRUE, virtual memory is made available to GDB, otherwise GDB9.510 + * accesses physical memory.9.511 + * @return TRUE if the server was bound successfully.9.512 + */9.513 +gboolean gdb_init_server( const char *interface, int port, cpu_desc_t cpu, gboolean mmu )9.514 +{9.515 + int fd = net_create_server_socket( interface, port );9.516 + if( fd == -1 ) {9.517 + return FALSE;9.518 + }9.519 +9.520 + struct gdb_server *server = calloc( sizeof(struct gdb_server), 1 );9.521 + server->cpu = cpu;9.522 + server->mmu = mmu;9.523 + server->fd = fd;9.524 + net_register_tcp_listener( fd, gdb_server_connect_callback, server, gdb_server_free );9.525 + INFO( "%s GDB server running on port %d", cpu->name, port );9.526 +}
10.1 --- a/src/gtkui/gtk_debug.c Tue Mar 24 11:04:51 2009 +000010.2 +++ b/src/gtkui/gtk_debug.c Tue Mar 24 11:15:57 2009 +000010.3 @@ -200,11 +200,16 @@10.4 arr[1] = buf;10.5 for( i=0; data->cpu->regs_info[i].name != NULL; i++ ) {10.6 arr[0] = data->cpu->regs_info[i].name;10.7 - if( data->cpu->regs_info->type == REG_INT )10.8 - sprintf( buf, "%08X", *((uint32_t *)data->cpu->regs_info[i].value) );10.9 - else10.10 - sprintf( buf, "%f", *((float *)data->cpu->regs_info[i].value) );10.11 - gtk_clist_append( data->regs_list, arr );10.12 + void *value = data->cpu->get_register(i);10.13 + if( value != NULL ) {10.14 + if( data->cpu->regs_info->type == REG_INT ) {10.15 + sprintf( buf, "%08X", *((uint32_t *)value) );10.16 + gtk_clist_append( data->regs_list, arr );10.17 + } else if( data->cpu->regs_info->type == REG_FLOAT ) {10.18 + sprintf( buf, "%f", *((float *)value) );10.19 + gtk_clist_append( data->regs_list, arr );10.20 + }10.21 + }10.22 }10.23 }10.25 @@ -214,27 +219,33 @@10.26 void debug_window_update( debug_window_t data )10.27 {10.28 int i;10.29 + int posn = 0;10.30 for( i=0; data->cpu->regs_info[i].name != NULL; i++ ) {10.31 - if( data->cpu->regs_info[i].type == REG_INT ) {10.32 - /* Yes this _is_ probably fairly evil */10.33 - if( *((uint32_t *)data->cpu->regs_info[i].value) !=10.34 - *((uint32_t *)((char *)data->saved_regs + ((char *)data->cpu->regs_info[i].value - (char *)data->cpu->regs))) ) {10.35 - char buf[20];10.36 - sprintf( buf, "%08X", *((uint32_t *)data->cpu->regs_info[i].value) );10.37 - gtk_clist_set_text( data->regs_list, i, 1, buf );10.38 - gtk_clist_set_foreground( data->regs_list, i, &gui_colour_changed );10.39 + void *value = data->cpu->get_register(i);10.40 + if( value != NULL ) {10.41 + if( data->cpu->regs_info[i].type == REG_INT ) {10.42 + /* Yes this _is_ probably fairly evil */10.43 + if( *((uint32_t *)value) !=10.44 + *((uint32_t *)((char *)data->saved_regs + ((char *)value - (char *)data->cpu->regs))) ) {10.45 + char buf[20];10.46 + sprintf( buf, "%08X", *((uint32_t *)value) );10.47 + gtk_clist_set_text( data->regs_list, posn, 1, buf );10.48 + gtk_clist_set_foreground( data->regs_list, posn, &gui_colour_changed );10.49 + } else {10.50 + gtk_clist_set_foreground( data->regs_list, posn, &gui_colour_normal );10.51 + }10.52 + posn++;10.53 } else {10.54 - gtk_clist_set_foreground( data->regs_list, i, &gui_colour_normal );10.55 - }10.56 - } else {10.57 - if( *((float *)data->cpu->regs_info[i].value) !=10.58 - *((float *)((char *)data->saved_regs + ((char *)data->cpu->regs_info[i].value - (char *)data->cpu->regs))) ) {10.59 - char buf[20];10.60 - sprintf( buf, "%f", *((float *)data->cpu->regs_info[i].value) );10.61 - gtk_clist_set_text( data->regs_list, i, 1, buf );10.62 - gtk_clist_set_foreground( data->regs_list, i, &gui_colour_changed );10.63 - } else {10.64 - gtk_clist_set_foreground( data->regs_list, i, &gui_colour_normal );10.65 + if( *((float *)value) !=10.66 + *((float *)((char *)data->saved_regs + ((char *)value - (char *)data->cpu->regs))) ) {10.67 + char buf[20];10.68 + sprintf( buf, "%f", *((float *)value) );10.69 + gtk_clist_set_text( data->regs_list, i, posn, buf );10.70 + gtk_clist_set_foreground( data->regs_list, posn, &gui_colour_changed );10.71 + } else {10.72 + gtk_clist_set_foreground( data->regs_list, posn, &gui_colour_normal );10.73 + }10.74 + posn++;10.75 }10.76 }10.77 }
11.1 --- a/src/main.c Tue Mar 24 11:04:51 2009 +000011.2 +++ b/src/main.c Tue Mar 24 11:15:57 2009 +000011.3 @@ -34,14 +34,16 @@11.4 #include "gdrom/gdrom.h"11.5 #include "maple/maple.h"11.6 #include "sh4/sh4.h"11.7 +#include "aica/armdasm.h"11.9 -11.10 -char *option_list = "a:A:c:dhHl:m:npt:T:uvV:x?";11.11 +char *option_list = "a:A:c:dg:G:hHl:m:npt:T:uvV:x?";11.12 struct option longopts[] = {11.13 { "aica", required_argument, NULL, 'a' },11.14 { "audio", required_argument, NULL, 'A' },11.15 { "config", required_argument, NULL, 'c' },11.16 { "debugger", no_argument, NULL, 'D' },11.17 + { "gdb-sh4", required_argument, NULL, 'g' },11.18 + { "gdb-arm", required_argument, NULL, 'G' },11.19 { "help", no_argument, NULL, 'h' },11.20 { "headless", no_argument, NULL, 'H' },11.21 { "log", required_argument, NULL,'l' },11.22 @@ -56,6 +58,8 @@11.23 char *display_driver_name = NULL;11.24 char *audio_driver_name = NULL;11.25 char *trace_regions = NULL;11.26 +char *sh4_gdb_port = NULL;11.27 +char *arm_gdb_port = NULL;11.28 gboolean start_immediately = FALSE;11.29 gboolean no_start = FALSE;11.30 gboolean headless = FALSE;11.31 @@ -78,6 +82,8 @@11.32 printf( " -A, --audio=DRIVER %s\n", _("Use the specified audio driver (? to list)") );11.33 printf( " -c, --config=CONFFILE %s\n", _("Load configuration from CONFFILE") );11.34 printf( " -d, --debugger %s\n", _("Start in debugger mode") );11.35 + printf( " -g, --gdb-sh4=PORT %s\n", _("Start GDB remote server on PORT for SH4") );11.36 + printf( " -G, --gdb-arm=PORT %s\n", _("Start GDB remote server on PORT for ARM") );11.37 printf( " -h, --help %s\n", _("Display this usage information") );11.38 printf( " -H, --headless %s\n", _("Run in headless (no video) mode") );11.39 printf( " -l, --log=LEVEL %s\n", _("Set the output log level") );11.40 @@ -130,6 +136,12 @@11.41 case 'd': /* Launch w/ debugger */11.42 show_debugger = TRUE;11.43 break;11.44 + case 'g':11.45 + sh4_gdb_port = optarg;11.46 + break;11.47 + case 'G':11.48 + arm_gdb_port = optarg;11.49 + break;11.50 case 'h': /* help */11.51 case '?':11.52 print_usage();11.53 @@ -242,6 +254,16 @@11.55 sh4_translate_set_enabled( use_xlat );11.57 + /* If requested, start the gdb server immediately before we go into the main11.58 + * loop.11.59 + */11.60 + if( sh4_gdb_port != NULL ) {11.61 + gdb_init_server( NULL, strtol(sh4_gdb_port,NULL,0), &sh4_cpu_desc, TRUE );11.62 + }11.63 + if( arm_gdb_port != NULL ) {11.64 + gdb_init_server( NULL, strtol(arm_gdb_port,NULL,0), &arm_cpu_desc, TRUE );11.65 + }11.66 +11.67 if( headless ) {11.68 dreamcast_run();11.69 } else {
12.1 --- /dev/null Thu Jan 01 00:00:00 1970 +000012.2 +++ b/src/netutil.c Tue Mar 24 11:15:57 2009 +000012.3 @@ -0,0 +1,54 @@12.4 +/**12.5 + * $Id: netutil.c 1018 2009-03-19 12:29:06Z nkeynes $12.6 + *12.7 + * Network support functions12.8 + *12.9 + * Copyright (c) 2009 Nathan Keynes.12.10 + *12.11 + * This program is free software; you can redistribute it and/or modify12.12 + * it under the terms of the GNU General Public License as published by12.13 + * the Free Software Foundation; either version 2 of the License, or12.14 + * (at your option) any later version.12.15 + *12.16 + * This program is distributed in the hope that it will be useful,12.17 + * but WITHOUT ANY WARRANTY; without even the implied warranty of12.18 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the12.19 + * GNU General Public License for more details.12.20 + */12.21 +12.22 +#include <string.h>12.23 +#include <unistd.h>12.24 +#include <sys/socket.h>12.25 +#include <netinet/in.h>12.26 +#include <arpa/inet.h>12.27 +#include <errno.h>12.28 +#include "netutil.h"12.29 +12.30 +int net_create_server_socket(const char *interface, int port )12.31 +{12.32 + struct sockaddr_in sin;12.33 + int fd = socket(AF_INET, SOCK_STREAM, 0);12.34 + if( fd == -1 ) {12.35 + ERROR( "Failed to create TCP socket!" );12.36 + return -1;12.37 + }12.38 +12.39 + sin.sin_family = AF_INET;12.40 + sin.sin_addr.s_addr = 0;12.41 + sin.sin_port = htons(port);12.42 +12.43 + if( interface != NULL ) {12.44 + if( !inet_aton(interface, &sin.sin_addr) ) {12.45 + /* TODO: hostname lookup */12.46 + }12.47 + }12.48 +12.49 + if( bind( fd, (struct sockaddr *)&sin, sizeof(sin) ) != 0 ||12.50 + listen(fd, 5) != 0 ) {12.51 + close(fd);12.52 + ERROR( "Failed to bind port %d (%s)", port, strerror(errno) );12.53 + return -1;12.54 + }12.55 + return fd;12.56 +}12.57 +
13.1 --- /dev/null Thu Jan 01 00:00:00 1970 +000013.2 +++ b/src/netutil.h Tue Mar 24 11:15:57 2009 +000013.3 @@ -0,0 +1,58 @@13.4 +/**13.5 + * $Id: netutil.h 1018 2009-03-19 12:29:06Z nkeynes $13.6 + *13.7 + * GDB RDP server stub - SH4 + ARM13.8 + *13.9 + * Copyright (c) 2009 Nathan Keynes.13.10 + *13.11 + * This program is free software; you can redistribute it and/or modify13.12 + * it under the terms of the GNU General Public License as published by13.13 + * the Free Software Foundation; either version 2 of the License, or13.14 + * (at your option) any later version.13.15 + *13.16 + * This program is distributed in the hope that it will be useful,13.17 + * but WITHOUT ANY WARRANTY; without even the implied warranty of13.18 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the13.19 + * GNU General Public License for more details.13.20 + */13.21 +13.22 +#ifndef lxdream_netutil_H13.23 +#define lxdream_netutil_H 113.24 +13.25 +#include <netinet/in.h>13.26 +#include "lxdream.h"13.27 +13.28 +/**13.29 + * Construct a server socket listening on the given interface and port. If port13.30 + * is 0, a dynamic port will be bound instead.13.31 + * This method does not register a listener.13.32 + * @return newly created socket fd, or -1 on failure.13.33 + */13.34 +int net_create_server_socket(const char *interface, int port );13.35 +13.36 +/**13.37 + * Callback invoked when data is available from the remote peer, or when the peer13.38 + * connects/disconnects.13.39 + *13.40 + * @param fd file descriptor of the connected socket13.41 + * @param data data supplied when the callback was registered13.42 + * @return TRUE to maintain the connection, FALSE to immediately disconnected + close.13.43 + */13.44 +typedef gboolean (*net_callback_t)( int fd, void *data );13.45 +13.46 +/**13.47 + * Register a TCP server socket listener on an already open (and listening)13.48 + * socket. The socket must not have been previously registered.13.49 + * @return TRUE on success, FALSE on failure.13.50 + *13.51 + * Note: Implementation is platform specific13.52 + */13.53 +gboolean net_register_tcp_listener( int fd, net_callback_t callback, void *data, void (*dealloc)(void*) );13.54 +13.55 +/**13.56 + * Unregister a socket that was previously registered with the system. This13.57 + * does not close the socket, but will remove any callbacks associated with the socket.13.58 + */13.59 +gboolean net_unregister_listener( int fd );13.60 +13.61 +#endif /* !lxdream_netutil_H */
14.1 --- a/src/sh4/sh4.c Tue Mar 24 11:04:51 2009 +000014.2 +++ b/src/sh4/sh4.c Tue Mar 24 11:15:57 2009 +000014.3 @@ -23,6 +23,7 @@14.4 #include <assert.h>14.5 #include "lxdream.h"14.6 #include "dreamcast.h"14.7 +#include "cpu.h"14.8 #include "mem.h"14.9 #include "clock.h"14.10 #include "eventq.h"14.11 @@ -30,6 +31,7 @@14.12 #include "sh4/intc.h"14.13 #include "sh4/mmu.h"14.14 #include "sh4/sh4core.h"14.15 +#include "sh4/sh4dasm.h"14.16 #include "sh4/sh4mmio.h"14.17 #include "sh4/sh4stat.h"14.18 #include "sh4/sh4trans.h"14.19 @@ -46,10 +48,99 @@14.20 void sh4_stop( void );14.21 void sh4_save_state( FILE *f );14.22 int sh4_load_state( FILE *f );14.23 +size_t sh4_debug_read_phys( unsigned char *buf, uint32_t addr, size_t length );14.24 +size_t sh4_debug_write_phys( uint32_t addr, unsigned char *buf, size_t length );14.25 +size_t sh4_debug_read_vma( unsigned char *buf, uint32_t addr, size_t length );14.26 +size_t sh4_debug_write_vma( uint32_t addr, unsigned char *buf, size_t length );14.28 uint32_t sh4_run_slice( uint32_t );14.29 uint32_t sh4_xlat_run_slice( uint32_t );14.31 +/* Note: this must match GDB's ordering */14.32 +const struct reg_desc_struct sh4_reg_map[] =14.33 + { {"R0", REG_INT, &sh4r.r[0]}, {"R1", REG_INT, &sh4r.r[1]},14.34 + {"R2", REG_INT, &sh4r.r[2]}, {"R3", REG_INT, &sh4r.r[3]},14.35 + {"R4", REG_INT, &sh4r.r[4]}, {"R5", REG_INT, &sh4r.r[5]},14.36 + {"R6", REG_INT, &sh4r.r[6]}, {"R7", REG_INT, &sh4r.r[7]},14.37 + {"R8", REG_INT, &sh4r.r[8]}, {"R9", REG_INT, &sh4r.r[9]},14.38 + {"R10",REG_INT, &sh4r.r[10]}, {"R11",REG_INT, &sh4r.r[11]},14.39 + {"R12",REG_INT, &sh4r.r[12]}, {"R13",REG_INT, &sh4r.r[13]},14.40 + {"R14",REG_INT, &sh4r.r[14]}, {"R15",REG_INT, &sh4r.r[15]},14.41 + {"PC", REG_INT, &sh4r.pc}, {"PR", REG_INT, &sh4r.pr},14.42 + {"GBR", REG_INT, &sh4r.gbr}, {"VBR",REG_INT, &sh4r.vbr},14.43 + {"MACH",REG_INT, ((uint32_t *)&sh4r.mac)+1}, {"MACL",REG_INT, &sh4r.mac},14.44 + {"SR", REG_INT, &sh4r.sr},14.45 + {"FPUL", REG_INT, &sh4r.fpul.i}, {"FPSCR", REG_INT, &sh4r.fpscr},14.46 +14.47 + {"FR0", REG_FLOAT, &sh4r.fr[0][1] },{"FR1", REG_FLOAT, &sh4r.fr[0][0]},14.48 + {"FR2", REG_FLOAT, &sh4r.fr[0][3] },{"FR3", REG_FLOAT, &sh4r.fr[0][2]},14.49 + {"FR4", REG_FLOAT, &sh4r.fr[0][5] },{"FR5", REG_FLOAT, &sh4r.fr[0][4]},14.50 + {"FR6", REG_FLOAT, &sh4r.fr[0][7] },{"FR7", REG_FLOAT, &sh4r.fr[0][6]},14.51 + {"FR8", REG_FLOAT, &sh4r.fr[0][9] },{"FR9", REG_FLOAT, &sh4r.fr[0][8]},14.52 + {"FR10", REG_FLOAT, &sh4r.fr[0][11] },{"FR11", REG_FLOAT, &sh4r.fr[0][10]},14.53 + {"FR12", REG_FLOAT, &sh4r.fr[0][13] },{"FR13", REG_FLOAT, &sh4r.fr[0][12]},14.54 + {"FR14", REG_FLOAT, &sh4r.fr[0][15] },{"FR15", REG_FLOAT, &sh4r.fr[0][14]},14.55 +14.56 + {"SSR",REG_INT, &sh4r.ssr}, {"SPC", REG_INT, &sh4r.spc},14.57 +14.58 + {"R0B0", REG_INT, NULL}, {"R1B0", REG_INT, NULL},14.59 + {"R2B0", REG_INT, NULL}, {"R3B0", REG_INT, NULL},14.60 + {"R4B0", REG_INT, NULL}, {"R5B0", REG_INT, NULL},14.61 + {"R6B0", REG_INT, NULL}, {"R7B0", REG_INT, NULL},14.62 + {"R0B1", REG_INT, NULL}, {"R1B1", REG_INT, NULL},14.63 + {"R2B1", REG_INT, NULL}, {"R3B1", REG_INT, NULL},14.64 + {"R4B1", REG_INT, NULL}, {"R5B1", REG_INT, NULL},14.65 + {"R6B1", REG_INT, NULL}, {"R7B1", REG_INT, NULL},14.66 +14.67 + {"SGR",REG_INT, &sh4r.sgr}, {"DBR", REG_INT, &sh4r.dbr},14.68 +14.69 + {"XF0", REG_FLOAT, &sh4r.fr[1][1] },{"XF1", REG_FLOAT, &sh4r.fr[1][0]},14.70 + {"XF2", REG_FLOAT, &sh4r.fr[1][3] },{"XF3", REG_FLOAT, &sh4r.fr[1][2]},14.71 + {"XF4", REG_FLOAT, &sh4r.fr[1][5] },{"XF5", REG_FLOAT, &sh4r.fr[1][4]},14.72 + {"XF6", REG_FLOAT, &sh4r.fr[1][7] },{"XF7", REG_FLOAT, &sh4r.fr[1][6]},14.73 + {"XF8", REG_FLOAT, &sh4r.fr[1][9] },{"XF9", REG_FLOAT, &sh4r.fr[1][8]},14.74 + {"XF10", REG_FLOAT, &sh4r.fr[1][11] },{"XF11", REG_FLOAT, &sh4r.fr[1][10]},14.75 + {"XF12", REG_FLOAT, &sh4r.fr[1][13] },{"XF13", REG_FLOAT, &sh4r.fr[1][12]},14.76 + {"XF14", REG_FLOAT, &sh4r.fr[1][15] },{"XF15", REG_FLOAT, &sh4r.fr[1][14]},14.77 +14.78 + {NULL, 0, NULL} };14.79 +14.80 +void *sh4_get_register( int reg )14.81 +{14.82 + if( reg < 0 || reg >= 94 ) {14.83 + return NULL;14.84 + } else if( reg < 43 ) {14.85 + return sh4_reg_map[reg].value;14.86 + } else if( reg < 51 ) {14.87 + /* r0b0..r7b0 */14.88 + if( (sh4r.sr & SR_MDRB) == SR_MDRB ) {14.89 + /* bank 1 is primary */14.90 + return &sh4r.r_bank[reg-43];14.91 + } else {14.92 + return &sh4r.r[reg-43];14.93 + }14.94 + } else if( reg < 59 ) {14.95 + /* r0b1..r7b1 */14.96 + if( (sh4r.sr & SR_MDRB) == SR_MDRB ) {14.97 + /* bank 1 is primary */14.98 + return &sh4r.r[reg-43];14.99 + } else {14.100 + return &sh4r.r_bank[reg-43];14.101 + }14.102 + } else {14.103 + return NULL; /* not supported at the moment */14.104 + }14.105 +}14.106 +14.107 +14.108 +const struct cpu_desc_struct sh4_cpu_desc =14.109 + { "SH4", sh4_disasm_instruction, sh4_get_register, sh4_has_page,14.110 + sh4_debug_read_phys, sh4_debug_write_phys, sh4_debug_read_vma, sh4_debug_write_vma,14.111 + sh4_execute_instruction,14.112 + sh4_set_breakpoint, sh4_clear_breakpoint, sh4_get_breakpoint, 2,14.113 + (char *)&sh4r, sizeof(sh4r), sh4_reg_map, 23, 59,14.114 + &sh4r.pc };14.115 +14.116 struct dreamcast_module sh4_module = { "SH4", sh4_init, sh4_poweron_reset,14.117 sh4_start, sh4_run_slice, sh4_stop,14.118 sh4_save_state, sh4_load_state };14.119 @@ -546,3 +637,77 @@14.120 sh4addr_t addr = mmu_vma_to_phys_disasm(vma);14.121 return addr != MMU_VMA_ERROR && mem_has_page(addr);14.122 }14.123 +14.124 +/**14.125 + * Go through ext_address_space page by page14.126 + */14.127 +size_t sh4_debug_read_phys( unsigned char *buf, uint32_t addr, size_t length )14.128 +{14.129 + /* Quick and very dirty */14.130 + unsigned char *region = mem_get_region(addr);14.131 + if( region == NULL ) {14.132 + memset( buf, 0, length );14.133 + } else {14.134 + memcpy( buf, region, length );14.135 + }14.136 + return length;14.137 +}14.138 +14.139 +size_t sh4_debug_write_phys( uint32_t addr, unsigned char *buf, size_t length )14.140 +{14.141 + unsigned char *region = mem_get_region(addr);14.142 + if( region != NULL ) {14.143 + memcpy( region, buf, length );14.144 + }14.145 + return length;14.146 +}14.147 +14.148 +/**14.149 + * Read virtual memory - for now just go 1K at a time14.150 + */14.151 +size_t sh4_debug_read_vma( unsigned char *buf, uint32_t addr, size_t length )14.152 +{14.153 + if( IS_TLB_ENABLED() ) {14.154 + size_t read_len = 0;14.155 + while( length > 0 ) {14.156 + sh4addr_t phys = mmu_vma_to_phys_disasm(addr);14.157 + if( phys == MMU_VMA_ERROR )14.158 + break;14.159 + int next_len = 1024 - (phys&0x000003FF);14.160 + if( next_len >= length ) {14.161 + next_len = length;14.162 + }14.163 + sh4_debug_read_phys( buf, phys, length );14.164 + buf += next_len;14.165 + addr += next_len;14.166 + read_len += next_len;14.167 + length -= next_len;14.168 + }14.169 + return read_len;14.170 + } else {14.171 + return sh4_debug_read_phys( buf, addr, length );14.172 + }14.173 +}14.174 +14.175 +size_t sh4_debug_write_vma( uint32_t addr, unsigned char *buf, size_t length )14.176 +{14.177 + if( IS_TLB_ENABLED() ) {14.178 + size_t read_len = 0;14.179 + while( length > 0 ) {14.180 + sh4addr_t phys = mmu_vma_to_phys_disasm(addr);14.181 + if( phys == MMU_VMA_ERROR )14.182 + break;14.183 + int next_len = 1024 - (phys&0x000003FF);14.184 + if( next_len >= length ) {14.185 + next_len = length;14.186 + }14.187 + sh4_debug_write_phys( phys, buf, length );14.188 + buf += next_len;14.189 + addr += next_len;14.190 + read_len += next_len;14.191 + length -= next_len;14.192 + }14.193 + } else {14.194 + return sh4_debug_write_phys( addr, buf, length );14.195 + }14.196 +}
15.1 --- a/src/sh4/sh4.h Tue Mar 24 11:04:51 2009 +000015.2 +++ b/src/sh4/sh4.h Tue Mar 24 11:15:57 2009 +000015.3 @@ -95,6 +95,8 @@15.5 extern struct sh4_registers sh4r;15.7 +extern const struct cpu_desc_struct sh4_cpu_desc;15.8 +15.9 /**15.10 * Switch between translation and emulation execution modes. Note that this15.11 * should only be used while the system is stopped. If the system was built
16.1 --- a/src/sh4/sh4dasm.h Tue Mar 24 11:04:51 2009 +000016.2 +++ b/src/sh4/sh4dasm.h Tue Mar 24 11:15:57 2009 +000016.3 @@ -30,8 +30,6 @@16.4 uint32_t sh4_disasm_instruction( uint32_t pc, char *buf, int len, char * );16.5 void sh4_disasm_region( FILE *f, int from, int to );16.7 -extern const struct cpu_desc_struct sh4_cpu_desc;16.8 -16.9 #ifdef __cplusplus16.10 }16.11 #endif
17.1 --- a/src/sh4/sh4dasm.in Tue Mar 24 11:04:51 2009 +000017.2 +++ b/src/sh4/sh4dasm.in Tue Mar 24 11:15:57 2009 +000017.3 @@ -23,32 +23,6 @@17.5 #define UNIMP(ir) snprintf( buf, len, "??? " )17.7 -17.8 -const struct reg_desc_struct sh4_reg_map[] =17.9 - { {"R0", REG_INT, &sh4r.r[0]}, {"R1", REG_INT, &sh4r.r[1]},17.10 - {"R2", REG_INT, &sh4r.r[2]}, {"R3", REG_INT, &sh4r.r[3]},17.11 - {"R4", REG_INT, &sh4r.r[4]}, {"R5", REG_INT, &sh4r.r[5]},17.12 - {"R6", REG_INT, &sh4r.r[6]}, {"R7", REG_INT, &sh4r.r[7]},17.13 - {"R8", REG_INT, &sh4r.r[8]}, {"R9", REG_INT, &sh4r.r[9]},17.14 - {"R10",REG_INT, &sh4r.r[10]}, {"R11",REG_INT, &sh4r.r[11]},17.15 - {"R12",REG_INT, &sh4r.r[12]}, {"R13",REG_INT, &sh4r.r[13]},17.16 - {"R14",REG_INT, &sh4r.r[14]}, {"R15",REG_INT, &sh4r.r[15]},17.17 - {"SR", REG_INT, &sh4r.sr}, {"GBR", REG_INT, &sh4r.gbr},17.18 - {"SSR",REG_INT, &sh4r.ssr}, {"SPC", REG_INT, &sh4r.spc},17.19 - {"SGR",REG_INT, &sh4r.sgr}, {"DBR", REG_INT, &sh4r.dbr},17.20 - {"VBR",REG_INT, &sh4r.vbr},17.21 - {"PC", REG_INT, &sh4r.pc}, {"PR", REG_INT, &sh4r.pr},17.22 - {"MACL",REG_INT, &sh4r.mac},{"MACH",REG_INT, ((uint32_t *)&sh4r.mac)+1},17.23 - {"FPUL", REG_INT, &sh4r.fpul.i}, {"FPSCR", REG_INT, &sh4r.fpscr},17.24 - {NULL, 0, NULL} };17.25 -17.26 -17.27 -const struct cpu_desc_struct sh4_cpu_desc =17.28 - { "SH4", sh4_disasm_instruction, sh4_execute_instruction, sh4_has_page,17.29 - sh4_set_breakpoint, sh4_clear_breakpoint, sh4_get_breakpoint, 2,17.30 - (char *)&sh4r, sizeof(sh4r), sh4_reg_map,17.31 - &sh4r.pc };17.32 -17.33 uint32_t sh4_disasm_instruction( sh4vma_t pc, char *buf, int len, char *opcode )17.34 {17.35 sh4addr_t addr = mmu_vma_to_phys_disasm(pc);
.