mirror of
https://github.com/n64dev/cen64.git
synced 2024-06-20 21:17:58 -04:00
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:
parent
156d592abb
commit
36a4a6fdfa
|
@ -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;
|
||||
|
|
|
@ -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
21
cen64.c
|
@ -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)) {
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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,
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
||||
|
|
|
@ -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);
|
||||
|
||||
|
|
Loading…
Reference in a new issue