Search
lxdream.org :: lxdream :: r1023:264e2fd90be8
lxdream 0.9.1
released Jun 29
Download Now
changeset1023:264e2fd90be8
parent1022:43f35b12ece7
child1024:c67f2d61ab97
authornkeynes
dateMon Jun 08 04:12:21 2009 +0000 (10 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
src/Makefile.am
src/Makefile.in
src/drivers/cd_linux.c
src/drivers/cd_mmc.c
src/drivers/cd_osx.c
src/drivers/osx_iokit.m
src/gdrom/cdi.c
src/gdrom/gddriver.h
src/gdrom/gdi.c
src/gdrom/gdimage.c
src/gdrom/gdrom.c
src/gdrom/gdrom.h
src/gdrom/ide.c
src/gdrom/mmc.c
src/gdrom/nrg.c
1.1 --- a/src/Makefile.am Wed Jun 03 11:39:06 2009 +0000
1.2 +++ b/src/Makefile.am Mon Jun 08 04:12:21 2009 +0000
1.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 +0000
2.2 +++ b/src/Makefile.in Mon Jun 08 04:12:21 2009 +0000
2.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.175
2.176 -mmc.o: gdrom/mmc.c
2.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; fi
2.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.c
2.182 -
2.183 -mmc.obj: gdrom/mmc.c
2.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; fi
2.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.c
2.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; fi
2.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.196
2.197 +cd_mmc.o: drivers/cd_mmc.c
2.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; fi
2.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.c
2.203 +
2.204 +cd_mmc.obj: drivers/cd_mmc.c
2.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; fi
2.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.c
2.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 +0000
3.2 +++ b/src/drivers/cd_linux.c Mon Jun 08 04:12:21 2009 +0000
3.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.15
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 1
3.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.25
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.48
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.95
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.104
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.121
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, &sector_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.267
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 error
3.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.281
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.288
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 +0000
4.2 +++ b/src/drivers/cd_mmc.c Mon Jun 08 04:12:21 2009 +0000
4.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 modify
4.12 + * it under the terms of the GNU General Public License as published by
4.13 + * the Free Software Foundation; either version 2 of the License, or
4.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 of
4.18 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
4.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 1
4.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 structure
4.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 the
4.122 + * INQUIRY command. On success, the disc display_name is updated with the
4.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, &sector_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 and
4.183 + * consider the drive empty for now, but warn about any other errors
4.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 +0000
5.2 +++ b/src/drivers/cd_osx.c Mon Jun 08 04:12:21 2009 +0000
5.3 @@ -35,30 +35,32 @@
5.4
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.11
5.12 struct gdrom_image_class cdrom_device_class = { "osx", NULL,
5.13 cdrom_osx_image_is_valid, cdrom_osx_open_device };
5.14
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.17
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.28
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.44
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.53
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.65
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.70
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.76
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.88
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 parse
5.112 * the requested data out ourselves
5.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.118
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 +0000
6.2 +++ b/src/drivers/osx_iokit.m Mon Jun 08 04:12:21 2009 +0000
6.3 @@ -50,6 +50,7 @@
6.4 };
6.5
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.8
6.9 /***************** IOKit Callbacks ******************/
6.10
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 interest
6.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.24
6.25 +/**
6.26 + * Retrieve a boolean property from the io object, and return as a gboolean. If
6.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 +0000
7.2 +++ b/src/gdrom/cdi.c Mon Jun 08 04:12:21 2009 +0000
7.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.16
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 +0000
8.2 +++ b/src/gdrom/gddriver.h Mon Jun 08 04:12:21 2009 +0000
8.3 @@ -32,15 +32,11 @@
8.4
8.5 #define MAX_SECTOR_SIZE 2352
8.6
8.7 +#define CD_MSF_START 150 /* MSF numbering starts after the initial pregap */
8.8 #define CD_FRAMES_PER_SECOND 75
8.9 #define CD_SECONDS_PER_MINUTE 60
8.10 #define CD_FRAMES_PER_MINUTE (CD_FRAMES_PER_SECOND*CD_SECONDS_PER_MINUTE)
8.11
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.18
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 0x06
8.25
8.26 +#define IDE_DISC_NONE 0x06
8.27 #define IDE_DISC_AUDIO 0x00
8.28 #define IDE_DISC_CDROM 0x10
8.29 #define IDE_DISC_CDROMXA 0x20
8.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.39
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 of
8.53 + * a change, this function should update the structure according to the
8.54 + * new media (including TOC), and return TRUE.
8.55 + * @return TRUE if the media has changed since the last check, otherwise
8.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 structure
8.63 @@ -113,70 +128,85 @@
8.64 unsigned char *buf, uint32_t *length );
8.65
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-rom
8.69 - * format.
8.70 - * @param disc pointer to the disc structure
8.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 the
8.77 - * supplied buffer.
8.78 - * @param disc pointer to the disc structure
8.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 sector
8.86 - * and return it in the supplied buffer. This method does not need to
8.87 - * write the first 4 bytes of the buffer.
8.88 - * @param disc pointer to the disc structure
8.89 - * @param lba sector to get position information for
8.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 the
8.96 - * IDE_DISC_* flags above.
8.97 - * @param disc pointer to the disc structure
8.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.106
8.107 + /**
8.108 + * Stop audio playback
8.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 operations
8.114 * (checking disc status, media changed, etc).
8.115 */
8.116 uint32_t (*run_time_slice)( struct gdrom_disc *disc, uint32_t nanosecs );
8.117
8.118 - /**
8.119 - * Close the disc and release any storage or resources allocated including
8.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 destroy
8.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.134
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 used
8.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't
8.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 in
8.152 + * response, not necessarily a CD read).
8.153 + * @param scsi The disc to execute the command
8.154 + * @param cmd The 12-byte command packet
8.155 + * @param buf The buffer to receive the read results
8.156 + * @param length On entry, the size of buf. Modified on exit to the number
8.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 command
8.167 + * @param cmd The 12-byte command packet
8.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, otherwise
8.174 + * FALSE. This method is used to implement the disc-level check_status
8.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 use
8.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.198
8.199 /**
8.200 *
8.201 @@ -194,27 +224,14 @@
8.202 extern struct gdrom_image_class cdrom_device_class;
8.203
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.210
8.211 /**
8.212 - * Destroy an image data structure without closing the file
8.213 - * (Intended for use from image loaders only)
8.214 + * Default disc destroy method, for chaining from subclasses
8.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 given
8.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.230
8.231 gdrom_device_t gdrom_device_new( const gchar *name, const gchar *dev_name );
8.232
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.235
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 disc
8.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 + mode
8.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.249
8.250 #endif /* !lxdream_gddriver_H */
9.1 --- a/src/gdrom/gdi.c Wed Jun 03 11:39:06 2009 +0000
9.2 +++ b/src/gdrom/gdi.c Mon Jun 08 04:12:21 2009 +0000
9.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.23
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 offset
9.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 offset
9.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 +0000
10.2 +++ b/src/gdrom/gdimage.c Mon Jun 08 04:12:21 2009 +0000
10.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.10
10.11 #include "gdrom/gddriver.h"
10.12 #include "gdrom/packet.h"
10.13 #include "ecc.h"
10.14 -#include "bootstrap.h"
10.15
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.24
10.25 static uint8_t gdrom_default_sync[12] = { 0, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 0 };
10.26
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.30
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.37
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 only
10.42 };
10.43
10.44 -/**
10.45 - * Initialize a gdrom_disc structure with the gdrom_image_* methods
10.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.80
10.81 + disc->check_status = gdrom_null_check_status;
10.82 + disc->destroy = gdrom_disc_destroy;
10.83 return disc;
10.84 }
10.85
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.144
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 image
10.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.237
10.238 /**
10.239 @@ -247,6 +291,15 @@
10.240 }
10.241
10.242 /**
10.243 + * Default check media status that does nothing and always returns
10.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.262
10.263 FILE *f;
10.264
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.280
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.285
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 disc
10.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 +0000
11.2 +++ b/src/gdrom/gdrom.c Mon Jun 08 04:12:21 2009 +0000
11.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.20
11.21 extern gdrom_disc_t gdrom_disc;
11.22
11.23 @@ -36,96 +37,40 @@
11.24 CALL_HOOKS( gdrom_disc_change_hook, disc, disc == NULL ? NULL : disc->name );
11.25 }
11.26
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.36
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.53
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.124
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.150
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.167
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 disc
11.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 +0000
12.2 +++ b/src/gdrom/gdrom.h Mon Jun 08 04:12:21 2009 +0000
12.3 @@ -28,6 +28,10 @@
12.4 extern "C" {
12.5 #endif
12.6
12.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.12
12.13
12.14 @@ -75,22 +79,54 @@
12.15
12.16 const gchar *gdrom_get_current_disc_title();
12.17
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.20
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_NODISC
12.31 + */
12.32 +gdrom_error_t gdrom_disc_check_media( gdrom_disc_t disc );
12.33
12.34 /**
12.35 * Retrieve the disc table of contents, and write it into the buffer in the
12.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 read
12.39 + * @param buf Buffer to receive the TOC data, which must be at least
12.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.45
12.46 /**
12.47 * Retrieve the short (6-byte) session info, and write it into the buffer.
12.48 + * @param disc The disc to read
12.49 + * @param session The session to read (numbered from 1), or 0
12.50 + * @param buf Buffer to receive the session data, which must be at least
12.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 read
12.60 + * @param lba The current head position
12.61 + * @param buf The buffer to receive the position data, which must be at least
12.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.71
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 +0000
13.2 +++ b/src/gdrom/ide.c Mon Jun 08 04:12:21 2009 +0000
13.3 @@ -174,8 +174,10 @@
13.4
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.15
13.16 @@ -441,14 +443,10 @@
13.17
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.27
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.30
13.31 /**
13.32 * Read the next sector from the active read, if any
13.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.39
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.50
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 +0000
14.2 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000
14.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 modify
14.12 - * it under the terms of the GNU General Public License as published by
14.13 - * the Free Software Foundation; either version 2 of the License, or
14.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 of
14.18 - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14.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 +0000
15.2 +++ b/src/gdrom/nrg.c Mon Jun 08 04:12:21 2009 +0000
15.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.16
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 else
15.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 else
15.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 }
15.168
.