Search
lxdream.org :: lxdream/src/loader.c
lxdream 0.9.1
released Jun 29
Download Now
filename src/loader.c
changeset 27:1ef09a52cd1e
prev26:ad258e3daaa5
next88:0a1bd43fa4ad
author nkeynes
date Sun Dec 25 08:24:11 2005 +0000 (18 years ago)
permissions -rw-r--r--
last change Finish adding header blocks to all files
file annotate diff log raw
nkeynes@26
     1
/**
nkeynes@27
     2
 * $Id: loader.c,v 1.8 2005-12-25 01:28:36 nkeynes Exp $
nkeynes@1
     3
 *
nkeynes@26
     4
 * File loading routines, mostly for loading demos without going through the
nkeynes@26
     5
 * whole procedure of making a CD image for them.
nkeynes@26
     6
 *
nkeynes@26
     7
 * Copyright (c) 2005 Nathan Keynes.
nkeynes@26
     8
 *
nkeynes@26
     9
 * This program is free software; you can redistribute it and/or modify
nkeynes@26
    10
 * it under the terms of the GNU General Public License as published by
nkeynes@26
    11
 * the Free Software Foundation; either version 2 of the License, or
nkeynes@26
    12
 * (at your option) any later version.
nkeynes@26
    13
 *
nkeynes@26
    14
 * This program is distributed in the hope that it will be useful,
nkeynes@26
    15
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
nkeynes@26
    16
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
nkeynes@26
    17
 * GNU General Public License for more details.
nkeynes@1
    18
 */
nkeynes@1
    19
nkeynes@1
    20
#include <stdio.h>
nkeynes@1
    21
#include <fcntl.h>
nkeynes@1
    22
#include <sys/stat.h>
nkeynes@1
    23
#include <errno.h>
nkeynes@1
    24
#include <stdint.h>
nkeynes@25
    25
#include "gui/gui.h"
nkeynes@26
    26
#include "mem.h"
nkeynes@1
    27
#include "sh4core.h"
nkeynes@26
    28
#include "bootstrap.h"
nkeynes@1
    29
nkeynes@26
    30
char bootstrap_magic[32] = "SEGA SEGAKATANA SEGA ENTERPRISES";
nkeynes@1
    31
char iso_magic[6] = "\001CD001";
nkeynes@26
    32
char *file_loader_extensions[][2] = { 
nkeynes@26
    33
    { "sbi", "Self Boot Inducer" },
nkeynes@26
    34
    { "bin", "SH4 Bin file" },
nkeynes@26
    35
    { NULL, NULL } };
nkeynes@26
    36
nkeynes@26
    37
#define BOOTSTRAP_LOAD_ADDR 0x8C008000
nkeynes@26
    38
#define BOOTSTRAP_SIZE 32768
nkeynes@26
    39
nkeynes@26
    40
#define BINARY_LOAD_ADDR 0x8C010000
nkeynes@1
    41
nkeynes@1
    42
#define CDI_V2 0x80000004
nkeynes@1
    43
#define CDI_V3 0x80000005
nkeynes@1
    44
nkeynes@26
    45
gboolean file_load_magic( const gchar *filename )
nkeynes@1
    46
{
nkeynes@1
    47
    char buf[32];
nkeynes@1
    48
    uint32_t tmpa[2];
nkeynes@1
    49
    struct stat st;
nkeynes@1
    50
    
nkeynes@1
    51
    int fd = open( filename, O_RDONLY );
nkeynes@1
    52
    if( fd == -1 ) {
nkeynes@1
    53
        ERROR( "Unable to open file: '%s' (%s)", filename,
nkeynes@1
    54
               strerror(errno) );
nkeynes@26
    55
        return FALSE;
nkeynes@1
    56
    }
nkeynes@1
    57
nkeynes@1
    58
    fstat( fd, &st );
nkeynes@1
    59
    if( st.st_size < 32768 ) {
nkeynes@1
    60
        ERROR( "File '%s' too small to be a dreamcast image", filename );
nkeynes@1
    61
        close(fd);
nkeynes@26
    62
        return FALSE;
nkeynes@1
    63
    }
nkeynes@1
    64
    
nkeynes@1
    65
    /* begin magic */
nkeynes@1
    66
    if( read( fd, buf, 32 ) != 32 ) {
nkeynes@1
    67
        ERROR( "Unable to read from file '%s'", filename );
nkeynes@1
    68
        close(fd);
nkeynes@26
    69
        return FALSE;
nkeynes@1
    70
    }
nkeynes@26
    71
    if( memcmp( buf, bootstrap_magic, 32 ) == 0 ) {
nkeynes@1
    72
        /* we have a DC bootstrap */
nkeynes@1
    73
        if( st.st_size == BOOTSTRAP_SIZE ) {
nkeynes@1
    74
            char *load = mem_get_region( BOOTSTRAP_LOAD_ADDR );
nkeynes@1
    75
            lseek( fd, 0, SEEK_SET );
nkeynes@1
    76
            read( fd, load, BOOTSTRAP_SIZE );
nkeynes@26
    77
            bootstrap_dump( load );
nkeynes@1
    78
            sh4_set_pc( BOOTSTRAP_LOAD_ADDR + 0x300 );
nkeynes@27
    79
            gtk_gui_update();
nkeynes@1
    80
        } else {
nkeynes@1
    81
            /* look for a valid ISO9660 header */
nkeynes@1
    82
            lseek( fd, 32768, SEEK_SET );
nkeynes@1
    83
            read( fd, buf, 8 );
nkeynes@1
    84
            if( memcmp( buf, iso_magic, 6 ) == 0 ) {
nkeynes@1
    85
                /* Alright, got it */
nkeynes@1
    86
                INFO( "Loading ISO9660 filesystem from '%s'",
nkeynes@1
    87
                      filename );
nkeynes@1
    88
            }
nkeynes@1
    89
        }
nkeynes@26
    90
    } else if( memcmp( buf, "PK\x03\x04", 4 ) == 0 ) {
nkeynes@26
    91
	/* ZIP file, aka SBI file */
nkeynes@26
    92
	WARN( "SBI files not supported yet" );
nkeynes@1
    93
    } else {
nkeynes@26
    94
	/* Assume raw binary */
nkeynes@26
    95
	file_load_binary( filename );
nkeynes@26
    96
    } 
nkeynes@1
    97
    close(fd);
nkeynes@26
    98
    return TRUE;
nkeynes@1
    99
}
nkeynes@19
   100
nkeynes@26
   101
int file_load_binary( const gchar *filename ) {
nkeynes@26
   102
    mem_load_block( filename, BINARY_LOAD_ADDR, -1 );
nkeynes@26
   103
    sh4_set_pc( BINARY_LOAD_ADDR );
nkeynes@27
   104
    gtk_gui_update();
nkeynes@19
   105
}
.