<html>
<body>
  <div id="body" style="background-color:#ffffff;" >
<table cellspacing="0" cellpadding="0" border="0" rules="cols">
<tr class="head" style="border-bottom-width:1px;border-bottom-style:solid;" ><td class="headtd" style="padding:0;padding-top:.2em;" colspan="4">Commit in <b><tt>lxdream/src</tt></b></td></tr>
<tr><td><tt><a href="#file1">Makefile.am</a></tt></td><td id="added" class="headtd2" style="padding-left:.3em;padding-right:.3em; background-color:#ddffdd;" align="right">+11</td><td id="removed" class="headtd2" style="padding-left:.3em;padding-right:.3em; background-color:#ffdddd;" align="right">-1</td><td class="headtd2" style="padding-left:.3em;padding-right:.3em;" nowrap="nowrap">4f2750753a6c -> 566cdeb157ec</td></tr>
<tr class="alt" style=";" ><td><tt><a href="#file2">Makefile.in</a></tt></td><td id="addedalt" class="headtd2" style="padding-left:.3em;padding-right:.3em; background-color:#ccf7cc;" align="right">+198</td><td id="removed" class="headtd2" style="padding-left:.3em;padding-right:.3em; background-color:#ffdddd;" align="right">-24</td><td class="headtd2" style="padding-left:.3em;padding-right:.3em;" nowrap="nowrap">4f2750753a6c -> 566cdeb157ec</td></tr>
<tr><td><tt><a href="#file3">bios.c</a></tt></td><td id="added" class="headtd2" style="padding-left:.3em;padding-right:.3em; background-color:#ddffdd;" align="right">+104</td><td></td><td class="headtd2" style="padding-left:.3em;padding-right:.3em;" nowrap="nowrap">4f2750753a6c -> 566cdeb157ec</td></tr>
<tr class="alt" style=";" ><td><tt><a href="#file4">bootstrap.c</a></tt></td><td id="addedalt" class="headtd2" style="padding-left:.3em;padding-right:.3em; background-color:#ccf7cc;" align="right">+68</td><td></td><td class="headtd2" style="padding-left:.3em;padding-right:.3em;" nowrap="nowrap">4f2750753a6c -> 566cdeb157ec</td></tr>
<tr><td><tt><a href="#file5">bootstrap.h</a></tt></td><td id="added" class="headtd2" style="padding-left:.3em;padding-right:.3em; background-color:#ddffdd;" align="right">+3</td><td></td><td class="headtd2" style="padding-left:.3em;padding-right:.3em;" nowrap="nowrap">4f2750753a6c -> 566cdeb157ec</td></tr>
<tr class="alt" style=";" ><td><tt>drivers/cdrom/<a href="#file6">cdrom.c</a></tt></td><td id="addedalt" class="headtd2" style="padding-left:.3em;padding-right:.3em; background-color:#ccf7cc;" align="right">+11</td><td id="removed" class="headtd2" style="padding-left:.3em;padding-right:.3em; background-color:#ffdddd;" align="right">-2</td><td class="headtd2" style="padding-left:.3em;padding-right:.3em;" nowrap="nowrap">4f2750753a6c -> 566cdeb157ec</td></tr>
<tr><td><tt>             /<a href="#file7">cdrom.h</a></tt></td><td id="added" class="headtd2" style="padding-left:.3em;padding-right:.3em; background-color:#ddffdd;" align="right">+5</td><td></td><td class="headtd2" style="padding-left:.3em;padding-right:.3em;" nowrap="nowrap">4f2750753a6c -> 566cdeb157ec</td></tr>
<tr class="alt" style=";" ><td><tt>             /<a href="#file8">drive.c</a></tt></td><td id="addedalt" class="headtd2" style="padding-left:.3em;padding-right:.3em; background-color:#ccf7cc;" align="right">+1</td><td></td><td class="headtd2" style="padding-left:.3em;padding-right:.3em;" nowrap="nowrap">4f2750753a6c -> 566cdeb157ec</td></tr>
<tr><td><tt>             /<a href="#file9"><span id="added" style="background-color:#ddffdd;" >iso_impl.h</span></a></tt></td><td id="added" class="headtd2" style="padding-left:.3em;padding-right:.3em; background-color:#ddffdd;" align="right">+128</td><td></td><td class="headtd2" style="padding-left:.3em;padding-right:.3em;" align="right" nowrap="nowrap">added 566cdeb157ec</td></tr>
<tr class="alt" style=";" ><td><tt>             /<a href="#file10"><span id="addedalt" style="background-color:#ccf7cc;" >isoread.c</span></a></tt></td><td id="addedalt" class="headtd2" style="padding-left:.3em;padding-right:.3em; background-color:#ccf7cc;" align="right">+392</td><td></td><td class="headtd2" style="padding-left:.3em;padding-right:.3em;" align="right" nowrap="nowrap">added 566cdeb157ec</td></tr>
<tr><td><tt>             /<a href="#file11"><span id="added" style="background-color:#ddffdd;" >isoread.h</span></a></tt></td><td id="added" class="headtd2" style="padding-left:.3em;padding-right:.3em; background-color:#ddffdd;" align="right">+95</td><td></td><td class="headtd2" style="padding-left:.3em;padding-right:.3em;" align="right" nowrap="nowrap">added 566cdeb157ec</td></tr>
<tr class="alt" style=";" ><td><tt>             /<a href="#file12">sector.c</a></tt></td><td id="addedalt" class="headtd2" style="padding-left:.3em;padding-right:.3em; background-color:#ccf7cc;" align="right">+7</td><td id="removed" class="headtd2" style="padding-left:.3em;padding-right:.3em; background-color:#ffdddd;" align="right">-4</td><td class="headtd2" style="padding-left:.3em;padding-right:.3em;" nowrap="nowrap">4f2750753a6c -> 566cdeb157ec</td></tr>
<tr><td><tt>test/<a href="#file13"><span id="added" style="background-color:#ddffdd;" >testisoread.c</span></a></tt></td><td id="added" class="headtd2" style="padding-left:.3em;padding-right:.3em; background-color:#ddffdd;" align="right">+63</td><td></td><td class="headtd2" style="padding-left:.3em;padding-right:.3em;" align="right" nowrap="nowrap">added 566cdeb157ec</td></tr>
<tr><td></td><td id="added" class="headtd2" style="padding-left:.3em;padding-right:.3em; background-color:#ddffdd;" align="right">+1086</td><td id="removed" class="headtd2" style="padding-left:.3em;padding-right:.3em; background-color:#ffdddd;" align="right">-31</td><td></td></tr>
</table>
<small id="info" style="color: #888888;" >4 added + 9 modified, total 13 files</small><br />
<pre class="comment" style="white-space:-moz-pre-wrap;white-space:-pre-wrap;white-space:-o-pre-wrap;white-space:pre-wrap;word-wrap:break-word;padding:4px;border:1px dashed #000000;background-color:#ffffdd;" >
First draft of basic ISO9660 filesystem reader
</pre>
<hr /><a name="file1" /><div class="file" style="border:1px solid #eeeeee;margin-top:1em;margin-bottom:1em;" >
<span class="pathname" style="font-family:monospace; float:right;" >lxdream/src</span><br />
<div class="fileheader" style="margin-bottom:.5em;" ><big><b>Makefile.am</b></big> <small id="info" style="color: #888888;" >4f2750753a6c -> 566cdeb157ec</small></div>
<pre class="diff" style="margin:0;" ><small id="info" style="color: #888888;" >--- lxdream/src/Makefile.am
+++ lxdream/src/Makefile.am
@@ -13,7 +13,7 @@
</small></pre><pre id="context" class="diff" style="margin:0; background-color:#eeeeee;" > PLUGINLDFLAGS = @PLUGINLDFLAGS@
 bin_PROGRAMS = lxdream
 noinst_PROGRAMS = gendec genglsl
</pre><pre id="removed" class="diff" style="margin:0; background-color:#ffdddd;" >-check_PROGRAMS = test/testxlt
</pre><pre id="added" class="diff" style="margin:0; background-color:#ddffdd;" >+check_PROGRAMS = test/testxlt test/testisoread
</pre><pre id="context" class="diff" style="margin:0; background-color:#eeeeee;" > 
 pkglib_PROGRAMS=
 EXTRA_DIST=drivers/genkeymap.pl checkver.pl drivers/dummy.c
</pre><pre class="diff" style="margin:0;" ><small id="info" style="color: #888888;" >@@ -73,6 +73,7 @@
</small></pre><pre id="context" class="diff" style="margin:0; background-color:#eeeeee;" >         drivers/cdrom/edc_ecc.c drivers/cdrom/ecc.h drivers/cdrom/drive.c \
         drivers/cdrom/edc_crctable.h drivers/cdrom/edc_encoder.h \
        drivers/cdrom/edc_l2sq.h drivers/cdrom/edc_scramble.h drivers/cdrom/cd_mmc.c \
</pre><pre id="added" class="diff" style="margin:0; background-color:#ddffdd;" >+     drivers/cdrom/isoread.h drivers/cdrom/isoread.c drivers/cdrom/iso_impl.h \
</pre><pre id="context" class="diff" style="margin:0; background-color:#eeeeee;" >    sh4/sh4.def sh4/sh4core.in sh4/sh4x86.in sh4/sh4dasm.in sh4/sh4stat.in \
        hotkeys.c hotkeys.h
 lxdream_CPPFLAGS = @LXDREAMCPPFLAGS@
</pre><pre class="diff" style="margin:0;" ><small id="info" style="color: #888888;" >@@ -238,6 +239,15 @@
</small></pre><pre id="context" class="diff" style="margin:0; background-color:#eeeeee;" > 
 
 test_testxlt_SOURCES = test/testxlt.c xlat/xltcache.c xlat/xltcache.h
</pre><pre id="added" class="diff" style="margin:0; background-color:#ddffdd;" >+test_testisoread_SOURCES = test/testisoread.c drivers/cdrom/isoread.c \
+       drivers/cdrom/isoread.h drivers/cdrom/isofs_impl.h drivers/cdrom/ecc.h \
+       drivers/cdrom/cdrom.c drivers/cdrom/cdrom.h drivers/cdrom/sector.h \
+       drivers/cdrom/sector.c drivers/cdrom/cdimpl.h drivers/cdrom/edc_ecc.c \
+       drivers/cdrom/edc_crctable.h drivers/cdrom/edc_encoder.h \
+       drivers/cdrom/edc_l2sq.h drivers/cdrom/edc_scramble.h \
+       drivers/cdrom/defs.h drivers/cdrom/drive.h drivers/cdrom/drive.c \
+       drivers/cdrom/cd_nrg.c drivers/cdrom/cd_cdi.c drivers/cdrom/cd_gdi.c
+test_testisoread_LDADD = @GLIB_LIBS@ $(INTLLIBS)
</pre><pre id="context" class="diff" style="margin:0; background-color:#eeeeee;" > 
 sh4/sh4core.c: gendec sh4/sh4.def sh4/sh4core.in
        $(mkdir_p) `dirname $@`
</pre></div>
<hr /><a name="file2" /><div class="file" style="border:1px solid #eeeeee;margin-top:1em;margin-bottom:1em;" >
<span class="pathname" style="font-family:monospace; float:right;" >lxdream/src</span><br />
<div class="fileheader" style="margin-bottom:.5em;" ><big><b>Makefile.in</b></big> <small id="info" style="color: #888888;" >4f2750753a6c -> 566cdeb157ec</small></div>
<pre class="diff" style="margin:0;" ><small id="info" style="color: #888888;" >--- lxdream/src/Makefile.in
+++ lxdream/src/Makefile.in
@@ -38,7 +38,8 @@
</small></pre><pre id="context" class="diff" style="margin:0; background-color:#eeeeee;" > host_triplet = @host@
 bin_PROGRAMS = lxdream$(EXEEXT)
 noinst_PROGRAMS = gendec$(EXEEXT) genglsl$(EXEEXT)
</pre><pre id="removed" class="diff" style="margin:0; background-color:#ffdddd;" >-check_PROGRAMS = test/testxlt$(EXEEXT) $(am__EXEEXT_1)
</pre><pre id="added" class="diff" style="margin:0; background-color:#ddffdd;" >+check_PROGRAMS = test/testxlt$(EXEEXT) test/testisoread$(EXEEXT) \
+       $(am__EXEEXT_1)
</pre><pre id="context" class="diff" style="margin:0; background-color:#eeeeee;" > pkglib_PROGRAMS = $(am__EXEEXT_2) $(am__EXEEXT_3) $(am__EXEEXT_4) \
        $(am__EXEEXT_5) $(am__EXEEXT_6) $(am__EXEEXT_7)
 @BUILD_SHARED_TRUE@am__append_1 = plugin.c plugin.h
