mirror of
https://github.com/n64dev/cen64.git
synced 2024-06-22 22:12:45 -04:00
Automatically seed the PIF RAM based on CIC type.
This commit is contained in:
parent
0524573137
commit
40ff6bd9ac
|
@ -74,7 +74,7 @@ struct cen64_device *device_create(struct cen64_device *device,
|
|||
}
|
||||
|
||||
// Initialize the SI.
|
||||
if (si_init(&device->si, &device->bus, pifrom->ptr) < 0) {
|
||||
if (si_init(&device->si, &device->bus, pifrom->ptr, cart->ptr) < 0) {
|
||||
printf("create_device: Failed to initialize the SI.\n");
|
||||
return NULL;
|
||||
}
|
||||
|
|
86
si/cic.c
Normal file
86
si/cic.c
Normal file
|
@ -0,0 +1,86 @@
|
|||
//
|
||||
// si/cic.c: PIF CIC security/lock out algorithms.
|
||||
//
|
||||
// CEN64: Cycle-Accurate Nintendo 64 Simulator.
|
||||
// Copyright (C) 2014, Tyler J. Stachecki.
|
||||
//
|
||||
// This file is subject to the terms and conditions defined in
|
||||
// 'LICENSE', which is part of this source code package.
|
||||
//
|
||||
|
||||
#include "common.h"
|
||||
#include "si/cic.h"
|
||||
|
||||
#define CIC_SEED_NUS_6101 0x00063F3FU
|
||||
#define CIC_SEED_NUS_6102 0x00023F3FU
|
||||
#define CIC_SEED_NUS_6103 0x0002783FU
|
||||
#define CIC_SEED_NUS_6105 0x0002913FU
|
||||
#define CIC_SEED_NUS_6106 0x0002853FU
|
||||
|
||||
#define CRC_NUS_6101 0x6170A4A1U
|
||||
#define CRC_NUS_6102 0x90BB6CB5U
|
||||
#define CRC_NUS_6103 0x0B050EE0U
|
||||
#define CRC_NUS_6105 0x98BC2C86U
|
||||
#define CRC_NUS_6106 0xACC8580AU
|
||||
|
||||
cen64_cold static uint32_t si_crc32(const uint8_t *data, size_t size);
|
||||
|
||||
// Determines the CIC seed for a cart, given the ROM data.
|
||||
int get_cic_seed(const uint8_t *rom_data, uint32_t *cic_seed) {
|
||||
uint32_t crc = si_crc32(rom_data + 0x40, 0x1000 - 0x40);
|
||||
|
||||
switch (crc) {
|
||||
case CRC_NUS_6101:
|
||||
*cic_seed = CIC_SEED_NUS_6101;
|
||||
break;
|
||||
|
||||
case CRC_NUS_6102:
|
||||
*cic_seed = CIC_SEED_NUS_6102;
|
||||
break;
|
||||
|
||||
case CRC_NUS_6103:
|
||||
*cic_seed = CIC_SEED_NUS_6103;
|
||||
break;
|
||||
|
||||
case CRC_NUS_6105:
|
||||
*cic_seed = CIC_SEED_NUS_6105;
|
||||
break;
|
||||
|
||||
case CRC_NUS_6106:
|
||||
*cic_seed = CIC_SEED_NUS_6106;
|
||||
break;
|
||||
|
||||
default:
|
||||
*cic_seed = 0;
|
||||
return 1;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
uint32_t si_crc32(const uint8_t *data, size_t size) {
|
||||
uint32_t table[256];
|
||||
unsigned n, k;
|
||||
uint32_t c;
|
||||
|
||||
for (n = 0; n < 256; n++) {
|
||||
c = (uint32_t) n;
|
||||
|
||||
for (k = 0; k < 8; k++) {
|
||||
if (c & 1)
|
||||
c = 0xEDB88320L ^ (c >> 1);
|
||||
else
|
||||
c = c >> 1;
|
||||
}
|
||||
|
||||
table[n] = c;
|
||||
}
|
||||
|
||||
c = 0L ^ 0xFFFFFFFF;
|
||||
|
||||
for (n = 0; n < size; n++)
|
||||
c = table[(c ^ data[n]) & 0xFF] ^ (c >> 8);
|
||||
|
||||
return c ^ 0xFFFFFFFF;
|
||||
}
|
||||
|
17
si/cic.h
Normal file
17
si/cic.h
Normal file
|
@ -0,0 +1,17 @@
|
|||
//
|
||||
// si/cic.h: PIF CIC security/lock out algorithms.
|
||||
//
|
||||
// CEN64: Cycle-Accurate Nintendo 64 Simulator.
|
||||
// Copyright (C) 2014, Tyler J. Stachecki.
|
||||
//
|
||||
// This file is subject to the terms and conditions defined in
|
||||
// 'LICENSE', which is part of this source code package.
|
||||
//
|
||||
|
||||
#ifndef __si_cic_h__
|
||||
#define __si_cic_h__
|
||||
|
||||
int get_cic_seed(const uint8_t *rom_data, uint32_t *cic_seed);
|
||||
|
||||
#endif
|
||||
|
|
@ -13,6 +13,7 @@
|
|||
#include "bus/controller.h"
|
||||
#include "os/main.h"
|
||||
#include "ri/controller.h"
|
||||
#include "si/cic.h"
|
||||
#include "si/controller.h"
|
||||
#include "vi/controller.h"
|
||||
#include "vr4300/interface.h"
|
||||
|
@ -31,13 +32,22 @@ static int pif_perform_command(struct si_controller *si, unsigned channel,
|
|||
uint8_t *send_buf, uint8_t send_bytes, uint8_t *recv_buf, uint8_t recv_bytes);
|
||||
|
||||
// Initializes the SI.
|
||||
int si_init(struct si_controller *si,
|
||||
struct bus_controller *bus, const uint8_t *rom) {
|
||||
si->bus = bus;
|
||||
si->rom = rom;
|
||||
int si_init(struct si_controller *si, struct bus_controller *bus,
|
||||
const uint8_t *pif_rom, const uint8_t *cart_rom) {
|
||||
uint32_t cic_seed;
|
||||
|
||||
si->ram[0x26] = 0x3F;
|
||||
si->ram[0x27] = 0x3F;
|
||||
si->bus = bus;
|
||||
si->rom = pif_rom;
|
||||
|
||||
if (get_cic_seed(cart_rom, &cic_seed)) {
|
||||
printf("Unknown CIC type; is this a byte-swapped ROM?\n");
|
||||
return 1;
|
||||
}
|
||||
|
||||
si->ram[0x24] = cic_seed >> 24;
|
||||
si->ram[0x25] = cic_seed >> 16;
|
||||
si->ram[0x26] = cic_seed >> 8;
|
||||
si->ram[0x27] = cic_seed >> 0;
|
||||
|
||||
// Specify 8MiB RDRAM for 6102/6105 carts.
|
||||
if (si->ram[0x26] == 0x3F && si->ram[0x27] == 0x3F)
|
||||
|
|
|
@ -36,8 +36,8 @@ struct si_controller {
|
|||
uint8_t input[4];
|
||||
};
|
||||
|
||||
cen64_cold int si_init(struct si_controller *si,
|
||||
struct bus_controller *bus, const uint8_t *rom);
|
||||
cen64_cold int si_init(struct si_controller *si, struct bus_controller *bus,
|
||||
const uint8_t *pif_rom, const uint8_t *cart_rom);
|
||||
|
||||
int read_pif_ram(void *opaque, uint32_t address, uint32_t *word);
|
||||
int read_pif_rom(void *opaque, uint32_t address, uint32_t *word);
|
||||
|
|
Loading…
Reference in a new issue