diff --git a/tools/stadium.c b/tools/stadium.c index 1f814801..ebea5879 100644 --- a/tools/stadium.c +++ b/tools/stadium.c @@ -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); }