mirror of
https://github.com/pret/pokegold.git
synced 2026-09-30 06:12:30 -04:00
+24
-27
@@ -5,24 +5,23 @@
|
||||
|
||||
// A matching ROM has 128 banks
|
||||
#define NUMBANKS 128
|
||||
// ROM banks are $4000 bytes
|
||||
// ROM banks are 0x4000 bytes
|
||||
#define BANKSIZE 0x4000
|
||||
// A matching ROM is $200000 bytes
|
||||
// A matching ROM is 2 MB
|
||||
#define ROMSIZE (NUMBANKS * BANKSIZE)
|
||||
|
||||
// ASCII "N64PS3" header
|
||||
#define N64PS3SIZE 6
|
||||
uint8_t n64ps3[N64PS3SIZE] = {'N', '6', '4', 'P', 'S', '3'};
|
||||
|
||||
// "N64PS3" + 2-byte CRC
|
||||
#define HEADERSIZE (N64PS3SIZE + 2)
|
||||
// header + 2-byte half-bank checksums
|
||||
#define DATASIZE (HEADERSIZE + NUMBANKS * 2 * 2)
|
||||
|
||||
// The Game Boy cartridge header stores a global checksum at 0x014E-0x014F
|
||||
#define GLOBALOFF 0x014E
|
||||
|
||||
// ASCII "N64PS3" header (Stadium G/S was the third Japanese Stadium release for N64)
|
||||
#define N64PS3SIZE 6
|
||||
uint8_t n64ps3[N64PS3SIZE] = {'N', '6', '4', 'P', 'S', '3'};
|
||||
// "N64PS3" + 2-byte CRC
|
||||
#define N64PS3HEADERSIZE (N64PS3SIZE + 2)
|
||||
// "N64PS3" + 2-byte CRC + per-half-bank 2-byte checksums
|
||||
#define N64PS3DATASIZE (N64PS3HEADERSIZE + NUMBANKS * 2 * 2)
|
||||
// The Stadium data is stored at the end of the ROM
|
||||
#define DATAOFF (ROMSIZE - DATASIZE)
|
||||
#define N64PS3DATAOFF (ROMSIZE - N64PS3DATASIZE)
|
||||
|
||||
// The CRC polynomial value
|
||||
#define CRC_POLY 0xC387
|
||||
@@ -34,9 +33,9 @@ uint8_t n64ps3[N64PS3SIZE] = {'N', '6', '4', 'P', 'S', '3'};
|
||||
file[(off) + 1] = (uint8_t)(((v) & 0x00FF) >> 0); \
|
||||
} while (0)
|
||||
|
||||
uint16_t calculate_checksum(uint16_t checksum, uint8_t *file, int start, int size) {
|
||||
for (int j = start; j < start + size; j++) {
|
||||
checksum += file[j];
|
||||
uint16_t calculate_checksum(uint16_t checksum, uint8_t *file, size_t size) {
|
||||
for (size_t i = 0; i < size; i++) {
|
||||
checksum += file[i];
|
||||
}
|
||||
return checksum;
|
||||
}
|
||||
@@ -44,12 +43,10 @@ uint16_t calculate_checksum(uint16_t checksum, uint8_t *file, int start, int siz
|
||||
void calculate_checksums(uint8_t *file) {
|
||||
// Initialize the CRC table
|
||||
uint16_t crc_table[256];
|
||||
for (int i = 0; i < 256; i++) {
|
||||
uint16_t c = i;
|
||||
for (uint16_t i = 0; i < sizeof(crc_table) / sizeof(*crc_table); i++) {
|
||||
uint16_t rem = 0;
|
||||
for (int y = 0; y < 8; y++) {
|
||||
for (uint16_t y = 0, c = i; y < 8; y++, c >>= 1) {
|
||||
rem = (rem >> 1) ^ ((rem ^ c) & 1 ? CRC_POLY : 0);
|
||||
c >>= 1;
|
||||
}
|
||||
crc_table[i] = rem;
|
||||
}
|
||||
@@ -58,24 +55,24 @@ void calculate_checksums(uint8_t *file) {
|
||||
SET_U16BE(file, GLOBALOFF, 0);
|
||||
|
||||
// Initialize the Stadium data (this should be free space anyway)
|
||||
memset(file + DATAOFF, 0, DATASIZE);
|
||||
memcpy(file + DATAOFF, n64ps3, N64PS3SIZE);
|
||||
memset(file + N64PS3DATAOFF, 0, N64PS3DATASIZE);
|
||||
memcpy(file + N64PS3DATAOFF, n64ps3, N64PS3SIZE);
|
||||
|
||||
// Calculate the half-bank checksums
|
||||
for (int i = 0; i < NUMBANKS * 2; i++) {
|
||||
uint16_t checksum = calculate_checksum(CRC_INIT, file, i * BANKSIZE / 2, BANKSIZE / 2);
|
||||
SET_U16BE(file, DATAOFF + HEADERSIZE + i * 2, checksum);
|
||||
for (size_t i = 0; i < NUMBANKS * 2; i++) {
|
||||
uint16_t checksum = calculate_checksum(CRC_INIT, file + i * BANKSIZE / 2, BANKSIZE / 2);
|
||||
SET_U16BE(file, N64PS3DATAOFF + N64PS3HEADERSIZE + i * 2, checksum);
|
||||
}
|
||||
|
||||
// Calculate the CRC of the half-bank checksums
|
||||
uint16_t crc = CRC_INIT;
|
||||
for (int i = DATAOFF + HEADERSIZE; i < DATAOFF + DATASIZE; i++) {
|
||||
for (size_t i = N64PS3DATAOFF + N64PS3HEADERSIZE; i < N64PS3DATAOFF + N64PS3DATASIZE; i++) {
|
||||
crc = (crc >> 8) ^ crc_table[(crc & 0xFF) ^ file[i]];
|
||||
}
|
||||
SET_U16BE(file, DATAOFF + HEADERSIZE - 2, crc);
|
||||
SET_U16BE(file, N64PS3DATAOFF + N64PS3HEADERSIZE - 2, crc);
|
||||
|
||||
// Calculate the global checksum
|
||||
uint16_t globalsum = calculate_checksum(0, file, 0, ROMSIZE);
|
||||
uint16_t globalsum = calculate_checksum(0, file, ROMSIZE);
|
||||
SET_U16BE(file, GLOBALOFF, globalsum);
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user