Search
lxdream.org :: lxdream/src/bios.c :: diff
lxdream 0.9.1
released Jun 29
Download Now
filename src/bios.c
changeset 1099:566cdeb157ec
prev1065:bc1cc0c54917
next1100:50e702af9373
author nkeynes
date Wed Feb 10 18:16:19 2010 +1000 (10 years ago)
permissions -rw-r--r--
last change First draft of basic ISO9660 filesystem reader
file annotate diff log raw
1.1 --- a/src/bios.c Sun Jul 05 13:52:50 2009 +1000
1.2 +++ b/src/bios.c Wed Feb 10 18:16:19 2010 +1000
1.3 @@ -20,7 +20,11 @@
1.4 #include "mem.h"
1.5 #include "syscall.h"
1.6 #include "dreamcast.h"
1.7 +#include "bootstrap.h"
1.8 #include "sh4/sh4.h"
1.9 +#include "drivers/cdrom/cdrom.h"
1.10 +#include "drivers/cdrom/isoread.h"
1.11 +#include "gdrom/gdrom.h"
1.12
1.13 #define COMMAND_QUEUE_LENGTH 16
1.14
1.15 @@ -203,6 +207,13 @@
1.16 }
1.17 }
1.18
1.19 +void bios_boot( uint32_t syscallid )
1.20 +{
1.21 + /* Initialize hardware */
1.22 + /* Boot disc if present */
1.23 + bios_boot_gdrom_disc();
1.24 +}
1.25 +
1.26 void bios_install( void )
1.27 {
1.28 bios_gdrom_init();
1.29 @@ -212,3 +223,96 @@
1.30 syscall_add_hook_vector( 0xBC, 0x8C0000BC, bios_syscall );
1.31 syscall_add_hook_vector( 0xE0, 0x8C0000E0, bios_syscall );
1.32 }
1.33 +
1.34 +#define MIN_ISO_SECTORS 32
1.35 +
1.36 +gboolean bios_boot_gdrom_disc( void )
1.37 +{
1.38 + cdrom_disc_t disc = gdrom_get_current_disc();
1.39 +
1.40 + int status = gdrom_get_drive_status();
1.41 + if( status == CDROM_DISC_NONE ) {
1.42 + ERROR( "No disc in drive" );
1.43 + return FALSE;
1.44 + }
1.45 +
1.46 + /* Find the bootable data track (if present) */
1.47 + cdrom_track_t track = gdrom_disc_get_boot_track(disc);
1.48 + if( track == NULL ) {
1.49 + ERROR( "Disc is not bootable" );
1.50 + return FALSE;
1.51 + }
1.52 + uint32_t lba = track->lba;
1.53 + uint32_t sectors = cdrom_disc_get_track_size(disc,track);
1.54 + if( sectors < MIN_ISO_SECTORS ) {
1.55 + ERROR( "Disc is not bootable" );
1.56 + return FALSE;
1.57 + }
1.58 + /* Load the initial bootstrap into DC ram at 8c008000 */
1.59 + size_t length = BOOTSTRAP_SIZE;
1.60 + unsigned char *bootstrap = mem_get_region(BOOTSTRAP_LOAD_ADDR);
1.61 + if( cdrom_disc_read_sectors( disc, track->lba, BOOTSTRAP_SIZE/2048,
1.62 + CDROM_READ_DATA|CDROM_READ_MODE2_FORM1, bootstrap, &length ) !=
1.63 + CDROM_ERROR_OK ) {
1.64 + ERROR( "Disc is not bootable" );
1.65 + return FALSE;
1.66 + }
1.67 +
1.68 + /* Check the magic just to be sure */
1.69 + dc_bootstrap_head_t metadata = (dc_bootstrap_head_t)bootstrap;
1.70 + if( memcmp( metadata->magic, BOOTSTRAP_MAGIC, BOOTSTRAP_MAGIC_SIZE ) != 0 ) {
1.71 + ERROR( "Disc is not bootable (missing dreamcast bootstrap)" );
1.72 + return FALSE;
1.73 + }
1.74 +
1.75 + /* Get the initial program from the bootstrap (usually 1ST_READ.BIN) */
1.76 + char program_name[17];
1.77 + memcpy(program_name, metadata->boot_file, 16);
1.78 + program_name[16] = '\0';
1.79 + for( int i=15; i >= 0 && program_name[i] == ' '; i-- ) {
1.80 + program_name[i] = '\0';
1.81 + }
1.82 +
1.83 + /* Bootstrap is good. Now find the program in the actual filesystem... */
1.84 + isofs_reader_t iso = isofs_reader_new_from_track( disc, track, NULL );
1.85 + if( iso == NULL ) {
1.86 + ERROR( "Disc is not bootable" );
1.87 + return FALSE;
1.88 + }
1.89 + isofs_reader_dirent_t ent = isofs_reader_get_file( iso, program_name );
1.90 + if( ent == NULL ) {
1.91 + ERROR( "Disc is not bootable (initial program '%s' not found)", program_name );
1.92 + isofs_reader_destroy(iso);
1.93 + return FALSE;
1.94 + }
1.95 +
1.96 + if( ent->size > (0x8D000000 - BINARY_LOAD_ADDR) ) {
1.97 + /* Bootstrap isn't going to fit in memory. Complain and abort */
1.98 + ERROR( "Disc is not bootable (initial program too large)" );
1.99 + isofs_reader_destroy(iso);
1.100 + return FALSE;
1.101 + }
1.102 + unsigned char *program = mem_get_region(BINARY_LOAD_ADDR);
1.103 + int program_sectors = (ent->size+2047)/2048;
1.104 + if( disc->disc_type == CDROM_DISC_GDROM ) {
1.105 + /* Load the binary directly into RAM */
1.106 + if( isofs_reader_read_file( iso, ent, 0, ent->size, program ) !=
1.107 + CDROM_ERROR_OK ) {
1.108 + ERROR( "Disc is not bootable (failed to read initial program)\n" );
1.109 + isofs_reader_destroy(iso);
1.110 + return FALSE;
1.111 + }
1.112 + } else {
1.113 + /* Load the binary into a temp buffer */
1.114 + unsigned char tmp[program_sectors*2048];
1.115 + if( isofs_reader_read_file( iso, ent, 0, ent->size, tmp ) !=
1.116 + CDROM_ERROR_OK ) {
1.117 + ERROR( "Disc is not bootable (failed to read initial program)\n" );
1.118 + isofs_reader_destroy(iso);
1.119 + return FALSE;
1.120 + }
1.121 + bootprogram_unscramble(program, tmp, ent->size);
1.122 + }
1.123 + isofs_reader_destroy(iso);
1.124 + dreamcast_program_loaded( "", BOOTSTRAP_LOAD_ADDR );
1.125 +}
.