</pre><pre class="diff" style="margin:0;" ><small id="info" style="color: #888888;" >@@ -171,11 +172,12 @@
</small></pre><pre id="context" class="diff" style="margin:0; background-color:#eeeeee;" >      drivers/cdrom/ecc.h drivers/cdrom/drive.c \
        drivers/cdrom/edc_crctable.h drivers/cdrom/edc_encoder.h \
        drivers/cdrom/edc_l2sq.h drivers/cdrom/edc_scramble.h \
</pre><pre id="removed" class="diff" style="margin:0; background-color:#ffdddd;" >-   drivers/cdrom/cd_mmc.c sh4/sh4.def sh4/sh4core.in \
-       sh4/sh4x86.in sh4/sh4dasm.in sh4/sh4stat.in hotkeys.c \
-       hotkeys.h plugin.c plugin.h sh4/sh4x86.c xlat/x86/x86op.h \
-       xlat/x86/ia32abi.h xlat/x86/amd64abi.h sh4/sh4trans.c \
-       sh4/sh4trans.h sh4/mmux86.c x86dasm/x86dasm.c \
</pre><pre id="added" class="diff" style="margin:0; background-color:#ddffdd;" >+     drivers/cdrom/cd_mmc.c drivers/cdrom/isoread.h \
+       drivers/cdrom/isoread.c drivers/cdrom/iso_impl.h sh4/sh4.def \
+       sh4/sh4core.in sh4/sh4x86.in sh4/sh4dasm.in sh4/sh4stat.in \
+       hotkeys.c hotkeys.h plugin.c plugin.h sh4/sh4x86.c \
+       xlat/x86/x86op.h xlat/x86/ia32abi.h xlat/x86/amd64abi.h \
+       sh4/sh4trans.c sh4/sh4trans.h sh4/mmux86.c x86dasm/x86dasm.c \
</pre><pre id="context" class="diff" style="margin:0; background-color:#eeeeee;" >    x86dasm/x86dasm.h x86dasm/i386-dis.c x86dasm/dis-init.c \
        x86dasm/dis-buf.c x86dasm/ansidecl.h x86dasm/bfd.h \
        x86dasm/dis-asm.h x86dasm/symcat.h x86dasm/sysdep.h \
</pre><pre class="diff" style="margin:0;" ><small id="info" style="color: #888888;" >@@ -275,13 +277,14 @@
</small></pre><pre id="context" class="diff" style="margin:0; background-color:#eeeeee;" >      lxdream-sector.$(OBJEXT) lxdream-cd_nrg.$(OBJEXT) \
        lxdream-cd_cdi.$(OBJEXT) lxdream-cd_gdi.$(OBJEXT) \
        lxdream-edc_ecc.$(OBJEXT) lxdream-drive.$(OBJEXT) \
</pre><pre id="removed" class="diff" style="margin:0; background-color:#ffdddd;" >-   lxdream-cd_mmc.$(OBJEXT) lxdream-hotkeys.$(OBJEXT) \
-       $(am__objects_1) $(am__objects_2) $(am__objects_3) \
-       $(am__objects_4) $(am__objects_5) $(am__objects_6) \
-       $(am__objects_7) $(am__objects_8) $(am__objects_9) \
-       $(am__objects_10) $(am__objects_11) $(am__objects_12) \
-       $(am__objects_13) $(am__objects_14) $(am__objects_15) \
-       $(am__objects_16) $(am__objects_17) $(am__objects_18)
</pre><pre id="added" class="diff" style="margin:0; background-color:#ddffdd;" >+     lxdream-cd_mmc.$(OBJEXT) lxdream-isoread.$(OBJEXT) \
+       lxdream-hotkeys.$(OBJEXT) $(am__objects_1) $(am__objects_2) \
+       $(am__objects_3) $(am__objects_4) $(am__objects_5) \
+       $(am__objects_6) $(am__objects_7) $(am__objects_8) \
+       $(am__objects_9) $(am__objects_10) $(am__objects_11) \
+       $(am__objects_12) $(am__objects_13) $(am__objects_14) \
+       $(am__objects_15) $(am__objects_16) $(am__objects_17) \
+       $(am__objects_18)
</pre><pre id="context" class="diff" style="margin:0; background-color:#eeeeee;" > lxdream_OBJECTS = $(am_lxdream_OBJECTS)
 lxdream_DEPENDENCIES = $(am__DEPENDENCIES_1) $(am__DEPENDENCIES_1) \
        $(am__DEPENDENCIES_1) $(am__DEPENDENCIES_1) \
</pre><pre class="diff" style="margin:0;" ><small id="info" style="color: #888888;" >@@ -290,6 +293,13 @@
</small></pre><pre id="context" class="diff" style="margin:0; background-color:#eeeeee;" > lxdream_dummy_@SOEXT@_OBJECTS = $(am_lxdream_dummy_@SOEXT@_OBJECTS)
 @BUILD_SHARED_TRUE@lxdream_dummy_@SOEXT@_DEPENDENCIES =  \
 @BUILD_SHARED_TRUE@    lxdream_dummy.lo
</pre><pre id="added" class="diff" style="margin:0; background-color:#ddffdd;" >+am_test_testisoread_OBJECTS = testisoread.$(OBJEXT) isoread.$(OBJEXT) \
+       cdrom.$(OBJEXT) sector.$(OBJEXT) edc_ecc.$(OBJEXT) \
+       drive.$(OBJEXT) cd_nrg.$(OBJEXT) cd_cdi.$(OBJEXT) \
+       cd_gdi.$(OBJEXT)
+test_testisoread_OBJECTS = $(am_test_testisoread_OBJECTS)
+test_testisoread_DEPENDENCIES = $(am__DEPENDENCIES_1)
+am__dirstamp = $(am__leading_dot)dirstamp
</pre><pre id="context" class="diff" style="margin:0; background-color:#eeeeee;" > am__test_testsh4x86_SOURCES_DIST = test/testsh4x86.c x86dasm/x86dasm.c \
        x86dasm/x86dasm.h x86dasm/i386-dis.c x86dasm/dis-init.c \
        x86dasm/dis-buf.c sh4/sh4trans.c sh4/sh4x86.c xlat/xltcache.c \
</pre><pre class="diff" style="margin:0;" ><small id="info" style="color: #888888;" >@@ -309,7 +319,6 @@
</small></pre><pre id="context" class="diff" style="margin:0; background-color:#eeeeee;" > @BUILD_SH4X86_TRUE@  test_testsh4x86-cpu.$(OBJEXT)
 test_testsh4x86_OBJECTS = $(am_test_testsh4x86_OBJECTS)
 test_testsh4x86_DEPENDENCIES =
</pre><pre id="removed" class="diff" style="margin:0; background-color:#ffdddd;" >-am__dirstamp = $(am__leading_dot)dirstamp
</pre><pre id="context" class="diff" style="margin:0; background-color:#eeeeee;" > am_test_testxlt_OBJECTS = testxlt.$(OBJEXT) xltcache.$(OBJEXT)
 test_testxlt_OBJECTS = $(am_test_testxlt_OBJECTS)
 test_testxlt_LDADD = $(LDADD)
</pre><pre class="diff" style="margin:0;" ><small id="info" style="color: #888888;" >@@ -329,13 +338,14 @@
</small></pre><pre id="context" class="diff" style="margin:0; background-color:#eeeeee;" >      $(audio_pulse_@SOEXT@_SOURCES) $(audio_sdl_@SOEXT@_SOURCES) \
        $(gendec_SOURCES) $(genglsl_SOURCES) \
        $(input_lirc_@SOEXT@_SOURCES) $(lxdream_SOURCES) \
</pre><pre id="removed" class="diff" style="margin:0; background-color:#ffdddd;" >-   $(lxdream_dummy_@SOEXT@_SOURCES) $(test_testsh4x86_SOURCES) \
-       $(test_testxlt_SOURCES)
</pre><pre id="added" class="diff" style="margin:0; background-color:#ddffdd;" >+     $(lxdream_dummy_@SOEXT@_SOURCES) $(test_testisoread_SOURCES) \
+       $(test_testsh4x86_SOURCES) $(test_testxlt_SOURCES)
</pre><pre id="context" class="diff" style="margin:0; background-color:#eeeeee;" > DIST_SOURCES = $(audio_alsa_@SOEXT@_SOURCES) \
        $(audio_esd_@SOEXT@_SOURCES) $(audio_pulse_@SOEXT@_SOURCES) \
        $(audio_sdl_@SOEXT@_SOURCES) $(gendec_SOURCES) \
        $(genglsl_SOURCES) $(input_lirc_@SOEXT@_SOURCES) \
        $(am__lxdream_SOURCES_DIST) $(lxdream_dummy_@SOEXT@_SOURCES) \
</pre><pre id="added" class="diff" style="margin:0; background-color:#ddffdd;" >+     $(test_testisoread_SOURCES) \
</pre><pre id="context" class="diff" style="margin:0; background-color:#eeeeee;" >    $(am__test_testsh4x86_SOURCES_DIST) $(test_testxlt_SOURCES)
 ETAGS = etags
 CTAGS = ctags
</pre><pre class="diff" style="margin:0;" ><small id="info" style="color: #888888;" >@@ -583,14 +593,15 @@
</small></pre><pre id="context" class="diff" style="margin:0; background-color:#eeeeee;" >      drivers/cdrom/drive.c drivers/cdrom/edc_crctable.h \
        drivers/cdrom/edc_encoder.h drivers/cdrom/edc_l2sq.h \
        drivers/cdrom/edc_scramble.h drivers/cdrom/cd_mmc.c \
</pre><pre id="removed" class="diff" style="margin:0; background-color:#ffdddd;" >-   sh4/sh4.def sh4/sh4core.in sh4/sh4x86.in sh4/sh4dasm.in \
-       sh4/sh4stat.in hotkeys.c hotkeys.h $(am__append_1) \
-       $(am__append_2) $(am__append_4) $(am__append_5) \
-       $(am__append_6) $(am__append_7) $(am__append_8) \
-       $(am__append_9) $(am__append_10) $(am__append_17) \
-       $(am__append_19) $(am__append_21) $(am__append_23) \
-       $(am__append_25) $(am__append_27) $(am__append_28) \
-       $(am__append_29) $(am__append_30)
</pre><pre id="added" class="diff" style="margin:0; background-color:#ddffdd;" >+     drivers/cdrom/isoread.h drivers/cdrom/isoread.c \
+       drivers/cdrom/iso_impl.h sh4/sh4.def sh4/sh4core.in \
+       sh4/sh4x86.in sh4/sh4dasm.in sh4/sh4stat.in hotkeys.c \
+       hotkeys.h $(am__append_1) $(am__append_2) $(am__append_4) \
+       $(am__append_5) $(am__append_6) $(am__append_7) \
+       $(am__append_8) $(am__append_9) $(am__append_10) \
+       $(am__append_17) $(am__append_19) $(am__append_21) \
+       $(am__append_23) $(am__append_25) $(am__append_27) \
+       $(am__append_28) $(am__append_29) $(am__append_30)
</pre><pre id="context" class="diff" style="margin:0; background-color:#eeeeee;" > lxdream_CPPFLAGS = @LXDREAMCPPFLAGS@
 @BUILD_SH4X86_TRUE@test_testsh4x86_LDADD = @LXDREAM_LIBS@ @GLIB_LIBS@ @GTK_LIBS@ @LIBPNG_LIBS@
 @BUILD_SH4X86_TRUE@test_testsh4x86_CPPFLAGS = @LXDREAMCPPFLAGS@
</pre><pre class="diff" style="margin:0;" ><small id="info" style="color: #888888;" >@@ -621,6 +632,16 @@
</small></pre><pre id="context" class="diff" style="margin:0; background-color:#eeeeee;" > gendec_LDADD = @GLIB_LIBS@ @GTK_LIBS@ $(INTLLIBS)
 genglsl_LDADD = @GLIB_LIBS@ @GTK_LIBS@ $(INTLLIBS)
 test_testxlt_SOURCES = test/testxlt.c xlat/xltcache.c xlat/xltcache.h
</pre><pre id="added" class="diff" style="margin:0; background-color:#ddffdd;" >+test_testisoread_SOURCES = test/testisoread.c drivers/cdrom/isoread.c \
+       drivers/cdrom/isoread.h drivers/cdrom/isofs_impl.h drivers/cdrom/ecc.h \
+       drivers/cdrom/cdrom.c drivers/cdrom/cdrom.h drivers/cdrom/sector.h \
+       drivers/cdrom/sector.c drivers/cdrom/cdimpl.h drivers/cdrom/edc_ecc.c \
+       drivers/cdrom/edc_crctable.h drivers/cdrom/edc_encoder.h \
+       drivers/cdrom/edc_l2sq.h drivers/cdrom/edc_scramble.h \
+       drivers/cdrom/defs.h drivers/cdrom/drive.h drivers/cdrom/drive.c \
+       drivers/cdrom/cd_nrg.c drivers/cdrom/cd_cdi.c drivers/cdrom/cd_gdi.c
+
+test_testisoread_LDADD = @GLIB_LIBS@ $(INTLLIBS)
</pre><pre id="context" class="diff" style="margin:0; background-color:#eeeeee;" > all: $(BUILT_SOURCES)
        $(MAKE) $(AM_MAKEFLAGS) all-am
 
