Search
lxdream.org :: lxdream/src/bios.c :: diff
lxdream 0.9.1
released Jun 29
Download Now
filename src/bios.c
changeset 1107:7b279d10f46f
prev1103:de9ad2c0cf56
next1298:d0eb2307b847
author nkeynes
date Sun Feb 12 16:30:26 2012 +1000 (10 years ago)
permissions -rw-r--r--
last change Add -Werror for mregparm check, so it actually fails if mregparm isn't
accepted
file annotate diff log raw
1.1 --- a/src/bios.c Sun Feb 21 11:19:59 2010 +1000
1.2 +++ b/src/bios.c Sun Feb 12 16:30:26 2012 +1000
1.3 @@ -24,7 +24,7 @@
1.4 #include "bootstrap.h"
1.5 #include "sh4/sh4.h"
1.6 #include "drivers/cdrom/cdrom.h"
1.7 -#include "drivers/cdrom/isoread.h"
1.8 +#include "drivers/cdrom/isofs.h"
1.9 #include "gdrom/gdrom.h"
1.10
1.11 gboolean bios_boot_gdrom_disc( void );
1.12 @@ -387,6 +387,56 @@
1.13
1.14 #define MIN_ISO_SECTORS 32
1.15
1.16 +static gboolean bios_load_ipl( cdrom_disc_t disc, cdrom_track_t track, const char *program_name,
1.17 + unsigned char *buffer, gboolean unscramble )
1.18 +{
1.19 + gboolean rv = TRUE;
1.20 +
1.21 + IsoImageFilesystem *iso = iso_filesystem_new_from_track( disc, track, NULL );
1.22 + if( iso == NULL ) {
1.23 + ERROR( "Disc is not bootable (invalid ISO9660 filesystem)" );
1.24 + return FALSE;
1.25 + }
1.26 + IsoFileSource *file = NULL;
1.27 + int status = iso->get_by_path(iso, program_name, &file );
1.28 + if( status != 1 ) {
1.29 + ERROR( "Disc is not bootable (initial program '%s' not found)", program_name );
1.30 + iso_filesystem_unref(iso);
1.31 + return FALSE;
1.32 + }
1.33 +
1.34 + struct stat st;
1.35 + if( iso_file_source_stat(file, &st) == 1 ) {
1.36 + if( st.st_size > (0x8D000000 - BINARY_LOAD_ADDR) ) {
1.37 + ERROR( "Disc is not bootable (Initial program is too large to fit into memory)" );
1.38 + rv = FALSE;
1.39 + } else if( iso_file_source_open(file) == 1 ) {
1.40 + size_t len;
1.41 + if( unscramble ) {
1.42 + char *tmp = g_malloc(st.st_size);
1.43 + len = iso_file_source_read(file, tmp, st.st_size);
1.44 + bootprogram_unscramble(buffer, tmp, st.st_size);
1.45 + g_free(tmp);
1.46 + } else {
1.47 + len = iso_file_source_read(file, buffer, st.st_size);
1.48 + }
1.49 +
1.50 + if( len != st.st_size ) {
1.51 + ERROR( "Disc is not bootable (Unable to read initial program '%s')", program_name );
1.52 + rv = FALSE;
1.53 + }
1.54 + iso_file_source_close(file);
1.55 + }
1.56 + } else {
1.57 + ERROR( "Disc is not bootable (Unable to get size of initial program '%s')", program_name );
1.58 + rv = FALSE;
1.59 + }
1.60 +
1.61 + iso_file_source_unref(file);
1.62 + iso_filesystem_unref(iso);
1.63 + return rv;
1.64 +}
1.65 +
1.66 gboolean bios_boot_gdrom_disc( void )
1.67 {
1.68 cdrom_disc_t disc = gdrom_get_current_disc();
1.69 @@ -427,56 +477,19 @@
1.70 }
1.71
1.72 /* Get the initial program from the bootstrap (usually 1ST_READ.BIN) */
1.73 - char program_name[17];
1.74 - memcpy(program_name, metadata->boot_file, 16);
1.75 - program_name[16] = '\0';
1.76 - for( int i=15; i >= 0 && program_name[i] == ' '; i-- ) {
1.77 + char program_name[18] = "/";
1.78 + memcpy(program_name+1, metadata->boot_file, 16);
1.79 + program_name[17] = '\0';
1.80 + for( int i=16; i >= 0 && program_name[i] == ' '; i-- ) {
1.81 program_name[i] = '\0';
1.82 }
1.83
1.84 /* Bootstrap is good. Now find the program in the actual filesystem... */
1.85 - isofs_reader_t iso = isofs_reader_new_from_track( disc, track, NULL );
1.86 - if( iso == NULL ) {
1.87 - ERROR( "Disc is not bootable" );
1.88 + unsigned char *program = mem_get_region(BINARY_LOAD_ADDR);
1.89 + gboolean isGDROM = (disc->disc_type == CDROM_DISC_GDROM );
1.90 + if( !bios_load_ipl( disc, track, program_name, program, !isGDROM ) )
1.91 return FALSE;
1.92 - }
1.93 - isofs_reader_dirent_t ent = isofs_reader_get_file( iso, program_name );
1.94 - if( ent == NULL ) {
1.95 - ERROR( "Disc is not bootable (initial program '%s' not found)", program_name );
1.96 - isofs_reader_destroy(iso);
1.97 - return FALSE;
1.98 - }
1.99 -
1.100 - if( ent->size > (0x8D000000 - BINARY_LOAD_ADDR) ) {
1.101 - /* Bootstrap isn't going to fit in memory. Complain and abort */
1.102 - ERROR( "Disc is not bootable (initial program too large)" );
1.103 - isofs_reader_destroy(iso);
1.104 - return FALSE;
1.105 - }
1.106 - unsigned char *program = mem_get_region(BINARY_LOAD_ADDR);
1.107 - int program_sectors = (ent->size+2047)/2048;
1.108 - if( disc->disc_type == CDROM_DISC_GDROM ) {
1.109 - /* Load the binary directly into RAM */
1.110 - if( isofs_reader_read_file( iso, ent, 0, ent->size, program ) !=
1.111 - CDROM_ERROR_OK ) {
1.112 - ERROR( "Disc is not bootable (failed to read initial program)\n" );
1.113 - isofs_reader_destroy(iso);
1.114 - return FALSE;
1.115 - }
1.116 - asic_enable_ide_interface(TRUE);
1.117 - } else {
1.118 - /* Load the binary into a temp buffer */
1.119 - unsigned char tmp[program_sectors*2048];
1.120 - if( isofs_reader_read_file( iso, ent, 0, ent->size, tmp ) !=
1.121 - CDROM_ERROR_OK ) {
1.122 - ERROR( "Disc is not bootable (failed to read initial program)\n" );
1.123 - isofs_reader_destroy(iso);
1.124 - return FALSE;
1.125 - }
1.126 - bootprogram_unscramble(program, tmp, ent->size);
1.127 - asic_enable_ide_interface(FALSE);
1.128 - }
1.129 - isofs_reader_destroy(iso);
1.130 + asic_enable_ide_interface(isGDROM);
1.131 dreamcast_program_loaded( "", BOOTSTRAP_ENTRY_ADDR );
1.132 return TRUE;
1.133 }
.