Search
lxdream.org :: lxdream/src/bootstrap.c
lxdream 0.9.1
released Jun 29
Download Now
filename src/bootstrap.c
changeset 422:61a0598e07ff
prev167:71c0cc416a64
next437:2c259474b474
author nkeynes
date Sat Oct 06 09:03:24 2007 +0000 (13 years ago)
permissions -rw-r--r--
last change Fix compilation warnings
file annotate diff log raw
nkeynes@26
     1
/**
nkeynes@422
     2
 * $Id: bootstrap.c,v 1.7 2007-10-06 08:59:42 nkeynes Exp $
nkeynes@26
     3
 *
nkeynes@26
     4
 * CD Bootstrap header parsing. Mostly for informational purposes.
nkeynes@26
     5
 *
nkeynes@26
     6
 * Copyright (c) 2005 Nathan Keynes.
nkeynes@26
     7
 *
nkeynes@26
     8
 * This program is free software; you can redistribute it and/or modify
nkeynes@26
     9
 * it under the terms of the GNU General Public License as published by
nkeynes@26
    10
 * the Free Software Foundation; either version 2 of the License, or
nkeynes@26
    11
 * (at your option) any later version.
nkeynes@26
    12
 *
nkeynes@26
    13
 * This program is distributed in the hope that it will be useful,
nkeynes@26
    14
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
nkeynes@26
    15
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
nkeynes@26
    16
 * GNU General Public License for more details.
nkeynes@26
    17
 */
nkeynes@1
    18
nkeynes@26
    19
#include "dream.h"
nkeynes@26
    20
#include "bootstrap.h"
nkeynes@26
    21
nkeynes@26
    22
/**
nkeynes@26
    23
 * Bootstrap header structure
nkeynes@26
    24
 */
nkeynes@26
    25
typedef struct dc_bootstrap_head {
nkeynes@26
    26
    char hardware_id[16]; /* must be "SEGA SEGAKATANA " */ 
nkeynes@26
    27
    char maker_id[16];    /* ditto,  "SEGA ENTERPRISES" */
nkeynes@26
    28
    char crc[4];
nkeynes@26
    29
    char padding;         /* normally ascii space */
nkeynes@26
    30
    char gdrom_id[6];
nkeynes@26
    31
    char disc_no[5];
nkeynes@26
    32
    char regions[8];
nkeynes@26
    33
    char peripherals[8];
nkeynes@26
    34
    char product_id[10];
nkeynes@26
    35
    char product_ver[6];
nkeynes@26
    36
    char product_date[16];
nkeynes@26
    37
    char boot_file[16];
nkeynes@26
    38
    char vendor_id[16];
nkeynes@26
    39
    char product_name[128];
nkeynes@26
    40
} *dc_bootstrap_head_t;
nkeynes@1
    41
nkeynes@1
    42
static uint32_t compute_crc16( dc_bootstrap_head_t h )
nkeynes@1
    43
{
nkeynes@1
    44
    /* Note: Algorithm taken from http://mc.pp.se/dc/ip0000.bin.html */
nkeynes@1
    45
    uint32_t i, c, n = 0xffff;
nkeynes@1
    46
    char *data = h->product_id;
nkeynes@1
    47
    for (i = 0; i < 16; i++)
nkeynes@1
    48
    {
nkeynes@1
    49
        n ^= (data[i]<<8);
nkeynes@1
    50
        for (c = 0; c < 8; c++)
nkeynes@1
    51
            if (n & 0x8000)
nkeynes@1
    52
                n = (n << 1) ^ 4129;
nkeynes@1
    53
            else
nkeynes@1
    54
                n = (n << 1);
nkeynes@1
    55
    }
nkeynes@1
    56
    return n & 0xffff;
nkeynes@1
    57
}
nkeynes@1
    58
nkeynes@26
    59
nkeynes@26
    60
static char *dc_peripherals[] = { "Uses WinCE", "Unknown (0x0000002)",
nkeynes@26
    61
                                  "Unknown (0x0000004)", "Unknown (0x0000008)",
nkeynes@26
    62
                                  "VGA Box", "Unknown (0x0000020)",
nkeynes@26
    63
                                  "Unknown (0x0000040)", "Unknown (0x0000080)",
nkeynes@26
    64
                                  "Other Expansions", "Puru Puru pack",
nkeynes@26
    65
                                  "Mike", "Memory card",
nkeynes@26
    66
                                  "Basic controller", "C button",
nkeynes@26
    67
                                  "D button", "X button",
nkeynes@26
    68
                                  "Y button", "Z button",
nkeynes@26
    69
                                  "Expanded direction buttons",
nkeynes@26
    70
                                  "Analog R trigger", "Analog L trigger",
nkeynes@26
    71
                                  "Analog horizontal", "Analog vertical",
nkeynes@26
    72
                                  "Expanded analog horizontal",
nkeynes@26
    73
                                  "Expanded analog vertical",
nkeynes@26
    74
                                  "Gun", "Keyboard", "Mouse" };
nkeynes@26
    75
nkeynes@26
    76
nkeynes@26
    77
/* Expansion units */
nkeynes@26
    78
#define DC_PERIPH_WINCE    0x0000001
nkeynes@26
    79
#define DC_PERIPH_VGABOX   0x0000010
nkeynes@26
    80
#define DC_PERIPH_OTHER    0x0000100
nkeynes@26
    81
#define DC_PERIPH_PURUPURU 0x0000200
nkeynes@26
    82
#define DC_PERIPH_MIKE     0x0000400
nkeynes@26
    83
#define DC_PERIPH_MEMCARD  0x0000800
nkeynes@26
    84
