revision 1023:264e2fd90be8
summary |
tree |
shortlog |
changelog |
graph |
changeset |
raw | bz2 | zip | gz changeset | 1023:264e2fd90be8 |
parent | 1022:43f35b12ece7 |
child | 1024:c67f2d61ab97 |
author | nkeynes |
date | Mon Jun 08 04:12:21 2009 +0000 (14 years ago) |
General cleanup of the GD-rom subsystem
- merge gdrom_image_t and gdrom_disc_t
- Abstract MMC devices using a lower-level scsi transport
- OSX: only look at the whole disc device, and ignore partitions
- merge gdrom_image_t and gdrom_disc_t
- Abstract MMC devices using a lower-level scsi transport
- OSX: only look at the whole disc device, and ignore partitions
src/Makefile.am | view | annotate | diff | log | ||
src/Makefile.in | view | annotate | diff | log | ||
src/drivers/cd_linux.c | view | annotate | diff | log | ||
src/drivers/cd_mmc.c | view | annotate | diff | log | ||
src/drivers/cd_osx.c | view | annotate | diff | log | ||
src/drivers/osx_iokit.m | view | annotate | diff | log | ||
src/gdrom/cdi.c | view | annotate | diff | log | ||
src/gdrom/gddriver.h | view | annotate | diff | log | ||
src/gdrom/gdi.c | view | annotate | diff | log | ||
src/gdrom/gdimage.c | view | annotate | diff | log | ||
src/gdrom/gdrom.c | view | annotate | diff | log | ||
src/gdrom/gdrom.h | view | annotate | diff | log | ||
src/gdrom/ide.c | view | annotate | diff | log | ||
src/gdrom/mmc.c | view | annotate | diff | log | ||
src/gdrom/nrg.c | view | annotate | diff | log |
1.1 --- a/src/Makefile.am Wed Jun 03 11:39:06 2009 +00001.2 +++ b/src/Makefile.am Mon Jun 08 04:12:21 2009 +00001.3 @@ -42,7 +42,7 @@1.4 gdrom/ide.c gdrom/ide.h gdrom/packet.h gdrom/gdimage.c \1.5 gdrom/gdrom.c gdrom/gdrom.h gdrom/nrg.c gdrom/cdi.c gdrom/gdi.c \1.6 gdrom/edc_ecc.c gdrom/ecc.h gdrom/edc_crctable.h gdrom/edc_encoder.h \1.7 - gdrom/edc_l2sq.h gdrom/edc_scramble.h gdrom/mmc.c gdrom/gddriver.h \1.8 + gdrom/edc_l2sq.h gdrom/edc_scramble.h gdrom/gddriver.h \1.9 dreamcast.c dreamcast.h eventq.c eventq.h \1.10 sh4/sh4.c sh4/intc.c sh4/intc.h sh4/sh4mem.c sh4/timer.c sh4/dmac.c \1.11 sh4/mmu.c sh4/sh4core.c sh4/sh4core.h sh4/sh4dasm.c sh4/sh4dasm.h \1.12 @@ -60,7 +60,7 @@1.13 maple/controller.c maple/kbd.c maple/mouse.c maple/lightgun.c \1.14 loader.c loader.h elf.h bootstrap.c bootstrap.h util.c gdlist.c gdlist.h \1.15 display.c display.h dckeysyms.h \1.16 - drivers/audio_null.c drivers/video_null.c \1.17 + drivers/audio_null.c drivers/video_null.c drivers/cd_mmc.c \1.18 drivers/video_gl.c drivers/video_gl.h drivers/gl_fbo.c \1.19 sh4/sh4.def sh4/sh4core.in sh4/sh4x86.in sh4/sh4dasm.in sh4/sh4stat.in \1.20 hotkeys.c hotkeys.h
2.1 --- a/src/Makefile.in Wed Jun 03 11:39:06 2009 +00002.2 +++ b/src/Makefile.in Mon Jun 08 04:12:21 2009 +00002.3 @@ -104,15 +104,15 @@2.4 gdrom/gdimage.c gdrom/gdrom.c gdrom/gdrom.h gdrom/nrg.c \2.5 gdrom/cdi.c gdrom/gdi.c gdrom/edc_ecc.c gdrom/ecc.h \2.6 gdrom/edc_crctable.h gdrom/edc_encoder.h gdrom/edc_l2sq.h \2.7 - gdrom/edc_scramble.h gdrom/mmc.c gdrom/gddriver.h dreamcast.c \2.8 - dreamcast.h eventq.c eventq.h sh4/sh4.c sh4/intc.c sh4/intc.h \2.9 - sh4/sh4mem.c sh4/timer.c sh4/dmac.c sh4/mmu.c sh4/sh4core.c \2.10 - sh4/sh4core.h sh4/sh4dasm.c sh4/sh4dasm.h sh4/sh4mmio.c \2.11 - sh4/sh4mmio.h sh4/scif.c sh4/sh4stat.c sh4/sh4stat.h \2.12 - xlat/xltcache.c xlat/xltcache.h sh4/sh4.h sh4/dmac.h sh4/pmm.c \2.13 - sh4/cache.c sh4/mmu.h aica/armcore.c aica/armcore.h \2.14 - aica/armdasm.c aica/armdasm.h aica/armmem.c aica/aica.c \2.15 - aica/aica.h aica/audio.c aica/audio.h pvr2/pvr2.c pvr2/pvr2.h \2.16 + gdrom/edc_scramble.h gdrom/gddriver.h dreamcast.c dreamcast.h \2.17 + eventq.c eventq.h sh4/sh4.c sh4/intc.c sh4/intc.h sh4/sh4mem.c \2.18 + sh4/timer.c sh4/dmac.c sh4/mmu.c sh4/sh4core.c sh4/sh4core.h \2.19 + sh4/sh4dasm.c sh4/sh4dasm.h sh4/sh4mmio.c sh4/sh4mmio.h \2.20 + sh4/scif.c sh4/sh4stat.c sh4/sh4stat.h xlat/xltcache.c \2.21 + xlat/xltcache.h sh4/sh4.h sh4/dmac.h sh4/pmm.c sh4/cache.c \2.22 + sh4/mmu.h aica/armcore.c aica/armcore.h aica/armdasm.c \2.23 + aica/armdasm.h aica/armmem.c aica/aica.c aica/aica.h \2.24 + aica/audio.c aica/audio.h pvr2/pvr2.c pvr2/pvr2.h \2.25 pvr2/pvr2mem.c pvr2/pvr2mmio.h pvr2/tacore.c pvr2/rendsort.c \2.26 pvr2/texcache.c pvr2/yuv.c pvr2/rendsave.c pvr2/scene.c \2.27 pvr2/scene.h pvr2/gl_sl.c pvr2/gl_slsrc.c pvr2/glutil.c \2.28 @@ -121,22 +121,23 @@2.29 maple/controller.c maple/kbd.c maple/mouse.c maple/lightgun.c \2.30 loader.c loader.h elf.h bootstrap.c bootstrap.h util.c \2.31 gdlist.c gdlist.h display.c display.h dckeysyms.h \2.32 - drivers/audio_null.c drivers/video_null.c drivers/video_gl.c \2.33 - drivers/video_gl.h drivers/gl_fbo.c sh4/sh4.def sh4/sh4core.in \2.34 - sh4/sh4x86.in sh4/sh4dasm.in sh4/sh4stat.in hotkeys.c \2.35 - hotkeys.h sh4/sh4x86.c xlat/x86/x86op.h xlat/x86/ia32abi.h \2.36 - xlat/x86/amd64abi.h sh4/sh4trans.c sh4/sh4trans.h sh4/mmux86.c \2.37 - x86dasm/x86dasm.c x86dasm/x86dasm.h x86dasm/i386-dis.c \2.38 - x86dasm/dis-init.c x86dasm/dis-buf.c x86dasm/ansidecl.h \2.39 - x86dasm/bfd.h x86dasm/dis-asm.h x86dasm/symcat.h \2.40 - x86dasm/sysdep.h gtkui/gtkui.c gtkui/gtkui.h gtkui/gtk_win.c \2.41 - gtkui/gtkcb.c gtkui/gtk_mmio.c gtkui/gtk_debug.c \2.42 - gtkui/gtk_dump.c gtkui/gtk_ctrl.c gtkui/gtk_path.c \2.43 - gtkui/gtk_gd.c gtkui/gtk_hotkeys.c drivers/net_glib.c \2.44 - drivers/video_gtk.c cocoaui/cocoaui.m cocoaui/cocoaui.h \2.45 - cocoaui/cocoa_win.m cocoaui/cocoa_gd.m cocoaui/cocoa_prefs.m \2.46 - cocoaui/cocoa_path.m cocoaui/cocoa_ctrl.m cocoaui/paths_osx.m \2.47 - drivers/net_osx.m drivers/video_osx.m drivers/mac_keymap.h \2.48 + drivers/audio_null.c drivers/video_null.c drivers/cd_mmc.c \2.49 + drivers/video_gl.c drivers/video_gl.h drivers/gl_fbo.c \2.50 + sh4/sh4.def sh4/sh4core.in sh4/sh4x86.in sh4/sh4dasm.in \2.51 + sh4/sh4stat.in hotkeys.c hotkeys.h sh4/sh4x86.c \2.52 + xlat/x86/x86op.h xlat/x86/ia32abi.h xlat/x86/amd64abi.h \2.53 + sh4/sh4trans.c sh4/sh4trans.h sh4/mmux86.c x86dasm/x86dasm.c \2.54 + x86dasm/x86dasm.h x86dasm/i386-dis.c x86dasm/dis-init.c \2.55 + x86dasm/dis-buf.c x86dasm/ansidecl.h x86dasm/bfd.h \2.56 + x86dasm/dis-asm.h x86dasm/symcat.h x86dasm/sysdep.h \2.57 + gtkui/gtkui.c gtkui/gtkui.h gtkui/gtk_win.c gtkui/gtkcb.c \2.58 + gtkui/gtk_mmio.c gtkui/gtk_debug.c gtkui/gtk_dump.c \2.59 + gtkui/gtk_ctrl.c gtkui/gtk_path.c gtkui/gtk_gd.c \2.60 + gtkui/gtk_hotkeys.c drivers/net_glib.c drivers/video_gtk.c \2.61 + cocoaui/cocoaui.m cocoaui/cocoaui.h cocoaui/cocoa_win.m \2.62 + cocoaui/cocoa_gd.m cocoaui/cocoa_prefs.m cocoaui/cocoa_path.m \2.63 + cocoaui/cocoa_ctrl.m cocoaui/paths_osx.m drivers/net_osx.m \2.64 + drivers/video_osx.m drivers/mac_keymap.h \2.65 drivers/mac_keymap.txt paths_unix.c drivers/video_gdk.c \2.66 drivers/video_glx.c drivers/video_glx.h drivers/video_nsgl.m \2.67 drivers/video_nsgl.h drivers/audio_osx.m drivers/audio_sdl.c \2.68 @@ -178,14 +179,13 @@2.69 syscall.$(OBJEXT) bios.$(OBJEXT) dcload.$(OBJEXT) \2.70 gdbserver.$(OBJEXT) netutil.$(OBJEXT) ide.$(OBJEXT) \2.71 gdimage.$(OBJEXT) gdrom.$(OBJEXT) nrg.$(OBJEXT) cdi.$(OBJEXT) \2.72 - gdi.$(OBJEXT) edc_ecc.$(OBJEXT) mmc.$(OBJEXT) \2.73 - dreamcast.$(OBJEXT) eventq.$(OBJEXT) sh4.$(OBJEXT) \2.74 - intc.$(OBJEXT) sh4mem.$(OBJEXT) timer.$(OBJEXT) dmac.$(OBJEXT) \2.75 - mmu.$(OBJEXT) sh4core.$(OBJEXT) sh4dasm.$(OBJEXT) \2.76 - sh4mmio.$(OBJEXT) scif.$(OBJEXT) sh4stat.$(OBJEXT) \2.77 - xltcache.$(OBJEXT) pmm.$(OBJEXT) cache.$(OBJEXT) \2.78 - armcore.$(OBJEXT) armdasm.$(OBJEXT) armmem.$(OBJEXT) \2.79 - aica.$(OBJEXT) audio.$(OBJEXT) pvr2.$(OBJEXT) \2.80 + gdi.$(OBJEXT) edc_ecc.$(OBJEXT) dreamcast.$(OBJEXT) \2.81 + eventq.$(OBJEXT) sh4.$(OBJEXT) intc.$(OBJEXT) sh4mem.$(OBJEXT) \2.82 + timer.$(OBJEXT) dmac.$(OBJEXT) mmu.$(OBJEXT) sh4core.$(OBJEXT) \2.83 + sh4dasm.$(OBJEXT) sh4mmio.$(OBJEXT) scif.$(OBJEXT) \2.84 + sh4stat.$(OBJEXT) xltcache.$(OBJEXT) pmm.$(OBJEXT) \2.85 + cache.$(OBJEXT) armcore.$(OBJEXT) armdasm.$(OBJEXT) \2.86 + armmem.$(OBJEXT) aica.$(OBJEXT) audio.$(OBJEXT) pvr2.$(OBJEXT) \2.87 pvr2mem.$(OBJEXT) tacore.$(OBJEXT) rendsort.$(OBJEXT) \2.88 texcache.$(OBJEXT) yuv.$(OBJEXT) rendsave.$(OBJEXT) \2.89 scene.$(OBJEXT) gl_sl.$(OBJEXT) gl_slsrc.$(OBJEXT) \2.90 @@ -193,14 +193,14 @@2.91 controller.$(OBJEXT) kbd.$(OBJEXT) mouse.$(OBJEXT) \2.92 lightgun.$(OBJEXT) loader.$(OBJEXT) bootstrap.$(OBJEXT) \2.93 util.$(OBJEXT) gdlist.$(OBJEXT) display.$(OBJEXT) \2.94 - audio_null.$(OBJEXT) video_null.$(OBJEXT) video_gl.$(OBJEXT) \2.95 - gl_fbo.$(OBJEXT) hotkeys.$(OBJEXT) $(am__objects_1) \2.96 - $(am__objects_2) $(am__objects_3) $(am__objects_4) \2.97 - $(am__objects_5) $(am__objects_6) $(am__objects_7) \2.98 - $(am__objects_8) $(am__objects_9) $(am__objects_10) \2.99 - $(am__objects_11) $(am__objects_12) $(am__objects_13) \2.100 - $(am__objects_14) $(am__objects_15) $(am__objects_16) \2.101 - $(am__objects_17)2.102 + audio_null.$(OBJEXT) video_null.$(OBJEXT) cd_mmc.$(OBJEXT) \2.103 + video_gl.$(OBJEXT) gl_fbo.$(OBJEXT) hotkeys.$(OBJEXT) \2.104 + $(am__objects_1) $(am__objects_2) $(am__objects_3) \2.105 + $(am__objects_4) $(am__objects_5) $(am__objects_6) \2.106 + $(am__objects_7) $(am__objects_8) $(am__objects_9) \2.107 + $(am__objects_10) $(am__objects_11) $(am__objects_12) \2.108 + $(am__objects_13) $(am__objects_14) $(am__objects_15) \2.109 + $(am__objects_16) $(am__objects_17)2.110 lxdream_OBJECTS = $(am_lxdream_OBJECTS)2.111 lxdream_DEPENDENCIES = $(am__DEPENDENCIES_1) $(am__DEPENDENCIES_1)2.112 am__test_testsh4x86_SOURCES_DIST = test/testsh4x86.c x86dasm/x86dasm.c \2.113 @@ -444,24 +444,24 @@2.114 gdrom/gdrom.h gdrom/nrg.c gdrom/cdi.c gdrom/gdi.c \2.115 gdrom/edc_ecc.c gdrom/ecc.h gdrom/edc_crctable.h \2.116 gdrom/edc_encoder.h gdrom/edc_l2sq.h gdrom/edc_scramble.h \2.117 - gdrom/mmc.c gdrom/gddriver.h dreamcast.c dreamcast.h eventq.c \2.118 - eventq.h sh4/sh4.c sh4/intc.c sh4/intc.h sh4/sh4mem.c \2.119 - sh4/timer.c sh4/dmac.c sh4/mmu.c sh4/sh4core.c sh4/sh4core.h \2.120 - sh4/sh4dasm.c sh4/sh4dasm.h sh4/sh4mmio.c sh4/sh4mmio.h \2.121 - sh4/scif.c sh4/sh4stat.c sh4/sh4stat.h xlat/xltcache.c \2.122 - xlat/xltcache.h sh4/sh4.h sh4/dmac.h sh4/pmm.c sh4/cache.c \2.123 - sh4/mmu.h aica/armcore.c aica/armcore.h aica/armdasm.c \2.124 - aica/armdasm.h aica/armmem.c aica/aica.c aica/aica.h \2.125 - aica/audio.c aica/audio.h pvr2/pvr2.c pvr2/pvr2.h \2.126 - pvr2/pvr2mem.c pvr2/pvr2mmio.h pvr2/tacore.c pvr2/rendsort.c \2.127 - pvr2/texcache.c pvr2/yuv.c pvr2/rendsave.c pvr2/scene.c \2.128 - pvr2/scene.h pvr2/gl_sl.c pvr2/gl_slsrc.c pvr2/glutil.c \2.129 - pvr2/glutil.h pvr2/glrender.c pvr2/vertex.glsl \2.130 - pvr2/fragment.glsl maple/maple.c maple/maple.h \2.131 - maple/controller.c maple/kbd.c maple/mouse.c maple/lightgun.c \2.132 - loader.c loader.h elf.h bootstrap.c bootstrap.h util.c \2.133 - gdlist.c gdlist.h display.c display.h dckeysyms.h \2.134 - drivers/audio_null.c drivers/video_null.c drivers/video_gl.c \2.135 + gdrom/gddriver.h dreamcast.c dreamcast.h eventq.c eventq.h \2.136 + sh4/sh4.c sh4/intc.c sh4/intc.h sh4/sh4mem.c sh4/timer.c \2.137 + sh4/dmac.c sh4/mmu.c sh4/sh4core.c sh4/sh4core.h sh4/sh4dasm.c \2.138 + sh4/sh4dasm.h sh4/sh4mmio.c sh4/sh4mmio.h sh4/scif.c \2.139 + sh4/sh4stat.c sh4/sh4stat.h xlat/xltcache.c xlat/xltcache.h \2.140 + sh4/sh4.h sh4/dmac.h sh4/pmm.c sh4/cache.c sh4/mmu.h \2.141 + aica/armcore.c aica/armcore.h aica/armdasm.c aica/armdasm.h \2.142 + aica/armmem.c aica/aica.c aica/aica.h aica/audio.c \2.143 + aica/audio.h pvr2/pvr2.c pvr2/pvr2.h pvr2/pvr2mem.c \2.144 + pvr2/pvr2mmio.h pvr2/tacore.c pvr2/rendsort.c pvr2/texcache.c \2.145 + pvr2/yuv.c pvr2/rendsave.c pvr2/scene.c pvr2/scene.h \2.146 + pvr2/gl_sl.c pvr2/gl_slsrc.c pvr2/glutil.c pvr2/glutil.h \2.147 + pvr2/glrender.c pvr2/vertex.glsl pvr2/fragment.glsl \2.148 + maple/maple.c maple/maple.h maple/controller.c maple/kbd.c \2.149 + maple/mouse.c maple/lightgun.c loader.c loader.h elf.h \2.150 + bootstrap.c bootstrap.h util.c gdlist.c gdlist.h display.c \2.151 + display.h dckeysyms.h drivers/audio_null.c \2.152 + drivers/video_null.c drivers/cd_mmc.c drivers/video_gl.c \2.153 drivers/video_gl.h drivers/gl_fbo.c sh4/sh4.def sh4/sh4core.in \2.154 sh4/sh4x86.in sh4/sh4dasm.in sh4/sh4stat.in hotkeys.c \2.155 hotkeys.h $(am__append_1) $(am__append_3) $(am__append_4) \2.156 @@ -587,6 +587,7 @@2.157 @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/bootstrap.Po@am__quote@2.158 @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/cache.Po@am__quote@2.159 @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/cd_linux.Po@am__quote@2.160 +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/cd_mmc.Po@am__quote@2.161 @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/cd_none.Po@am__quote@2.162 @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/cd_osx.Po@am__quote@2.163 @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/cdi.Po@am__quote@2.164 @@ -641,7 +642,6 @@2.165 @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/main.Po@am__quote@2.166 @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/maple.Po@am__quote@2.167 @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/mem.Po@am__quote@2.168 -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/mmc.Po@am__quote@2.169 @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/mmu.Po@am__quote@2.170 @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/mmux86.Po@am__quote@2.171 @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/mouse.Po@am__quote@2.172 @@ -856,20 +856,6 @@2.173 @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@2.174 @am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o edc_ecc.obj `if test -f 'gdrom/edc_ecc.c'; then $(CYGPATH_W) 'gdrom/edc_ecc.c'; else $(CYGPATH_W) '$(srcdir)/gdrom/edc_ecc.c'; fi`2.176 -mmc.o: gdrom/mmc.c2.177 -@am__fastdepCC_TRUE@ if $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT mmc.o -MD -MP -MF "$(DEPDIR)/mmc.Tpo" -c -o mmc.o `test -f 'gdrom/mmc.c' || echo '$(srcdir)/'`gdrom/mmc.c; \2.178 -@am__fastdepCC_TRUE@ then mv -f "$(DEPDIR)/mmc.Tpo" "$(DEPDIR)/mmc.Po"; else rm -f "$(DEPDIR)/mmc.Tpo"; exit 1; fi2.179 -@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='gdrom/mmc.c' object='mmc.o' libtool=no @AMDEPBACKSLASH@2.180 -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@2.181 -@am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o mmc.o `test -f 'gdrom/mmc.c' || echo '$(srcdir)/'`gdrom/mmc.c2.182 -2.183 -mmc.obj: gdrom/mmc.c2.184 -@am__fastdepCC_TRUE@ if $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT mmc.obj -MD -MP -MF "$(DEPDIR)/mmc.Tpo" -c -o mmc.obj `if test -f 'gdrom/mmc.c'; then $(CYGPATH_W) 'gdrom/mmc.c'; else $(CYGPATH_W) '$(srcdir)/gdrom/mmc.c'; fi`; \2.185 -@am__fastdepCC_TRUE@ then mv -f "$(DEPDIR)/mmc.Tpo" "$(DEPDIR)/mmc.Po"; else rm -f "$(DEPDIR)/mmc.Tpo"; exit 1; fi2.186 -@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='gdrom/mmc.c' object='mmc.obj' libtool=no @AMDEPBACKSLASH@2.187 -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@2.188 -@am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o mmc.obj `if test -f 'gdrom/mmc.c'; then $(CYGPATH_W) 'gdrom/mmc.c'; else $(CYGPATH_W) '$(srcdir)/gdrom/mmc.c'; fi`2.189 -2.190 sh4.o: sh4/sh4.c2.191 @am__fastdepCC_TRUE@ if $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT sh4.o -MD -MP -MF "$(DEPDIR)/sh4.Tpo" -c -o sh4.o `test -f 'sh4/sh4.c' || echo '$(srcdir)/'`sh4/sh4.c; \2.192 @am__fastdepCC_TRUE@ then mv -f "$(DEPDIR)/sh4.Tpo" "$(DEPDIR)/sh4.Po"; else rm -f "$(DEPDIR)/sh4.Tpo"; exit 1; fi2.193 @@ -1402,6 +1388,20 @@2.194 @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@2.195 @am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o video_null.obj `if test -f 'drivers/video_null.c'; then $(CYGPATH_W) 'drivers/video_null.c'; else $(CYGPATH_W) '$(srcdir)/drivers/video_null.c'; fi`2.197 +cd_mmc.o: drivers/cd_mmc.c2.198 +@am__fastdepCC_TRUE@ if $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT cd_mmc.o -MD -MP -MF "$(DEPDIR)/cd_mmc.Tpo" -c -o cd_mmc.o `test -f 'drivers/cd_mmc.c' || echo '$(srcdir)/'`drivers/cd_mmc.c; \2.199 +@am__fastdepCC_TRUE@ then mv -f "$(DEPDIR)/cd_mmc.Tpo" "$(DEPDIR)/cd_mmc.Po"; else rm -f "$(DEPDIR)/cd_mmc.Tpo"; exit 1; fi2.200 +@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='drivers/cd_mmc.c' object='cd_mmc.o' libtool=no @AMDEPBACKSLASH@2.201 +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@2.202 +@am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o cd_mmc.o `test -f 'drivers/cd_mmc.c' || echo '$(srcdir)/'`drivers/cd_mmc.c2.203 +2.204 +cd_mmc.obj: drivers/cd_mmc.c2.205 +@am__fastdepCC_TRUE@ if $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT cd_mmc.obj -MD -MP -MF "$(DEPDIR)/cd_mmc.Tpo" -c -o cd_mmc.obj `if test -f 'drivers/cd_mmc.c'; then $(CYGPATH_W) 'drivers/cd_mmc.c'; else $(CYGPATH_W) '$(srcdir)/drivers/cd_mmc.c'; fi`; \2.206 +@am__fastdepCC_TRUE@ then mv -f "$(DEPDIR)/cd_mmc.Tpo" "$(DEPDIR)/cd_mmc.Po"; else rm -f "$(DEPDIR)/cd_mmc.Tpo"; exit 1; fi2.207 +@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='drivers/cd_mmc.c' object='cd_mmc.obj' libtool=no @AMDEPBACKSLASH@2.208 +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@2.209 +@am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o cd_mmc.obj `if test -f 'drivers/cd_mmc.c'; then $(CYGPATH_W) 'drivers/cd_mmc.c'; else $(CYGPATH_W) '$(srcdir)/drivers/cd_mmc.c'; fi`2.210 +2.211 video_gl.o: drivers/video_gl.c2.212 @am__fastdepCC_TRUE@ if $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT video_gl.o -MD -MP -MF "$(DEPDIR)/video_gl.Tpo" -c -o video_gl.o `test -f 'drivers/video_gl.c' || echo '$(srcdir)/'`drivers/video_gl.c; \2.213 @am__fastdepCC_TRUE@ then mv -f "$(DEPDIR)/video_gl.Tpo" "$(DEPDIR)/video_gl.Po"; else rm -f "$(DEPDIR)/video_gl.Tpo"; exit 1; fi
3.1 --- a/src/drivers/cd_linux.c Wed Jun 03 11:39:06 2009 +00003.2 +++ b/src/drivers/cd_linux.c Mon Jun 08 04:12:21 2009 +00003.3 @@ -1,7 +1,7 @@3.4 /**3.5 * $Id$3.6 *3.7 - * Linux cd-rom device driver.3.8 + * Linux cd-rom device driver. Implemented using the SCSI transport.3.9 *3.10 * Copyright (c) 2005 Nathan Keynes.3.11 *3.12 @@ -31,35 +31,31 @@3.13 #include "gdrom/packet.h"3.14 #include "dream.h"3.16 -#define MAXTOCENTRIES 600 /* This is a fairly generous overestimate really */3.17 -#define MAXTOCSIZE 4 + (MAXTOCENTRIES*11)3.18 -#define MAX_SECTORS_PER_CALL 13.19 +static gboolean linux_is_cdrom_device( FILE *f );3.20 +static gdrom_disc_t linux_open_device( const gchar *filename, FILE *f );3.21 +static gdrom_error_t linux_packet_read( gdrom_disc_t disc, unsigned char *cmd,3.22 + unsigned char *buf, uint32_t *buflen );3.23 +static gdrom_error_t linux_packet_cmd( gdrom_disc_t disc, unsigned char *cmd );3.24 +static gboolean linux_media_changed( gdrom_disc_t disc );3.26 -static uint32_t inline lbatomsf( uint32_t lba ) {3.27 - union cdrom_addr addr;3.28 - lba = lba + CD_MSF_OFFSET;3.29 - addr.msf.frame = lba % CD_FRAMES;3.30 - int seconds = lba / CD_FRAMES;3.31 - addr.msf.second = seconds % CD_SECS;3.32 - addr.msf.minute = seconds / CD_SECS;3.33 - return addr.lba;3.34 -}3.35 -3.36 -#define LBATOMSF( lba ) lbatomsf(lba)3.37 -3.38 -3.39 -static gboolean linux_image_is_valid( FILE *f );3.40 -static gdrom_disc_t linux_open_device( const gchar *filename, FILE *f );3.41 -static gdrom_error_t linux_read_disc_toc( gdrom_image_t disc );3.42 -static gdrom_error_t linux_identify_drive( int fd, char *buf, int buflen );3.43 -static gdrom_error_t linux_read_sector( gdrom_disc_t disc, uint32_t sector,3.44 - int mode, unsigned char *buf, uint32_t *length );3.45 -static gdrom_error_t linux_send_command( int fd, char *cmd, unsigned char *buffer, uint32_t *buflen,3.46 - int direction );3.47 -static int linux_drive_status( gdrom_disc_t disc );3.49 struct gdrom_image_class cdrom_device_class = { "Linux", NULL,3.50 - linux_image_is_valid, linux_open_device };3.51 + linux_is_cdrom_device, linux_open_device };3.52 +3.53 +static struct gdrom_scsi_transport linux_scsi_transport = {3.54 + linux_packet_read, linux_packet_cmd, linux_media_changed };3.55 +3.56 +static gboolean linux_is_cdrom_device( FILE *f )3.57 +{3.58 + int caps = ioctl(fileno(f), CDROM_GET_CAPABILITY);3.59 + if( caps == -1 ) {3.60 + /* Quick check that this is really a CD device */3.61 + return FALSE;3.62 + } else {3.63 + return TRUE;3.64 + }3.65 +}3.66 +3.67 GList *cdrom_get_native_devices(void)3.68 {3.69 GList *list = NULL;3.70 @@ -76,11 +72,17 @@3.71 int caps = ioctl(fd, CDROM_GET_CAPABILITY);3.72 if( caps != -1 ) {3.73 /* Appears to support CDROM functions */3.74 - char buf[32];3.75 - linux_identify_drive( fd, buf, sizeof(buf) );3.76 - list = g_list_append( list, gdrom_device_new(ent->fs_spec, buf));3.77 + FILE *f = fdopen(fd,"r");3.78 + gdrom_disc_t disc = gdrom_scsi_disc_new(ent->fs_spec, f, &linux_scsi_transport);3.79 + if( disc != NULL ) {3.80 + list = g_list_append( list, gdrom_device_new(disc->name, disc->display_name) );3.81 + disc->destroy(disc,TRUE);3.82 + } else {3.83 + close(fd);3.84 + }3.85 + } else {3.86 + close(fd);3.87 }3.88 - close(fd);3.89 }3.90 }3.91 return list;3.92 @@ -91,177 +93,36 @@3.93 return NULL;3.94 }3.96 -static gboolean linux_image_is_valid( FILE *f )3.97 +static gdrom_disc_t linux_open_device( const gchar *filename, FILE *f )3.98 {3.99 - struct stat st;3.100 - struct cdrom_tochdr tochdr;3.101 + if( !linux_is_cdrom_device(f) ) {3.102 + return NULL;3.103 + }3.105 - if( fstat(fileno(f), &st) == -1 ) {3.106 - return FALSE; /* can't stat device? */3.107 - }3.108 - if( !S_ISBLK(st.st_mode) ) {3.109 - return FALSE; /* Not a block device */3.110 - }3.111 -3.112 - int caps = ioctl(fileno(f), CDROM_GET_CAPABILITY);3.113 - if( caps == -1 ) {3.114 - /* Quick check that this is really a CD device */3.115 - return FALSE;3.116 - }3.117 -3.118 - return TRUE;3.119 + return gdrom_scsi_disc_new(filename, f, &linux_scsi_transport);3.120 }3.122 -static gdrom_disc_t linux_open_device( const gchar *filename, FILE *f )3.123 +static gboolean linux_media_changed( gdrom_disc_t disc )3.124 {3.125 - gdrom_disc_t disc;3.126 -3.127 - disc = gdrom_image_new(filename, f);3.128 - if( disc == NULL ) {3.129 - ERROR("Unable to allocate memory!");3.130 - return NULL;3.131 - }3.132 -3.133 - int status = ioctl(fileno(f), CDROM_DRIVE_STATUS, CDSL_CURRENT);3.134 - if( status == CDS_DISC_OK ) {3.135 - status = linux_read_disc_toc( (gdrom_image_t)disc );3.136 - if( status != 0 ) {3.137 - gdrom_image_destroy_no_close(disc);3.138 - if( status == 0xFFFF ) {3.139 - ERROR("Unable to load disc table of contents (%s)", strerror(errno));3.140 - } else {3.141 - ERROR("Unable to load disc table of contents (sense %d,%d)",3.142 - status &0xFF, status >> 8 );3.143 - }3.144 - return NULL;3.145 - }3.146 - } else {3.147 - ((gdrom_image_t)disc)->disc_type = IDE_DISC_NONE;3.148 - }3.149 - disc->read_sector = linux_read_sector;3.150 - disc->drive_status = linux_drive_status;3.151 - return disc;3.152 -}3.153 -3.154 -static int linux_drive_status( gdrom_disc_t disc )3.155 -{3.156 - int fd = fileno(((gdrom_image_t)disc)->file);3.157 + int fd = fileno(disc->file);3.158 int status = ioctl(fd, CDROM_DRIVE_STATUS, CDSL_CURRENT);3.159 if( status == CDS_DISC_OK ) {3.160 status = ioctl(fd, CDROM_MEDIA_CHANGED, CDSL_CURRENT);3.161 - if( status != 0 ) {3.162 - linux_read_disc_toc( (gdrom_image_t)disc);3.163 - }3.164 - return ((gdrom_image_t)disc)->disc_type | IDE_DISC_READY;3.165 + return status == 0 ? FALSE : TRUE;3.166 } else {3.167 - return IDE_DISC_NONE;3.168 + return disc->disc_type == IDE_DISC_NONE ? FALSE : TRUE;3.169 }3.170 }3.171 -/**3.172 - * Read the full table of contents into the disc from the device.3.173 - */3.174 -static gdrom_error_t linux_read_disc_toc( gdrom_image_t disc )3.175 -{3.176 - int fd = fileno(disc->file);3.177 - unsigned char buf[MAXTOCSIZE];3.178 - uint32_t buflen = sizeof(buf);3.179 - char cmd[12] = { 0x43, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0 };3.180 -3.181 - cmd[7] = (sizeof(buf))>>8;3.182 - cmd[8] = (sizeof(buf))&0xFF;3.183 - memset( buf, 0, sizeof(buf) );3.184 - gdrom_error_t status = linux_send_command( fd, cmd, buf, &buflen, CGC_DATA_READ );3.185 - if( status != 0 ) {3.186 - return status;3.187 - }3.188 - mmc_parse_toc2( disc, buf );3.189 - return 0;3.190 -}3.191 -3.192 -gdrom_error_t linux_play_audio( gdrom_disc_t disc, uint32_t lba, uint32_t endlba )3.193 -{3.194 - int fd = fileno( ((gdrom_image_t)disc)->file );3.195 - uint32_t real_sector = lba - CD_MSF_OFFSET;3.196 - uint32_t length = endlba - lba;3.197 - uint32_t buflen = 0;3.198 - char cmd[12] = { 0xA5, 0,0,0, 0,0,0,0, 0,0,0,0 };3.199 - cmd[2] = (real_sector >> 24) & 0xFF;3.200 - cmd[3] = (real_sector >> 16) & 0xFF;3.201 - cmd[4] = (real_sector >> 8) & 0xFF;3.202 - cmd[5] = real_sector & 0xFF;3.203 - cmd[6] = (length >> 24) & 0xFF;3.204 - cmd[7] = (length >> 16) & 0xFF;3.205 - cmd[8] = (length >> 8) & 0xFF;3.206 - cmd[9] = length & 0xFF;3.207 -3.208 - return linux_send_command( fd, cmd, NULL, &buflen, CGC_DATA_NONE );3.209 -}3.210 -3.211 -gdrom_error_t linux_stop_audio( gdrom_disc_t disc )3.212 -{3.213 - int fd = fileno( ((gdrom_image_t)disc)->file );3.214 - uint32_t buflen = 0;3.215 - char cmd[12] = {0x4E,0,0,0, 0,0,0,0, 0,0,0,0};3.216 - return linux_send_command( fd, cmd, NULL, &buflen, CGC_DATA_NONE );3.217 -}3.218 -3.219 -static char *trim( char *src )3.220 -{3.221 - char *p = src + strlen(src)-1;3.222 - while( isspace(*src) )3.223 - src++;3.224 - while( p >= src && isspace(*p) )3.225 - *p-- = '\0';3.226 - return src;3.227 -}3.228 -static gdrom_error_t linux_identify_drive( int fd, char *buf, int buflen )3.229 -{3.230 - unsigned char ident[256];3.231 - uint32_t identlen = 256;3.232 - char cmd[12] = {0x12,0,0,0, 0xFF,0,0,0, 0,0,0,0};3.233 - gdrom_error_t status =3.234 - linux_send_command( fd, cmd, ident, &identlen, CGC_DATA_READ );3.235 - if( status == 0 ) {3.236 - char vendorid[9];3.237 - char productid[17];3.238 - char productrev[5];3.239 - memcpy( vendorid, ident+8, 8 ); vendorid[8] = 0;3.240 - memcpy( productid, ident+16, 16 ); productid[16] = 0;3.241 - memcpy( productrev, ident+32, 4 ); productrev[4] = 0;3.242 -3.243 - snprintf( buf, buflen, "%.8s %.16s %.4s", trim(vendorid),3.244 - trim(productid), trim(productrev) );3.245 - }3.246 - return status;3.247 -}3.248 -3.249 -static gdrom_error_t linux_read_sector( gdrom_disc_t disc, uint32_t sector,3.250 - int mode, unsigned char *buf, uint32_t *length )3.251 -{3.252 - gdrom_image_t image = (gdrom_image_t)disc;3.253 - int fd = fileno(image->file);3.254 - uint32_t real_sector = sector - CD_MSF_OFFSET;3.255 - uint32_t sector_size = MAX_SECTOR_SIZE;3.256 - char cmd[12];3.257 -3.258 - mmc_make_read_cd_cmd( cmd, real_sector, mode );3.259 -3.260 - gdrom_error_t status = linux_send_command( fd, cmd, buf, §or_size, CGC_DATA_READ );3.261 - if( status != 0 ) {3.262 - return status;3.263 - }3.264 - *length = 2048;3.265 - return 0;3.266 -}3.268 /**3.269 * Send a packet command to the device and wait for a response.3.270 * @return 0 on success, -1 on an operating system error, or a sense error3.271 * code on a device error.3.272 */3.273 -static gdrom_error_t linux_send_command( int fd, char *cmd, unsigned char *buffer, uint32_t *buflen,3.274 - int direction )3.275 +static gdrom_error_t linux_packet_read( gdrom_disc_t disc, unsigned char *cmd,3.276 + unsigned char *buffer, uint32_t *buflen )3.277 {3.278 + int fd = fileno(disc->file);3.279 struct request_sense sense;3.280 struct cdrom_generic_command cgc;3.282 @@ -271,7 +132,7 @@3.283 cgc.buffer = buffer;3.284 cgc.buflen = *buflen;3.285 cgc.sense = &sense;3.286 - cgc.data_direction = direction;3.287 + cgc.data_direction = CGC_DATA_READ;3.289 if( ioctl(fd, CDROM_SEND_PACKET, &cgc) < 0 ) {3.290 if( sense.sense_key == 0 ) {3.291 @@ -285,3 +146,29 @@3.292 return 0;3.293 }3.294 }3.295 +3.296 +static gdrom_error_t linux_packet_cmd( gdrom_disc_t disc, unsigned char *cmd )3.297 +{3.298 + int fd = fileno(disc->file);3.299 + struct request_sense sense;3.300 + struct cdrom_generic_command cgc;3.301 +3.302 + memset( &cgc, 0, sizeof(cgc) );3.303 + memset( &sense, 0, sizeof(sense) );3.304 + memcpy( cgc.cmd, cmd, 12 );3.305 + cgc.buffer = 0;3.306 + cgc.buflen = 0;3.307 + cgc.sense = &sense;3.308 + cgc.data_direction = CGC_DATA_NONE;3.309 +3.310 + if( ioctl(fd, CDROM_SEND_PACKET, &cgc) < 0 ) {3.311 + if( sense.sense_key == 0 ) {3.312 + return -1;3.313 + } else {3.314 + /* TODO: Map newer codes back to the ones used by the gd-rom. */3.315 + return sense.sense_key | (sense.asc<<8);3.316 + }3.317 + } else {3.318 + return 0;3.319 + }3.320 +}
4.1 --- /dev/null Thu Jan 01 00:00:00 1970 +00004.2 +++ b/src/drivers/cd_mmc.c Mon Jun 08 04:12:21 2009 +00004.3 @@ -0,0 +1,242 @@4.4 +/**4.5 + * $Id$4.6 + *4.7 + * SCSI/MMC device interface (depends on lower-level SCSI transport)4.8 + *4.9 + * Copyright (c) 2009 Nathan Keynes.4.10 + *4.11 + * This program is free software; you can redistribute it and/or modify4.12 + * it under the terms of the GNU General Public License as published by4.13 + * the Free Software Foundation; either version 2 of the License, or4.14 + * (at your option) any later version.4.15 + *4.16 + * This program is distributed in the hope that it will be useful,4.17 + * but WITHOUT ANY WARRANTY; without even the implied warranty of4.18 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the4.19 + * GNU General Public License for more details.4.20 + */4.21 +4.22 +#include <string.h>4.23 +#include "lxdream.h"4.24 +#include "gettext.h"4.25 +#include "gdrom/gddriver.h"4.26 +#include "gdrom/packet.h"4.27 +4.28 +#define MAXTOCENTRIES 600 /* This is a fairly generous overestimate really */4.29 +#define MAXTOCSIZE 4 + (MAXTOCENTRIES*11)4.30 +#define MAX_SECTORS_PER_CALL 14.31 +4.32 +#define MSFTOLBA( m,s,f ) (f + (s*CD_FRAMES_PER_SECOND) + (m*CD_FRAMES_PER_MINUTE))4.33 +4.34 +static void mmc_make_read_cd_cmd( char *cmd, uint32_t real_sector, int mode )4.35 +{4.36 + cmd[0] = 0xBE;4.37 + cmd[1] = (mode & 0x0E) << 1;4.38 + cmd[2] = (real_sector >> 24) & 0xFF;4.39 + cmd[3] = (real_sector >> 16) & 0xFF;4.40 + cmd[4] = (real_sector >> 8) & 0xFF;4.41 + cmd[5] = real_sector & 0xFF;4.42 + cmd[6] = 0;4.43 + cmd[7] = 0;4.44 + cmd[8] = 1;4.45 + cmd[9] = 0;4.46 + cmd[10]= 0;4.47 + cmd[11]= 0;4.48 +4.49 + if( READ_CD_RAW(mode) ) {4.50 + cmd[9] = 0xF0;4.51 + } else {4.52 + if( READ_CD_HEADER(mode) ) {4.53 + cmd[9] = 0xA0;4.54 + }4.55 + if( READ_CD_SUBHEAD(mode) ) {4.56 + cmd[9] |= 0x40;4.57 + }4.58 + if( READ_CD_DATA(mode) ) {4.59 + cmd[9] |= 0x10;4.60 + }4.61 + }4.62 +}4.63 +4.64 +/**4.65 + * Parse the TOC (format 2) into the gdrom_disc structure4.66 + */4.67 +void mmc_parse_toc2( gdrom_disc_t disc, unsigned char *buf )4.68 +{4.69 + int max_track = 0;4.70 + int last_track = -1;4.71 + int leadout = -1;4.72 + int len = (buf[0] << 8) | buf[1];4.73 + int session_type = -1;4.74 + int i;4.75 + for( i = 4; i<len; i+=11 ) {4.76 + int session = buf[i];4.77 + int adr = buf[i+1] >> 4;4.78 + int point = buf[i+3];4.79 + if( adr == 0x01 && point > 0 && point < 100 ) {4.80 + /* Track info */4.81 + int trackno = point-1;4.82 + if( point > max_track ) {4.83 + max_track = point;4.84 + }4.85 + disc->track[trackno].flags = (buf[i+1] & 0x0F) << 4;4.86 + disc->track[trackno].session = session - 1;4.87 + disc->track[trackno].lba = MSFTOLBA(buf[i+8],buf[i+9],buf[i+10]);4.88 + if( disc->track[trackno].flags & TRACK_DATA ) {4.89 + disc->track[trackno].mode = GDROM_MODE1;4.90 + } else {4.91 + disc->track[trackno].mode = GDROM_CDDA;4.92 + }4.93 + if( last_track != -1 ) {4.94 + disc->track[last_track].sector_count = disc->track[trackno].lba -4.95 + disc->track[last_track].lba;4.96 + }4.97 + last_track = trackno;4.98 + } else switch( (adr << 8) | point ) {4.99 + case 0x1A0: /* session info */4.100 + if( buf[i+9] == 0x20 ) {4.101 + session_type = IDE_DISC_CDROMXA;4.102 + } else {4.103 + session_type = IDE_DISC_CDROM;4.104 + }4.105 + disc->disc_type = session_type;4.106 + break;4.107 + case 0x1A2: /* leadout */4.108 + leadout = MSFTOLBA(buf[i+8], buf[i+9], buf[i+10]);4.109 + break;4.110 + }4.111 + }4.112 + disc->track_count = max_track;4.113 +4.114 + if( leadout != -1 && last_track != -1 ) {4.115 + disc->track[last_track].sector_count = leadout - disc->track[last_track].lba;4.116 + }4.117 +}4.118 +4.119 +4.120 +/**4.121 + * Construct a drive indentification string based on the response to the4.122 + * INQUIRY command. On success, the disc display_name is updated with the4.123 + * drive name, otherwise the display_name is unchanged.4.124 + * @return PKT_ERR_OK on success, otherwise the host failure code.4.125 + */4.126 +static gdrom_error_t gdrom_scsi_identify_drive( gdrom_disc_t disc )4.127 +{4.128 + unsigned char ident[256];4.129 + uint32_t identlen = 256;4.130 + char cmd[12] = {0x12,0,0,0, 0xFF,0,0,0, 0,0,0,0};4.131 + gdrom_error_t status = SCSI_TRANSPORT(disc)->packet_read( disc, cmd, ident, &identlen );4.132 + if( status == PKT_ERR_OK ) {4.133 + char vendorid[9];4.134 + char productid[17];4.135 + char productrev[5];4.136 + memcpy( vendorid, ident+8, 8 ); vendorid[8] = 0;4.137 + memcpy( productid, ident+16, 16 ); productid[16] = 0;4.138 + memcpy( productrev, ident+32, 4 ); productrev[4] = 0;4.139 + g_free( (char *)disc->display_name );4.140 + disc->display_name = g_strdup_printf( "%.8s %.16s %.4s", g_strstrip(vendorid),4.141 + g_strstrip(productid), g_strstrip(productrev) );4.142 + }4.143 + return status;4.144 +}4.145 +4.146 +4.147 +static gdrom_error_t gdrom_scsi_read_sector( gdrom_disc_t disc, uint32_t sector,4.148 + int mode, unsigned char *buf, uint32_t *length )4.149 +{4.150 + uint32_t real_sector = sector - GDROM_PREGAP;4.151 + uint32_t sector_size = MAX_SECTOR_SIZE;4.152 + char cmd[12];4.153 +4.154 + mmc_make_read_cd_cmd( cmd, real_sector, mode );4.155 +4.156 + gdrom_error_t status = SCSI_TRANSPORT(disc)->packet_read( disc, cmd, buf, §or_size );4.157 + if( status != 0 ) {4.158 + return status;4.159 + }4.160 + /* FIXME */4.161 + *length = 2048;4.162 + return 0;4.163 +}4.164 +4.165 +/**4.166 + * Read the full table of contents into the disc from the device.4.167 + */4.168 +static gdrom_error_t gdrom_scsi_read_toc( gdrom_disc_t disc )4.169 +{4.170 + unsigned char buf[MAXTOCSIZE];4.171 + uint32_t buflen = sizeof(buf);4.172 + char cmd[12] = { 0x43, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0 };4.173 +4.174 + cmd[7] = (sizeof(buf))>>8;4.175 + cmd[8] = (sizeof(buf))&0xFF;4.176 + memset( buf, 0, sizeof(buf) );4.177 + gdrom_error_t status = SCSI_TRANSPORT(disc)->packet_read(disc, cmd, buf, &buflen );4.178 + if( status == PKT_ERR_OK ) {4.179 + mmc_parse_toc2( disc, buf );4.180 + } else {4.181 + if( status & 0xFF != 0x02 ) {4.182 + /* Sense key 2 == Not Ready (ie temporary failure). Just ignore and4.183 + * consider the drive empty for now, but warn about any other errors4.184 + * we get. */4.185 + WARN( _("Unable to read disc table of contents (error %04x)"), status );4.186 + }4.187 + disc->disc_type = IDE_DISC_NONE;4.188 + }4.189 + return status;4.190 +}4.191 +4.192 +static gboolean gdrom_scsi_check_status( gdrom_disc_t disc )4.193 +{4.194 + if( SCSI_TRANSPORT(disc)->media_changed(disc) ) {4.195 + gdrom_scsi_read_toc(disc);4.196 + return TRUE;4.197 + } else {4.198 + return FALSE;4.199 + }4.200 +}4.201 +4.202 +static gdrom_error_t gdrom_scsi_play_audio( gdrom_disc_t disc, uint32_t lba, uint32_t endlba )4.203 +{4.204 + uint32_t real_sector = lba - GDROM_PREGAP;4.205 + uint32_t length = endlba - lba;4.206 +4.207 + char cmd[12] = { 0xA5, 0,0,0, 0,0,0,0, 0,0,0,0 };4.208 + cmd[2] = (real_sector >> 24) & 0xFF;4.209 + cmd[3] = (real_sector >> 16) & 0xFF;4.210 + cmd[4] = (real_sector >> 8) & 0xFF;4.211 + cmd[5] = real_sector & 0xFF;4.212 + cmd[6] = (length >> 24) & 0xFF;4.213 + cmd[7] = (length >> 16) & 0xFF;4.214 + cmd[8] = (length >> 8) & 0xFF;4.215 + cmd[9] = length & 0xFF;4.216 +4.217 + return SCSI_TRANSPORT(disc)->packet_cmd( disc, cmd );4.218 +}4.219 +4.220 +4.221 +gdrom_error_t gdrom_scsi_stop_audio( gdrom_disc_t disc )4.222 +{4.223 + int fd = fileno(disc->file);4.224 + uint32_t buflen = 0;4.225 + char cmd[12] = {0x4E,0,0,0, 0,0,0,0, 0,0,0,0};4.226 +4.227 + return SCSI_TRANSPORT(disc)->packet_cmd( disc, cmd );4.228 +}4.229 +4.230 +4.231 +gdrom_disc_t gdrom_scsi_disc_new( const gchar *filename, FILE *f, gdrom_scsi_transport_t scsi )4.232 +{4.233 + gdrom_disc_t disc = gdrom_disc_new(filename,f);4.234 + if( disc != NULL ) {4.235 + /* Initialize */4.236 + disc->impl_data = scsi;4.237 + disc->check_status = gdrom_scsi_check_status;4.238 + disc->read_sector = gdrom_scsi_read_sector;4.239 + disc->play_audio = gdrom_scsi_play_audio;4.240 + disc->run_time_slice = NULL;4.241 + gdrom_scsi_identify_drive(disc);4.242 + gdrom_scsi_read_toc(disc);4.243 + }4.244 + return disc;4.245 +}4.246 \ No newline at end of file
5.1 --- a/src/drivers/cd_osx.c Wed Jun 03 11:39:06 2009 +00005.2 +++ b/src/drivers/cd_osx.c Mon Jun 08 04:12:21 2009 +00005.3 @@ -35,30 +35,32 @@5.5 static gboolean cdrom_osx_image_is_valid( FILE *f );5.6 static gdrom_disc_t cdrom_osx_open_device( const gchar *filename, FILE *f );5.7 -static gdrom_error_t cdrom_osx_read_toc( gdrom_image_t disc );5.8 +static gdrom_error_t cdrom_osx_read_toc( gdrom_disc_t disc );5.9 static gdrom_error_t cdrom_osx_read_sector( gdrom_disc_t disc, uint32_t sector,5.10 int mode, unsigned char *buf, uint32_t *length );5.12 struct gdrom_image_class cdrom_device_class = { "osx", NULL,5.13 cdrom_osx_image_is_valid, cdrom_osx_open_device };5.15 -#define OSX_DRIVE(disc) ( (osx_cdrom_drive_t)(((gdrom_image_t)disc)->private) )5.16 +#define OSX_DRIVE(disc) ( (osx_cdrom_drive_t)(((gdrom_disc_t)disc)->impl_data) )5.18 -static void cdrom_osx_destroy( gdrom_disc_t disc )5.19 +static void cdrom_osx_destroy( gdrom_disc_t disc, gboolean close_fh )5.20 {5.21 - osx_cdrom_close_drive( OSX_DRIVE(disc) );5.22 - gdrom_image_destroy_no_close( disc );5.23 + if( close_fh ) {5.24 + osx_cdrom_close_drive( OSX_DRIVE(disc) );5.25 + }5.26 + gdrom_disc_destroy( disc, FALSE ); /* chain to the main destroy */5.27 }5.29 static void cdrom_osx_media_changed( osx_cdrom_drive_t drive, gboolean present,5.30 void *user_data )5.31 {5.32 - gdrom_image_t image = (gdrom_image_t)user_data;5.33 + gdrom_disc_t disc = (gdrom_disc_t)user_data;5.34 if( present ) {5.35 - cdrom_osx_read_toc( image );5.36 + cdrom_osx_read_toc( disc );5.37 } else {5.38 - image->disc_type = IDE_DISC_NONE;5.39 - image->track_count = 0;5.40 + disc->disc_type = IDE_DISC_NONE;5.41 + disc->track_count = 0;5.42 }5.43 }5.45 @@ -67,14 +69,14 @@5.46 {5.47 char tmp[strlen(name)+7];5.48 sprintf( tmp, "dvd://%s", name );5.49 - gdrom_image_t image = (gdrom_image_t)gdrom_image_new(tmp, NULL);5.50 - image->private = drive;5.51 + gdrom_disc_t disc = gdrom_disc_new(tmp, NULL);5.52 + disc->impl_data = drive;5.54 - image->disc.read_sector = cdrom_osx_read_sector;5.55 - image->disc.close = cdrom_osx_destroy;5.56 - cdrom_osx_read_toc(image);5.57 - osx_cdrom_set_media_changed_callback( drive, cdrom_osx_media_changed, image );5.58 - return (gdrom_disc_t)image;5.59 + disc->read_sector = cdrom_osx_read_sector;5.60 + disc->destroy = cdrom_osx_destroy;5.61 + cdrom_osx_read_toc(disc);5.62 + osx_cdrom_set_media_changed_callback( drive, cdrom_osx_media_changed, disc );5.63 + return (gdrom_disc_t)disc;5.64 }5.66 gdrom_disc_t cdrom_open_device( const gchar *method, const gchar *path )5.67 @@ -123,14 +125,14 @@5.68 return NULL;5.69 }5.71 -static gdrom_error_t cdrom_osx_read_toc( gdrom_image_t image )5.72 +static gdrom_error_t cdrom_osx_read_toc( gdrom_disc_t disc )5.73 {5.74 - osx_cdrom_drive_t drive = OSX_DRIVE(image);5.75 + osx_cdrom_drive_t drive = OSX_DRIVE(disc);5.77 int fh = osx_cdrom_get_media_handle(drive);5.78 if( fh == -1 ) {5.79 - image->disc_type = IDE_DISC_NONE;5.80 - image->track_count = 0;5.81 + disc->disc_type = IDE_DISC_NONE;5.82 + disc->track_count = 0;5.83 return -1;5.84 } else {5.85 unsigned char buf[MAXTOCSIZE];5.86 @@ -143,11 +145,12 @@5.87 readtoc.buffer = buf;5.89 if( ioctl(fh, DKIOCCDREADTOC, &readtoc ) == -1 ) {5.90 - image->disc_type = IDE_DISC_NONE;5.91 - image->track_count = 0;5.92 + WARN( "Failed to read TOC (%s)", strerror(errno) );5.93 + disc->disc_type = IDE_DISC_NONE;5.94 + disc->track_count = 0;5.95 return -1;5.96 } else {5.97 - mmc_parse_toc2( image, buf );5.98 + mmc_parse_toc2( disc, buf );5.99 }5.100 }5.101 return 0;5.102 @@ -156,7 +159,6 @@5.103 static gdrom_error_t cdrom_osx_read_sector( gdrom_disc_t disc, uint32_t lba,5.104 int mode, unsigned char *buf, uint32_t *length )5.105 {5.106 - gdrom_image_t image = (gdrom_image_t)disc;5.107 int real_lba = lba - 150;5.108 int sector_size = 2352;5.109 int direct_read = 1;5.110 @@ -179,8 +181,8 @@5.111 /* Sector could be anything - need to do a raw read and then parse5.112 * the requested data out ourselves5.113 */5.114 - int track_no = gdrom_image_get_track_by_lba( image, lba );5.115 - struct gdrom_track *track = &image->track[track_no-1];5.116 + int track_no = gdrom_disc_get_track_by_lba( disc, lba );5.117 + struct gdrom_track *track = &disc->track[track_no-1];5.119 sector_size = 2352;5.120 if( track->mode == GDROM_CDDA ) {
6.1 --- a/src/drivers/osx_iokit.m Wed Jun 03 11:39:06 2009 +00006.2 +++ b/src/drivers/osx_iokit.m Mon Jun 08 04:12:21 2009 +00006.3 @@ -50,6 +50,7 @@6.4 };6.6 static gboolean get_bsdname_for_iomedia( io_object_t iomedia, char *buf, int buflen );6.7 +static gboolean get_boolean_property( io_object_t io, CFStringRef key, gboolean def );6.9 /***************** IOKit Callbacks ******************/6.11 @@ -91,7 +92,8 @@6.12 io_string_t iopath = "";6.13 IORegistryEntryGetPath( object, kIOServicePlane, iopath );6.14 if( drive != NULL && g_str_has_prefix(iopath, drive->ioservice_path ) &&6.15 - get_bsdname_for_iomedia(object, drive->media_path, sizeof(drive->media_path)) ) {6.16 + get_boolean_property(object, CFSTR("Whole"), TRUE) &&6.17 + get_bsdname_for_iomedia(object, drive->media_path, sizeof(drive->media_path)) ) {6.18 // A disc was inserted within the drive of interest6.19 if( drive->media_fh != -1 ) {6.20 close(drive->media_fh);6.21 @@ -143,6 +145,21 @@6.22 return result;6.23 }6.25 +/**6.26 + * Retrieve a boolean property from the io object, and return as a gboolean. If6.27 + * the key is not present, return def instead.6.28 + */6.29 +static gboolean get_boolean_property( io_object_t io, CFStringRef key, gboolean def )6.30 +{6.31 + gboolean result = def;6.32 + CFTypeRef ref = IORegistryEntryCreateCFProperty(io, key, kCFAllocatorDefault, 0 );6.33 + if( ref ) {6.34 + result = CFBooleanGetValue(ref);6.35 + CFRelease(ref);6.36 + }6.37 + return result;6.38 + }6.39 +6.40 static gboolean osx_cdrom_drive_get_name( io_object_t object, char *vendor, int vendor_len,6.41 char *product, int product_len )6.42 {
7.1 --- a/src/gdrom/cdi.c Wed Jun 03 11:39:06 2009 +00007.2 +++ b/src/gdrom/cdi.c Mon Jun 08 04:12:21 2009 +00007.3 @@ -76,7 +76,6 @@7.4 gdrom_disc_t cdi_image_open( const gchar *filename, FILE *f )7.5 {7.6 gdrom_disc_t disc = NULL;7.7 - gdrom_image_t image;7.8 int i,j;7.9 uint16_t session_count;7.10 uint16_t track_count;7.11 @@ -110,13 +109,12 @@7.12 ERROR("Unable to allocate memory!");7.13 return NULL;7.14 }7.15 - image = (gdrom_image_t)disc;7.17 for( i=0; i< session_count; i++ ) {7.18 fread( &track_count, sizeof(track_count), 1, f );7.19 if( track_count + total_tracks > 99 ) {7.20 ERROR( "Invalid number of tracks, bad cdi image\n" );7.21 - gdrom_image_destroy_no_close(disc);7.22 + disc->destroy(disc,FALSE);7.23 return NULL;7.24 }7.25 for( j=0; j<track_count; j++ ) {7.26 @@ -130,7 +128,7 @@7.27 fread( marker, 20, 1, f );7.28 if( memcmp( marker, TRACK_START_MARKER, 20) != 0 ) {7.29 ERROR( "Track start marker not found, error reading cdi image\n" );7.30 - gdrom_image_destroy_no_close(disc);7.31 + disc->destroy(disc,FALSE);7.32 return NULL;7.33 }7.34 fseek( f, 4, SEEK_CUR );7.35 @@ -144,56 +142,56 @@7.36 fseek( f, 2, SEEK_CUR );7.37 }7.38 fread( &trk, sizeof(trk), 1, f );7.39 - image->track[total_tracks].session = i;7.40 - image->track[total_tracks].lba = trk.start_lba + 150;7.41 - image->track[total_tracks].sector_count = trk.length;7.42 + disc->track[total_tracks].session = i;7.43 + disc->track[total_tracks].lba = trk.start_lba + 150;7.44 + disc->track[total_tracks].sector_count = trk.length;7.45 switch( trk.mode ) {7.46 case 0:7.47 - image->track[total_tracks].mode = GDROM_CDDA;7.48 - image->track[total_tracks].sector_size = 2352;7.49 - image->track[total_tracks].flags = 0x01;7.50 + disc->track[total_tracks].mode = GDROM_CDDA;7.51 + disc->track[total_tracks].sector_size = 2352;7.52 + disc->track[total_tracks].flags = 0x01;7.53 if( trk.sector_size != 2 ) {7.54 ERROR( "Invalid combination of mode %d with size %d", trk.mode, trk.sector_size );7.55 - gdrom_image_destroy_no_close(disc);7.56 + disc->destroy(disc,FALSE);7.57 return NULL;7.58 }7.59 break;7.60 case 1:7.61 - image->track[total_tracks].mode = GDROM_MODE1;7.62 - image->track[total_tracks].sector_size = 2048;7.63 - image->track[total_tracks].flags = 0x41;7.64 + disc->track[total_tracks].mode = GDROM_MODE1;7.65 + disc->track[total_tracks].sector_size = 2048;7.66 + disc->track[total_tracks].flags = 0x41;7.67 if( trk.sector_size != 0 ) {7.68 ERROR( "Invalid combination of mode %d with size %d", trk.mode, trk.sector_size );7.69 - gdrom_image_destroy_no_close(disc);7.70 + disc->destroy(disc,FALSE);7.71 return NULL;7.72 }7.73 break;7.74 case 2:7.75 - image->track[total_tracks].flags = 0x41;7.76 + disc->track[total_tracks].flags = 0x41;7.77 switch( trk.sector_size ) {7.78 case 0:7.79 - image->track[total_tracks].mode = GDROM_MODE2_FORM1;7.80 - image->track[total_tracks].sector_size = 2048;7.81 + disc->track[total_tracks].mode = GDROM_MODE2_FORM1;7.82 + disc->track[total_tracks].sector_size = 2048;7.83 break;7.84 case 1:7.85 - image->track[total_tracks].mode = GDROM_SEMIRAW_MODE2;7.86 - image->track[total_tracks].sector_size = 2336;7.87 + disc->track[total_tracks].mode = GDROM_SEMIRAW_MODE2;7.88 + disc->track[total_tracks].sector_size = 2336;7.89 break;7.90 case 2:7.91 default:7.92 ERROR( "Invalid combination of mode %d with size %d", trk.mode, trk.sector_size );7.93 - gdrom_image_destroy_no_close(disc);7.94 + disc->destroy(disc,FALSE);7.95 return NULL;7.96 }7.97 break;7.98 default:7.99 ERROR( "Unsupported track mode %d", trk.mode );7.100 - gdrom_image_destroy_no_close(disc);7.101 + disc->destroy(disc,FALSE);7.102 return NULL;7.103 }7.104 - image->track[total_tracks].offset = posn +7.105 - trk.pregap_length * image->track[total_tracks].sector_size ;7.106 - posn += trk.total_length * image->track[total_tracks].sector_size;7.107 + disc->track[total_tracks].offset = posn +7.108 + trk.pregap_length * disc->track[total_tracks].sector_size ;7.109 + posn += trk.total_length * disc->track[total_tracks].sector_size;7.110 total_tracks++;7.111 fread( marker, 1, 9, f );7.112 if( memcmp( marker, EXT_MARKER, 9 ) == 0 ) {7.113 @@ -204,6 +202,6 @@7.114 }7.115 fseek( f, 12, SEEK_CUR );7.116 }7.117 - image->track_count = total_tracks;7.118 + disc->track_count = total_tracks;7.119 return disc;7.120 }
8.1 --- a/src/gdrom/gddriver.h Wed Jun 03 11:39:06 2009 +00008.2 +++ b/src/gdrom/gddriver.h Mon Jun 08 04:12:21 2009 +00008.3 @@ -32,15 +32,11 @@8.5 #define MAX_SECTOR_SIZE 23528.7 +#define CD_MSF_START 150 /* MSF numbering starts after the initial pregap */8.8 #define CD_FRAMES_PER_SECOND 758.9 #define CD_SECONDS_PER_MINUTE 608.10 #define CD_FRAMES_PER_MINUTE (CD_FRAMES_PER_SECOND*CD_SECONDS_PER_MINUTE)8.12 -struct gdrom_toc {8.13 - uint32_t track[99];8.14 - uint32_t first, last, leadout;8.15 -};8.16 -8.17 #define GDROM_PREGAP 150 /* Sectors */8.19 extern uint32_t gdrom_sector_size[];8.20 @@ -75,8 +71,8 @@8.21 */8.22 #define IDE_DISC_READY 0x01 /* ored with above */8.23 #define IDE_DISC_IDLE 0x02 /* ie spun-down */8.24 -#define IDE_DISC_NONE 0x068.26 +#define IDE_DISC_NONE 0x068.27 #define IDE_DISC_AUDIO 0x008.28 #define IDE_DISC_CDROM 0x108.29 #define IDE_DISC_CDROMXA 0x208.30 @@ -94,11 +90,30 @@8.31 uint32_t lba; /* start sector address */8.32 uint32_t sector_size; /* For convenience, determined by mode */8.33 uint32_t sector_count;8.34 - uint32_t offset; /* File offset of start of track - image files only */8.35 - FILE *file;8.36 + uint32_t offset; /* File offset of start of track (image files only) */8.37 + FILE *file; /* Per-track file handle (if any) */8.38 } *gdrom_track_t;8.40 struct gdrom_disc {8.41 + int disc_type; /* One of the IDE_DISC_* flags */8.42 + const gchar *name; /* Device name / Image filename (owned) */8.43 + const gchar *display_name; /* User-friendly device name, if any (owned) */8.44 + gchar mcn[14]; /* Media catalogue number */8.45 + char title[129]; /* Disc title (if any) from bootstrap */8.46 + int track_count;8.47 + struct gdrom_track track[99];8.48 + FILE *file; /* Image file / device handle */8.49 + void *impl_data; /* Implementation private data */8.50 +8.51 + /* Check for media change. If the media cannot change (ie image file)8.52 + * or is notified asynchonously, this should be a no-op. In the event of8.53 + * a change, this function should update the structure according to the8.54 + * new media (including TOC), and return TRUE.8.55 + * @return TRUE if the media has changed since the last check, otherwise8.56 + * FALSE.8.57 + */8.58 + gboolean (*check_status)( struct gdrom_disc *disc );8.59 +8.60 /**8.61 * Read a single sector from the disc at the specified logical address.8.62 * @param disc pointer to the disc structure8.63 @@ -113,70 +128,85 @@8.64 unsigned char *buf, uint32_t *length );8.66 /**8.67 - * Read the TOC from the disc and write it into the specified buffer.8.68 - * The method is responsible for returning the data in gd-rom8.69 - * format.8.70 - * @param disc pointer to the disc structure8.71 - * @param buf buffer to receive data (0x198 bytes long)8.72 - */8.73 - gdrom_error_t (*read_toc)(struct gdrom_disc *disc, unsigned char *buf);8.74 -8.75 - /**8.76 - * Read the information for the specified sector and return it in the8.77 - * supplied buffer.8.78 - * @param disc pointer to the disc structure8.79 - * @param session of interest. If 0, return end of disc information.8.80 - * @param buf buffer to receive data (6 bytes)8.81 - */8.82 - gdrom_error_t (*read_session)(struct gdrom_disc *disc, int session, unsigned char *buf);8.83 -8.84 - /**8.85 - * Read the position information (subchannel) for the specified sector8.86 - * and return it in the supplied buffer. This method does not need to8.87 - * write the first 4 bytes of the buffer.8.88 - * @param disc pointer to the disc structure8.89 - * @param lba sector to get position information for8.90 - * @param buf buffer to receive data (14 bytes)8.91 - */8.92 - gdrom_error_t (*read_position)(struct gdrom_disc *disc, uint32_t lba, unsigned char *buf);8.93 -8.94 - /**8.95 - * Return the current disc status, expressed as a combination of the8.96 - * IDE_DISC_* flags above.8.97 - * @param disc pointer to the disc structure8.98 - * @return an integer status value.8.99 - */8.100 - int (*drive_status)(struct gdrom_disc *disc);8.101 -8.102 - /**8.103 * Begin playing audio from the given lba address on the disc.8.104 */8.105 gdrom_error_t (*play_audio)(struct gdrom_disc *disc, uint32_t lba, uint32_t endlba);8.107 + /**8.108 + * Stop audio playback8.109 + */8.110 + gdrom_error_t (*stop_audio)(struct gdrom_disc *disc);8.111 +8.112 /**8.113 * Executed once per time slice to perform house-keeping operations8.114 * (checking disc status, media changed, etc).8.115 */8.116 uint32_t (*run_time_slice)( struct gdrom_disc *disc, uint32_t nanosecs );8.118 - /**8.119 - * Close the disc and release any storage or resources allocated including8.120 - * the disc structure itself.8.121 - */8.122 - void (*close)( struct gdrom_disc *disc );8.123 - const gchar *name; /* Device name / Image filename */8.124 - char title[129]; /* Disc title (if any) */8.125 + /**8.126 + * Release all memory and system resources, including the gdrom_disc itself.8.127 + * (implicitly calls close() if not already closed.8.128 + * @param disc The disc to destroy8.129 + * @param close_fh if TRUE, close the main file/device, otherwise leave open.8.130 + * This is mainly used when the handle will be immediately reused.8.131 + */8.132 + void (*destroy)( struct gdrom_disc *disc, gboolean close_fh );8.133 };8.135 -typedef struct gdrom_image {8.136 - struct gdrom_disc disc;8.137 - int disc_type;8.138 - int track_count;8.139 - struct gdrom_track track[99];8.140 - gchar mcn[14]; /* Media catalogue number */8.141 - FILE *file; /* Open file stream */8.142 - void *private; /* image private data */8.143 -} *gdrom_image_t;8.144 +/**8.145 + * Low-level SCSI transport provided to the main SCSI/MMC driver. When used8.146 + * this will be set as the disc->impl_data field.8.147 + * Note: For symmetry there should be a packet_write variant, but we don't8.148 + * currently need it for anything. YAGNI, etc.8.149 + */8.150 +typedef struct gdrom_scsi_transport {8.151 + /* Execute a read command (ie a command that returns a block of data in8.152 + * response, not necessarily a CD read).8.153 + * @param scsi The disc to execute the command8.154 + * @param cmd The 12-byte command packet8.155 + * @param buf The buffer to receive the read results8.156 + * @param length On entry, the size of buf. Modified on exit to the number8.157 + * of bytes actually read.8.158 + * @return PKT_ERR_OK on success, otherwise the host error code.8.159 + */8.160 + gdrom_error_t (*packet_read)( struct gdrom_disc *disc,8.161 + unsigned char *cmd, unsigned char *buf,8.162 + unsigned int *length );8.163 +8.164 + /* Execute a generic command that does not write or return any data.8.165 + * (eg play audio).8.166 + * @param scsi The disc to execute the command8.167 + * @param cmd The 12-byte command packet8.168 + * @return PKT_ERR_OK on success, otherwise the host error code.8.169 + */8.170 + gdrom_error_t (*packet_cmd)( struct gdrom_disc *disc,8.171 + unsigned char *cmd );8.172 +8.173 + /* Return TRUE if the media has changed since the last call, otherwise8.174 + * FALSE. This method is used to implement the disc-level check_status8.175 + * and should have no side-effects.8.176 + */8.177 + gboolean (*media_changed)( struct gdrom_disc *disc );8.178 +} *gdrom_scsi_transport_t;8.179 +8.180 +/**8.181 + * Allocate a new gdrom_disc_t and initialize the filename and file fields.8.182 + * The disc is otherwise uninitialized - this is an internal method for use8.183 + * by the concrete implementations.8.184 + */8.185 +gdrom_disc_t gdrom_disc_new(const gchar *filename, FILE *f);8.186 +8.187 +/**8.188 + * Construct a new SCSI/MMC disc using the supplied transport implementation.8.189 + */8.190 +gdrom_disc_t gdrom_scsi_disc_new(const gchar *filename, FILE *f, gdrom_scsi_transport_t transport);8.191 +8.192 +/**8.193 + * Construct a new image file using the default methods.8.194 + */8.195 +gdrom_disc_t gdrom_image_new( const gchar *filename, FILE *f );8.196 +8.197 +#define SCSI_TRANSPORT(disc) ((gdrom_scsi_transport_t)disc->impl_data)8.199 /**8.200 *8.201 @@ -194,27 +224,14 @@8.202 extern struct gdrom_image_class cdrom_device_class;8.204 /**8.205 - * Construct a new image file using the default methods.8.206 + * Determine the track number containing the specified sector by lba.8.207 */8.208 -gdrom_disc_t gdrom_image_new( const gchar *filename, FILE *f );8.209 +int gdrom_disc_get_track_by_lba( gdrom_disc_t image, uint32_t lba );8.211 /**8.212 - * Destroy an image data structure without closing the file8.213 - * (Intended for use from image loaders only)8.214 + * Default disc destroy method, for chaining from subclasses8.215 */8.216 -void gdrom_image_destroy_no_close( gdrom_disc_t d );8.217 -8.218 -/**8.219 - * Determine the track number containing the specified sector by lba.8.220 - */8.221 -int gdrom_image_get_track_by_lba( gdrom_image_t image, uint32_t lba );8.222 -8.223 -/**8.224 - * Given a base filename (eg for a .cue file), generate the path for the given8.225 - * find_name relative to the original file.8.226 - * @return a newly allocated string.8.227 - */8.228 -gchar *gdrom_get_relative_filename( const gchar *base_name, const gchar *find_name );8.229 +void gdrom_disc_destroy( gdrom_disc_t disc, gboolean close_fh );8.231 gdrom_device_t gdrom_device_new( const gchar *name, const gchar *dev_name );8.233 @@ -230,13 +247,10 @@8.234 void gdrom_extract_raw_data_sector( char *sector_data, int mode, unsigned char *buf, uint32_t *length );8.236 /**8.237 - * Parse a format 2 TOC, and write the results into the supplied disc structure.8.238 + * Check the disc for a useable DC bootstrap, and update the disc8.239 + * with the title accordingly.8.240 + * @return TRUE if we found a bootstrap, otherwise FALSE.8.241 */8.242 -void mmc_parse_toc2( gdrom_image_t disc, unsigned char *buf );8.243 -8.244 -/**8.245 - * Construct a Read CD command for the given sector + mode8.246 - */8.247 -void mmc_make_read_cd_cmd( char *cmd, uint32_t sector, int mode );8.248 +gboolean gdrom_disc_read_title( gdrom_disc_t disc );8.250 #endif /* !lxdream_gddriver_H */
9.1 --- a/src/gdrom/gdi.c Wed Jun 03 11:39:06 2009 +00009.2 +++ b/src/gdrom/gdi.c Mon Jun 08 04:12:21 2009 +00009.3 @@ -54,7 +54,6 @@9.4 int i;9.5 uint32_t track_count;9.6 gdrom_disc_t disc;9.7 - gdrom_image_t image;9.8 struct stat st;9.9 char line[512];9.10 int session = 0;9.11 @@ -76,15 +75,14 @@9.12 return NULL;9.13 }9.14 dirname = g_path_get_dirname(filename);9.15 - image = (gdrom_image_t)disc;9.16 - image->disc_type = IDE_DISC_GDROM;9.17 - image->track_count = track_count;9.18 + disc->disc_type = IDE_DISC_GDROM;9.19 + disc->track_count = track_count;9.20 for( i=0; i<track_count; i++ ) {9.21 int track_no, start_lba, flags, size, offset;9.22 char filename[256];9.24 if( fgets( line, sizeof(line), f ) == NULL ) {9.25 - gdrom_image_destroy_no_close(disc);9.26 + disc->destroy(disc,FALSE);9.27 return NULL;9.28 }9.29 sscanf( line, "%d %d %d %d %s %d", &track_no, &start_lba, &flags, &size,9.30 @@ -92,47 +90,47 @@9.31 if( start_lba >= 45000 ) {9.32 session = 1;9.33 }9.34 - image->track[i].session = session;9.35 - image->track[i].lba = start_lba + 150; // 2-second offset9.36 - image->track[i].flags = (flags & 0x0F)<<4;9.37 - image->track[i].sector_size = size;9.38 + disc->track[i].session = session;9.39 + disc->track[i].lba = start_lba + 150; // 2-second offset9.40 + disc->track[i].flags = (flags & 0x0F)<<4;9.41 + disc->track[i].sector_size = size;9.42 if( strcasecmp( filename, "none" ) == 0 ) {9.43 - image->track[i].file = NULL;9.44 - image->track[i].sector_count = 0;9.45 - image->track[i].mode = GDROM_MODE1;9.46 + disc->track[i].file = NULL;9.47 + disc->track[i].sector_count = 0;9.48 + disc->track[i].mode = GDROM_MODE1;9.49 } else {9.50 gchar *pathname = g_strdup_printf( "%s%c%s", dirname, G_DIR_SEPARATOR, filename );9.51 - image->track[i].file = fopen( pathname, "ro" );9.52 + disc->track[i].file = fopen( pathname, "ro" );9.53 g_free(pathname);9.54 - if( image->track[i].file == NULL ) {9.55 - gdrom_image_destroy_no_close(disc);9.56 + if( disc->track[i].file == NULL ) {9.57 + disc->destroy(disc,FALSE);9.58 g_free(dirname);9.59 return NULL;9.60 }9.61 - fstat( fileno(image->track[i].file), &st );9.62 - image->track[i].sector_count = st.st_size / size;9.63 - if( image->track[i].flags & TRACK_DATA ) {9.64 + fstat( fileno(disc->track[i].file), &st );9.65 + disc->track[i].sector_count = st.st_size / size;9.66 + if( disc->track[i].flags & TRACK_DATA ) {9.67 /* Data track */9.68 switch(size) {9.69 - case 2048: image->track[i].mode = GDROM_MODE1; break;9.70 - case 2336: image->track[i].mode = GDROM_SEMIRAW_MODE2; break;9.71 - case 2352: image->track[i].mode = GDROM_RAW_XA; break;9.72 + case 2048: disc->track[i].mode = GDROM_MODE1; break;9.73 + case 2336: disc->track[i].mode = GDROM_SEMIRAW_MODE2; break;9.74 + case 2352: disc->track[i].mode = GDROM_RAW_XA; break;9.75 default:9.76 - gdrom_image_destroy_no_close(disc);9.77 + disc->destroy(disc,FALSE);9.78 g_free(dirname);9.79 return NULL;9.80 }9.81 } else {9.82 /* Audio track */9.83 - image->track[i].mode = GDROM_CDDA;9.84 + disc->track[i].mode = GDROM_CDDA;9.85 if( size != 2352 ) {9.86 - gdrom_image_destroy_no_close(disc);9.87 + disc->destroy(disc,FALSE);9.88 g_free(dirname);9.89 return NULL;9.90 }9.91 }9.92 }9.93 - image->track[i].offset = offset;9.94 + disc->track[i].offset = offset;9.95 }9.96 g_free(dirname);9.97 return disc;
10.1 --- a/src/gdrom/gdimage.c Wed Jun 03 11:39:06 2009 +000010.2 +++ b/src/gdrom/gdimage.c Mon Jun 08 04:12:21 2009 +000010.3 @@ -21,20 +21,17 @@10.4 #include <string.h>10.5 #include <ctype.h>10.6 #include <sys/types.h>10.7 +#include <sys/stat.h>10.8 +#include <fcntl.h>10.9 #include <netinet/in.h>10.11 #include "gdrom/gddriver.h"10.12 #include "gdrom/packet.h"10.13 #include "ecc.h"10.14 -#include "bootstrap.h"10.16 -static void gdrom_image_destroy( gdrom_disc_t disc );10.17 +static gboolean gdrom_null_check_status( gdrom_disc_t disc );10.18 static gdrom_error_t gdrom_image_read_sector( gdrom_disc_t disc, uint32_t lba, int mode,10.19 unsigned char *buf, uint32_t *readlength );10.20 -static gdrom_error_t gdrom_image_read_toc( gdrom_disc_t disc, unsigned char *buf );10.21 -static gdrom_error_t gdrom_image_read_session( gdrom_disc_t disc, int session, unsigned char *buf );10.22 -static gdrom_error_t gdrom_image_read_position( gdrom_disc_t disc, uint32_t lba, unsigned char *buf );10.23 -static int gdrom_image_drive_status( gdrom_disc_t disc );10.25 static uint8_t gdrom_default_sync[12] = { 0, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 0 };10.27 @@ -44,7 +41,11 @@10.28 /* Data offset (from start of raw sector) by sector mode */10.29 static int gdrom_data_offset[] = { 16, 16, 16, 24, 24, 0, 8, 0, 0 };10.31 -10.32 +gdrom_image_class_t gdrom_image_classes[] = { &cdrom_device_class,10.33 + &nrg_image_class,10.34 + &cdi_image_class,10.35 + &gdi_image_class,10.36 + NULL };10.38 struct cdrom_sector_header {10.39 uint8_t sync[12];10.40 @@ -53,96 +54,139 @@10.41 uint8_t subhead[8]; // Mode-2 XA sectors only10.42 };10.44 -/**10.45 - * Initialize a gdrom_disc structure with the gdrom_image_* methods10.46 - */10.47 -void gdrom_image_init( gdrom_disc_t disc )10.48 +gdrom_disc_t gdrom_disc_new( const gchar *filename, FILE *f )10.49 {10.50 - memset( disc, 0, sizeof(struct gdrom_disc) ); /* safety */10.51 - disc->read_sector = gdrom_image_read_sector;10.52 - disc->read_toc = gdrom_image_read_toc;10.53 - disc->read_session = gdrom_image_read_session;10.54 - disc->read_position = gdrom_image_read_position;10.55 - disc->drive_status = gdrom_image_drive_status;10.56 - disc->play_audio = NULL; /* not supported yet */10.57 - disc->run_time_slice = NULL; /* not needed */10.58 - disc->close = gdrom_image_destroy;10.59 -}10.60 -10.61 -gdrom_disc_t gdrom_image_new( const gchar *filename, FILE *f )10.62 -{10.63 - gdrom_image_t image = (gdrom_image_t)g_malloc0(sizeof(struct gdrom_image));10.64 - if( image == NULL ) {10.65 + gdrom_disc_t disc = (gdrom_disc_t)g_malloc0(sizeof(struct gdrom_disc));10.66 + if( disc == NULL ) {10.67 return NULL;10.68 }10.69 - image->disc_type = IDE_DISC_CDROMXA;10.70 - image->file = f;10.71 - gdrom_disc_t disc = (gdrom_disc_t)image;10.72 - gdrom_image_init(disc);10.73 + disc->disc_type = IDE_DISC_NONE;10.74 + disc->file = f;10.75 if( filename == NULL ) {10.76 disc->name = NULL;10.77 } else {10.78 disc->name = g_strdup(filename);10.79 }10.81 + disc->check_status = gdrom_null_check_status;10.82 + disc->destroy = gdrom_disc_destroy;10.83 return disc;10.84 }10.86 -static void gdrom_image_destroy( gdrom_disc_t disc )10.87 +void gdrom_disc_destroy( gdrom_disc_t disc, gboolean close_fh )10.88 {10.89 int i;10.90 FILE *lastfile = NULL;10.91 - gdrom_image_t img = (gdrom_image_t)disc;10.92 - if( img->file != NULL ) {10.93 - fclose(img->file);10.94 - img->file = NULL;10.95 + if( disc->file != NULL ) {10.96 + if( close_fh ) {10.97 + fclose(disc->file);10.98 + }10.99 + disc->file = NULL;10.100 }10.101 - for( i=0; i<img->track_count; i++ ) {10.102 - if( img->track[i].file != NULL && img->track[i].file != lastfile ) {10.103 - lastfile = img->track[i].file;10.104 + for( i=0; i<disc->track_count; i++ ) {10.105 + if( disc->track[i].file != NULL && disc->track[i].file != lastfile ) {10.106 + lastfile = disc->track[i].file;10.107 + /* Track files (if any) are closed regardless of the value of close_fh */10.108 fclose(lastfile);10.109 - img->track[i].file = NULL;10.110 + disc->track[i].file = NULL;10.111 }10.112 }10.113 if( disc->name != NULL ) {10.114 g_free( (gpointer)disc->name );10.115 disc->name = NULL;10.116 }10.117 - free( disc );10.118 -}10.119 -10.120 -void gdrom_image_destroy_no_close( gdrom_disc_t disc )10.121 -{10.122 - int i;10.123 - FILE *lastfile = NULL;10.124 - gdrom_image_t img = (gdrom_image_t)disc;10.125 - if( img->file != NULL ) {10.126 - img->file = NULL;10.127 - }10.128 - for( i=0; i<img->track_count; i++ ) {10.129 - if( img->track[i].file != NULL && img->track[i].file != lastfile ) {10.130 - lastfile = img->track[i].file;10.131 - fclose(lastfile);10.132 - img->track[i].file = NULL;10.133 - }10.134 - }10.135 - if( disc->name != NULL ) {10.136 - g_free( (gpointer)disc->name );10.137 - disc->name = NULL;10.138 + if( disc->display_name != NULL ) {10.139 + g_free( (gpointer)disc->name );10.140 + disc->display_name = NULL;10.141 }10.142 free( disc );10.143 }10.145 -int gdrom_image_get_track_by_lba( gdrom_image_t image, uint32_t lba )10.146 +/**10.147 + * Construct a new gdrom_disc_t and initalize the vtable to the gdrom image10.148 + * default functions.10.149 + */10.150 +gdrom_disc_t gdrom_image_new( const gchar *filename, FILE *f )10.151 {10.152 + gdrom_disc_t disc = gdrom_disc_new( filename, f );10.153 + if( disc != NULL ) {10.154 + disc->read_sector = gdrom_image_read_sector;10.155 + disc->play_audio = NULL; /* not supported yet */10.156 + disc->run_time_slice = NULL; /* not needed */10.157 + }10.158 +}10.159 +10.160 +10.161 +gdrom_disc_t gdrom_image_open( const gchar *inFilename )10.162 +{10.163 + const gchar *filename = inFilename;10.164 + const gchar *ext = strrchr(filename, '.');10.165 + gdrom_disc_t disc = NULL;10.166 + int fd;10.167 + FILE *f;10.168 int i;10.169 - for( i=0; i<image->track_count; i++ ) {10.170 - if( image->track[i].lba <= lba &&10.171 - lba < (image->track[i].lba + image->track[i].sector_count) ) {10.172 - return i+1;10.173 + gdrom_image_class_t extclz = NULL;10.174 +10.175 + // Check for a url-style filename.10.176 + char *lizard_lips = strstr( filename, "://" );10.177 + if( lizard_lips != NULL ) {10.178 + gchar *path = lizard_lips + 3;10.179 + int method_len = (lizard_lips-filename);10.180 + gchar method[method_len + 1];10.181 + memcpy( method, filename, method_len );10.182 + method[method_len] = '\0';10.183 +10.184 + if( strcasecmp( method, "file" ) == 0 ) {10.185 + filename = path;10.186 + } else if( strcasecmp( method, "dvd" ) == 0 ||10.187 + strcasecmp( method, "cd" ) == 0 ||10.188 + strcasecmp( method, "cdrom" ) ) {10.189 + return cdrom_open_device( method, path );10.190 + } else {10.191 + ERROR( "Unrecognized URL method '%s' in filename '%s'", method, filename );10.192 + return NULL;10.193 }10.194 }10.195 - return -1;10.196 +10.197 + fd = open( filename, O_RDONLY | O_NONBLOCK );10.198 + if( fd == -1 ) {10.199 + return NULL;10.200 + }10.201 +10.202 + f = fdopen(fd, "ro");10.203 +10.204 +10.205 + /* try extensions */10.206 + if( ext != NULL ) {10.207 + ext++; /* Skip the '.' */10.208 + for( i=0; gdrom_image_classes[i] != NULL; i++ ) {10.209 + if( gdrom_image_classes[i]->extension != NULL &&10.210 + strcasecmp( gdrom_image_classes[i]->extension, ext ) == 0 ) {10.211 + extclz = gdrom_image_classes[i];10.212 + if( extclz->is_valid_file(f) ) {10.213 + disc = extclz->open_image_file(filename, f);10.214 + if( disc != NULL )10.215 + return disc;10.216 + }10.217 + break;10.218 + }10.219 + }10.220 + }10.221 +10.222 + /* Okay, fall back to magic */10.223 + gboolean recognized = FALSE;10.224 + for( i=0; gdrom_image_classes[i] != NULL; i++ ) {10.225 + if( gdrom_image_classes[i] != extclz &&10.226 + gdrom_image_classes[i]->is_valid_file(f) ) {10.227 + recognized = TRUE;10.228 + disc = gdrom_image_classes[i]->open_image_file(filename, f);10.229 + if( disc != NULL )10.230 + return disc;10.231 + }10.232 + }10.233 +10.234 + fclose(f);10.235 + return NULL;10.236 }10.238 /**10.239 @@ -247,6 +291,15 @@10.240 }10.242 /**10.243 + * Default check media status that does nothing and always returns10.244 + * false (unchanged).10.245 + */10.246 +static gboolean gdrom_null_check_status( gdrom_disc_t disc )10.247 +{10.248 + return FALSE;10.249 +}10.250 +10.251 +/**10.252 * Read a single sector from a disc image. If you thought this would be simple,10.253 * I have just one thing to say to you: Bwahahahahahahahah.10.254 *10.255 @@ -264,23 +317,22 @@10.256 static gdrom_error_t gdrom_image_read_sector( gdrom_disc_t disc, uint32_t lba,10.257 int mode, unsigned char *buf, uint32_t *length )10.258 {10.259 - gdrom_image_t image = (gdrom_image_t)disc;10.260 struct cdrom_sector_header secthead;10.261 int file_offset, read_len, track_no;10.263 FILE *f;10.265 - track_no = gdrom_image_get_track_by_lba( image, lba );10.266 + track_no = gdrom_disc_get_track_by_lba( disc, lba );10.267 if( track_no == -1 ) {10.268 return PKT_ERR_BADREAD;10.269 }10.270 - struct gdrom_track *track = &image->track[track_no-1];10.271 + struct gdrom_track *track = &disc->track[track_no-1];10.272 file_offset = track->offset + track->sector_size * (lba - track->lba);10.273 read_len = track->sector_size;10.274 if( track->file != NULL ) {10.275 f = track->file;10.276 } else {10.277 - f = image->file;10.278 + f = disc->file;10.279 }10.281 /* First figure out what the real sector mode is for raw/semiraw sectors */10.282 @@ -387,142 +439,3 @@10.283 return PKT_ERR_OK;10.284 }10.286 -static gdrom_error_t gdrom_image_read_toc( gdrom_disc_t disc, unsigned char *buf )10.287 -{10.288 - gdrom_image_t image = (gdrom_image_t)disc;10.289 - struct gdrom_toc *toc = (struct gdrom_toc *)buf;10.290 - int i;10.291 -10.292 - for( i=0; i<image->track_count; i++ ) {10.293 - toc->track[i] = htonl( image->track[i].lba ) | image->track[i].flags;10.294 - }10.295 - toc->first = 0x0100 | image->track[0].flags;10.296 - toc->last = (image->track_count<<8) | image->track[i-1].flags;10.297 - toc->leadout = htonl(image->track[i-1].lba + image->track[i-1].sector_count) |10.298 - image->track[i-1].flags;10.299 - for( ;i<99; i++ )10.300 - toc->track[i] = 0xFFFFFFFF;10.301 - return PKT_ERR_OK;10.302 -}10.303 -10.304 -static gdrom_error_t gdrom_image_read_session( gdrom_disc_t disc, int session, unsigned char *buf )10.305 -{10.306 - gdrom_image_t image = (gdrom_image_t)disc;10.307 - struct gdrom_track *last_track = &image->track[image->track_count-1];10.308 - unsigned int end_of_disc = last_track->lba + last_track->sector_count;10.309 - int i;10.310 - buf[0] = 0x01; /* Disc status? */10.311 - buf[1] = 0;10.312 -10.313 - if( session == 0 ) {10.314 - buf[2] = last_track->session+1; /* last session */10.315 - buf[3] = (end_of_disc >> 16) & 0xFF;10.316 - buf[4] = (end_of_disc >> 8) & 0xFF;10.317 - buf[5] = end_of_disc & 0xFF;10.318 - return PKT_ERR_OK;10.319 - } else {10.320 - session--;10.321 - for( i=0; i<image->track_count; i++ ) {10.322 - if( image->track[i].session == session ) {10.323 - buf[2] = i+1; /* first track of session */10.324 - buf[3] = (image->track[i].lba >> 16) & 0xFF;10.325 - buf[4] = (image->track[i].lba >> 8) & 0xFF;10.326 - buf[5] = image->track[i].lba & 0xFF;10.327 - return PKT_ERR_OK;10.328 - }10.329 - }10.330 - return PKT_ERR_BADFIELD; /* No such session */10.331 - }10.332 -}10.333 -10.334 -static gdrom_error_t gdrom_image_read_position( gdrom_disc_t disc, uint32_t lba, unsigned char *buf )10.335 -{10.336 - gdrom_image_t image = (gdrom_image_t)disc;10.337 - int track_no = gdrom_image_get_track_by_lba( image, lba );10.338 - if( track_no == -1 ) {10.339 - track_no = 1;10.340 - lba = 150;10.341 - }10.342 - struct gdrom_track *track = &image->track[track_no-1];10.343 - uint32_t offset = lba - track->lba;10.344 - buf[4] = track->flags;10.345 - buf[5] = track_no;10.346 - buf[6] = 0x01; /* ?? */10.347 - buf[7] = (offset >> 16) & 0xFF;10.348 - buf[8] = (offset >> 8) & 0xFF;10.349 - buf[9] = offset & 0xFF;10.350 - buf[10] = 0;10.351 - buf[11] = (lba >> 16) & 0xFF;10.352 - buf[12] = (lba >> 8) & 0xFF;10.353 - buf[13] = lba & 0xFF;10.354 - return PKT_ERR_OK;10.355 -}10.356 -10.357 -static int gdrom_image_drive_status( gdrom_disc_t disc )10.358 -{10.359 - gdrom_image_t image = (gdrom_image_t)disc;10.360 - if( image->disc_type == IDE_DISC_NONE ) {10.361 - return IDE_DISC_NONE;10.362 - } else {10.363 - return image->disc_type | IDE_DISC_READY;10.364 - }10.365 -}10.366 -10.367 -gdrom_device_t gdrom_device_new( const gchar *name, const gchar *dev_name )10.368 -{10.369 - struct gdrom_device *dev = g_malloc0( sizeof(struct gdrom_device) );10.370 - dev->name = g_strdup(name);10.371 - dev->device_name = g_strdup(dev_name);10.372 - return dev;10.373 -}10.374 -10.375 -void gdrom_device_destroy( gdrom_device_t dev )10.376 -{10.377 - if( dev->name != NULL ) {10.378 - g_free( dev->name );10.379 - dev->name = NULL;10.380 - }10.381 - if( dev->device_name != NULL ) {10.382 - g_free( dev->device_name );10.383 - dev->device_name = NULL;10.384 - }10.385 - g_free( dev );10.386 -}10.387 -10.388 -/**10.389 - * Check the disc for a useable DC bootstrap, and update the disc10.390 - * with the title accordingly.10.391 - * @return TRUE if we found a bootstrap, otherwise FALSE.10.392 - */10.393 -gboolean gdrom_image_read_info( gdrom_disc_t d ) {10.394 - gdrom_image_t disc = (gdrom_image_t)d;10.395 - if( disc->track_count > 0 ) {10.396 - /* Find the first data track of the last session */10.397 - int last_session = disc->track[disc->track_count-1].session;10.398 - int i, boot_track = -1;10.399 - for( i=disc->track_count-1; i>=0 && disc->track[i].session == last_session; i-- ) {10.400 - if( disc->track[i].flags & TRACK_DATA ) {10.401 - boot_track = i;10.402 - }10.403 - }10.404 - if( boot_track != -1 ) {10.405 - unsigned char boot_sector[MAX_SECTOR_SIZE];10.406 - uint32_t length = sizeof(boot_sector);10.407 - if( d->read_sector( d, disc->track[boot_track].lba, 0x28,10.408 - boot_sector, &length ) == PKT_ERR_OK ) {10.409 - if( memcmp( boot_sector, "SEGA SEGAKATANA SEGA ENTERPRISES", 32) == 0 ) {10.410 - /* Got magic */10.411 - memcpy( d->title, boot_sector+128, 128 );10.412 - for( i=127; i>=0; i-- ) {10.413 - if( !isspace(d->title[i]) )10.414 - break;10.415 - }10.416 - d->title[i+1] = '\0';10.417 - }10.418 - bootstrap_dump(boot_sector, FALSE);10.419 - return TRUE;10.420 - }10.421 - }10.422 - }10.423 - return FALSE;10.424 -}
11.1 --- a/src/gdrom/gdrom.c Wed Jun 03 11:39:06 2009 +000011.2 +++ b/src/gdrom/gdrom.c Mon Jun 08 04:12:21 2009 +000011.3 @@ -1,4 +1,3 @@11.4 -11.5 /**11.6 * $Id$11.7 *11.8 @@ -20,12 +19,14 @@11.9 #include <stdio.h>11.10 #include <fcntl.h>11.11 #include <errno.h>11.12 +#include <ctype.h>11.13 #include <glib/gutils.h>11.14 #include "gdrom/ide.h"11.15 #include "gdrom/gdrom.h"11.16 #include "gdrom/gddriver.h"11.17 #include "gdrom/packet.h"11.18 #include "dream.h"11.19 +#include "bootstrap.h"11.21 extern gdrom_disc_t gdrom_disc;11.23 @@ -36,96 +37,40 @@11.24 CALL_HOOKS( gdrom_disc_change_hook, disc, disc == NULL ? NULL : disc->name );11.25 }11.27 -gdrom_image_class_t gdrom_image_classes[] = { &cdrom_device_class,11.28 - &nrg_image_class,11.29 - &cdi_image_class,11.30 - &gdi_image_class,11.31 - NULL };11.32 -11.33 char *gdrom_mode_names[] = { "Mode 0", "Mode 1", "Mode 2", "Mode 2 Form 1", "Mode 2 Form 2", "Audio",11.34 "Mode 2 semiraw", "XA Raw", "Non-XA Raw" };11.35 uint32_t gdrom_sector_size[] = { 0, 2048, 2336, 2048, 2324, 2352, 2336, 2352, 2352 };11.37 -gdrom_disc_t gdrom_image_open( const gchar *inFilename )11.38 +11.39 +gdrom_device_t gdrom_device_new( const gchar *name, const gchar *dev_name )11.40 {11.41 - const gchar *filename = inFilename;11.42 - const gchar *ext = strrchr(filename, '.');11.43 - gdrom_disc_t disc = NULL;11.44 - int fd;11.45 - FILE *f;11.46 - int i;11.47 - gdrom_image_class_t extclz = NULL;11.48 + struct gdrom_device *dev = g_malloc0( sizeof(struct gdrom_device) );11.49 + dev->name = g_strdup(name);11.50 + dev->device_name = g_strdup(dev_name);11.51 + return dev;11.52 +}11.54 - // Check for a url-style filename.11.55 - char *lizard_lips = strstr( filename, "://" );11.56 - if( lizard_lips != NULL ) {11.57 - gchar *path = lizard_lips + 3;11.58 - int method_len = (lizard_lips-filename);11.59 - gchar method[method_len + 1];11.60 - memcpy( method, filename, method_len );11.61 - method[method_len] = '\0';11.62 -11.63 - if( strcasecmp( method, "file" ) == 0 ) {11.64 - filename = path;11.65 - } else if( strcasecmp( method, "dvd" ) == 0 ||11.66 - strcasecmp( method, "cd" ) == 0 ||11.67 - strcasecmp( method, "cdrom" ) ) {11.68 - return cdrom_open_device( method, path );11.69 - } else {11.70 - ERROR( "Unrecognized URL method '%s' in filename '%s'", method, filename );11.71 - return NULL;11.72 - }11.73 +void gdrom_device_destroy( gdrom_device_t dev )11.74 +{11.75 + if( dev->name != NULL ) {11.76 + g_free( dev->name );11.77 + dev->name = NULL;11.78 }11.79 -11.80 - fd = open( filename, O_RDONLY | O_NONBLOCK );11.81 - if( fd == -1 ) {11.82 - return NULL;11.83 + if( dev->device_name != NULL ) {11.84 + g_free( dev->device_name );11.85 + dev->device_name = NULL;11.86 }11.87 -11.88 - f = fdopen(fd, "ro");11.89 -11.90 -11.91 - /* try extensions */11.92 - if( ext != NULL ) {11.93 - ext++; /* Skip the '.' */11.94 - for( i=0; gdrom_image_classes[i] != NULL; i++ ) {11.95 - if( gdrom_image_classes[i]->extension != NULL &&11.96 - strcasecmp( gdrom_image_classes[i]->extension, ext ) == 0 ) {11.97 - extclz = gdrom_image_classes[i];11.98 - if( extclz->is_valid_file(f) ) {11.99 - disc = extclz->open_image_file(filename, f);11.100 - if( disc != NULL )11.101 - return disc;11.102 - }11.103 - break;11.104 - }11.105 - }11.106 - }11.107 -11.108 - /* Okay, fall back to magic */11.109 - gboolean recognized = FALSE;11.110 - for( i=0; gdrom_image_classes[i] != NULL; i++ ) {11.111 - if( gdrom_image_classes[i] != extclz &&11.112 - gdrom_image_classes[i]->is_valid_file(f) ) {11.113 - recognized = TRUE;11.114 - disc = gdrom_image_classes[i]->open_image_file(filename, f);11.115 - if( disc != NULL )11.116 - return disc;11.117 - }11.118 - }11.119 -11.120 - fclose(f);11.121 - return NULL;11.122 + g_free( dev );11.123 }11.125 void gdrom_mount_disc( gdrom_disc_t disc )11.126 {11.127 if( disc != gdrom_disc ) {11.128 if( gdrom_disc != NULL ) {11.129 - gdrom_disc->close(gdrom_disc);11.130 + gdrom_disc->destroy(gdrom_disc,TRUE);11.131 }11.132 gdrom_disc = disc;11.133 - gdrom_image_read_info( disc );11.134 + gdrom_disc_read_title( disc );11.135 gdrom_fire_disc_changed( disc );11.136 }11.137 }11.138 @@ -143,7 +88,7 @@11.139 void gdrom_unmount_disc( )11.140 {11.141 if( gdrom_disc != NULL ) {11.142 - gdrom_disc->close(gdrom_disc);11.143 + gdrom_disc->destroy(gdrom_disc, TRUE);11.144 gdrom_fire_disc_changed(NULL);11.145 gdrom_disc = NULL;11.146 }11.147 @@ -172,11 +117,160 @@11.148 }11.149 }11.151 -gchar *gdrom_get_relative_filename( const gchar *base_name, const gchar *rel_name )11.152 +int gdrom_disc_get_track_by_lba( gdrom_disc_t disc, uint32_t lba )11.153 {11.154 - gchar *dirname = g_path_get_dirname(base_name);11.155 - gchar *pathname = g_strdup_printf( "%s%c%s", dirname, G_DIR_SEPARATOR, rel_name );11.156 - g_free(dirname);11.157 - return pathname;11.158 + int i;11.159 + for( i=0; i<disc->track_count; i++ ) {11.160 + if( disc->track[i].lba <= lba &&11.161 + lba < (disc->track[i].lba + disc->track[i].sector_count) ) {11.162 + return i+1;11.163 + }11.164 + }11.165 + return -1;11.166 }11.168 +#define CHECK_DISC(disc) do { \11.169 + if( disc == NULL ) { return PKT_ERR_NODISC; } \11.170 + disc->check_status(disc); \11.171 + if( disc->disc_type == IDE_DISC_NONE ) { return PKT_ERR_NODISC; } \11.172 + } while(0)11.173 +11.174 +gdrom_error_t gdrom_disc_check_media( gdrom_disc_t disc )11.175 +{11.176 + CHECK_DISC(disc);11.177 + return PKT_ERR_OK;11.178 +}11.179 +11.180 +gdrom_error_t gdrom_disc_get_toc( gdrom_disc_t disc, unsigned char *buf )11.181 +{11.182 + struct gdrom_toc {11.183 + uint32_t track[99];11.184 + uint32_t first, last, leadout;11.185 + };11.186 +11.187 + struct gdrom_toc *toc = (struct gdrom_toc *)buf;11.188 + int i;11.189 +11.190 + CHECK_DISC(disc);11.191 +11.192 + for( i=0; i<disc->track_count; i++ ) {11.193 + toc->track[i] = htonl( disc->track[i].lba ) | disc->track[i].flags;11.194 + }11.195 + toc->first = 0x0100 | disc->track[0].flags;11.196 + toc->last = (disc->track_count<<8) | disc->track[i-1].flags;11.197 + toc->leadout = htonl(disc->track[i-1].lba + disc->track[i-1].sector_count) |11.198 + disc->track[i-1].flags;11.199 + for( ;i<99; i++ )11.200 + toc->track[i] = 0xFFFFFFFF;11.201 + return PKT_ERR_OK;11.202 +}11.203 +11.204 +gdrom_error_t gdrom_disc_get_session_info( gdrom_disc_t disc, int session, unsigned char *buf )11.205 +{11.206 + CHECK_DISC(disc);11.207 +11.208 + struct gdrom_track *last_track = &disc->track[disc->track_count-1];11.209 + unsigned int end_of_disc = last_track->lba + last_track->sector_count;11.210 + int i;11.211 + buf[0] = 0x01; /* Disc status? */11.212 + buf[1] = 0;11.213 +11.214 + if( session == 0 ) {11.215 + buf[2] = last_track->session+1; /* last session */11.216 + buf[3] = (end_of_disc >> 16) & 0xFF;11.217 + buf[4] = (end_of_disc >> 8) & 0xFF;11.218 + buf[5] = end_of_disc & 0xFF;11.219 + return PKT_ERR_OK;11.220 + } else {11.221 + session--;11.222 + for( i=0; i<disc->track_count; i++ ) {11.223 + if( disc->track[i].session == session ) {11.224 + buf[2] = i+1; /* first track of session */11.225 + buf[3] = (disc->track[i].lba >> 16) & 0xFF;11.226 + buf[4] = (disc->track[i].lba >> 8) & 0xFF;11.227 + buf[5] = disc->track[i].lba & 0xFF;11.228 + return PKT_ERR_OK;11.229 + }11.230 + }11.231 + return PKT_ERR_BADFIELD; /* No such session */11.232 + }11.233 +}11.234 +11.235 +gdrom_error_t gdrom_disc_get_short_status( gdrom_disc_t disc, uint32_t lba, unsigned char *buf )11.236 +{11.237 + CHECK_DISC(disc);11.238 +11.239 + int track_no = gdrom_disc_get_track_by_lba( disc, lba );11.240 + if( track_no == -1 ) {11.241 + track_no = 1;11.242 + lba = 150;11.243 + }11.244 + struct gdrom_track *track = &disc->track[track_no-1];11.245 + uint32_t offset = lba - track->lba;11.246 + buf[0] = 0x00;11.247 + buf[1] = 0x15; /* audio status ? */11.248 + buf[2] = 0x00;11.249 + buf[3] = 0x0E;11.250 + buf[4] = track->flags;11.251 + buf[5] = track_no;11.252 + buf[6] = 0x01; /* ?? */11.253 + buf[7] = (offset >> 16) & 0xFF;11.254 + buf[8] = (offset >> 8) & 0xFF;11.255 + buf[9] = offset & 0xFF;11.256 + buf[10] = 0;11.257 + buf[11] = (lba >> 16) & 0xFF;11.258 + buf[12] = (lba >> 8) & 0xFF;11.259 + buf[13] = lba & 0xFF;11.260 + return PKT_ERR_OK;11.261 +}11.262 +11.263 +int gdrom_disc_get_drive_status( gdrom_disc_t disc )11.264 +{11.265 + if( disc == NULL ) {11.266 + return IDE_DISC_NONE;11.267 + }11.268 +11.269 + disc->check_status(disc);11.270 + if( disc->disc_type == IDE_DISC_NONE ) {11.271 + return IDE_DISC_NONE;11.272 + } else {11.273 + return disc->disc_type | IDE_DISC_READY;11.274 + }11.275 +}11.276 +11.277 +/**11.278 + * Check the disc for a useable DC bootstrap, and update the disc11.279 + * with the title accordingly.11.280 + * @return TRUE if we found a bootstrap, otherwise FALSE.11.281 + */11.282 +gboolean gdrom_disc_read_title( gdrom_disc_t disc ) {11.283 + if( disc->track_count > 0 ) {11.284 + /* Find the first data track of the last session */11.285 + int last_session = disc->track[disc->track_count-1].session;11.286 + int i, boot_track = -1;11.287 + for( i=disc->track_count-1; i>=0 && disc->track[i].session == last_session; i-- ) {11.288 + if( disc->track[i].flags & TRACK_DATA ) {11.289 + boot_track = i;11.290 + }11.291 + }11.292 + if( boot_track != -1 ) {11.293 + unsigned char boot_sector[MAX_SECTOR_SIZE];11.294 + uint32_t length = sizeof(boot_sector);11.295 + if( disc->read_sector( disc, disc->track[boot_track].lba, 0x28,11.296 + boot_sector, &length ) == PKT_ERR_OK ) {11.297 + if( memcmp( boot_sector, "SEGA SEGAKATANA SEGA ENTERPRISES", 32) == 0 ) {11.298 + /* Got magic */11.299 + memcpy( disc->title, boot_sector+128, 128 );11.300 + for( i=127; i>=0; i-- ) {11.301 + if( !isspace(disc->title[i]) )11.302 + break;11.303 + }11.304 + disc->title[i+1] = '\0';11.305 + }11.306 + bootstrap_dump(boot_sector, FALSE);11.307 + return TRUE;11.308 + }11.309 + }11.310 + }11.311 + return FALSE;11.312 +}
12.1 --- a/src/gdrom/gdrom.h Wed Jun 03 11:39:06 2009 +000012.2 +++ b/src/gdrom/gdrom.h Mon Jun 08 04:12:21 2009 +000012.3 @@ -28,6 +28,10 @@12.4 extern "C" {12.5 #endif12.7 +#define GDROM_TOC_SIZE (102*4) /* Size of GDROM TOC structure */12.8 +#define GDROM_SESSION_INFO_SIZE 6 /* Size of GDROM session info structure */12.9 +#define GDROM_SHORT_STATUS_SIZE 14 /* Size of GDROM short status structure */12.10 +12.11 typedef uint16_t gdrom_error_t;12.14 @@ -75,22 +79,54 @@12.16 const gchar *gdrom_get_current_disc_title();12.18 -uint32_t gdrom_read_sectors( uint32_t sector, uint32_t sector_count,12.19 - int mode, unsigned char *buf, uint32_t *length );12.21 +/**12.22 + * Find the track (numbered from 1) containing the sector specified by LBA.12.23 + * Note: this function does not check for media change.12.24 + * @return The track number, or -1 if no track contains the sector.12.25 + */12.26 +int gdrom_disc_get_track_by_lba( gdrom_disc_t disc, uint32_t lba );12.27 +12.28 +/**12.29 + * Check if the disc contains valid media.12.30 + * @return PKT_ERR_OK if disc is present, otherwise PKT_ERR_NODISC12.31 + */12.32 +gdrom_error_t gdrom_disc_check_media( gdrom_disc_t disc );12.34 /**12.35 * Retrieve the disc table of contents, and write it into the buffer in the12.36 * format expected by the DC.12.37 - * @return 0 on success, error code on failure (eg no disc mounted)12.38 + * @param disc The disc to read12.39 + * @param buf Buffer to receive the TOC data, which must be at least12.40 + * GDROM_TOC_SIZE bytes long.12.41 + * @return 0 on success, error code on failure (eg no disc)12.42 */12.43 -gdrom_error_t gdrom_get_toc( unsigned char *buf );12.44 +gdrom_error_t gdrom_disc_get_toc( gdrom_disc_t disc, unsigned char *buf );12.46 /**12.47 * Retrieve the short (6-byte) session info, and write it into the buffer.12.48 + * @param disc The disc to read12.49 + * @param session The session to read (numbered from 1), or 012.50 + * @param buf Buffer to receive the session data, which must be at least12.51 + * GDROM_SESSION_INFO_SIZE bytes long.12.52 * @return 0 on success, error code on failure.12.53 */12.54 -gdrom_error_t gdrom_get_info( unsigned char *buf, int session );12.55 +gdrom_error_t gdrom_disc_get_session_info( gdrom_disc_t disc, int session, unsigned char *buf );12.56 +12.57 +/**12.58 + * Generate the position data as returned from a STATUS(1) packet.12.59 + * @param disc The disc to read12.60 + * @param lba The current head position12.61 + * @param buf The buffer to receive the position data, which must be at least12.62 + * GDROM_SHORT_STATUS_SIZE bytes long.12.63 + * @return 0 on success, error code on failure.12.64 + */12.65 +gdrom_error_t gdrom_disc_get_short_status( gdrom_disc_t disc, uint32_t lba, unsigned char *buf );12.66 +12.67 +/**12.68 + * Return the 1-byte status code for the disc (combination of IDE_DISC_* flags)12.69 + */12.70 +int gdrom_disc_get_drive_status( gdrom_disc_t disc );12.72 /**12.73 * Native CD-ROM API - provided by drivers/cd_*.c
13.1 --- a/src/gdrom/ide.c Wed Jun 03 11:39:06 2009 +000013.2 +++ b/src/gdrom/ide.c Mon Jun 08 04:12:21 2009 +000013.3 @@ -174,8 +174,10 @@13.5 static int ide_load_state( FILE *f )13.6 {13.7 - fread( &idereg, sizeof(idereg), 1, f );13.8 - fread( data_buffer, MAX_SECTOR_SIZE, 1, f );13.9 + if( fread( &idereg, sizeof(idereg), 1, f ) != 1 ||13.10 + fread( data_buffer, MAX_SECTOR_SIZE, 1, f ) != 1 ) {13.11 + return -1;13.12 + }13.13 return 0;13.14 }13.16 @@ -441,14 +443,10 @@13.18 uint8_t ide_get_drive_status( void )13.19 {13.20 - if( gdrom_disc == NULL ) {13.21 - return IDE_DISC_NONE;13.22 - } else {13.23 - return gdrom_disc->drive_status(gdrom_disc);13.24 - }13.25 + return gdrom_disc_get_drive_status(gdrom_disc);13.26 }13.28 -#define REQUIRE_DISC() if( gdrom_disc == NULL ) { ide_set_packet_result( PKT_ERR_NODISC ); return; }13.29 +#define REQUIRE_DISC() if( gdrom_disc == NULL || gdrom_disc->disc_type == IDE_DISC_NONE ) { ide_set_packet_result( PKT_ERR_NODISC ); return; }13.31 /**13.32 * Read the next sector from the active read, if any13.33 @@ -509,7 +507,7 @@13.34 uint8_t status = ide_get_drive_status();13.35 /* FIXME: Refactor read_position to avoid this kind of crud */13.36 unsigned char tmp[16];13.37 - gdrom_disc->read_position( gdrom_disc, idereg.current_lba, tmp );13.38 + gdrom_disc_get_short_status( gdrom_disc, idereg.current_lba, tmp );13.40 length = cmd[4];13.41 if( lba+length > GDROM_DRIVE_STATUS_LENGTH )13.42 @@ -563,10 +561,10 @@13.43 case PKT_CMD_READ_TOC:13.44 REQUIRE_DISC();13.45 length = (cmd[3]<<8) | cmd[4];13.46 - if( length > sizeof(struct gdrom_toc) )13.47 - length = sizeof(struct gdrom_toc);13.48 + if( length > GDROM_TOC_SIZE )13.49 + length = GDROM_TOC_SIZE;13.51 - status = gdrom_disc->read_toc( gdrom_disc, data_buffer );13.52 + status = gdrom_disc_get_toc( gdrom_disc, data_buffer );13.53 if( status != PKT_ERR_OK ) {13.54 ide_set_packet_result( status );13.55 } else {13.56 @@ -578,7 +576,7 @@13.57 length = cmd[4];13.58 if( length > 6 )13.59 length = 6;13.60 - status = gdrom_disc->read_session( gdrom_disc, cmd[2], data_buffer );13.61 + status = gdrom_disc_get_session_info( gdrom_disc, cmd[2], data_buffer );13.62 if( status != PKT_ERR_OK ) {13.63 ide_set_packet_result( status );13.64 } else {13.65 @@ -619,11 +617,7 @@13.66 if( length > 14 ) {13.67 length = 14;13.68 }13.69 - gdrom_disc->read_position( gdrom_disc, idereg.current_lba, data_buffer );13.70 - data_buffer[0] = 0x00;13.71 - data_buffer[1] = 0x15; /* audio status ? */13.72 - data_buffer[2] = 0x00;13.73 - data_buffer[3] = 0x0E;13.74 + gdrom_disc_get_short_status( gdrom_disc, idereg.current_lba, data_buffer );13.75 ide_start_packet_read( length, 0 );13.76 break;13.77 }
14.1 --- a/src/gdrom/mmc.c Wed Jun 03 11:39:06 2009 +000014.2 +++ /dev/null Thu Jan 01 00:00:00 1970 +000014.3 @@ -1,104 +0,0 @@14.4 -/**14.5 - * $Id$14.6 - *14.7 - * MMC host-side support functions.14.8 - *14.9 - * Copyright (c) 2008 Nathan Keynes.14.10 - *14.11 - * This program is free software; you can redistribute it and/or modify14.12 - * it under the terms of the GNU General Public License as published by14.13 - * the Free Software Foundation; either version 2 of the License, or14.14 - * (at your option) any later version.14.15 - *14.16 - * This program is distributed in the hope that it will be useful,14.17 - * but WITHOUT ANY WARRANTY; without even the implied warranty of14.18 - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the14.19 - * GNU General Public License for more details.14.20 - */14.21 -14.22 -#include "gdrom/gddriver.h"14.23 -#include "gdrom/packet.h"14.24 -14.25 -#define MSFTOLBA( m,s,f ) (f + (s*CD_FRAMES_PER_SECOND) + (m*CD_FRAMES_PER_MINUTE))14.26 -14.27 -void mmc_make_read_cd_cmd( char *cmd, uint32_t real_sector, int mode )14.28 -{14.29 - cmd[0] = 0xBE;14.30 - cmd[1] = (mode & 0x0E) << 1;14.31 - cmd[2] = (real_sector >> 24) & 0xFF;14.32 - cmd[3] = (real_sector >> 16) & 0xFF;14.33 - cmd[4] = (real_sector >> 8) & 0xFF;14.34 - cmd[5] = real_sector & 0xFF;14.35 - cmd[6] = 0;14.36 - cmd[7] = 0;14.37 - cmd[8] = 1;14.38 - cmd[9] = 0;14.39 - cmd[10]= 0;14.40 - cmd[11]= 0;14.41 -14.42 - if( READ_CD_RAW(mode) ) {14.43 - cmd[9] = 0xF0;14.44 - } else {14.45 - if( READ_CD_HEADER(mode) ) {14.46 - cmd[9] = 0xA0;14.47 - }14.48 - if( READ_CD_SUBHEAD(mode) ) {14.49 - cmd[9] |= 0x40;14.50 - }14.51 - if( READ_CD_DATA(mode) ) {14.52 - cmd[9] |= 0x10;14.53 - }14.54 - }14.55 -}14.56 -14.57 -void mmc_parse_toc2( gdrom_image_t disc, unsigned char *buf )14.58 -{14.59 - int max_track = 0;14.60 - int last_track = -1;14.61 - int leadout = -1;14.62 - int len = (buf[0] << 8) | buf[1];14.63 - int session_type = -1;14.64 - int i;14.65 - for( i = 4; i<len; i+=11 ) {14.66 - int session = buf[i];14.67 - int adr = buf[i+1] >> 4;14.68 - int point = buf[i+3];14.69 - if( adr == 0x01 && point > 0 && point < 100 ) {14.70 - /* Track info */14.71 - int trackno = point-1;14.72 - if( point > max_track ) {14.73 - max_track = point;14.74 - }14.75 - disc->track[trackno].flags = (buf[i+1] & 0x0F) << 4;14.76 - disc->track[trackno].session = session - 1;14.77 - disc->track[trackno].lba = MSFTOLBA(buf[i+8],buf[i+9],buf[i+10]);14.78 - if( disc->track[trackno].flags & TRACK_DATA ) {14.79 - disc->track[trackno].mode = GDROM_MODE1;14.80 - } else {14.81 - disc->track[trackno].mode = GDROM_CDDA;14.82 - }14.83 - if( last_track != -1 ) {14.84 - disc->track[last_track].sector_count = disc->track[trackno].lba -14.85 - disc->track[last_track].lba;14.86 - }14.87 - last_track = trackno;14.88 - } else switch( (adr << 8) | point ) {14.89 - case 0x1A0: /* session info */14.90 - if( buf[i+9] == 0x20 ) {14.91 - session_type = IDE_DISC_CDROMXA;14.92 - } else {14.93 - session_type = IDE_DISC_CDROM;14.94 - }14.95 - disc->disc_type = session_type;14.96 - break;14.97 - case 0x1A2: /* leadout */14.98 - leadout = MSFTOLBA(buf[i+8], buf[i+9], buf[i+10]);14.99 - break;14.100 - }14.101 - }14.102 - disc->track_count = max_track;14.103 -14.104 - if( leadout != -1 && last_track != -1 ) {14.105 - disc->track[last_track].sector_count = leadout - disc->track[last_track].lba;14.106 - }14.107 -}
15.1 --- a/src/gdrom/nrg.c Wed Jun 03 11:39:06 2009 +000015.2 +++ b/src/gdrom/nrg.c Mon Jun 08 04:12:21 2009 +000015.3 @@ -186,7 +186,6 @@15.4 struct nrg_etnf *etnf;15.5 struct nrg_etn2 *etn2;15.6 gdrom_disc_t disc;15.7 - gdrom_image_t image;15.8 gboolean end = FALSE;15.9 uint32_t chunk_id;15.10 int session_id = 0;15.11 @@ -213,7 +212,6 @@15.12 ERROR("Unable to allocate memory!");15.13 return NULL;15.14 }15.15 - image = (gdrom_image_t)disc;15.17 do {15.18 fread( &chunk, sizeof(chunk), 1, f );15.19 @@ -239,34 +237,34 @@15.20 if( cue->track == 0 )15.21 continue; /* Track 0. Leadin? always 0? */15.22 if( cue->track == 0xAA ) { /* end of disc */15.23 - image->track[track_id-1].sector_count =15.24 - lba - image->track[track_id-1].lba;15.25 + disc->track[track_id-1].sector_count =15.26 + lba - disc->track[track_id-1].lba;15.27 } else {15.28 track = bcd_to_uint8(cue->track) - 1;15.29 if( (cue->control & 0x01) == 0 ) {15.30 /* Pre-gap address. */15.31 if( track != 0 ) {15.32 - image->track[track-1].sector_count =15.33 - lba - image->track[track-1].lba;15.34 + disc->track[track-1].sector_count =15.35 + lba - disc->track[track-1].lba;15.36 }15.37 } else { /* Track-start address */15.38 - image->track[track].lba = lba;15.39 - image->track[track].flags = cue->type;15.40 + disc->track[track].lba = lba;15.41 + disc->track[track].flags = cue->type;15.42 }15.43 }15.44 }15.45 break;15.46 case DAOI_ID:15.47 dao = (struct nrg_daoi *)data;15.48 - memcpy( image->mcn, dao->mcn, 13 );15.49 - image->mcn[13] = '\0';15.50 + memcpy( disc->mcn, dao->mcn, 13 );15.51 + disc->mcn[13] = '\0';15.52 assert( (dao->track_count - cue_track_id) * 30 + 22 == chunk.length );15.53 assert( dao->track_count == track_id );15.54 for( i=0; i<(dao->track_count-cue_track_id); i++ ) {15.55 - image->track[cue_track_id].sector_size = GUINT32_FROM_BE(dao->track[i].sector_size);15.56 - image->track[cue_track_id].offset = GUINT32_FROM_BE(dao->track[i].offset);15.57 - image->track[cue_track_id].mode = nrg_track_mode( dao->track[i].mode );15.58 - image->track[cue_track_id].sector_count =15.59 + disc->track[cue_track_id].sector_size = GUINT32_FROM_BE(dao->track[i].sector_size);15.60 + disc->track[cue_track_id].offset = GUINT32_FROM_BE(dao->track[i].offset);15.61 + disc->track[cue_track_id].mode = nrg_track_mode( dao->track[i].mode );15.62 + disc->track[cue_track_id].sector_count =15.63 (GUINT32_FROM_BE(dao->track[i].end) - GUINT32_FROM_BE(dao->track[i].offset))/15.64 GUINT32_FROM_BE(dao->track[i].sector_size);15.65 cue_track_id++;15.66 @@ -274,15 +272,15 @@15.67 break;15.68 case DAOX_ID:15.69 daox = (struct nrg_daox *)data;15.70 - memcpy( image->mcn, daox->mcn, 13 );15.71 - image->mcn[13] = '\0';15.72 + memcpy( disc->mcn, daox->mcn, 13 );15.73 + disc->mcn[13] = '\0';15.74 assert( (daox->track_count - cue_track_id) * 42 + 22 == chunk.length );15.75 assert( daox->track_count == track_id );15.76 for( i=0; i<(daox->track_count-cue_track_id); i++ ) {15.77 - image->track[cue_track_id].sector_size = GUINT32_FROM_BE(daox->track[i].sector_size);15.78 - image->track[cue_track_id].offset = GUINT64_FROM_BE(daox->track[i].offset);15.79 - image->track[cue_track_id].mode = nrg_track_mode( daox->track[i].mode );15.80 - image->track[cue_track_id].sector_count =15.81 + disc->track[cue_track_id].sector_size = GUINT32_FROM_BE(daox->track[i].sector_size);15.82 + disc->track[cue_track_id].offset = GUINT64_FROM_BE(daox->track[i].offset);15.83 + disc->track[cue_track_id].mode = nrg_track_mode( daox->track[i].mode );15.84 + disc->track[cue_track_id].sector_count =15.85 (GUINT64_FROM_BE(daox->track[i].end) - GUINT64_FROM_BE(daox->track[i].offset))/15.86 GUINT32_FROM_BE(daox->track[i].sector_size);15.87 cue_track_id++;15.88 @@ -293,27 +291,27 @@15.89 /* Data is a single 32-bit number representing number of tracks in session */15.90 i = GUINT32_FROM_BE( *(uint32_t *)data );15.91 while( i-- > 0 )15.92 - image->track[session_track_id++].session = session_id;15.93 + disc->track[session_track_id++].session = session_id;15.94 session_id++;15.95 break;15.96 case ETNF_ID:15.97 etnf = (struct nrg_etnf *)data;15.98 count = chunk.length / sizeof(struct nrg_etnf);15.99 for( i=0; i < count; i++, etnf++ ) {15.100 - image->track[track_id].offset = GUINT32_FROM_BE(etnf->offset);15.101 - image->track[track_id].lba = GUINT32_FROM_BE(etnf->lba) + (i+1)*GDROM_PREGAP;15.102 - image->track[track_id].mode = nrg_track_mode( GUINT32_FROM_BE(etnf->mode) );15.103 - if( image->track[track_id].mode == -1 ) {15.104 - gdrom_image_destroy_no_close(disc);15.105 + disc->track[track_id].offset = GUINT32_FROM_BE(etnf->offset);15.106 + disc->track[track_id].lba = GUINT32_FROM_BE(etnf->lba) + (i+1)*GDROM_PREGAP;15.107 + disc->track[track_id].mode = nrg_track_mode( GUINT32_FROM_BE(etnf->mode) );15.108 + if( disc->track[track_id].mode == -1 ) {15.109 + disc->destroy(disc,FALSE);15.110 return NULL;15.111 }15.112 - if( image->track[track_id].mode == GDROM_CDDA )15.113 - image->track[track_id].flags = 0x01;15.114 + if( disc->track[track_id].mode == GDROM_CDDA )15.115 + disc->track[track_id].flags = 0x01;15.116 else15.117 - image->track[track_id].flags = 0x01 | TRACK_DATA;15.118 - image->track[track_id].sector_size = GDROM_SECTOR_SIZE(image->track[track_id].mode);15.119 - image->track[track_id].sector_count = GUINT32_FROM_BE(etnf->length) /15.120 - image->track[track_id].sector_size;15.121 + disc->track[track_id].flags = 0x01 | TRACK_DATA;15.122 + disc->track[track_id].sector_size = GDROM_SECTOR_SIZE(disc->track[track_id].mode);15.123 + disc->track[track_id].sector_count = GUINT32_FROM_BE(etnf->length) /15.124 + disc->track[track_id].sector_size;15.125 track_id++;15.126 }15.127 break;15.128 @@ -321,20 +319,20 @@15.129 etn2 = (struct nrg_etn2 *)data;15.130 count = chunk.length / sizeof(struct nrg_etn2);15.131 for( i=0; i < count; i++, etn2++ ) {15.132 - image->track[track_id].offset = (uint32_t)GUINT64_FROM_BE(etn2->offset);15.133 - image->track[track_id].lba = GUINT32_FROM_BE(etn2->lba) + (i+1)*GDROM_PREGAP;15.134 - image->track[track_id].mode = nrg_track_mode( GUINT32_FROM_BE(etn2->mode) );15.135 - if( image->track[track_id].mode == -1 ) {15.136 - gdrom_image_destroy_no_close(disc);15.137 + disc->track[track_id].offset = (uint32_t)GUINT64_FROM_BE(etn2->offset);15.138 + disc->track[track_id].lba = GUINT32_FROM_BE(etn2->lba) + (i+1)*GDROM_PREGAP;15.139 + disc->track[track_id].mode = nrg_track_mode( GUINT32_FROM_BE(etn2->mode) );15.140 + if( disc->track[track_id].mode == -1 ) {15.141 + disc->destroy(disc,FALSE);15.142 return NULL;15.143 }15.144 - if( image->track[track_id].mode == GDROM_CDDA )15.145 - image->track[track_id].flags = 0x01;15.146 + if( disc->track[track_id].mode == GDROM_CDDA )15.147 + disc->track[track_id].flags = 0x01;15.148 else15.149 - image->track[track_id].flags = 0x01 | TRACK_DATA;15.150 - image->track[track_id].sector_size = GDROM_SECTOR_SIZE(image->track[track_id].mode);15.151 - image->track[track_id].sector_count = (uint32_t)(GUINT64_FROM_BE(etn2->length) /15.152 - image->track[track_id].sector_size);15.153 + disc->track[track_id].flags = 0x01 | TRACK_DATA;15.154 + disc->track[track_id].sector_size = GDROM_SECTOR_SIZE(disc->track[track_id].mode);15.155 + disc->track[track_id].sector_count = (uint32_t)(GUINT64_FROM_BE(etn2->length) /15.156 + disc->track[track_id].sector_size);15.157 track_id++;15.158 }15.159 break;15.160 @@ -344,7 +342,7 @@15.161 break;15.162 }15.163 } while( !end );15.164 - image->track_count = track_id;15.165 + disc->track_count = track_id;15.166 return disc;15.167 }
.