<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>drivers/cdrom/<a href="#file1">cdrom.c</a></tt></td><td id="added" class="headtd2" style="padding-left:.3em;padding-right:.3em; background-color:#ddffdd;" align="right">+75</td><td id="removed" class="headtd2" style="padding-left:.3em;padding-right:.3em; background-color:#ffdddd;" align="right">-12</td><td class="headtd2" style="padding-left:.3em;padding-right:.3em;" nowrap="nowrap">7b279d10f46f -> 305ef2082079</td></tr>
<tr class="alt" style=";" ><td><tt> /<a href="#file2">cdrom.h</a></tt></td><td id="addedalt" class="headtd2" style="padding-left:.3em;padding-right:.3em; background-color:#ccf7cc;" align="right">+9</td><td></td><td class="headtd2" style="padding-left:.3em;padding-right:.3em;" nowrap="nowrap">7b279d10f46f -> 305ef2082079</td></tr>
<tr><td><tt> /<a href="#file3">isofs.c</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">7b279d10f46f -> 305ef2082079</td></tr>
<tr class="alt" style=";" ><td><tt> /<a href="#file4">isofs.h</a></tt></td><td id="addedalt" class="headtd2" style="padding-left:.3em;padding-right:.3em; background-color:#ccf7cc;" align="right">+4</td><td></td><td class="headtd2" style="padding-left:.3em;padding-right:.3em;" nowrap="nowrap">7b279d10f46f -> 305ef2082079</td></tr>
<tr><td><tt> /<a href="#file5">sector.c</a></tt></td><td id="added" class="headtd2" style="padding-left:.3em;padding-right:.3em; background-color:#ddffdd;" align="right">+1</td><td></td><td class="headtd2" style="padding-left:.3em;padding-right:.3em;" nowrap="nowrap">7b279d10f46f -> 305ef2082079</td></tr>
<tr class="alt" style=";" ><td><tt><a href="#file6">loader.c</a></tt></td><td id="addedalt" class="headtd2" style="padding-left:.3em;padding-right:.3em; background-color:#ccf7cc;" align="right">+248</td><td id="removed" class="headtd2" style="padding-left:.3em;padding-right:.3em; background-color:#ffdddd;" align="right">-12</td><td class="headtd2" style="padding-left:.3em;padding-right:.3em;" nowrap="nowrap">7b279d10f46f -> 305ef2082079</td></tr>
<tr><td><tt><a href="#file7">loader.h</a></tt></td><td id="added" class="headtd2" style="padding-left:.3em;padding-right:.3em; background-color:#ddffdd;" align="right">+4</td><td></td><td class="headtd2" style="padding-left:.3em;padding-right:.3em;" nowrap="nowrap">7b279d10f46f -> 305ef2082079</td></tr>
<tr class="alt" style=";" ><td><tt><a href="#file8">main.c</a></tt></td><td id="addedalt" class="headtd2" style="padding-left:.3em;padding-right:.3em; background-color:#ccf7cc;" align="right">+21</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">7b279d10f46f -> 305ef2082079</td></tr>
<tr><td></td><td id="added" class="headtd2" style="padding-left:.3em;padding-right:.3em; background-color:#ddffdd;" align="right">+373</td><td id="removed" class="headtd2" style="padding-left:.3em;padding-right:.3em; background-color:#ffdddd;" align="right">-27</td><td></td></tr>
</table>
<small id="info" style="color: #888888;" >8 modified 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;" >
Add ability to wrap a binary program up in a virtual cd image (so that we
can boot it normally)
</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/drivers/cdrom</span><br />
<div class="fileheader" style="margin-bottom:.5em;" ><big><b>cdrom.c</b></big> <small id="info" style="color: #888888;" >7b279d10f46f -> 305ef2082079</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
@@ -24,6 +24,7 @@
</small></pre><pre id="context" class="diff" style="margin:0; background-color:#eeeeee;" > #include "lxdream.h"
#include "drivers/cdrom/cdrom.h"
#include "drivers/cdrom/cdimpl.h"
</pre><pre id="added" class="diff" style="margin:0; background-color:#ddffdd;" >+#include "drivers/cdrom/isofs.h"
</pre><pre id="context" class="diff" style="margin:0; background-color:#eeeeee;" >
extern struct cdrom_disc_factory linux_cdrom_drive_factory;
extern struct cdrom_disc_factory nrg_disc_factory;
</pre><pre class="diff" style="margin:0;" ><small id="info" style="color: #888888;" >@@ -193,20 +194,24 @@
</small></pre><pre id="context" class="diff" style="margin:0; background-color:#eeeeee;" >
gboolean cdrom_disc_read_toc( cdrom_disc_t disc, ERROR *err )
{
</pre><pre id="removed" class="diff" style="margin:0; background-color:#ffdddd;" >- /* First set the defaults for an empty disc */
- cdrom_disc_clear_toc(disc);
</pre><pre id="added" class="diff" style="margin:0; background-color:#ddffdd;" >+ if( disc->read_toc != NULL ) {
+ /* First set the defaults for an empty disc */
+ cdrom_disc_clear_toc(disc);
</pre><pre id="context" class="diff" style="margin:0; background-color:#eeeeee;" >
</pre><pre id="removed" class="diff" style="margin:0; background-color:#ffdddd;" >- if( disc->read_toc(disc, err ) ) {
- /* Success - update disc type and leadout if the TOC read didn't set them */
- if( disc->disc_type == CDROM_DISC_NONE )
- cdrom_disc_set_default_disc_type(disc);
- cdrom_disc_compute_leadout(disc);
</pre><pre id="added" class="diff" style="margin:0; background-color:#ddffdd;" >+ if( disc->read_toc(disc, err ) ) {
+ /* Success - update disc type and leadout if the TOC read didn't set them */
+ if( disc->disc_type == CDROM_DISC_NONE )
+ cdrom_disc_set_default_disc_type(disc);
+ cdrom_disc_compute_leadout(disc);
+ return TRUE;
+ } else {
+ /* Reset to an empty disc in case the reader left things in an
+ * inconsistent state */
+ cdrom_disc_clear_toc(disc);
+ return FALSE;
+ }
+ } else {
</pre><pre id="context" class="diff" style="margin:0; background-color:#eeeeee;" > return TRUE;
</pre><pre id="removed" class="diff" style="margin:0; background-color:#ffdddd;" >- } else {
- /* Reset to an empty disc in case the reader left things in an
- * inconsistent state */
- cdrom_disc_clear_toc(disc);
- return FALSE;
</pre><pre id="context" class="diff" style="margin:0; background-color:#eeeeee;" > }
}
</pre><pre class="diff" style="margin:0;" ><small id="info" style="color: #888888;" >@@ -273,6 +278,64 @@
</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;" >+ * Construct a disc around a source track.
+ * @param type Disc type, which must be compatible with the track mode
+ * @param track The source of data for the main track
+ * @param lba The position on disc of the main track. If non-zero,
+ * a filler track is added before it, in 2 separate sessions.
+ */
+cdrom_disc_t cdrom_disc_new_from_track( cdrom_disc_type_t type, sector_source_t track, cdrom_lba_t lba )
+{
+ cdrom_disc_t disc = cdrom_disc_new( NULL, NULL );
+ if( disc != NULL ) {
+ disc->disc_type = type;
+ int trackno = 0;
+ if( lba != 0 ) {
+ cdrom_count_t size = lba - 150;
+ if( lba < 150 )
+ size = lba;
+ disc->track[0].trackno = 1;
+ disc->track[0].sessionno = 1;
+ disc->track[0].lba = 0;
+ disc->track[0].flags = 0;
+ disc->track[0].source = null_sector_source_new( SECTOR_CDDA, size );
+ sector_source_ref( disc->track[0].source );
+ trackno++;
+ }
+ disc->track[trackno].trackno = trackno+1;
+ disc->track[trackno].sessionno = trackno+1;
+ disc->track[trackno].lba = lba;
+ disc->track[trackno].flags = (track->mode == SECTOR_CDDA ? 0 : TRACK_FLAG_DATA);
+ disc->track[trackno].source = track;
+ sector_source_ref(track);
+
+ disc->track_count = trackno+1;
+ disc->session_count = trackno+1;
+ cdrom_disc_compute_leadout(disc);
+ }
+ return disc;
+}
+
+/**
+ * Construct a disc around an IsoImage track (convenience function)
+ */
+cdrom_disc_t cdrom_disc_new_from_iso_image( cdrom_disc_type_t type, IsoImage *iso, cdrom_lba_t lba,
+ const char *bootstrap, ERROR *err )
+{
+ sector_mode_t mode = (type == CDROM_DISC_NONXA ? SECTOR_MODE1 : SECTOR_MODE2_FORM1 );
+ sector_source_t source = iso_sector_source_new( iso, mode, lba, bootstrap, err );
+ if( source != NULL ) {
+ cdrom_disc_t disc = cdrom_disc_new_from_track(type, source, lba);
+ if( disc == NULL ) {
+ sector_source_unref( source );
+ } else {
+ return disc;
+ }
+ }
+ return NULL;
+}
+
+/**
</pre><pre id="context" class="diff" style="margin:0; background-color:#eeeeee;" > * Get the track information for the given track. If there is no such track,
* return NULL;
*/
</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/drivers/cdrom</span><br />
<div class="fileheader" style="margin-bottom:.5em;" ><big><b>cdrom.h</b></big> <small id="info" style="color: #888888;" >7b279d10f46f -> 305ef2082079</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
@@ -97,6 +97,15 @@
</small></pre><pre id="context" class="diff" style="margin:0; background-color:#eeeeee;" > cdrom_disc_t cdrom_disc_open( const char *filename, ERROR *err );
/**
</pre><pre id="added" class="diff" style="margin:0; background-color:#ddffdd;" >+ * Construct a disc around a source track.
+ * @param type Disc type, which must be compatible with the track mode
+ * @param track The source of data for the main track
+ * @param lba The position on disc of the main track. If non-zero,
+ * a filler track is added before it, in 2 separate sessions.
+ */
+cdrom_disc_t cdrom_disc_new_from_track( cdrom_disc_type_t type, sector_source_t track, cdrom_lba_t lba );
+
+/**
</pre><pre id="context" class="diff" style="margin:0; background-color:#eeeeee;" > * Get the track information for the given track. If there is no such track,
* return NULL;
*/
</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/drivers/cdrom</span><br />
<div class="fileheader" style="margin-bottom:.5em;" ><big><b>isofs.c</b></big> <small id="info" style="color: #888888;" >7b279d10f46f -> 305ef2082079</small></div>
<pre class="diff" style="margin:0;" ><small id="info" style="color: #888888;" >--- lxdream/src/drivers/cdrom/isofs.c
+++ lxdream/src/drivers/cdrom/isofs.c
@@ -17,6 +17,8 @@
</small></pre><pre id="context" class="diff" style="margin:0; background-color:#eeeeee;" > */
#include <assert.h>
</pre><pre id="added" class="diff" style="margin:0; background-color:#ddffdd;" >+#include <stdio.h>
+#include <unistd.h>
</pre><pre id="context" class="diff" style="margin:0; background-color:#eeeeee;" > #include <glib/gmem.h>
#define LIBISOFS_WITHOUT_LIBBURN 1
</pre><pre class="diff" style="margin:0;" ><small id="info" style="color: #888888;" >@@ -169,8 +171,15 @@
</small></pre><pre id="context" class="diff" style="margin:0; background-color:#eeeeee;" > char buf[2048];
cdrom_count_t expect = size/2048;
cdrom_count_t count = 0;
</pre><pre id="added" class="diff" style="margin:0; background-color:#ddffdd;" >+ int fd = file_sector_source_get_fd(source);
+ source->size = expect;
+ lseek( fd, 0, SEEK_SET );
</pre><pre id="context" class="diff" style="margin:0; background-color:#eeeeee;" > for( cdrom_count_t count = 0; count < expect; count++ ) {
</pre><pre id="removed" class="diff" style="margin:0; background-color:#ffdddd;" >- status = burn->read(burn, buf, 2048);
</pre><pre id="added" class="diff" style="margin:0; background-color:#ddffdd;" >+ if( burn->read == NULL ) {
+ status = burn->read_xt(burn, buf, 2048);
+ } else {
+ status = burn->read(burn, buf, 2048);
+ }
</pre><pre id="context" class="diff" style="margin:0; background-color:#eeeeee;" > if( status == 0 ) {
/* EOF */
break;
</pre><pre class="diff" style="margin:0;" ><small id="info" style="color: #888888;" >@@ -180,6 +189,7 @@
</small></pre><pre id="context" class="diff" style="margin:0; background-color:#eeeeee;" > source = NULL;
break;
}
</pre><pre id="added" class="diff" style="margin:0; background-color:#ddffdd;" >+ write( fd, buf, 2048 );
</pre><pre id="context" class="diff" style="margin:0; background-color:#eeeeee;" > }
burn->free_data(burn);
free(burn);
</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/drivers/cdrom</span><br />
<div class="fileheader" style="margin-bottom:.5em;" ><big><b>isofs.h</b></big> <small id="info" style="color: #888888;" >7b279d10f46f -> 305ef2082079</small></div>
<pre class="diff" style="margin:0;" ><small id="info" style="color: #888888;" >--- lxdream/src/drivers/cdrom/isofs.h
+++ lxdream/src/drivers/cdrom/isofs.h
@@ -55,4 +55,8 @@
</small></pre><pre id="context" class="diff" style="margin:0; background-color:#eeeeee;" > sector_source_t iso_sector_source_new( IsoImage *image, sector_mode_t mode, cdrom_lba_t start_sector,
const char *bootstrap, ERROR *err );
</pre><pre id="added" class="diff" style="margin:0; background-color:#ddffdd;" >+
+/** Prototypes for "Internal" Libisofs functions */
+int iso_memory_stream_new(unsigned char *buf, size_t size, IsoStream **stream);
+
</pre><pre id="context" class="diff" style="margin:0; background-color:#eeeeee;" > #endif /* !cdrom_isofs_H */
</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/drivers/cdrom</span><br />
<div class="fileheader" style="margin-bottom:.5em;" ><big><b>sector.c</b></big> <small id="info" style="color: #888888;" >7b279d10f46f -> 305ef2082079</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
@@ -608,6 +608,7 @@
</small></pre><pre id="context" class="diff" style="margin:0; background-color:#eeeeee;" > dev->filename = tempfile;
sector_source_t source = sector_source_init( &dev->file.dev, FILE_SECTOR_SOURCE, mode, 0, file_sector_source_read, tmpfile_sector_source_destroy );
tmpfile_open_list = g_list_append(tmpfile_open_list, source);
</pre><pre id="added" class="diff" style="margin:0; background-color:#ddffdd;" >+ return source;
</pre><pre id="context" class="diff" style="margin:0; background-color:#eeeeee;" > }
/************************ Memory device implementation *************************/
</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</span><br />
<div class="fileheader" style="margin-bottom:.5em;" ><big><b>loader.c</b></big> <small id="info" style="color: #888888;" >7b279d10f46f -> 305ef2082079</small></div>
<pre class="diff" style="margin:0;" ><small id="info" style="color: #888888;" >--- lxdream/src/loader.c
+++ lxdream/src/loader.c
@@ -2,7 +2,7 @@
</small></pre><pre id="context" class="diff" style="margin:0; background-color:#eeeeee;" > * $Id$
*
* File loading routines, mostly for loading demos without going through the
</pre><pre id="removed" class="diff" style="margin:0; background-color:#ffdddd;" >- * whole procedure of making a CD image for them.
</pre><pre id="added" class="diff" style="margin:0; background-color:#ddffdd;" >+ * whole procedure of ma<span id="addedchars" style="background-color:#99ff99;font-weight:bolder;" >nually ma</span>king a CD image for them.
</pre><pre id="context" class="diff" style="margin:0; background-color:#eeeeee;" > *
* Copyright (c) 2005 Nathan Keynes.
*
</pre><pre class="diff" style="margin:0;" ><small id="info" style="color: #888888;" >@@ -24,24 +24,63 @@
</small></pre><pre id="context" class="diff" style="margin:0; background-color:#eeeeee;" > #include <sys/stat.h>
#include <errno.h>
#include <stdint.h>
</pre><pre id="added" class="diff" style="margin:0; background-color:#ddffdd;" >+#include <glib/gstrfuncs.h>
</pre><pre id="context" class="diff" style="margin:0; background-color:#eeeeee;" > #include <elf.h>
#include "mem.h"
#include "bootstrap.h"
#include "dreamcast.h"
#include "config.h"
#include "loader.h"
</pre><pre id="added" class="diff" style="margin:0; background-color:#ddffdd;" >+#include "drivers/cdrom/cdrom.h"
+#include "drivers/cdrom/isofs.h"
</pre><pre id="context" class="diff" style="margin:0; background-color:#eeeeee;" >
</pre><pre id="removed" class="diff" style="margin:0; background-color:#ffdddd;" >-char bootstrap_magic[32] = "SEGA SEGAKATANA SEGA ENTERPRISES";
-char iso_magic[6] = "\001CD001";
</pre><pre id="added" class="diff" style="margin:0; background-color:#ddffdd;" >+const char bootstrap_magic[32] = "SEGA SEGAKATANA SEGA ENTERPRISES";
+const char iso_magic[6] = "\001CD001";
</pre><pre id="context" class="diff" style="margin:0; background-color:#eeeeee;" > char *file_loader_extensions[][2] = {
{ "sbi", "Self Boot Inducer" },
{ "bin", "SH4 Bin file" },
{ NULL, NULL } };
</pre><pre id="removed" class="diff" style="margin:0; background-color:#ffdddd;" >-#define CDI_V2 0x80000004
-#define CDI_V3 0x80000005
</pre><pre id="added" class="diff" style="margin:0; background-color:#ddffdd;" >+gboolean file_load_elf_fd( const gchar *filename, int fd );
</pre><pre id="context" class="diff" style="margin:0; background-color:#eeeeee;" >
</pre><pre id="removed" class="diff" style="margin:0; background-color:#ffdddd;" >-gboolean file_load_elf_fd( const gchar *filename, int fd );
</pre><pre id="added" class="diff" style="margin:0; background-color:#ddffdd;" >+typedef enum {
+ FILE_ERROR,
+ FILE_BINARY,
+ FILE_ELF,
+ FILE_ISO,
+ FILE_DISC,
+ FILE_ZIP,
+ FILE_SAVE_STATE,
+} lxdream_file_type_t;
+
+static lxdream_file_type_t file_magic( const gchar *filename, int fd, ERROR *err )
+{
+ char buf[32];
+
+ /* begin magic */
+ if( read( fd, buf, 32 ) != 32 ) {
+ SET_ERROR( err, errno, "Unable to read from file '%s'", filename );
+ return FILE_ERROR;
+
+ }
+
+ lseek( fd, 0, SEEK_SET );
+ if( buf[0] == 0x7F && buf[1] == 'E' &&
+ buf[2] == 'L' && buf[3] == 'F' ) {
+ return FILE_ELF;
+ } else if( memcmp( buf, "PK\x03\x04", 4 ) == 0 ) {
+ return FILE_ZIP;
+ } else if( memcmp( buf, DREAMCAST_SAVE_MAGIC, 16 ) == 0 ) {
+ return FILE_SAVE_STATE;
+ } else if( lseek( fd, 32768, SEEK_SET ) == 32768 &&
+ read( fd, buf, 8 ) == 8 &&
+ memcmp( buf, iso_magic, 6) == 0 ) {
+ lseek( fd, 0, SEEK_SET );
+ return FILE_ISO;
+ }
+ lseek( fd, 0, SEEK_SET );
+ return FILE_BINARY;
+}
</pre><pre id="context" class="diff" style="margin:0; background-color:#eeeeee;" >
gboolean file_load_magic( const gchar *filename )
</pre><pre class="diff" style="margin:0;" ><small id="info" style="color: #888888;" >@@ -128,6 +167,26 @@
</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;" >+gboolean is_sh4_elf( Elf32_Ehdr *head )
+{
+ return ( head->e_ident[EI_CLASS] == ELFCLASS32 &&
+ head->e_ident[EI_DATA] == ELFDATA2LSB &&
+ head->e_ident[EI_VERSION] == 1 &&
+ head->e_type == ET_EXEC &&
+ head->e_machine == EM_SH &&
+ head->e_version == 1 );
+}
+
+gboolean is_arm_elf( Elf32_Ehdr *head )
+{
+ return ( head->e_ident[EI_CLASS] == ELFCLASS32 &&
+ head->e_ident[EI_DATA] == ELFDATA2LSB &&
+ head->e_ident[EI_VERSION] == 1 &&
+ head->e_type == ET_EXEC &&
+ head->e_machine == EM_ARM &&
+ head->e_version == 1 );
+}
+
</pre><pre id="context" class="diff" style="margin:0; background-color:#eeeeee;" > gboolean file_load_elf_fd( const gchar *filename, int fd )
{
Elf32_Ehdr head;
</pre><pre class="diff" style="margin:0;" ><small id="info" style="color: #888888;" >@@ -136,12 +195,7 @@
</small></pre><pre id="context" class="diff" style="margin:0; background-color:#eeeeee;" >
if( read( fd, &head, sizeof(head) ) != sizeof(head) )
return FALSE;
</pre><pre id="removed" class="diff" style="margin:0; background-color:#ffdddd;" >- if( head.e_ident[EI_CLASS] != ELFCLASS32 ||
- head.e_ident[EI_DATA] != ELFDATA2LSB ||
- head.e_ident[EI_VERSION] != 1 ||
- head.e_type != ET_EXEC ||
- head.e_machine != EM_SH ||
- head.e_version != 1 ) {
</pre><pre id="added" class="diff" style="margin:0; background-color:#ddffdd;" >+ if( !is_sh4_elf(&head) ) {
</pre><pre id="context" class="diff" style="margin:0; background-color:#eeeeee;" > ERROR( "File is not an SH4 ELF executable file" );
return FALSE;
}
</pre><pre class="diff" style="margin:0;" ><small id="info" style="color: #888888;" >@@ -164,3 +218,185 @@
</small></pre><pre id="context" class="diff" style="margin:0; background-color:#eeeeee;" > file_load_postload( filename, head.e_entry );
return TRUE;
}
</pre><pre id="added" class="diff" style="margin:0; background-color:#ddffdd;" >+
+/**
+ * Create a new CDROM disc containing a single 1ST_READ.BIN.
+ * @param type The disc type - must be CDROM_DISC_GDROM or CDROM_DISC_XA
+ * @param bin The binary data (takes ownership)
+ * @param bin_size
+ */
+cdrom_disc_t cdrom_disc_new_wrapped_binary( cdrom_disc_type_t type, const gchar *filename, unsigned char *bin, size_t bin_size,
+ ERROR *err )
+{
+ IsoImage *iso = NULL;
+ unsigned char *data = bin;
+ cdrom_lba_t start_lba = 45000; /* GDROM_START */
+ char bootstrap[32768];
+
+ /* 1. Load in the bootstrap */
+ gchar *bootstrap_file = lxdream_get_global_config_path_value(CONFIG_BOOTSTRAP);
+ if( bootstrap_file == NULL || bootstrap_file[0] == '\0' ) {
+ g_free(data);
+ SET_ERROR( err, ENOENT, "Unable to create CD image: bootstrap file is not configured" );
+ return NULL;
+ }
+
+ FILE *f = fopen( bootstrap_file, "ro" );
+ if( f == NULL ) {
+ g_free(data);
+ SET_ERROR( err, errno, "Unable to create CD image: bootstrap file '%s' could not be opened", bootstrap_file );
+ return FALSE;
+ }
+ size_t len = fread( bootstrap, 1, 32768, f );
+ fclose(f);
+ if( len != 32768 ) {
+ g_free(data);
+ SET_ERROR( err, EINVAL, "Unable to create CD image: bootstrap file '%s' is invalid", bootstrap_file );
+ return FALSE;
+ }
+
+ /* 2. Scramble the binary if necessary (and set type settings) */
+ if( type != CDROM_DISC_GDROM ) {
+ /* scramble the binary if we're going the MIL-CD route */
+ unsigned char *scramblebin = g_malloc(bin_size);
+ bootprogram_scramble( scramblebin, bin, bin_size );
+ data = scramblebin;
+ start_lba = 0x2DB6; /* CDROM_START (does it matter?) */
+ g_free(bin);
+ }
+
+ /* 3. Frob the bootstrap data */
+ dc_bootstrap_head_t boot_header = (dc_bootstrap_head_t)bootstrap;
+ memcpy( boot_header->boot_file, "1ST_READ.BIN ", 16 );
+ char tmp[129];
+ int name_len = snprintf( tmp, 129, "lxdream wrapped image: %s", filename );
+ if( name_len < 128 )
+ memset( tmp+name_len, ' ', 128-name_len );
+ memcpy( boot_header->product_name, tmp, 128 );
+// bootstrap_update_crc(bootstrap);
+
+
+ /* 4. Build the ISO image */
+ int status = iso_image_new("autocd", &iso);
+ if( status != 1 ) {
+ g_free(data);
+ return NULL;
+ }
+
+ IsoStream *stream;
+ if( iso_memory_stream_new(data, bin_size, &stream) != 1 ) {
+ g_free(data);
+ iso_image_unref(iso);
+ return NULL;
+ }
+ iso_tree_add_new_file(iso_image_get_root(iso), "1ST_READ.BIN", stream, NULL);
+ sector_source_t track = iso_sector_source_new( iso, SECTOR_MODE2_FORM1, start_lba,
+ bootstrap, err );
+ if( track == NULL ) {
+ iso_image_unref(iso);
+ return NULL;
+ }
+
+ cdrom_disc_t disc = cdrom_disc_new_from_track( type, track, start_lba );
+ iso_image_unref(iso);
+ if( disc != NULL ) {
+ disc->name = g_strdup(filename);
+ }
+ return disc;
+}
+
+cdrom_disc_t cdrom_wrap_elf_fd( cdrom_disc_type_t type, const gchar *filename, int fd, ERROR *err )
+{
+ Elf32_Ehdr head;
+ int i;
+
+ /* Check the file header is actually an SH4 binary */
+ if( read( fd, &head, sizeof(head) ) != sizeof(head) )
+ return FALSE;
+ if( !is_sh4_elf(&head) ) {
+ SET_ERROR( err, EINVAL, "File is not an SH4 ELF executable file" );
+ return FALSE;
+ }
+ if( head.e_entry != BINARY_LOAD_ADDR ) {
+ SET_ERROR( err, EINVAL, "SH4 Binary has incorrect entry point (should be %08X but is %08X)", BINARY_LOAD_ADDR, head.e_entry );
+ return FALSE;
+ }
+
+ /* Load the program headers */
+ Elf32_Phdr phdr[head.e_phnum];
+ lseek( fd, head.e_phoff, SEEK_SET );
+ if( read( fd, phdr, sizeof(phdr) ) != sizeof(phdr) ) {
+ SET_ERROR( err, EINVAL, "File is not a valid executable file" );
+ return FALSE;
+ }
+
+ sh4addr_t start = (sh4addr_t)-1, end=0;
+ /* Scan program headers for memory range in use */
+ for( i=0; i<head.e_phnum; i++ ) {
+ if( phdr[i].p_type == PT_LOAD ) {
+ if( phdr[i].p_vaddr < start )
+ start = phdr[i].p_vaddr;
+ if( phdr[i].p_vaddr + phdr[i].p_memsz > end )
+ end = phdr[i].p_vaddr + phdr[i].p_memsz;
+ }
+ }
+
+ if( start != BINARY_LOAD_ADDR ) {
+ SET_ERROR( err, EINVAL, "SH4 Binary has incorrect load address (should be %08X but is %08X)", BINARY_LOAD_ADDR, start );
+ return FALSE;
+ }
+ if( end >= 0x8D000000 ) {
+ SET_ERROR( err, EINVAL, "SH4 binary is too large to fit in memory (end address is %08X)", end );
+ return FALSE;
+ }
+
+ /* Load the program into memory */
+ char *program = g_malloc0( end-start );
+ for( i=0; i<head.e_phnum; i++ ) {
+ if( phdr[i].p_type == PT_LOAD ) {
+ lseek( fd, phdr[i].p_offset, SEEK_SET );
+ uint32_t size = MIN( phdr[i].p_filesz, phdr[i].p_memsz);
+ read( fd, program + phdr[i].p_vaddr, size );
+ }
+ }
+
+ /* And finally pass it over to the disc wrapper */
+ return cdrom_disc_new_wrapped_binary(type, filename, program, end-start, err );
+}
+
+cdrom_disc_t cdrom_wrap_magic( cdrom_disc_type_t type, const gchar *filename, ERROR *err )
+{
+ cdrom_disc_t disc;
+ char *data;
+ int len;
+ struct stat st;
+ int fd = open( filename, O_RDONLY );
+ if( fd == -1 ) {
+ SET_ERROR( err, errno, "Unable to open file '%s'", filename );
+ return NULL;
+ }
+
+
+ lxdream_file_type_t filetype = file_magic( filename, fd, err );
+ switch( filetype ) {
+ case FILE_BINARY:
+ fstat( fd, &st );
+ data = g_malloc(st.st_size);
+ len = read( fd, data, st.st_size );
+ close(fd);
+ if( len != st.st_size ) {
+ SET_ERROR( err, errno, "Error reading binary file '%s'", filename );
+ return NULL;
+ }
+ return cdrom_disc_new_wrapped_binary( type, filename, data, st.st_size, err );
+ case FILE_ELF:
+ disc = cdrom_wrap_elf_fd(type, filename, fd, err);
+ close(fd);
+ return disc;
+ default:
+ close(fd);
+ SET_ERROR( err, EINVAL, "File '%s' cannot be wrapped (not a binary)", filename );
+ return NULL;
+ }
+
+}
</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</span><br />
<div class="fileheader" style="margin-bottom:.5em;" ><big><b>loader.h</b></big> <small id="info" style="color: #888888;" >7b279d10f46f -> 305ef2082079</small></div>
<pre class="diff" style="margin:0;" ><small id="info" style="color: #888888;" >--- lxdream/src/loader.h
+++ lxdream/src/loader.h
@@ -22,6 +22,8 @@
</small></pre><pre id="context" class="diff" style="margin:0; background-color:#eeeeee;" > #include <stdio.h>
#include <glib/gtypes.h>
</pre><pre id="added" class="diff" style="margin:0; background-color:#ddffdd;" >+#include "drivers/cdrom/cdrom.h"
+
</pre><pre id="context" class="diff" style="margin:0; background-color:#eeeeee;" > #ifdef __cplusplus
extern "C" {
#endif
</pre><pre class="diff" style="margin:0;" ><small id="info" style="color: #888888;" >@@ -64,6 +66,8 @@
</small></pre><pre id="context" class="diff" style="margin:0; background-color:#eeeeee;" > */
gboolean file_load_magic( const gchar *filename );
</pre><pre id="added" class="diff" style="margin:0; background-color:#ddffdd;" >+cdrom_disc_t cdrom_wrap_magic( cdrom_disc_type_t type, const gchar *filename, ERROR *err );
+
</pre><pre id="context" class="diff" style="margin:0; background-color:#eeeeee;" > #ifdef __cplusplus
}
#endif
</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</span><br />
<div class="fileheader" style="margin-bottom:.5em;" ><big><b>main.c</b></big> <small id="info" style="color: #888888;" >7b279d10f46f -> 305ef2082079</small></div>
<pre class="diff" style="margin:0;" ><small id="info" style="color: #888888;" >--- lxdream/src/main.c
+++ lxdream/src/main.c
@@ -42,13 +42,13 @@
</small></pre><pre id="context" class="diff" style="margin:0; background-color:#eeeeee;" > #include "hotkeys.h"
#include "plugin.h"
</pre><pre id="removed" class="diff" style="margin:0; background-color:#ffdddd;" >-char *option_list = "a:A:bc:dfg:G:hHl:m:npt:T:uvV:x?";
</pre><pre id="added" class="diff" style="margin:0; background-color:#ddffdd;" >+char *option_list = "a:A:bc:dfg:G:hHl:m:npt:T:uvV:<span id="addedchars" style="background-color:#99ff99;font-weight:bolder;" >w:</span>x?";
</pre><pre id="context" class="diff" style="margin:0; background-color:#eeeeee;" > struct option longopts[] = {
{ "aica", required_argument, NULL, 'a' },
{ "audio", required_argument, NULL, 'A' },
{ "biosless", no_argument, NULL, 'b' },
{ "config", required_argument, NULL, 'c' },
</pre><pre id="removed" class="diff" style="margin:0; background-color:#ffdddd;" >- { "debugger", no_argument, NULL, '<span id="removedchars" style="background-color:#ff9999;font-weight:bolder;" >D</span>' },
</pre><pre id="added" class="diff" style="margin:0; background-color:#ddffdd;" >+ { "debugger", no_argument, NULL, '<span id="addedchars" style="background-color:#99ff99;font-weight:bolder;" >d</span>' },
</pre><pre id="context" class="diff" style="margin:0; background-color:#eeeeee;" > { "fullscreen", no_argument, NULL, 'f' },
{ "gdb-sh4", required_argument, NULL, 'g' },
{ "gdb-arm", required_argument, NULL, 'G' },
</pre><pre class="diff" style="margin:0;" ><small id="info" style="color: #888888;" >@@ -61,6 +61,7 @@
</small></pre><pre id="context" class="diff" style="margin:0; background-color:#eeeeee;" > { "unsafe", no_argument, NULL, 'u' },
{ "video", no_argument, NULL, 'V' },
{ "version", no_argument, NULL, 'v' },
</pre><pre id="added" class="diff" style="margin:0; background-color:#ddffdd;" >+ { "wrap", required_argument, NULL, 'w' },
</pre><pre id="context" class="diff" style="margin:0; background-color:#eeeeee;" > { NULL, 0, 0, 0 } };
char *aica_program = NULL;
char *display_driver_name = NULL;
</pre><pre class="diff" style="margin:0;" ><small id="info" style="color: #888888;" >@@ -107,6 +108,7 @@
</small></pre><pre id="context" class="diff" style="margin:0; background-color:#eeeeee;" > printf( " -u, --unsafe %s\n", _("Allow unsafe dcload syscalls") );
printf( " -v, --version %s\n", _("Print the lxdream version string") );
printf( " -V, --video=DRIVER %s\n", _("Use the specified video driver (? to list)") );
</pre><pre id="added" class="diff" style="margin:0; background-color:#ddffdd;" >+ printf( " -w, --wrap=FILENAME %s\n", _("Wrap the specified binary file in a disc image") );
</pre><pre id="context" class="diff" style="margin:0; background-color:#eeeeee;" > printf( " -x %s\n", _("Disable the SH4 translator") );
}
</pre><pre class="diff" style="margin:0;" ><small id="info" style="color: #888888;" >@@ -124,6 +126,7 @@
</small></pre><pre id="context" class="diff" style="margin:0; background-color:#eeeeee;" > double t;
gboolean display_ok;
uint32_t time_secs, time_nanos;
</pre><pre id="added" class="diff" style="margin:0; background-color:#ddffdd;" >+ const char *wrap_name = NULL;
</pre><pre id="context" class="diff" style="margin:0; background-color:#eeeeee;" >
install_crash_handler();
bind_gettext_domain();
</pre><pre class="diff" style="margin:0;" ><small id="info" style="color: #888888;" >@@ -200,6 +203,9 @@
</small></pre><pre id="context" class="diff" style="margin:0; background-color:#eeeeee;" > case 'V': /* Video driver */
display_driver_name = optarg;
break;
</pre><pre id="added" class="diff" style="margin:0; background-color:#ddffdd;" >+ case 'w': /* Wrap image file */
+ wrap_name = optarg;
+ break;
</pre><pre id="context" class="diff" style="margin:0; background-color:#eeeeee;" > case 'x': /* Disable translator */
use_xlat = FALSE;
break;
</pre><pre class="diff" style="margin:0;" ><small id="info" style="color: #888888;" >@@ -262,6 +268,19 @@
</small></pre><pre id="context" class="diff" style="margin:0; background-color:#eeeeee;" > maple_reattach_all();
INFO( "%s! ready...", APP_NAME );
</pre><pre id="added" class="diff" style="margin:0; background-color:#ddffdd;" >+ if( wrap_name != NULL ) {
+ ERROR err;
+ cdrom_disc_t disc = cdrom_wrap_magic( CDROM_DISC_XA, wrap_name, &err );
+ if( disc == NULL )
+ ERROR(err.msg);
+ else {
+ gdrom_mount_disc(disc);
+ if( !no_start ) {
+ start_immediately = TRUE;
+ }
+ }
+ }
+
</pre><pre id="context" class="diff" style="margin:0; background-color:#eeeeee;" > for( ; optind < argc; optind++ ) {
gboolean ok = gdrom_mount_image(argv[optind]);
if( !ok ) {
</pre></div>
<center><small>Chaos Theory</small></center>
</div></body></html>