perfect_dark/tools/mkrom/rom.c

124 lines
2.1 KiB
C

#include <stdio.h>
#include <stdlib.h>
#include "mkrom.h"
extern struct state state;
/**
* Load the stage1 ROM into memory.
*/
void rom_load(char *filename)
{
FILE *fp = fopen(filename, "rb");
if (!fp) {
fprintf(stderr, "Unable to open \"%s\" for reading\n", filename);
exit(1);
}
fseek(fp, 0, SEEK_END);
state.romlen = ftell(fp);
state.rom = malloc(state.romlen);
if (!state.rom) {
fprintf(stderr, "Unable to allocate memory for ROM\n");
exit(1);
}
fseek(fp, 0, SEEK_SET);
fread(state.rom, state.romlen, 1, fp);
fclose(fp);
}
/**
* Write the ROM to the given filename and truncate it to 32MB.
*/
void rom_write(char *filename)
{
FILE *fp = fopen(filename, "wb");
if (!fp) {
fprintf(stderr, "Unable to open \"%s\" for writing\n", filename);
exit(1);
}
fwrite(state.rom, 1024 * 1024 * 32, 1, fp);
fclose(fp);
}
static uint32_t rol(uint32_t i, uint32_t b)
{
return (i << b) | (i >> (32 - b));
}
static uint32_t r4(unsigned char *b)
{
return b[0] * 0x1000000 + b[1] * 0x10000 + b[2] * 0x100 + b[3];
}
static void crc(unsigned char *rom, uint32_t *crc1, uint32_t *crc2)
{
uint32_t seed = 0xdf26f436;
uint32_t t1 = seed;
uint32_t t2 = seed;
uint32_t t3 = seed;
uint32_t t4 = seed;
uint32_t t5 = seed;
uint32_t t6 = seed;
uint32_t offset;
uint32_t d;
uint32_t r;
uint32_t temp;
unsigned char *lookup = &rom[0x40 + 0x0710];
for (offset = 0x1000; offset < 0x101000; offset += 4) {
d = r4(&rom[offset]);
if ((t6 + d) < t6) {
t4++;
}
t6 += d;
t3 ^= d;
r = rol(d, d & 0x1f);
t5 += r;
if (t2 > d) {
t2 ^= r;
} else {
t2 ^= t6 ^ d;
}
temp = r4(&lookup[offset & 0xff]);
t1 += temp ^ d;
}
*crc1 = t6 ^ t4 ^ t3;
*crc2 = t5 ^ t2 ^ t1;
}
/**
* Calculate the checksum of the ROM and write it to the ROM header.
*/
void rom_update_crc(void)
{
uint32_t crc1;
uint32_t crc2;
crc(state.rom, &crc1, &crc2);
state.rom[0x10] = (crc1 >> 24) & 0xff;
state.rom[0x11] = (crc1 >> 16) & 0xff;
state.rom[0x12] = (crc1 >> 8) & 0xff;
state.rom[0x13] = crc1 & 0xff;
state.rom[0x14] = (crc2 >> 24) & 0xff;
state.rom[0x15] = (crc2 >> 16) & 0xff;
state.rom[0x16] = (crc2 >> 8) & 0xff;
state.rom[0x17] = crc2 & 0xff;
}