Search
lxdream.org :: lxdream/src/loader.c
lxdream 0.9.1
released Jun 29
Download Now
filename src/loader.c
changeset 19:9da7a8e38f9d
prev18:9a1b5d75703f
next25:fa2d21d57942
author nkeynes
date Thu Dec 22 13:52:02 2005 +0000 (18 years ago)
permissions -rw-r--r--
last change Implement status clearing correctly
file annotate diff log raw
nkeynes@1
     1
/*
nkeynes@1
     2
 *
nkeynes@1
     3
 */
nkeynes@1
     4
nkeynes@1
     5
#include <stdio.h>
nkeynes@1
     6
#include <fcntl.h>
nkeynes@1
     7
#include <sys/stat.h>
nkeynes@1
     8
#include <sys/mman.h>
nkeynes@1
     9
#include <errno.h>
nkeynes@1
    10
#include <stdint.h>
nkeynes@1
    11
#include "gui.h"
nkeynes@1
    12
#include "ipbin.h"
nkeynes@1
    13
#include "sh4core.h"
nkeynes@19
    14
#include "pvr2.h"
nkeynes@1
    15
#include "mem.h"
nkeynes@1
    16
nkeynes@1
    17
char ip_bin_magic[32] = "SEGA SEGAKATANA SEGA ENTERPRISES";
nkeynes@1
    18
char iso_magic[6] = "\001CD001";
nkeynes@1
    19
nkeynes@1
    20
#define CDI_V2 0x80000004
nkeynes@1
    21
#define CDI_V3 0x80000005
nkeynes@1
    22
nkeynes@18
    23
int open_file( const gchar *filename )
nkeynes@1
    24
{
nkeynes@1
    25
    char buf[32];
nkeynes@1
    26
    uint32_t tmpa[2];
nkeynes@1
    27
    struct stat st;
nkeynes@1
    28
    
nkeynes@1
    29
    int fd = open( filename, O_RDONLY );
nkeynes@1
    30
    if( fd == -1 ) {
nkeynes@1
    31
        ERROR( "Unable to open file: '%s' (%s)", filename,
nkeynes@1
    32
               strerror(errno) );
nkeynes@1
    33
        return;
nkeynes@1
    34
    }
nkeynes@1
    35
nkeynes@1
    36
    fstat( fd, &st );
nkeynes@1
    37
    if( st.st_size < 32768 ) {
nkeynes@1
    38
        ERROR( "File '%s' too small to be a dreamcast image", filename );
nkeynes@1
    39
        close(fd);
nkeynes@1
    40
        return;
nkeynes@1
    41
    }
nkeynes@1
    42
    
nkeynes@1
    43
    /* begin magic */
nkeynes@1
    44
    if( read( fd, buf, 32 ) != 32 ) {
nkeynes@1
    45
        ERROR( "Unable to read from file '%s'", filename );
nkeynes@1
    46
        close(fd);
nkeynes@1
    47
        return;
nkeynes@1
    48
    }
nkeynes@1
    49
    if( memcmp( buf, ip_bin_magic, 32 ) == 0 ) {
nkeynes@1
    50
        /* we have a DC bootstrap */
nkeynes@1
    51
        if( st.st_size == BOOTSTRAP_SIZE ) {
nkeynes@1
    52
            char *load = mem_get_region( BOOTSTRAP_LOAD_ADDR );
nkeynes@1
    53
            /* Just the bootstrap, no image... */
nkeynes@1
    54
            WARN( "File '%s' contains bootstrap only, loading anyway",
nkeynes@1
    55
                  filename );
nkeynes@1
    56
            lseek( fd, 0, SEEK_SET );
nkeynes@1
    57
            read( fd, load, BOOTSTRAP_SIZE );
nkeynes@1
    58
            parse_ipbin( load );
nkeynes@1
    59
            sh4_reset();
nkeynes@1
    60
            sh4_set_pc( BOOTSTRAP_LOAD_ADDR + 0x300 );
nkeynes@9
    61
            set_disassembly_region( main_debug, BOOTSTRAP_LOAD_ADDR );
nkeynes@9
    62
            set_disassembly_pc( main_debug, sh4r.pc, TRUE );
nkeynes@2
    63
            update_gui();
nkeynes@1
    64
        } else {
nkeynes@1
    65
            /* look for a valid ISO9660 header */
nkeynes@1
    66
            lseek( fd, 32768, SEEK_SET );
nkeynes@1
    67
            read( fd, buf, 8 );
nkeynes@1
    68
            if( memcmp( buf, iso_magic, 6 ) == 0 ) {
nkeynes@1
    69
                /* Alright, got it */
nkeynes@1
    70
                INFO( "Loading ISO9660 filesystem from '%s'",
nkeynes@1
    71
                      filename );
nkeynes@1
    72
            }
nkeynes@1
    73
        }
nkeynes@1
    74
    } else {
nkeynes@1
    75
        /* check if it's a CDI file: */
nkeynes@1
    76
        lseek( fd, -8, SEEK_END );
nkeynes@1
    77
        read( fd, &tmpa, 8 );
nkeynes@1
    78
        if( tmpa[0] == CDI_V2 || tmpa[0] == CDI_V3 ) {
nkeynes@1
    79
            /* Yup, it is */
nkeynes@1
    80
            INFO( "Loading CDI file '%s'", filename );
nkeynes@1
    81
        } else {
nkeynes@1
    82
            ERROR( "Don't know what to do with '%s'", filename );
nkeynes@1
    83
        }
nkeynes@1
    84
    }
nkeynes@1
    85
    close(fd);
nkeynes@18
    86
    return 0;
nkeynes@1
    87
}
nkeynes@19
    88
nkeynes@19
    89
int load_bin_file( const gchar *filename ) {
nkeynes@19
    90
    mem_load_block( filename, 0x8c010000, -1 );
nkeynes@19
    91
    sh4_set_pc( 0x8c010000 );
nkeynes@19
    92
    set_disassembly_region( main_debug, 0x8c010000 );
nkeynes@19
    93
    set_disassembly_pc( main_debug, sh4r.pc, TRUE );
nkeynes@19
    94
    pvr2_set_base_address( 0x00025940 );
nkeynes@19
    95
    update_gui();
nkeynes@19
    96
}
.