</pre><pre class="diff" style="margin:0;" ><small id="info" style="color: #888888;" >@@ -737,6 +758,9 @@
</small></pre><pre id="context" class="diff" style="margin:0; background-color:#eeeeee;" > test/$(am__dirstamp):
        @$(mkdir_p) test
        @: > test/$(am__dirstamp)
</pre><pre id="added" class="diff" style="margin:0; background-color:#ddffdd;" >+test/testisoread$(EXEEXT): $(test_testisoread_OBJECTS) $(test_testisoread_DEPENDENCIES) test/$(am__dirstamp)
+       @rm -f test/testisoread$(EXEEXT)
+       $(LINK) $(test_testisoread_LDFLAGS) $(test_testisoread_OBJECTS) $(test_testisoread_LDADD) $(LIBS)
</pre><pre id="context" class="diff" style="margin:0; background-color:#eeeeee;" > test/testsh4x86$(EXEEXT): $(test_testsh4x86_OBJECTS) $(test_testsh4x86_DEPENDENCIES) test/$(am__dirstamp)
        @rm -f test/testsh4x86$(EXEEXT)
        $(LINK) $(test_testsh4x86_LDFLAGS) $(test_testsh4x86_OBJECTS) $(test_testsh4x86_LDADD) $(LIBS)
</pre><pre class="diff" style="margin:0;" ><small id="info" style="color: #888888;" >@@ -751,9 +775,16 @@
</small></pre><pre id="context" class="diff" style="margin:0; background-color:#eeeeee;" >      -rm -f *.tab.c
 
 @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/actparse.Po@am__quote@
</pre><pre id="added" class="diff" style="margin:0; background-color:#ddffdd;" >+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/cd_cdi.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/cd_gdi.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/cd_nrg.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/cdrom.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/drive.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/edc_ecc.Po@am__quote@
</pre><pre id="context" class="diff" style="margin:0; background-color:#eeeeee;" > @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/gendec.Po@am__quote@
 @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/genglsl.Po@am__quote@
 @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/insparse.Po@am__quote@
</pre><pre id="added" class="diff" style="margin:0; background-color:#ddffdd;" >+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/isoread.Po@am__quote@
</pre><pre id="context" class="diff" style="margin:0; background-color:#eeeeee;" > @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/lxdream-aica.Po@am__quote@
 @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/lxdream-armcore.Po@am__quote@
 @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/lxdream-armdasm.Po@am__quote@
</pre><pre class="diff" style="margin:0;" ><small id="info" style="color: #888888;" >@@ -820,6 +851,7 @@
</small></pre><pre id="context" class="diff" style="margin:0; background-color:#eeeeee;" > @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/lxdream-io_glib.Po@am__quote@
 @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/lxdream-io_osx.Po@am__quote@
 @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/lxdream-ioutil.Po@am__quote@
</pre><pre id="added" class="diff" style="margin:0; background-color:#ddffdd;" >+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/lxdream-isoread.Po@am__quote@
</pre><pre id="context" class="diff" style="margin:0; background-color:#eeeeee;" > @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/lxdream-joy_linux.Po@am__quote@
 @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/lxdream-kbd.Po@am__quote@
 @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/lxdream-lightgun.Po@am__quote@
</pre><pre class="diff" style="margin:0;" ><small id="info" style="color: #888888;" >@@ -873,6 +905,7 @@
</small></pre><pre id="context" class="diff" style="margin:0; background-color:#eeeeee;" > @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/lxdream-x86dasm.Po@am__quote@
 @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/lxdream-xltcache.Po@am__quote@
 @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/lxdream-yuv.Po@am__quote@
</pre><pre id="added" class="diff" style="margin:0; background-color:#ddffdd;" >+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/sector.Po@am__quote@
</pre><pre id="context" class="diff" style="margin:0; background-color:#eeeeee;" > @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/test_testsh4x86-cpu.Po@am__quote@
 @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/test_testsh4x86-dis-buf.Po@am__quote@
 @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/test_testsh4x86-dis-init.Po@am__quote@
</pre><pre class="diff" style="margin:0;" ><small id="info" style="color: #888888;" >@@ -885,6 +918,7 @@
</small></pre><pre id="context" class="diff" style="margin:0; background-color:#eeeeee;" > @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/test_testsh4x86-util.Po@am__quote@
 @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/test_testsh4x86-x86dasm.Po@am__quote@
 @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/test_testsh4x86-xltcache.Po@am__quote@
</pre><pre id="added" class="diff" style="margin:0; background-color:#ddffdd;" >+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/testisoread.Po@am__quote@
</pre><pre id="context" class="diff" style="margin:0; background-color:#eeeeee;" > @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/testxlt.Po@am__quote@
 @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/xltcache.Po@am__quote@
 
