dd: identify IPL and add support for all known dumped IPLs

This also fixes a regression introduced in 3900be4 that prevented the DD
IPL from booting.
This commit is contained in:
Mike Ryan 2016-08-31 18:31:02 -07:00
parent 156d592abb
commit 36a4a6fdfa
10 changed files with 112 additions and 21 deletions

View file

@ -39,7 +39,7 @@ static int bus_dead_write(void *opaque, uint32_t address, uint32_t word,
uint32_t dqm);
// Initializes the bus component.
int bus_init(struct bus_controller *bus) {
int bus_init(struct bus_controller *bus, int dd_present) {
unsigned i;
static const struct bus_controller_mapping mappings[NUM_MAPPINGS] = {
@ -91,7 +91,7 @@ int bus_init(struct bus_controller *bus) {
memory_wr_function wr = mappings[i].write;
void *instance = instances[i];
if (instance == bus->dd && bus->dd->ipl_rom == NULL) {
if (instance == bus->dd && !dd_present) {
rd = bus_open_read;
wr = bus_dead_write;
instance = NULL;

View file

@ -46,7 +46,7 @@ struct bus_controller {
jmp_buf unwind_data;
};
cen64_cold int bus_init(struct bus_controller *bus);
cen64_cold int bus_init(struct bus_controller *bus, int dd_present);
// General-purpose accesssor functions.
cen64_flatten cen64_hot int bus_read_word(void *component,

21
cen64.c
View file

@ -24,6 +24,7 @@
cen64_cold static int load_roms(const char *ddipl_path, const char *ddrom_path,
const char *pifrom_path, const char *cart_path, struct rom_file *ddipl,
const struct dd_variant **dd_variant,
struct rom_file *ddrom, struct rom_file *pifrom, struct rom_file *cart);
cen64_cold static int load_paks(struct controller *controller);
cen64_cold static int validate_sha(struct rom_file *rom, const uint8_t *good_sum);
@ -37,6 +38,7 @@ int cen64_main(int argc, const char **argv) {
struct cen64_options options = default_cen64_options;
options.controller = controller;
struct rom_file ddipl, ddrom, pifrom, cart;
const struct dd_variant *dd_variant;
struct cen64_mem cen64_device_mem;
struct cen64_device *device;
int status;
@ -76,9 +78,10 @@ int cen64_main(int argc, const char **argv) {
memset(&eeprom, 0, sizeof(eeprom));
memset(&sram, 0, sizeof(sram));
memset(&flashram, 0, sizeof(flashram));
dd_variant = NULL;
if (load_roms(options.ddipl_path, options.ddrom_path, options.pifrom_path,
options.cart_path, &ddipl, &ddrom, &pifrom, &cart)) {
options.cart_path, &ddipl, &dd_variant, &ddrom, &pifrom, &cart)) {
cen64_alloc_cleanup();
return EXIT_FAILURE;
}
@ -122,7 +125,8 @@ int cen64_main(int argc, const char **argv) {
else {
device = (struct cen64_device *) cen64_device_mem.ptr;
if (device_create(device, &ddipl, &ddrom, &pifrom, &cart, &eeprom, &sram,
if (device_create(device, &ddipl, dd_variant, &ddrom,
&pifrom, &cart, &eeprom, &sram,
&flashram, controller, options.no_audio, options.no_video) == NULL) {
printf("Failed to create a device.\n");
status = EXIT_FAILURE;
@ -155,6 +159,7 @@ int cen64_main(int argc, const char **argv) {
// Load any ROM images required for simulation.
int load_roms(const char *ddipl_path, const char *ddrom_path,
const char *pifrom_path, const char *cart_path, struct rom_file *ddipl,
const struct dd_variant **dd_variant,
struct rom_file *ddrom, struct rom_file *pifrom, struct rom_file *cart) {
memset(ddipl, 0, sizeof(*ddipl));
@ -164,13 +169,11 @@ int load_roms(const char *ddipl_path, const char *ddrom_path,
return 1;
}
if (ddipl_path != NULL && !validate_sha(ddipl, sha1_dd_ipl)) {
printf("Invalid SHA1 on DD IPL.\n");
#if 0
close_rom_file(ddipl);
return 6;
#endif
*dd_variant = NULL;
if (ddipl_path != NULL) {
*dd_variant = dd_identify_variant(ddipl);
if (*dd_variant != NULL)
printf("DD variant: %s\n", (*dd_variant)->description);
}
if (ddrom_path && open_rom_file(ddrom_path, ddrom)) {

View file

@ -587,3 +587,60 @@ void get_dd_time(uint8_t *out) {
out[5] = byte2bcd(now.sec);
}
#define COUNT_OF(x) ((sizeof(x)/sizeof(0[x])) / ((size_t)(!(sizeof(x) % sizeof(0[x])))))
const struct dd_variant *dd_identify_variant(struct rom_file *ipl) {
static struct dd_variant variants[] = {
{
"Japanese Retail (v1.2)",
0xDD,
{ 0xbf, 0x86, 0x19, 0x22, 0xdc, 0xb7, 0x8c, 0x31, 0x63, 0x60,
0xe3, 0xe7, 0x42, 0xf4, 0xf7, 0x0f, 0xf6, 0x3c, 0x9b, 0xc3, },
}, {
"USA Retail Prototype",
0xDE,
{ 0x3c, 0x5b, 0x93, 0xca, 0x23, 0x15, 0x50, 0xc6, 0x86, 0x93,
0xa1, 0x4f, 0x03, 0xce, 0xa8, 0xd5, 0xdb, 0xd1, 0xbe, 0x9e, },
}, {
"Japanese Dev (v1.0) [DOES NOT BOOT]",
0xDD,
{ 0x58, 0x67, 0x0c, 0x00, 0x63, 0x79, 0x3a, 0x8f, 0x3b, 0xe9,
0x57, 0xd7, 0x1d, 0x93, 0x7b, 0x61, 0x88, 0x29, 0xba, 0x9e, },
}, {
"Japanese Dev (v1.1)",
0xDD,
{ 0xb3, 0xe2, 0x6d, 0xbb, 0x4e, 0x94, 0x5f, 0x78, 0xc9, 0x18,
0xfa, 0xbc, 0x5b, 0x9e, 0x60, 0xfc, 0xf2, 0x62, 0xc4, 0x7b, },
}, {
"Japanese TOOL",
0xDD,
{ 0x10, 0xc4, 0x17, 0x3c, 0x2a, 0x7e, 0xb0, 0x9c, 0x65, 0x79,
0x81, 0x8f, 0x72, 0xef, 0x18, 0xfa, 0x0b, 0x6d, 0x32, 0xde, },
},
};
static struct dd_variant unknown = { "Unknown", 0xDD, { 0, } };
unsigned long i;
uint8_t sha1_calc[20];
struct dd_variant *variant = NULL;
if (ipl == NULL || ipl->ptr == NULL)
return NULL;
if (ipl->size != 0x400000)
return &unknown;
sha1(ipl->ptr, ipl->size, sha1_calc);
for (i = 0; i < COUNT_OF(variants); ++i) {
if (memcmp(sha1_calc, variants[i].sha1, SHA1_SIZE) == 0) {
variant = &variants[i];
break;
}
}
if (variant == NULL)
variant = &unknown;
return variant;
}

View file

@ -12,6 +12,8 @@
#define __dd_controller_h__
#include "common.h"
#include "bus/address.h"
#include "device/sha1.h"
#include "os/common/rom_file.h"
struct bus_controller *bus;
@ -26,6 +28,14 @@ enum dd_register {
extern const char *dd_register_mnemonics[NUM_DD_REGISTERS];
#endif
struct dd_variant {
const char *description;
uint8_t seed;
const uint8_t sha1[SHA1_SIZE];
};
const struct dd_variant *dd_identify_variant(struct rom_file *ipl);
struct dd_controller {
struct bus_controller *bus;
const uint8_t *ipl_rom;

View file

@ -39,7 +39,8 @@ cen64_flatten cen64_hot static CEN64_THREAD_RETURN_TYPE run_vr4300_thread(void *
// Creates and initializes a device.
struct cen64_device *device_create(struct cen64_device *device,
const struct rom_file *ddipl, const struct rom_file *ddrom,
const struct rom_file *ddipl, const struct dd_variant *dd_variant,
const struct rom_file *ddrom,
const struct rom_file *pifrom, const struct rom_file *cart,
const struct save_file *eeprom, const struct save_file *sram,
const struct save_file *flashram, const struct controller *controller,
@ -58,7 +59,7 @@ struct cen64_device *device_create(struct cen64_device *device,
device->bus.vr4300 = &device->vr4300;
// Initialize the bus.
if (bus_init(&device->bus)) {
if (bus_init(&device->bus, dd_variant != NULL)) {
debug("create_device: Failed to initialize the bus.\n");
return NULL;
}
@ -90,7 +91,7 @@ struct cen64_device *device_create(struct cen64_device *device,
// Initialize the SI.
if (si_init(&device->si, &device->bus, pifrom->ptr,
cart->ptr, ddipl->ptr != NULL, eeprom->ptr, eeprom->size,
cart->ptr, dd_variant, eeprom->ptr, eeprom->size,
controller)) {
debug("create_device: Failed to initialize the SI.\n");
return NULL;

View file

@ -56,7 +56,8 @@ struct cen64_device {
cen64_cold void device_destroy(struct cen64_device *device);
cen64_cold struct cen64_device *device_create(struct cen64_device *device,
const struct rom_file *ddipl, const struct rom_file *ddrom,
const struct rom_file *ddipl, const struct dd_variant *dd_variant,
const struct rom_file *ddrom,
const struct rom_file *pifrom, const struct rom_file *cart,
const struct save_file *eeprom, const struct save_file *sram,
const struct save_file *flashram, const struct controller *controller,

View file

@ -26,9 +26,25 @@ const uint8_t sha1_pifrom_ntsc_j[SHA1_SIZE] = {
0Xfd, 0X94, 0X14, 0X06, 0Xab, 0X46, 0Xb9, 0Xdc, 0X9b, 0Xdd,
};
const uint8_t sha1_dd_ipl[SHA1_SIZE] = {
const uint8_t sha1_dd_ipl_jp_v10[SHA1_SIZE] = {
0x58, 0x67, 0x0c, 0x00, 0x63, 0x79, 0x3a, 0x8f, 0x3b, 0xe9,
0x57, 0xd7, 0x1d, 0x93, 0x7b, 0x61, 0x88, 0x29, 0xba, 0x9e,
};
const uint8_t sha1_dd_ipl_jp_v11[SHA1_SIZE] = {
0xb3, 0xe2, 0x6d, 0xbb, 0x4e, 0x94, 0x5f, 0x78, 0xc9, 0x18,
0xfa, 0xbc, 0x5b, 0x9e, 0x60, 0xfc, 0xf2, 0x62, 0xc4, 0x7b
};
// JP retail
const uint8_t sha1_dd_ipl_jp_v12[SHA1_SIZE] = {
0xbf, 0x86, 0x19, 0x22, 0xdc, 0xb7, 0x8c, 0x31, 0x63, 0x60,
0xe3, 0xe7, 0x42, 0xf4, 0xf7, 0x0f, 0xf6, 0x3c, 0x9b, 0xc3,
};
const uint8_t sha1_dd_ipl_us[SHA1_SIZE] = {
0x3c, 0x5b, 0x93, 0xca, 0x23, 0x15, 0x50, 0xc6, 0x86, 0x93,
0xa1, 0x4f, 0x03, 0xce, 0xa8, 0xd5, 0xdb, 0xd1, 0xbe, 0x9e
};
#endif

View file

@ -41,7 +41,8 @@ static int eeprom_write(struct eeprom *eeprom, uint8_t *send_buf, uint8_t send_b
// Initializes the SI.
int si_init(struct si_controller *si, struct bus_controller *bus,
const uint8_t *pif_rom, const uint8_t *cart_rom, bool dd_present,
const uint8_t *pif_rom, const uint8_t *cart_rom,
const struct dd_variant *dd_variant,
uint8_t *eeprom, size_t eeprom_size,
const struct controller *controller) {
uint32_t cic_seed;
@ -61,10 +62,10 @@ int si_init(struct si_controller *si, struct bus_controller *bus,
si->ram[0x27] = cic_seed >> 0;
}
else if (dd_present) {
else if (dd_variant != NULL) {
si->ram[0x24] = 0x00;
si->ram[0x25] = 0x0A;
si->ram[0x26] = 0xDD;
si->ram[0x26] = dd_variant->seed; // 0xDD - JP, 0xDE - US
si->ram[0x27] = 0x3F;
}

View file

@ -12,6 +12,7 @@
#define __si_controller_h__
#include "common.h"
#include "si/pak.h"
#include "dd/controller.h"
struct bus_controller *bus;
@ -45,7 +46,8 @@ struct si_controller {
};
cen64_cold int si_init(struct si_controller *si, struct bus_controller *bus,
const uint8_t *pif_rom, const uint8_t *cart_rom, bool dd_present,
const uint8_t *pif_rom, const uint8_t *cart_rom,
const struct dd_variant *dd_variant,
uint8_t *eeprom, size_t eeprom_size,
const struct controller *controller);