/* Basic requirements */
nkeynes@26
    85
#define DC_PERIPH_BASIC    0x0001000 /* Basic controls - start, a, b, arrows */
nkeynes@26
    86
#define DC_PERIPH_C_BUTTON 0x0002000
nkeynes@26
    87
#define DC_PERIPH_D_BUTTON 0x0004000
nkeynes@26
    88
#define DC_PERIPH_X_BUTTON 0x0008000
nkeynes@26
    89
#define DC_PERIPH_Y_BUTTON 0x0010000
nkeynes@26
    90
#define DC_PERIPH_Z_BUTTON 0x0020000
nkeynes@26
    91
#define DC_PERIPH_EXP_DIR  0x0040000 /* Expanded direction buttons */
nkeynes@26
    92
#define DC_PERIPH_ANALOG_R 0x0080000 /* Analog R trigger */
nkeynes@26
    93
#define DC_PERIPH_ANALOG_L 0x0100000 /* Analog L trigger */
nkeynes@26
    94
#define DC_PERIPH_ANALOG_H 0x0200000 /* Analog horizontal controller */
nkeynes@26
    95
#define DC_PERIPH_ANALOG_V 0x0400000 /* Analog vertical controller */
nkeynes@26
    96
#define DC_PERIPH_EXP_AH   0x0800000 /* Expanded analog horizontal (?) */
nkeynes@26
    97
#define DC_PERIPH_EXP_AV   0x1000000 /* Expanded analog vertical (?) */
nkeynes@26
    98
/* Optional peripherals */
nkeynes@26
    99
#define DC_PERIPH_GUN      0x2000000
nkeynes@26
   100
#define DC_PERIPH_KEYBOARD 0x4000000
nkeynes@26
   101
#define DC_PERIPH_MOUSE    0x8000000
nkeynes@26
   102
nkeynes@26
   103
/**
nkeynes@26
   104
 * Dump the bootstrap info to the output log for infomational/debugging
nkeynes@26
   105
 * purposes.
nkeynes@167
   106
 * @param detail true to include a ful information dump, false for just
nkeynes@167
   107
 *  the facts, maam.
nkeynes@26
   108
 */
nkeynes@422
   109
void bootstrap_dump( unsigned char *data, gboolean detail )
nkeynes@1
   110
{
nkeynes@1
   111
    struct dc_bootstrap_head *head;
nkeynes@1
   112
    int i, got, periph, crc, hcrc;
nkeynes@1
   113
    char *prot_symbols;
nkeynes@1
   114
    char buf[512];
nkeynes@1
   115
nkeynes@1
   116
    /* Dump out the bootstrap metadata table */
nkeynes@1
   117
    head = (struct dc_bootstrap_head *)data;
nkeynes@1
   118
    prot_symbols = ((char *)data) + 0x3700;
nkeynes@1
   119
    memcpy( buf, head->product_name, 128 );
nkeynes@1
   120
    for( i=127; i>0 && buf[i] == ' '; i-- );
nkeynes@1
   121
    buf[i] = '\0';
nkeynes@1
   122
    periph = strtol( head->peripherals, NULL, 16 );
nkeynes@167
   123
    INFO( "Name: %s   Author: %-16.16s",
nkeynes@1
   124
          buf, head->vendor_id );
nkeynes@1
   125
    sprintf( buf, "%4.4s", head->crc );
nkeynes@1
   126
    crc = compute_crc16(head);
nkeynes@1
   127
    hcrc = strtol( buf, NULL, 16 );
nkeynes@1
   128
    INFO( "  Product ID:   %-10.10s   Product Ver: %-6.6s   Date: %-8.8s",
nkeynes@1
   129
          head->product_id, head->product_ver, head->product_date );
nkeynes@167
   130
    if( detail ) {
nkeynes@167
   131
	emit( NULL, crc == hcrc ? EMIT_INFO : EMIT_WARN, "File", 
nkeynes@167
   132
              "  Header CRC:   %04X (Computed %04X)", hcrc, crc );
nkeynes@167
   133
	INFO( "  Boot File:    %-16.16s", head->boot_file );
nkeynes@167
   134
	INFO( "  Disc ID:      %-11.11s  Regions:      %-8.8s   Peripherals: %07X",
nkeynes@167
   135
	      head->gdrom_id, head->regions, periph );
nkeynes@167
   136
	strcpy( buf, "     Supports: " );
nkeynes@167
   137
	got = 0;
nkeynes@167
   138
	for( i=0; i<28; i++ ) {
nkeynes@167
   139
	    if( periph & (1<<i) ){
nkeynes@167
   140
		if( got ) strcat( buf, ", " );
nkeynes@167
   141
		strcat( buf, dc_peripherals[i] );
nkeynes@167
   142
		got = 1;
nkeynes@167
   143
	    }
nkeynes@167
   144
	    if( i == 11 ) i = 23; /* Skip 8-23 */
nkeynes@167
   145
	}
nkeynes@167
   146
	INFO( buf, NULL );
nkeynes@167
   147
	strcpy( buf, "     Requires: " );
nkeynes@167
   148
	got = 0;
nkeynes@167
   149
	for( i=12; i<24; i++ ) {
nkeynes@167
   150
	    if( periph & (1<<i) ) {
nkeynes@167
   151
		if( got ) strcat( buf, ", " );
nkeynes@167
   152
		strcat( buf, dc_peripherals[i] );
nkeynes@167
   153
		got = 1;
nkeynes@167
   154
	    }
nkeynes@167
   155
	}
nkeynes@167
   156
	INFO( buf, NULL );
nkeynes@1
   157
    }
nkeynes@1
   158
}
.