</pre><pre class="diff" style="margin:0;" ><small id="info" style="color: #888888;" >@@ -2008,6 +2042,20 @@
</small></pre><pre id="context" class="diff" style="margin:0; background-color:#eeeeee;" > @AMDEP_TRUE@@am__fastdepCC_FALSE@    DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
 @am__fastdepCC_FALSE@  $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(lxdream_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o lxdream-cd_mmc.obj `if test -f 'drivers/cdrom/cd_mmc.c'; then $(CYGPATH_W) 'drivers/cdrom/cd_mmc.c'; else $(CYGPATH_W) '$(srcdir)/drivers/cdrom/cd_mmc.c'; fi`
 
</pre><pre id="added" class="diff" style="margin:0; background-color:#ddffdd;" >+lxdream-isoread.o: drivers/cdrom/isoread.c
+@am__fastdepCC_TRUE@   if $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(lxdream_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT lxdream-isoread.o -MD -MP -MF "$(DEPDIR)/lxdream-isoread.Tpo" -c -o lxdream-isoread.o `test -f 'drivers/cdrom/isoread.c' || echo '$(srcdir)/'`drivers/cdrom/isoread.c; \
+@am__fastdepCC_TRUE@   then mv -f "$(DEPDIR)/lxdream-isoread.Tpo" "$(DEPDIR)/lxdream-isoread.Po"; else rm -f "$(DEPDIR)/lxdream-isoread.Tpo"; exit 1; fi
+@AMDEP_TRUE@@am__fastdepCC_FALSE@      source='drivers/cdrom/isoread.c' object='lxdream-isoread.o' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@      DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@  $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(lxdream_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o lxdream-isoread.o `test -f 'drivers/cdrom/isoread.c' || echo '$(srcdir)/'`drivers/cdrom/isoread.c
+
+lxdream-isoread.obj: drivers/cdrom/isoread.c
+@am__fastdepCC_TRUE@   if $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(lxdream_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT lxdream-isoread.obj -MD -MP -MF "$(DEPDIR)/lxdream-isoread.Tpo" -c -o lxdream-isoread.obj `if test -f 'drivers/cdrom/isoread.c'; then $(CYGPATH_W) 'drivers/cdrom/isoread.c'; else $(CYGPATH_W) '$(srcdir)/drivers/cdrom/isoread.c'; fi`; \
+@am__fastdepCC_TRUE@   then mv -f "$(DEPDIR)/lxdream-isoread.Tpo" "$(DEPDIR)/lxdream-isoread.Po"; else rm -f "$(DEPDIR)/lxdream-isoread.Tpo"; exit 1; fi
+@AMDEP_TRUE@@am__fastdepCC_FALSE@      source='drivers/cdrom/isoread.c' object='lxdream-isoread.obj' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@      DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@  $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(lxdream_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o lxdream-isoread.obj `if test -f 'drivers/cdrom/isoread.c'; then $(CYGPATH_W) 'drivers/cdrom/isoread.c'; else $(CYGPATH_W) '$(srcdir)/drivers/cdrom/isoread.c'; fi`
+
</pre><pre id="context" class="diff" style="margin:0; background-color:#eeeeee;" > lxdream-hotkeys.o: hotkeys.c
 @am__fastdepCC_TRUE@   if $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(lxdream_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT lxdream-hotkeys.o -MD -MP -MF "$(DEPDIR)/lxdream-hotkeys.Tpo" -c -o lxdream-hotkeys.o `test -f 'hotkeys.c' || echo '$(srcdir)/'`hotkeys.c; \
 @am__fastdepCC_TRUE@   then mv -f "$(DEPDIR)/lxdream-hotkeys.Tpo" "$(DEPDIR)/lxdream-hotkeys.Po"; else rm -f "$(DEPDIR)/lxdream-hotkeys.Tpo"; exit 1; fi
</pre><pre class="diff" style="margin:0;" ><small id="info" style="color: #888888;" >@@ -2456,6 +2504,132 @@
</small></pre><pre id="context" class="diff" style="margin:0; background-color:#eeeeee;" > @AMDEP_TRUE@@am__fastdepCC_FALSE@    DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
 @am__fastdepCC_FALSE@  $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(lxdream_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o lxdream-joy_linux.obj `if test -f 'drivers/joy_linux.c'; then $(CYGPATH_W) 'drivers/joy_linux.c'; else $(CYGPATH_W) '$(srcdir)/drivers/joy_linux.c'; fi`
 
</pre><pre id="added" class="diff" style="margin:0; background-color:#ddffdd;" >+testisoread.o: test/testisoread.c
+@am__fastdepCC_TRUE@   if $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT testisoread.o -MD -MP -MF "$(DEPDIR)/testisoread.Tpo" -c -o testisoread.o `test -f 'test/testisoread.c' || echo '$(srcdir)/'`test/testisoread.c; \
+@am__fastdepCC_TRUE@   then mv -f "$(DEPDIR)/testisoread.Tpo" "$(DEPDIR)/testisoread.Po"; else rm -f "$(DEPDIR)/testisoread.Tpo"; exit 1; fi
+@AMDEP_TRUE@@am__fastdepCC_FALSE@      source='test/testisoread.c' object='testisoread.o' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@      DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@  $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o testisoread.o `test -f 'test/testisoread.c' || echo '$(srcdir)/'`test/testisoread.c
+
+testisoread.obj: test/testisoread.c
+@am__fastdepCC_TRUE@   if $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT testisoread.obj -MD -MP -MF "$(DEPDIR)/testisoread.Tpo" -c -o testisoread.obj `if test -f 'test/testisoread.c'; then $(CYGPATH_W) 'test/testisoread.c'; else $(CYGPATH_W) '$(srcdir)/test/testisoread.c'; fi`; \
+@am__fastdepCC_TRUE@   then mv -f "$(DEPDIR)/testisoread.Tpo" "$(DEPDIR)/testisoread.Po"; else rm -f "$(DEPDIR)/testisoread.Tpo"; exit 1; fi
+@AMDEP_TRUE@@am__fastdepCC_FALSE@      source='test/testisoread.c' object='testisoread.obj' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@      DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@  $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o testisoread.obj `if test -f 'test/testisoread.c'; then $(CYGPATH_W) 'test/testisoread.c'; else $(CYGPATH_W) '$(srcdir)/test/testisoread.c'; fi`
+
+isoread.o: drivers/cdrom/isoread.c
+@am__fastdepCC_TRUE@   if $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT isoread.o -MD -MP -MF "$(DEPDIR)/isoread.Tpo" -c -o isoread.o `test -f 'drivers/cdrom/isoread.c' || echo '$(srcdir)/'`drivers/cdrom/isoread.c; \
+@am__fastdepCC_TRUE@   then mv -f "$(DEPDIR)/isoread.Tpo" "$(DEPDIR)/isoread.Po"; else rm -f "$(DEPDIR)/isoread.Tpo"; exit 1; fi
+@AMDEP_TRUE@@am__fastdepCC_FALSE@      source='drivers/cdrom/isoread.c' object='isoread.o' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@      DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@  $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o isoread.o `test -f 'drivers/cdrom/isoread.c' || echo '$(srcdir)/'`drivers/cdrom/isoread.c
+
+isoread.obj: drivers/cdrom/isoread.c
+@am__fastdepCC_TRUE@   if $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT isoread.obj -MD -MP -MF "$(DEPDIR)/isoread.Tpo" -c -o isoread.obj `if test -f 'drivers/cdrom/isoread.c'; then $(CYGPATH_W) 'drivers/cdrom/isoread.c'; else $(CYGPATH_W) '$(srcdir)/drivers/cdrom/isoread.c'; fi`; \
+@am__fastdepCC_TRUE@   then mv -f "$(DEPDIR)/isoread.Tpo" "$(DEPDIR)/isoread.Po"; else rm -f "$(DEPDIR)/isoread.Tpo"; exit 1; fi
+@AMDEP_TRUE@@am__fastdepCC_FALSE@      source='drivers/cdrom/isoread.c' object='isoread.obj' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@      DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@  $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o isoread.obj `if test -f 'drivers/cdrom/isoread.c'; then $(CYGPATH_W) 'drivers/cdrom/isoread.c'; else $(CYGPATH_W) '$(srcdir)/drivers/cdrom/isoread.c'; fi`
+
+cdrom.o: drivers/cdrom/cdrom.c
+@am__fastdepCC_TRUE@   if $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT cdrom.o -MD -MP -MF "$(DEPDIR)/cdrom.Tpo" -c -o cdrom.o `test -f 'drivers/cdrom/cdrom.c' || echo '$(srcdir)/'`drivers/cdrom/cdrom.c; \
+@am__fastdepCC_TRUE@   then mv -f "$(DEPDIR)/cdrom.Tpo" "$(DEPDIR)/cdrom.Po"; else rm -f "$(DEPDIR)/cdrom.Tpo"; exit 1; fi
+@AMDEP_TRUE@@am__fastdepCC_FALSE@      source='drivers/cdrom/cdrom.c' object='cdrom.o' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@      DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@  $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o cdrom.o `test -f 'drivers/cdrom/cdrom.c' || echo '$(srcdir)/'`drivers/cdrom/cdrom.c
+
+cdrom.obj: drivers/cdrom/cdrom.c
+@am__fastdepCC_TRUE@   if $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT cdrom.obj -MD -MP -MF "$(DEPDIR)/cdrom.Tpo" -c -o cdrom.obj `if test -f 'drivers/cdrom/cdrom.c'; then $(CYGPATH_W) 'drivers/cdrom/cdrom.c'; else $(CYGPATH_W) '$(srcdir)/drivers/cdrom/cdrom.c'; fi`; \
+@am__fastdepCC_TRUE@   then mv -f "$(DEPDIR)/cdrom.Tpo" "$(DEPDIR)/cdrom.Po"; else rm -f "$(DEPDIR)/cdrom.Tpo"; exit 1; fi
+@AMDEP_TRUE@@am__fastdepCC_FALSE@      source='drivers/cdrom/cdrom.c' object='cdrom.obj' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@      DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@  $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o cdrom.obj `if test -f 'drivers/cdrom/cdrom.c'; then $(CYGPATH_W) 'drivers/cdrom/cdrom.c'; else $(CYGPATH_W) '$(srcdir)/drivers/cdrom/cdrom.c'; fi`
+
+sector.o: drivers/cdrom/sector.c
+@am__fastdepCC_TRUE@   if $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT sector.o -MD -MP -MF "$(DEPDIR)/sector.Tpo" -c -o sector.o `test -f 'drivers/cdrom/sector.c' || echo '$(srcdir)/'`drivers/cdrom/sector.c; \
+@am__fastdepCC_TRUE@   then mv -f "$(DEPDIR)/sector.Tpo" "$(DEPDIR)/sector.Po"; else rm -f "$(DEPDIR)/sector.Tpo"; exit 1; fi
+@AMDEP_TRUE@@am__fastdepCC_FALSE@      source='drivers/cdrom/sector.c' object='sector.o' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@      DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@  $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o sector.o `test -f 'drivers/cdrom/sector.c' || echo '$(srcdir)/'`drivers/cdrom/sector.c
+
+sector.obj: drivers/cdrom/sector.c
+@am__fastdepCC_TRUE@   if $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT sector.obj -MD -MP -MF "$(DEPDIR)/sector.Tpo" -c -o sector.obj `if test -f 'drivers/cdrom/sector.c'; then $(CYGPATH_W) 'drivers/cdrom/sector.c'; else $(CYGPATH_W) '$(srcdir)/drivers/cdrom/sector.c'; fi`; \
+@am__fastdepCC_TRUE@   then mv -f "$(DEPDIR)/sector.Tpo" "$(DEPDIR)/sector.Po"; else rm -f "$(DEPDIR)/sector.Tpo"; exit 1; fi
+@AMDEP_TRUE@@am__fastdepCC_FALSE@      source='drivers/cdrom/sector.c' object='sector.obj' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@      DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@  $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o sector.obj `if test -f 'drivers/cdrom/sector.c'; then $(CYGPATH_W) 'drivers/cdrom/sector.c'; else $(CYGPATH_W) '$(srcdir)/drivers/cdrom/sector.c'; fi`
+
+edc_ecc.o: drivers/cdrom/edc_ecc.c
+@am__fastdepCC_TRUE@   if $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT edc_ecc.o -MD -MP -MF "$(DEPDIR)/edc_ecc.Tpo" -c -o edc_ecc.o `test -f 'drivers/cdrom/edc_ecc.c' || echo '$(srcdir)/'`drivers/cdrom/edc_ecc.c; \
+@am__fastdepCC_TRUE@   then mv -f "$(DEPDIR)/edc_ecc.Tpo" "$(DEPDIR)/edc_ecc.Po"; else rm -f "$(DEPDIR)/edc_ecc.Tpo"; exit 1; fi
+@AMDEP_TRUE@@am__fastdepCC_FALSE@      source='drivers/cdrom/edc_ecc.c' object='edc_ecc.o' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@      DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@  $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o edc_ecc.o `test -f 'drivers/cdrom/edc_ecc.c' || echo '$(srcdir)/'`drivers/cdrom/edc_ecc.c
+
+edc_ecc.obj: drivers/cdrom/edc_ecc.c
+@am__fastdepCC_TRUE@   if $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT edc_ecc.obj -MD -MP -MF "$(DEPDIR)/edc_ecc.Tpo" -c -o edc_ecc.obj `if test -f 'drivers/cdrom/edc_ecc.c'; then $(CYGPATH_W) 'drivers/cdrom/edc_ecc.c'; else $(CYGPATH_W) '$(srcdir)/drivers/cdrom/edc_ecc.c'; fi`; \
+@am__fastdepCC_TRUE@   then mv -f "$(DEPDIR)/edc_ecc.Tpo" "$(DEPDIR)/edc_ecc.Po"; else rm -f "$(DEPDIR)/edc_ecc.Tpo"; exit 1; fi
+@AMDEP_TRUE@@am__fastdepCC_FALSE@      source='drivers/cdrom/edc_ecc.c' object='edc_ecc.obj' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@      DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@  $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o edc_ecc.obj `if test -f 'drivers/cdrom/edc_ecc.c'; then $(CYGPATH_W) 'drivers/cdrom/edc_ecc.c'; else $(CYGPATH_W) '$(srcdir)/drivers/cdrom/edc_ecc.c'; fi`
+
+drive.o: drivers/cdrom/drive.c
+@am__fastdepCC_TRUE@   if $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT drive.o -MD -MP -MF "$(DEPDIR)/drive.Tpo" -c -o drive.o `test -f 'drivers/cdrom/drive.c' || echo '$(srcdir)/'`drivers/cdrom/drive.c; \
+@am__fastdepCC_TRUE@   then mv -f "$(DEPDIR)/drive.Tpo" "$(DEPDIR)/drive.Po"; else rm -f "$(DEPDIR)/drive.Tpo"; exit 1; fi
+@AMDEP_TRUE@@am__fastdepCC_FALSE@      source='drivers/cdrom/drive.c' object='drive.o' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@      DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@  $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o drive.o `test -f 'drivers/cdrom/drive.c' || echo '$(srcdir)/'`drivers/cdrom/drive.c
+
+drive.obj: drivers/cdrom/drive.c
+@am__fastdepCC_TRUE@   if $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT drive.obj -MD -MP -MF "$(DEPDIR)/drive.Tpo" -c -o drive.obj `if test -f 'drivers/cdrom/drive.c'; then $(CYGPATH_W) 'drivers/cdrom/drive.c'; else $(CYGPATH_W) '$(srcdir)/drivers/cdrom/drive.c'; fi`; \
+@am__fastdepCC_TRUE@   then mv -f "$(DEPDIR)/drive.Tpo" "$(DEPDIR)/drive.Po"; else rm -f "$(DEPDIR)/drive.Tpo"; exit 1; fi
+@AMDEP_TRUE@@am__fastdepCC_FALSE@      source='drivers/cdrom/drive.c' object='drive.obj' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@      DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@  $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o drive.obj `if test -f 'drivers/cdrom/drive.c'; then $(CYGPATH_W) 'drivers/cdrom/drive.c'; else $(CYGPATH_W) '$(srcdir)/drivers/cdrom/drive.c'; fi`
+
+cd_nrg.o: drivers/cdrom/cd_nrg.c
+@am__fastdepCC_TRUE@   if $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT cd_nrg.o -MD -MP -MF "$(DEPDIR)/cd_nrg.Tpo" -c -o cd_nrg.o `test -f 'drivers/cdrom/cd_nrg.c' || echo '$(srcdir)/'`drivers/cdrom/cd_nrg.c; \
+@am__fastdepCC_TRUE@   then mv -f "$(DEPDIR)/cd_nrg.Tpo" "$(DEPDIR)/cd_nrg.Po"; else rm -f "$(DEPDIR)/cd_nrg.Tpo"; exit 1; fi
+@AMDEP_TRUE@@am__fastdepCC_FALSE@      source='drivers/cdrom/cd_nrg.c' object='cd_nrg.o' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@      DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@  $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o cd_nrg.o `test -f 'drivers/cdrom/cd_nrg.c' || echo '$(srcdir)/'`drivers/cdrom/cd_nrg.c
+
+cd_nrg.obj: drivers/cdrom/cd_nrg.c
+@am__fastdepCC_TRUE@   if $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT cd_nrg.obj -MD -MP -MF "$(DEPDIR)/cd_nrg.Tpo" -c -o cd_nrg.obj `if test -f 'drivers/cdrom/cd_nrg.c'; then $(CYGPATH_W) 'drivers/cdrom/cd_nrg.c'; else $(CYGPATH_W) '$(srcdir)/drivers/cdrom/cd_nrg.c'; fi`; \
+@am__fastdepCC_TRUE@   then mv -f "$(DEPDIR)/cd_nrg.Tpo" "$(DEPDIR)/cd_nrg.Po"; else rm -f "$(DEPDIR)/cd_nrg.Tpo"; exit 1; fi
+@AMDEP_TRUE@@am__fastdepCC_FALSE@      source='drivers/cdrom/cd_nrg.c' object='cd_nrg.obj' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@      DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@  $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o cd_nrg.obj `if test -f 'drivers/cdrom/cd_nrg.c'; then $(CYGPATH_W) 'drivers/cdrom/cd_nrg.c'; else $(CYGPATH_W) '$(srcdir)/drivers/cdrom/cd_nrg.c'; fi`
+
+cd_cdi.o: drivers/cdrom/cd_cdi.c
+@am__fastdepCC_TRUE@   if $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT cd_cdi.o -MD -MP -MF "$(DEPDIR)/cd_cdi.Tpo" -c -o cd_cdi.o `test -f 'drivers/cdrom/cd_cdi.c' || echo '$(srcdir)/'`drivers/cdrom/cd_cdi.c; \
+@am__fastdepCC_TRUE@   then mv -f "$(DEPDIR)/cd_cdi.Tpo" "$(DEPDIR)/cd_cdi.Po"; else rm -f "$(DEPDIR)/cd_cdi.Tpo"; exit 1; fi
+@AMDEP_TRUE@@am__fastdepCC_FALSE@      source='drivers/cdrom/cd_cdi.c' object='cd_cdi.o' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@      DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@  $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o cd_cdi.o `test -f 'drivers/cdrom/cd_cdi.c' || echo '$(srcdir)/'`drivers/cdrom/cd_cdi.c
+
+cd_cdi.obj: drivers/cdrom/cd_cdi.c
+@am__fastdepCC_TRUE@   if $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT cd_cdi.obj -MD -MP -MF "$(DEPDIR)/cd_cdi.Tpo" -c -o cd_cdi.obj `if test -f 'drivers/cdrom/cd_cdi.c'; then $(CYGPATH_W) 'drivers/cdrom/cd_cdi.c'; else $(CYGPATH_W) '$(srcdir)/drivers/cdrom/cd_cdi.c'; fi`; \
+@am__fastdepCC_TRUE@   then mv -f "$(DEPDIR)/cd_cdi.Tpo" "$(DEPDIR)/cd_cdi.Po"; else rm -f "$(DEPDIR)/cd_cdi.Tpo"; exit 1; fi
+@AMDEP_TRUE@@am__fastdepCC_FALSE@      source='drivers/cdrom/cd_cdi.c' object='cd_cdi.obj' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@      DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@  $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o cd_cdi.obj `if test -f 'drivers/cdrom/cd_cdi.c'; then $(CYGPATH_W) 'drivers/cdrom/cd_cdi.c'; else $(CYGPATH_W) '$(srcdir)/drivers/cdrom/cd_cdi.c'; fi`
+
+cd_gdi.o: drivers/cdrom/cd_gdi.c
+@am__fastdepCC_TRUE@   if $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT cd_gdi.o -MD -MP -MF "$(DEPDIR)/cd_gdi.Tpo" -c -o cd_gdi.o `test -f 'drivers/cdrom/cd_gdi.c' || echo '$(srcdir)/'`drivers/cdrom/cd_gdi.c; \
+@am__fastdepCC_TRUE@   then mv -f "$(DEPDIR)/cd_gdi.Tpo" "$(DEPDIR)/cd_gdi.Po"; else rm -f "$(DEPDIR)/cd_gdi.Tpo"; exit 1; fi
+@AMDEP_TRUE@@am__fastdepCC_FALSE@      source='drivers/cdrom/cd_gdi.c' object='cd_gdi.o' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@      DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@  $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o cd_gdi.o `test -f 'drivers/cdrom/cd_gdi.c' || echo '$(srcdir)/'`drivers/cdrom/cd_gdi.c
+
+cd_gdi.obj: drivers/cdrom/cd_gdi.c
+@am__fastdepCC_TRUE@   if $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT cd_gdi.obj -MD -MP -MF "$(DEPDIR)/cd_gdi.Tpo" -c -o cd_gdi.obj `if test -f 'drivers/cdrom/cd_gdi.c'; then $(CYGPATH_W) 'drivers/cdrom/cd_gdi.c'; else $(CYGPATH_W) '$(srcdir)/drivers/cdrom/cd_gdi.c'; fi`; \
+@am__fastdepCC_TRUE@   then mv -f "$(DEPDIR)/cd_gdi.Tpo" "$(DEPDIR)/cd_gdi.Po"; else rm -f "$(DEPDIR)/cd_gdi.Tpo"; exit 1; fi
+@AMDEP_TRUE@@am__fastdepCC_FALSE@      source='drivers/cdrom/cd_gdi.c' object='cd_gdi.obj' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@      DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@  $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o cd_gdi.obj `if test -f 'drivers/cdrom/cd_gdi.c'; then $(CYGPATH_W) 'drivers/cdrom/cd_gdi.c'; else $(CYGPATH_W) '$(srcdir)/drivers/cdrom/cd_gdi.c'; fi`
+
</pre><pre id="context" class="diff" style="margin:0; background-color:#eeeeee;" > test_testsh4x86-testsh4x86.o: test/testsh4x86.c
 @am__fastdepCC_TRUE@   if $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(test_testsh4x86_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT test_testsh4x86-testsh4x86.o -MD -MP -MF "$(DEPDIR)/test_testsh4x86-testsh4x86.Tpo" -c -o test_testsh4x86-testsh4x86.o `test -f 'test/testsh4x86.c' || echo '$(srcdir)/'`test/testsh4x86.c; \
 @am__fastdepCC_TRUE@   then mv -f "$(DEPDIR)/test_testsh4x86-testsh4x86.Tpo" "$(DEPDIR)/test_testsh4x86-testsh4x86.Po"; else rm -f "$(DEPDIR)/test_testsh4x86-testsh4x86.Tpo"; exit 1; fi
</pre></div>
<hr /><a name="file3" /><div class="file" style="border:1px solid #eeeeee;margin-top:1em;margin-bottom:1em;" >
<span class="pathname" style="font-family:monospace; float:right;" >lxdream/src</span><br />
<div class="fileheader" style="margin-bottom:.5em;" ><big><b>bios.c</b></big> <small id="info" style="color: #888888;" >4f2750753a6c -> 566cdeb157ec</small></div>
<pre class="diff" style="margin:0;" ><small id="info" style="color: #888888;" >--- lxdream/src/bios.c
+++ lxdream/src/bios.c
@@ -20,7 +20,11 @@
</small></pre><pre id="context" class="diff" style="margin:0; background-color:#eeeeee;" > #include "mem.h"
 #include "syscall.h"
 #include "dreamcast.h"
</pre><pre id="added" class="diff" style="margin:0; background-color:#ddffdd;" >+#include "bootstrap.h"
</pre><pre id="context" class="diff" style="margin:0; background-color:#eeeeee;" > #include "sh4/sh4.h"
</pre><pre id="added" class="diff" style="margin:0; background-color:#ddffdd;" >+#include "drivers/cdrom/cdrom.h"
+#include "drivers/cdrom/isoread.h"
+#include "gdrom/gdrom.h"
</pre><pre id="context" class="diff" style="margin:0; background-color:#eeeeee;" > 
 #define COMMAND_QUEUE_LENGTH 16
 
</pre><pre class="diff" style="margin:0;" ><small id="info" style="color: #888888;" >@@ -203,6 +207,13 @@
</small></pre><pre id="context" class="diff" style="margin:0; background-color:#eeeeee;" >     }
 }
 
</pre><pre id="added" class="diff" style="margin:0; background-color:#ddffdd;" >+void bios_boot( uint32_t syscallid )
+{
+    /* Initialize hardware */
+    /* Boot disc if present */
+    bios_boot_gdrom_disc();
+}
+
</pre><pre id="context" class="diff" style="margin:0; background-color:#eeeeee;" > void bios_install( void ) 
 {
     bios_gdrom_init();
</pre><pre class="diff" style="margin:0;" ><small id="info" style="color: #888888;" >@@ -212,3 +223,96 @@
</small></pre><pre id="context" class="diff" style="margin:0; background-color:#eeeeee;" >     syscall_add_hook_vector( 0xBC, 0x8C0000BC, bios_syscall );
     syscall_add_hook_vector( 0xE0, 0x8C0000E0, bios_syscall );
 }
</pre><pre id="added" class="diff" style="margin:0; background-color:#ddffdd;" >+
+#define MIN_ISO_SECTORS 32
+
+gboolean bios_boot_gdrom_disc( void )
+{
+    cdrom_disc_t disc = gdrom_get_current_disc();
+
+    int status = gdrom_get_drive_status();
+    if( status == CDROM_DISC_NONE ) {
+        ERROR( "No disc in drive" );
+        return FALSE;
+    }
+
+    /* Find the bootable data track (if present) */
+    cdrom_track_t track = gdrom_disc_get_boot_track(disc);
+    if( track == NULL ) {
+        ERROR( "Disc is not bootable" );
+        return FALSE;
+    }
+    uint32_t lba = track->lba;
+    uint32_t sectors = cdrom_disc_get_track_size(disc,track);
+    if( sectors < MIN_ISO_SECTORS ) {
+        ERROR( "Disc is not bootable" );
+        return FALSE;
+    }
+    /* Load the initial bootstrap into DC ram at 8c008000 */
+    size_t length = BOOTSTRAP_SIZE;
+    unsigned char *bootstrap = mem_get_region(BOOTSTRAP_LOAD_ADDR);
+    if( cdrom_disc_read_sectors( disc, track->lba, BOOTSTRAP_SIZE/2048,
+            CDROM_READ_DATA|CDROM_READ_MODE2_FORM1, bootstrap, &length ) !=
+            CDROM_ERROR_OK ) {
+        ERROR( "Disc is not bootable" );
+        return FALSE;
+    }
+
+    /* Check the magic just to be sure */
+    dc_bootstrap_head_t metadata = (dc_bootstrap_head_t)bootstrap;
+    if( memcmp( metadata->magic, BOOTSTRAP_MAGIC, BOOTSTRAP_MAGIC_SIZE ) != 0 ) {
+        ERROR( "Disc is not bootable (missing dreamcast bootstrap)" );
+        return FALSE;
+    }
+
+    /* Get the initial program from the bootstrap (usually 1ST_READ.BIN) */
+    char program_name[17];
+    memcpy(program_name, metadata->boot_file, 16);
+    program_name[16] = '\0';
+    for( int i=15; i >= 0 && program_name[i] == ' '; i-- ) {
+        program_name[i] = '\0';
+    }
+
+    /* Bootstrap is good. Now find the program in the actual filesystem... */
+    isofs_reader_t iso = isofs_reader_new_from_track( disc, track, NULL );
+    if( iso == NULL ) {
+        ERROR( "Disc is not bootable" );
+        return FALSE;
+    }
+    isofs_reader_dirent_t ent = isofs_reader_get_file( iso, program_name );
+    if( ent == NULL ) {
+        ERROR( "Disc is not bootable (initial program '%s' not found)", program_name );
+        isofs_reader_destroy(iso);
+        return FALSE;
+    }
+
+    if( ent->size > (0x8D000000 - BINARY_LOAD_ADDR) ) {
+        /* Bootstrap isn't going to fit in memory. Complain and abort */
+        ERROR( "Disc is not bootable (initial program too large)" );
+        isofs_reader_destroy(iso);
+        return FALSE;
+    }
+    unsigned char *program = mem_get_region(BINARY_LOAD_ADDR);
+    int program_sectors = (ent->size+2047)/2048;
+    if( disc->disc_type == CDROM_DISC_GDROM ) {
+        /* Load the binary directly into RAM */
+        if( isofs_reader_read_file( iso, ent, 0, ent->size, program ) !=
+                CDROM_ERROR_OK ) {
+            ERROR( "Disc is not bootable (failed to read initial program)\n" );
+            isofs_reader_destroy(iso);
+            return FALSE;
+        }
+    } else {
+        /* Load the binary into a temp buffer */
+        unsigned char tmp[program_sectors*2048];
+        if( isofs_reader_read_file( iso, ent, 0, ent->size, tmp ) !=
+                CDROM_ERROR_OK ) {
+            ERROR( "Disc is not bootable (failed to read initial program)\n" );
+            isofs_reader_destroy(iso);
+            return FALSE;
+        }
+        bootprogram_unscramble(program, tmp, ent->size);
+    }
+    isofs_reader_destroy(iso);
+    dreamcast_program_loaded( "", BOOTSTRAP_LOAD_ADDR );
+}
</pre></div>
<hr /><a name="file4" /><div class="file" style="border:1px solid #eeeeee;margin-top:1em;margin-bottom:1em;" >
<span class="pathname" style="font-family:monospace; float:right;" >lxdream/src</span><br />
<div class="fileheader" style="margin-bottom:.5em;" ><big><b>bootstrap.c</b></big> <small id="info" style="color: #888888;" >4f2750753a6c -> 566cdeb157ec</small></div>
<pre class="diff" style="margin:0;" ><small id="info" style="color: #888888;" >--- lxdream/src/bootstrap.c
+++ lxdream/src/bootstrap.c
@@ -135,3 +135,71 @@
</small></pre><pre id="context" class="diff" style="margin:0; background-color:#eeeeee;" >         INFO( buf, NULL );
     }
 }
</pre><pre id="added" class="diff" style="margin:0; background-color:#ddffdd;" >+
+/* Scramble/unscramble, based on Marcus Comstedt's algorithm. */
+
+typedef uint16_t randseed;
+
+#define MAXBLOCK (2048*1024)
+#define CHUNKSIZE 32
+#define NEXT(seed)  (((seed = (seed*2109+9273)&0x7fff) + 0xC000) & 0xFFFF)
+
+void bootprogram_scramble( unsigned char *dest, unsigned char *src, size_t length )
+{
+    randseed seed = length & 0xFFFF;
+    unsigned table[MAXBLOCK/32];
+    unsigned char *s = src;
+    unsigned char *d = dest;
+
+    for( unsigned blocksize = MAXBLOCK; blocksize >= CHUNKSIZE; blocksize >>= 1 ) {
+        while( length >= blocksize ) {
+            unsigned nchunks = blocksize/CHUNKSIZE;
+            for( unsigned i=0; i<nchunks; i++ ) {
+                table[i] = i; // Identity
+            }
+            for( unsigned i = nchunks-1; i != (unsigned)-1; --i ) {
+                unsigned j = (NEXT(seed) * i)>>16;
+                unsigned tmp = table[i];
+                table[i] = table[j];
+                table[j] = tmp;
+                memcpy( d, s + CHUNKSIZE*table[i], CHUNKSIZE );
+                d+= CHUNKSIZE;
+            }
+            length -= blocksize;
+            s += blocksize;
+        }
+    }
+    if( length ) {
+        memcpy( d, s, length );
+    }
+}
+
+void bootprogram_unscramble( unsigned char *dest, unsigned char *src, size_t length )
+{
+    randseed seed = length & 0xFFFF;
+    unsigned table[MAXBLOCK/32];
+    unsigned char *s = src;
+    unsigned char *d = dest;
+
+    for( unsigned blocksize = MAXBLOCK; blocksize >= CHUNKSIZE; blocksize >>= 1 ) {
+        while( length >= blocksize ) {
+            unsigned nchunks = blocksize/CHUNKSIZE;
+            for( unsigned i=0; i<nchunks; i++ ) {
+                table[i] = i; // Identity
+            }
+            for( unsigned i = nchunks-1; i != (unsigned)-1; --i ) {
+                unsigned j = (NEXT(seed) * i)>>16;
+                unsigned tmp = table[i];
+                table[i] = table[j];
+                table[j] = tmp;
+                memcpy( d + CHUNKSIZE*table[i], s, CHUNKSIZE );
+                s+= CHUNKSIZE;
+            }
+            length -= blocksize;
+            d += blocksize;
+        }
+    }
+    if( length ) {
+        memcpy( d, s, length );
+    }
+}
</pre></div>
<hr /><a name="file5" /><div class="file" style="border:1px solid #eeeeee;margin-top:1em;margin-bottom:1em;" >
<span class="pathname" style="font-family:monospace; float:right;" >lxdream/src</span><br />
<div class="fileheader" style="margin-bottom:.5em;" ><big><b>bootstrap.h</b></big> <small id="info" style="color: #888888;" >4f2750753a6c -> 566cdeb157ec</small></div>
<pre class="diff" style="margin:0;" ><small id="info" style="color: #888888;" >--- lxdream/src/bootstrap.h
+++ lxdream/src/bootstrap.h
@@ -31,6 +31,7 @@
</small></pre><pre id="context" class="diff" style="margin:0; background-color:#eeeeee;" > #define BOOTSTRAP_LOAD_ADDR 0x8C008000
 #define BOOTSTRAP_SIZE 32768
 #define BOOTSTRAP_MAGIC "SEGA SEGAKATANA SEGA ENTERPRISES"
</pre><pre id="added" class="diff" style="margin:0; background-color:#ddffdd;" >+#define BOOTSTRAP_MAGIC_SIZE 32
</pre><pre id="context" class="diff" style="margin:0; background-color:#eeeeee;" > 
 #define BINARY_LOAD_ADDR 0x8C010000
 
</pre><pre class="diff" style="margin:0;" ><small id="info" style="color: #888888;" >@@ -59,6 +60,8 @@
</small></pre><pre id="context" class="diff" style="margin:0; background-color:#eeeeee;" >  */
 void bootstrap_dump(void *data, gboolean detail);
 
</pre><pre id="added" class="diff" style="margin:0; background-color:#ddffdd;" >+void bootprogram_scramble( unsigned char *dest, unsigned char *src, size_t length );
+void bootprogram_unscramble( unsigned char *dest, unsigned char *src, size_t length );
</pre><pre id="context" class="diff" style="margin:0; background-color:#eeeeee;" > #ifdef __cplusplus
 }
 #endif
</pre></div>
<hr /><a name="file6" /><div class="file" style="border:1px solid #eeeeee;margin-top:1em;margin-bottom:1em;" >
<span class="pathname" style="font-family:monospace; float:right;" >lxdream/src/drivers/cdrom</span><br />
<div class="fileheader" style="margin-bottom:.5em;" ><big><b>cdrom.c</b></big> <small id="info" style="color: #888888;" >4f2750753a6c -> 566cdeb157ec</small></div>
<pre class="diff" style="margin:0;" ><small id="info" style="color: #888888;" >--- lxdream/src/drivers/cdrom/cdrom.c
+++ lxdream/src/drivers/cdrom/cdrom.c
@@ -74,7 +74,8 @@
</small></pre><pre id="context" class="diff" style="margin:0; background-color:#eeeeee;" >         len += tmplen;
         current += sub_count;
     }
</pre><pre id="removed" class="diff" style="margin:0; background-color:#ffdddd;" >-    *length = len;
</pre><pre id="added" class="diff" style="margin:0; background-color:#ddffdd;" >+    if( length != NULL )
+        *length = len;
</pre><pre id="context" class="diff" style="margin:0; background-color:#eeeeee;" >     return CDROM_ERROR_OK;
 }
 
</pre><pre class="diff" style="margin:0;" ><small id="info" style="color: #888888;" >@@ -310,6 +311,15 @@
</small></pre><pre id="context" class="diff" style="margin:0; background-color:#eeeeee;" >     return &disc->track[disc->track_count-1];
 }
 
</pre><pre id="added" class="diff" style="margin:0; background-color:#ddffdd;" >+cdrom_track_t cdrom_disc_get_last_data_track( cdrom_disc_t disc )
+{
+    for( unsigned i=disc->track_count; i>0; i-- ) {
+        if( disc->track[i-1].flags & TRACK_FLAG_DATA ) {
+            return &disc->track[i-1];
+        }
+    }
+    return NULL;
+}
</pre><pre id="context" class="diff" style="margin:0; background-color:#eeeeee;" > cdrom_track_t cdrom_disc_prev_track( cdrom_disc_t disc, cdrom_track_t track )
 {
     if( track->trackno <= 1 )
</pre><pre class="diff" style="margin:0;" ><small id="info" style="color: #888888;" >@@ -383,4 +393,3 @@
</small></pre><pre id="context" class="diff" style="margin:0; background-color:#eeeeee;" > {
     cdrom_disc_print_toc( stderr, disc );
 }
</pre><pre id="removed" class="diff" style="margin:0; background-color:#ffdddd;" >-
</pre></div>
<hr /><a name="file7" /><div class="file" style="border:1px solid #eeeeee;margin-top:1em;margin-bottom:1em;" >
<span class="pathname" style="font-family:monospace; float:right;" >lxdream/src/drivers/cdrom</span><br />
<div class="fileheader" style="margin-bottom:.5em;" ><big><b>cdrom.h</b></big> <small id="info" style="color: #888888;" >4f2750753a6c -> 566cdeb157ec</small></div>
<pre class="diff" style="margin:0;" ><small id="info" style="color: #888888;" >--- lxdream/src/drivers/cdrom/cdrom.h
+++ lxdream/src/drivers/cdrom/cdrom.h
@@ -110,6 +110,11 @@
</small></pre><pre id="context" class="diff" style="margin:0; background-color:#eeeeee;" > 
 cdrom_track_t cdrom_disc_get_last_track( cdrom_disc_t disc );
 
</pre><pre id="added" class="diff" style="margin:0; background-color:#ddffdd;" >+/**
+ * Get the track information for the last data track  on the disc
+ */
+cdrom_track_t cdrom_disc_get_last_data_track( cdrom_disc_t disc );
+
</pre><pre id="context" class="diff" style="margin:0; background-color:#eeeeee;" > cdrom_track_t cdrom_disc_prev_track( cdrom_disc_t disc, cdrom_track_t track );
 cdrom_track_t cdrom_disc_next_track( cdrom_disc_t disc, cdrom_track_t track );
 
</pre></div>
<hr /><a name="file8" /><div class="file" style="border:1px solid #eeeeee;margin-top:1em;margin-bottom:1em;" >
<span class="pathname" style="font-family:monospace; float:right;" >lxdream/src/drivers/cdrom</span><br />
<div class="fileheader" style="margin-bottom:.5em;" ><big><b>drive.c</b></big> <small id="info" style="color: #888888;" >4f2750753a6c -> 566cdeb157ec</small></div>
<pre class="diff" style="margin:0;" ><small id="info" style="color: #888888;" >--- lxdream/src/drivers/cdrom/drive.c
+++ lxdream/src/drivers/cdrom/drive.c
@@ -17,6 +17,7 @@
</small></pre><pre id="context" class="diff" style="margin:0; background-color:#eeeeee;" >  */
 
 #include <stdlib.h>
</pre><pre id="added" class="diff" style="margin:0; background-color:#ddffdd;" >+#include <string.h>
</pre><pre id="context" class="diff" style="margin:0; background-color:#eeeeee;" > #include <glib/gstrfuncs.h>
 #include <glib/gmem.h>
 #include "drivers/cdrom/drive.h"
</pre></div>
<hr /><a name="file9" /><div class="file" style="border:1px solid #eeeeee;margin-top:1em;margin-bottom:1em;" >
<span id="added" class="pathname" style="font-family:monospace; float:right; background-color:#ddffdd;" >lxdream/src/drivers/cdrom</span><br />
<div id="added" class="fileheader" style="margin-bottom:.5em; background-color:#ddffdd;" ><big><b>iso_impl.h</b></big> <small id="info" style="color: #888888;" >added at 566cdeb157ec</small></div>
<pre class="diff" style="margin:0;" ><small id="info" style="color: #888888;" >--- lxdream/src/drivers/cdrom/iso_impl.h
+++ lxdream/src/drivers/cdrom/iso_impl.h
@@ -0,0 +1,128 @@
</small></pre><pre id="added" class="diff" style="margin:0; background-color:#ddffdd;" >+/**
+ * $Id$
+ *
+ * ISO9660 filesystem support
+ *
+ * Copyright (c) 2009 Nathan Keynes.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ */
+
+#define ISO_SUPERBLOCK_OFFSET 16
+#define ISO_BOOT_DESCRIPTOR 0
+#define ISO_PRIMARY_DESCRIPTOR 1
+#define ISO_SECONDARY_DESCRIPTOR 2
+#define ISO_PARTITION_DESCRIPTOR 3
+#define ISO_TERMINAL_DESCRIPTOR 0xFF
+
+typedef struct iso_timestamp_full { /* 17 bytes */
+    char year[4];
+    char month[2];
+    char day[2];
+    char hour[2];
+    char minute[2];
+    char second[2];
+    char hundredths[2];
+    int8_t utc_offset; /* 15 min intervals from -48 to +52 7.1.2 */
+} *iso_timestamp_full_t;
+
+typedef struct iso_timestamp { /* 7 bytes */
+    uint8_t year; /* Since 1900 */
+    uint8_t month; /* 1 .. 12 */
+    uint8_t day; /* 1 ..  31 */
+    uint8_t hour; /* 0 .. 23 */
+    uint8_t minute; /* 0 .. 59 */
+    uint8_t second; /* 0 .. 59 */
+    uint8_t utc_offset; /* 15 min intervals from -48 to +52 7.1.2 */
+} *iso_timestamp_t;
+
+#define ISO_FILE_EXISTS   0x01
+#define ISO_FILE_DIR      0x02
+#define ISO_FILE_ASSOC    0x04 /* Associated file */
+#define ISO_FILE_RECORD   0x08 /* Structure specified by XA record */
+#define ISO_FILE_PROTECT  0x10 /* Permissions specified */
+#define ISO_FILE_MULTIEXT 0x80 /* Multiple extents */
+
+typedef struct iso_dirent { /* 34+ bytes 9.1 */
+    uint8_t record_len;
+    uint8_t xa_record_len;
+    uint32_t file_lba_le, file_lba_be;
+    uint32_t file_size_le, file_size_be;
+    struct iso_timestamp timestamp;
+    uint8_t flags;
+    uint8_t unit_size;
+    uint8_t gap_size;
+    uint16_t volume_seq_le, volume_seq_be;
+    uint8_t file_id_len;
+    char file_id[1];
+} __attribute__((packed)) *iso_dirent_t;
+
+typedef struct iso_pathtabrec { /* 8+ bytes 9.4 */
+    uint8_t record_len;
+    uint8_t xa_record_len;
+    uint32_t file_lba;
+    uint16_t parent_dir_no;
+    char file_id[];
+} *iso_pathtabrec_t;
+
+typedef struct iso_xattrrec {
+    uint16_t uid_le, uid_be;
+    uint16_t gid_le, gid_be;
+    uint16_t permissions;
+    struct iso_timestamp_full create_time;
+    struct iso_timestamp_full modify_time;
+    struct iso_timestamp_full expiry_time;
+    struct iso_timestamp_full effective_time;
+    uint8_t record_format;
+    uint8_t record_attrs;
+    uint16_t record_len_le, record_len_be;
+    char system_id[32];
+    char system_use[64];
+    uint8_t record_version; /* Should be 1 */
+    uint8_t escape_len;
+    char reserved[64];
+    uint16_t app_use_len_le, app_use_len_be;
+    char app_use[];
+} *iso_xattrrec_t;
+
+/** Primary Volume Descriptor */
+typedef struct iso_pvd {
+    uint8_t desc_type;
+    char tag[5];
+    uint8_t desc_version;
+    char pad0;
+    char system_id[32];
+    char volume_id[32];
+    char pad1[8];
+    uint32_t volume_size_le, volume_size_be;
+    char pad2[32];
+    uint16_t volume_sets_le, volume_sets_be;
+    uint16_t volume_seq_le, volume_seq_be;
+    uint16_t block_size_le, block_size_be;
+    uint32_t pathtab_size_le, pathtab_size_be;
+    uint32_t pathtab_offset_le, pathtab2_offset_le;
+    uint32_t pathtab_offset_be, pathtab2_offset_be;
+    struct iso_dirent root_dirent;
+    char volume_set_id[128];
+    char publisher_id[128];
+    char preparer_id[128];
+    char app_id[128];
+    char copyright_file_id[37];
+    char abstract_file_id[37];
+    char biblio_file_id[37];
+    struct iso_timestamp_full create_time;
+    struct iso_timestamp_full modify_time;
+    struct iso_timestamp_full expiry_time;
+    struct iso_timestamp_full effective_time;
+    uint8_t fs_version; /* must be 1 */
+    char pad3[1166];
+} *iso_pvd_t;
+
</pre></div>
<hr /><a name="file10" /><div class="file" style="border:1px solid #eeeeee;margin-top:1em;margin-bottom:1em;" >
<span id="added" class="pathname" style="font-family:monospace; float:right; background-color:#ddffdd;" >lxdream/src/drivers/cdrom</span><br />
<div id="added" class="fileheader" style="margin-bottom:.5em; background-color:#ddffdd;" ><big><b>isoread.c</b></big> <small id="info" style="color: #888888;" >added at 566cdeb157ec</small></div>
<pre class="diff" style="margin:0;" ><small id="info" style="color: #888888;" >--- lxdream/src/drivers/cdrom/isoread.c
+++ lxdream/src/drivers/cdrom/isoread.c
@@ -0,0 +1,392 @@
</small></pre><pre id="added" class="diff" style="margin:0; background-color:#ddffdd;" >+/**
+ * $Id$
+ *
+ * ISO9660 filesystem reading support
+ *
+ * Copyright (c) 2010 Nathan Keynes.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ */
+
+#include "drivers/cdrom/cdrom.h"
+#include "drivers/cdrom/isoread.h"
+#include "drivers/cdrom/iso_impl.h"
+
+#include <string.h>
+#include <errno.h>
+
+static char isofs_magic[5] = { 'C', 'D', '0', '0', '1' };
+
+#define ISO_DIR_TAG 0x52494449
+
+struct isofs_reader_dir {
+    uint32_t tag;
+    isofs_reader_dir_t parent;
+    size_t num_entries;
+    struct isofs_reader_dirent entries[];
+};
+
+struct isofs_reader {
+    /**
+     * Base sector source to read the filesystem from (must support Mode 1 reads)
+     */
+    sector_source_t source;
+
+    /**
+     * Offset of the source relative to the start of the (notional) disc -
+     * this is subtracted from all source lba addresses.
+     */
+    cdrom_lba_t source_offset;
+
+    /**
+     * Start of the ISO9660 filesystem relative to the start of the disc.
+     * (The actual superblock is at fs_start+16)
+     */
+    cdrom_lba_t fs_start;
+
+    /**
+     * If TRUE, read the little-endian side of the FS, otherwise the big-endian
+     * side. (They should normally give the same result, but in case it matters...)
+     */
+    gboolean little_endian;
+
+    /**
+     * The volume sequence number, for multi-volume sets.
+     */
+    uint16_t volume_seq_no;
+
+    char volume_label[33];
+
+    /**
+     * Filesystem root directory
+     */
+    isofs_reader_dir_t root_dir;
+};
+
+/**
+ * Read a 16-bit dual-endian field using the defined endianness of the reader
+ */
+#define ISO_GET_DE16( iso, field ) \
+    ( ((iso)->little_endian) ? GINT16_FROM_LE(field) : GINT16_FROM_BE(*((&field)+1)) )
+
+/**
+ * Read a 32-bit dual-endian field using the defined endianness of the reader
+ */
+#define ISO_GET_DE32( iso, field ) \
+    ( ((iso)->little_endian) ? GINT32_FROM_LE(field) : GINT32_FROM_BE(*((&field)+1)) )
+
+
+static void isofs_reader_convert_dirent( isofs_reader_t iso, isofs_reader_dirent_t dest, iso_dirent_t src,
+                                         char **strp )
+{
+    dest->start_lba = ISO_GET_DE32(iso, src->file_lba_le);
+    dest->size = ISO_GET_DE32(iso, src->file_size_le);
+    dest->is_dir = (src->flags & ISO_FILE_DIR) ? TRUE : FALSE;
+    dest->interleave_gap = src->gap_size;
+    dest->interleave_size = src->unit_size;
+    dest->name = *strp;
+    memcpy( *strp, src->file_id, src->file_id_len );
+    (*strp)[src->file_id_len] = '\0';
+    *strp += src->file_id_len + 1;
+}
+
+/**
+ * Read a directory from the disc into memory.
+ */
+isofs_reader_dir_t isofs_reader_read_dir( isofs_reader_t iso, cdrom_lba_t lba, size_t size )
+{
+    cdrom_count_t count = (size+2047)/2048;
+
+    char buf[count*2048];
+
+    if( isofs_reader_read_sectors( iso, lba, count, buf ) != CDROM_ERROR_OK )
+        return NULL;
+
+    size_t len = 0;
+    unsigned num_entries = 0, i=0, offset=0;
+    /* Compute number of entries and total string length */
+    while( offset < size ) {
+        struct iso_dirent *p = (struct iso_dirent *)&buf[offset];
+        offset += p->record_len;
+        if( offset > size || p->record_len < sizeof(struct iso_dirent) )
+            break; // Bad record length
+        if( p->file_id_len + sizeof(struct iso_dirent)-1 > p->record_len )
+            break; // Bad fileid length
+        if( p->file_id_len == 1 && (p->file_id[0] == 0 || p->file_id[0] == 1 ) )
+            continue; /* self and parent-dir references */
+        num_entries++;
+        len += p->file_id_len + 1;
+    }
+
+    size_t table_len = num_entries * sizeof(struct isofs_reader_dirent);
+    isofs_reader_dir_t dir = g_malloc0( sizeof(struct isofs_reader_dir) + table_len + len );
+    dir->tag = ISO_DIR_TAG;
+    dir->num_entries = num_entries;
+
+    char *strp = (char *)&dir->entries[num_entries];
+    offset = 0;
+    for( i=0; i < num_entries; i++ ) {
+        struct iso_dirent *p;
+        do {
+            p = (struct iso_dirent *)&buf[offset];
+            offset += p->record_len;
+            /* Skip over self and parent-dir references */
+        } while( p->file_id_len == 1 && (p->file_id[0] == 0 || p->file_id[0] == 1 ) );
+
+        isofs_reader_convert_dirent( iso, &dir->entries[i], p, &strp );
+
+    }
+    return dir;
+}
+
+static gboolean isofs_reader_dirent_match_exact( const char *file, const char *find )
+{
+    return strcasecmp( file, find ) == 0;
+}
+
+static gboolean isofs_reader_dirent_match_unversioned( const char *file, const char *find )
+{
+    char *semi = strchr(file, ';');
+    if( semi == NULL ) {
+        /* Unversioned ISO file */
+        return strcasecmp( file, find ) == 0;
+    } else {
+        int len = semi - file;
+        return strncasecmp( file, find, len ) == 0 && strlen(find) == len;
+    }
+}
+
+/**
+ * Search a directory for a given filename. If found, return the corresponding
+ * dirent structure, otherwise NULL. Comparison is case-insensitive, and returns
+ * the most recent (highest numbered) version of a file in case of multiple
+ * versions unless the requested component is also explicitly versioned.
+ *
+ * For now just do a linear search, although we could do a binary search given
+ * that the directory should be sorted.
+ */
+static isofs_reader_dirent_t isofs_reader_get_file_component( isofs_reader_dir_t dir, const char *component )
+{
+
+    if( strchr( component, ';' ) != NULL ) {
+        for( unsigned i=0; i<dir->num_entries; i++ ) {
+            if( isofs_reader_dirent_match_exact(dir->entries[i].name,component) ) {
+                return &dir->entries[i];
+            }
+        }
+    } else {
+        for( unsigned i=0; i<dir->num_entries; i++ ) {
+            if( isofs_reader_dirent_match_unversioned(dir->entries[i].name,component) ) {
+                return &dir->entries[i];
+            }
+        }
+    }
+    return NULL;
+}
+
+isofs_reader_dirent_t isofs_reader_get_file( isofs_reader_t iso, const char *pathname )
+{
+    int pathlen = strlen(pathname);
+    char tmp[pathlen+1];
+    char *p = tmp;
+    isofs_reader_dir_t dir = iso->root_dir;
+
+    memcpy( tmp, pathname, pathlen+1 );
+    char *q = strchr(p, '/');
+    while( q != NULL ) {
+        *q = '\0';
+        isofs_reader_dirent_t ent = isofs_reader_get_file_component( dir, p );
+        if( ent == NULL || !ent->is_dir ) {
+            return NULL;
+        }
+        if( ent->subdir == NULL ) {
+            ent->subdir = dir = isofs_reader_read_dir( iso, ent->start_lba, ent->size );
+            if( dir == NULL ) {
+                return NULL;
+            }
+        }
+
+        p = q+1;
+        q = strchr(p, '/');
+
+    }
+    return isofs_reader_get_file_component( dir, p );
+}
+
+cdrom_error_t isofs_reader_read_file( isofs_reader_t iso, isofs_reader_dirent_t file,
+                                      size_t offset, size_t byte_count, unsigned char *buf )
+{
+    char tmp[2048];
+
+    if( offset + byte_count > file->size )
+        return CDROM_ERROR_BADREAD;
+
+    if( file->interleave_gap == 0 ) {
+        cdrom_lba_t lba = file->start_lba + (offset>>11);
+        lba += ((file->xa_size+2047)>>11); /* Skip XA record if present */
+
+        if( (offset & 2047) != 0 ) {
+            /* Read an unaligned start block */
+            cdrom_error_t status = isofs_reader_read_sectors( iso, lba, 1, tmp );
+            if( status != CDROM_ERROR_OK )
+                return status;
+            unsigned align = offset & 2047;
+            size_t length = 2048 - align;
+            if( length >= byte_count ) {
+                memcpy( buf, &tmp[align], byte_count );
+                return CDROM_ERROR_OK;
+            } else {
+                memcpy( buf, &tmp[align], length );
+                byte_count -= length;
+                buf += length;
+                lba++;
+            }
+        }
+        /* Read the bulk of the data */
+        cdrom_count_t sector_count = byte_count >> 11;
+        if( sector_count > 0 ) {
+            cdrom_error_t status = isofs_reader_read_sectors( iso, lba, sector_count, buf );
+            if( status != CDROM_ERROR_OK )
+                return status;
+            buf += (sector_count << 11);
+            lba += sector_count;
+        }
+        /* Finally read a partial final block */
+        if( (byte_count & 2047) != 0 ) {
+            cdrom_error_t status = isofs_reader_read_sectors( iso, lba, 1, tmp );
+            if( status != CDROM_ERROR_OK )
+                return status;
+            memcpy( buf, tmp, byte_count & 2047 );
+        }
+        return CDROM_ERROR_OK;
+    } else {
+        // ERROR("Interleaved files not supported");
+        return CDROM_ERROR_BADREAD;
+    }
+}
+
+void isofs_reader_destroy_dir( isofs_reader_dir_t dir )
+{
+    dir->tag = 0;
+    for( unsigned i=0; i<dir->num_entries; i++ ) {
+        if( dir->entries[i].subdir != NULL ) {
+            isofs_reader_dir_t subdir = dir->entries[i].subdir;
+            dir->entries[i].subdir = NULL;
+            isofs_reader_destroy_dir(dir);
+        }
+    }
+    g_free(dir);
+}
+
+cdrom_error_t isofs_reader_read_sectors( isofs_reader_t iso, cdrom_lba_t lba, cdrom_count_t count,
+                                         unsigned char *buf )
+{
+    if( lba < iso->source_offset )
+        return CDROM_ERROR_BADREAD;
+    return sector_source_read_sectors( iso->source, lba - iso->source_offset, count,
+           CDROM_READ_MODE2_FORM1|CDROM_READ_DATA, buf, NULL );
+}
+
+
+isofs_reader_t isofs_reader_new( sector_source_t source, cdrom_lba_t offset, cdrom_lba_t start, ERROR *err )
+{
+    char buf[2048];
+    iso_pvd_t pvd = (iso_pvd_t)&buf;
+    unsigned i = 0;
+
+    isofs_reader_t iso = g_malloc0( sizeof(struct isofs_reader) );
+    if( iso == NULL ) {
+        SET_ERROR( err, ENOMEM, "Unable to allocate memory" );
+        return NULL;
+    }
+    iso->source = source;
+    iso->source_offset = offset;
+    iso->fs_start = start;
+    iso->little_endian = TRUE;
+
+    do {
+        /* Find the primary volume descriptor */
+        cdrom_error_t status = isofs_reader_read_sectors( iso, iso->fs_start + ISO_SUPERBLOCK_OFFSET + i, 1, buf );
+        if( status != CDROM_ERROR_OK ) {
+            SET_ERROR( err, EBADF, "Unable to read superblock from ISO9660 filesystem" );
+            g_free(iso);
+            return NULL;
+        }
+        if( memcmp(pvd->tag, isofs_magic, 5) != 0 || /* Not an ISO volume descriptor */
+                pvd->desc_type == ISO_TERMINAL_DESCRIPTOR ) { /* Reached the end of the descriptor list */
+            SET_ERROR( err, EINVAL, "ISO9660 filesystem not found" );
+            g_free(iso);
+            return NULL;
+        }
+        i++;
+    } while( pvd->desc_type != ISO_PRIMARY_DESCRIPTOR );
+
+    if( pvd->desc_version != 1 ) {
+        SET_ERROR( err, EINVAL, "Incompatible ISO9660 filesystem" );
+        g_free(iso);
+        return NULL;
+    }
+
+    iso->volume_seq_no = ISO_GET_DE16(iso, pvd->volume_seq_le);
+    memcpy( iso->volume_label, pvd->volume_id, 32 );
+    for( i=32; i>0 && iso->volume_label[i-1] == ' '; i-- );
+    iso->volume_label[i] = '\0';
+
+    iso->root_dir = isofs_reader_read_dir( iso,
+            ISO_GET_DE32(iso, pvd->root_dirent.file_lba_le),
+            ISO_GET_DE32(iso, pvd->root_dirent.file_size_le) );
+    if( iso->root_dir == NULL ) {
+        SET_ERROR( err, EINVAL, "Unable to read root directory from ISO9660 filesystem" );
+        g_free(iso);
+        return NULL;
+    }
+
+    sector_source_ref( source );
+    return iso;
+}
+
+isofs_reader_t isofs_reader_new_from_disc( cdrom_disc_t disc, cdrom_lba_t lba, ERROR *err )
+{
+    return isofs_reader_new( &disc->source, 0, lba, err );
+}
+
+isofs_reader_t isofs_reader_new_from_track( cdrom_disc_t disc, cdrom_track_t track, ERROR *err )
+{
+    return isofs_reader_new( &disc->source, 0, track->lba, err );
+}
+
+isofs_reader_t isofs_reader_new_from_source( sector_source_t source, ERROR *err )
+{
+    return isofs_reader_new( source, 0, 0, err );
+}
+
+void isofs_reader_destroy( isofs_reader_t iso )
+{
+    isofs_reader_destroy_dir( iso->root_dir );
+    iso->root_dir = NULL;
+    sector_source_unref( iso->source );
+    iso->source = NULL;
+    g_free( iso );
+}
+
+isofs_reader_dir_t isofs_reader_get_root_dir( isofs_reader_t iso )
+{
+    return iso->root_dir;
+}
+
+void isofs_reader_print_dir( FILE *f, isofs_reader_dir_t dir )
+{
+    fprintf( f, "Total %d files\n", dir->num_entries );
+    for( unsigned i=0; i<dir->num_entries; i++ ) {
+        fprintf( f, "%7d %s\n", dir->entries[i].size, dir->entries[i].name );
+    }
+
+}
</pre></div>
<hr /><a name="file11" /><div class="file" style="border:1px solid #eeeeee;margin-top:1em;margin-bottom:1em;" >
<span id="added" class="pathname" style="font-family:monospace; float:right; background-color:#ddffdd;" >lxdream/src/drivers/cdrom</span><br />
<div id="added" class="fileheader" style="margin-bottom:.5em; background-color:#ddffdd;" ><big><b>isoread.h</b></big> <small id="info" style="color: #888888;" >added at 566cdeb157ec</small></div>
<pre class="diff" style="margin:0;" ><small id="info" style="color: #888888;" >--- lxdream/src/drivers/cdrom/isoread.h
+++ lxdream/src/drivers/cdrom/isoread.h
@@ -0,0 +1,95 @@
</small></pre><pre id="added" class="diff" style="margin:0; background-color:#ddffdd;" >+/**
+ * $Id$
+ *
+ * ISO9660 filesystem reading support
+ *
+ * Copyright (c) 2010 Nathan Keynes.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ */
+
+
+#ifndef cdrom_isoread_H
+#define cdrom_isoread_H 1
+
+#include "drivers/cdrom/defs.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+typedef struct isofs_reader_dir *isofs_reader_dir_t;
+
+typedef struct isofs_reader_dirent {
+    const char *name;
+    size_t size;
+    gboolean is_dir;
+
+    cdrom_lba_t start_lba;
+    size_t xa_size;
+    unsigned interleave_gap;
+    unsigned interleave_size;
+    isofs_reader_dir_t subdir;
+} *isofs_reader_dirent_t;
+
+/**
+ * ISO9600 filesystem reader.
+ */
+typedef struct isofs_reader *isofs_reader_t;
+
+/**
+ * Construct an isofs reader from an existing sector source. On error, returns
+ * NULL.
+ */
+isofs_reader_t isofs_reader_new_from_source( sector_source_t track, ERROR *err );
+
+/**
+ * Construct an isofs from a cdrom disc and sector position.
+ * @return a new isofs_reader, or NULL on an error (and sets err).
+ */
+isofs_reader_t isofs_reader_new_from_disc( cdrom_disc_t disc, cdrom_lba_t start_sector, ERROR *err );
+
+isofs_reader_t isofs_reader_new_from_track( cdrom_disc_t disc, cdrom_track_t track, ERROR *err );
+
+/**
+ * Destroy an isofs reader.
+ */
+void isofs_reader_destroy( isofs_reader_t reader );
+
+/**
+ * Read 0 or more 2048-byte sectors from the filesystem.
+ */
+cdrom_error_t isofs_reader_read_sectors( isofs_reader_t iso, cdrom_lba_t sector, cdrom_count_t count,
+                                         unsigned char *buf );
+
+
+/**
+ * Search the filesystem for the specific fully-qualified file.
+ * @return FALSE if the file could not be found, otherwise TRUE and the iterator
+ * is updated to point to the requested file.
+ */
+isofs_reader_dirent_t isofs_reader_get_file( isofs_reader_t iso, const char *filename );
+
+cdrom_error_t isofs_reader_read_file( isofs_reader_t iso, isofs_reader_dirent_t file,
+                                      size_t offset, size_t byte_count, unsigned char *buf );
+
+/**
+ * Print an isofs directory to the given stream (mostly for debugging purposes)
+ */
+void isofs_reader_print_dir( FILE *f, isofs_reader_dir_t dir );
+
+isofs_reader_dir_t isofs_reader_get_root_dir( isofs_reader_t iso );
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* !cdrom_isoread_H */
</pre></div>
<hr /><a name="file12" /><div class="file" style="border:1px solid #eeeeee;margin-top:1em;margin-bottom:1em;" >
<span class="pathname" style="font-family:monospace; float:right;" >lxdream/src/drivers/cdrom</span><br />
<div class="fileheader" style="margin-bottom:.5em;" ><big><b>sector.c</b></big> <small id="info" style="color: #888888;" >4f2750753a6c -> 566cdeb157ec</small></div>
<pre class="diff" style="margin:0;" ><small id="info" style="color: #888888;" >--- lxdream/src/drivers/cdrom/sector.c
+++ lxdream/src/drivers/cdrom/sector.c
@@ -32,7 +32,7 @@
</small></pre><pre id="context" class="diff" style="margin:0; background-color:#eeeeee;" > #define CHECK_READ(dev,lba,count) \
     if( !IS_SECTOR_SOURCE(dev) ) { \
         return CDROM_ERROR_NODISC; \
</pre><pre id="removed" class="diff" style="margin:0; background-color:#ffdddd;" >-    } else if( (lba) >= (dev)->size || (lba+block_count) > (dev)->size ) { \
</pre><pre id="added" class="diff" style="margin:0; background-color:#ddffdd;" >+    } else if( (dev)->size != 0 && ((lba) >= (dev)->size || (lba+block_count) > (dev)->size) ) { \
</pre><pre id="context" class="diff" style="margin:0; background-color:#eeeeee;" >         return CDROM_ERROR_BADREAD; \
     }
 
</pre><pre class="diff" style="margin:0;" ><small id="info" style="color: #888888;" >@@ -340,11 +340,13 @@
</small></pre><pre id="context" class="diff" style="margin:0; background-color:#eeeeee;" >         if( err != CDROM_ERROR_OK )
             return err;
         if( read_sector_fields == 0 ) { /* Read nothing */
</pre><pre id="removed" class="diff" style="margin:0; background-color:#ffdddd;" >-            *length = 0;
</pre><pre id="added" class="diff" style="margin:0; background-color:#ddffdd;" >+            if( length != NULL )
+                *length = 0;
</pre><pre id="context" class="diff" style="margin:0; background-color:#eeeeee;" >             return CDROM_ERROR_OK;
         } else if( read_sector_fields == CDROM_READ_DATA ) {
             /* Data-only */
</pre><pre id="removed" class="diff" style="margin:0; background-color:#ffdddd;" >-            *length = block_count * CDROM_SECTOR_SIZE(device->mode);
</pre><pre id="added" class="diff" style="margin:0; background-color:#ddffdd;" >+            if( length != NULL )
+                *length = block_count * CDROM_SECTOR_SIZE(device->mode);
</pre><pre id="context" class="diff" style="margin:0; background-color:#eeeeee;" >             return device->read_blocks( device, lba, block_count, buf );
         } else if( read_sector_fields == CDROM_READ_RAW ) {
             for( i=0; i<block_count; i++ ) {
</pre><pre class="diff" style="margin:0;" ><small id="info" style="color: #888888;" >@@ -366,7 +368,8 @@
</small></pre><pre id="context" class="diff" style="margin:0; background-color:#eeeeee;" >             }
         }
     }
</pre><pre id="removed" class="diff" style="margin:0; background-color:#ffdddd;" >-    *length = len;
</pre><pre id="added" class="diff" style="margin:0; background-color:#ddffdd;" >+    if( length != NULL )
+        *length = len;
</pre><pre id="context" class="diff" style="margin:0; background-color:#eeeeee;" >     return CDROM_ERROR_OK;
 
 }
</pre></div>
<hr /><a name="file13" /><div class="file" style="border:1px solid #eeeeee;margin-top:1em;margin-bottom:1em;" >
<span id="added" class="pathname" style="font-family:monospace; float:right; background-color:#ddffdd;" >lxdream/src/test</span><br />
<div id="added" class="fileheader" style="margin-bottom:.5em; background-color:#ddffdd;" ><big><b>testisoread.c</b></big> <small id="info" style="color: #888888;" >added at 566cdeb157ec</small></div>
<pre class="diff" style="margin:0;" ><small id="info" style="color: #888888;" >--- lxdream/src/test/testisoread.c
+++ lxdream/src/test/testisoread.c
@@ -0,0 +1,63 @@
</small></pre><pre id="added" class="diff" style="margin:0; background-color:#ddffdd;" >+/**
+ * $Id$
+ *
+ * Unit tests for the ISO9660 filesystem reader
+ *
+ * Copyright (c) 2010 Nathan Keynes.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ */
+
+#include "drivers/cdrom/cdrom.h"
+#include "drivers/cdrom/isoread.h"
+#include <stdio.h>
+
+int main( int argc, char *argv[] )
+{
+    if( argc < 2 ) {
+        fprintf( stderr, "Usage: testisoread <disc image>\n" );
+        return 1;
+    }
+
+    ERROR err;
+    cdrom_disc_t disc = cdrom_disc_open(argv[1], &err);
+
+    if( disc == NULL ) {
+        fprintf( stderr, "Unable to open disc image '%s': %s\n", argv[1], err.msg );
+        return 2;
+    }
+    cdrom_track_t track = cdrom_disc_get_last_data_track(disc);
+    if( track == NULL ) {
+        fprintf( stderr, "Disc has no data tracks\n" );
+        return 3;
+    }
+
+    isofs_reader_t iso = isofs_reader_new_from_track( disc, track, &err );
+    if( iso == NULL ) {
+        fprintf( stderr, "Unable to open ISO filesystem: %s\n", err.msg );
+        return 4;
+    }
+    isofs_reader_print_dir( stdout, isofs_reader_get_root_dir(iso) );
+
+    isofs_reader_dirent_t boot = isofs_reader_get_file( iso, "1st_read.bin" );
+    if( boot == NULL ) {
+        fprintf( stderr, "Unable to find 1st_read.bin" );
+        return 5;
+    }
+
+    printf( "Bootstrap: %s (%d)\n", boot->name, boot->size );
+    char tmp[boot->size];
+    if( isofs_reader_read_file( iso, boot, 0, boot->size, tmp ) != CDROM_ERROR_OK ) {
+        fprintf( stderr, "Unable to read 1st_read.bin" );
+        return 6;
+    }
+    return 0;
+}
</pre></div>
<center><small>Chaos Theory</small></center>
</div></body></html>