diff --git a/src/rgbfix/main.c b/src/rgbfix/main.c index 1a36d6ef..71ce586f 100644 --- a/src/rgbfix/main.c +++ b/src/rgbfix/main.c @@ -13,10 +13,10 @@ * */ -#define OPTF_DEBUG 0x01L -#define OPTF_PAD 0x02L +#define OPTF_DEBUG 0x01L +#define OPTF_PAD 0x02L #define OPTF_VALIDATE 0x04L -#define OPTF_TITLE 0x08L +#define OPTF_TITLE 0x08L #define OPTF_TRUNCATE 0x10L unsigned long ulOptions; @@ -27,12 +27,12 @@ unsigned long ulOptions; */ unsigned char NintendoChar[48] = { - 0xCE, 0xED, 0x66, 0x66, 0xCC, 0x0D, 0x00, 0x0B, 0x03, 0x73, 0x00, 0x83, - 0x00, 0x0C, 0x00, 0x0D, - 0x00, 0x08, 0x11, 0x1F, 0x88, 0x89, 0x00, 0x0E, 0xDC, 0xCC, 0x6E, 0xE6, - 0xDD, 0xDD, 0xD9, 0x99, - 0xBB, 0xBB, 0x67, 0x63, 0x6E, 0x0E, 0xEC, 0xCC, 0xDD, 0xDC, 0x99, 0x9F, - 0xBB, 0xB9, 0x33, 0x3E + 0xCE, 0xED, 0x66, 0x66, 0xCC, 0x0D, 0x00, 0x0B, + 0x03, 0x73, 0x00, 0x83, 0x00, 0x0C, 0x00, 0x0D, + 0x00, 0x08, 0x11, 0x1F, 0x88, 0x89, 0x00, 0x0E, + 0xDC, 0xCC, 0x6E, 0xE6, 0xDD, 0xDD, 0xD9, 0x99, + 0xBB, 0xBB, 0x67, 0x63, 0x6E, 0x0E, 0xEC, 0xCC, + 0xDD, 0xDC, 0x99, 0x9F, 0xBB, 0xB9, 0x33, 0x3E, }; /* @@ -42,19 +42,18 @@ unsigned char NintendoChar[48] = { void PrintUsage(void) { - printf("RGBFix v" RGBFIX_VERSION " (part of ASMotor " ASMOTOR_VERSION - ")\n\n"); + printf("RGBFix v" RGBFIX_VERSION + " (part of ASMotor " ASMOTOR_VERSION ")\n\n"); + printf("Usage: rgbfix [options] image[.gb]\n"); printf("Options:\n"); printf("\t-h\t\tThis text\n"); printf("\t-d\t\tDebug: Don't change image\n"); - printf - ("\t-p\t\tPad image to valid size\n\t\t\tPads to 32/64/128/256/512kB as appropriate\n"); - printf - ("\t-r\t\ttRuncate image to valid size\n\t\t\tTruncates to 32/64/128/256/512kB as appropriate\n"); + printf("\t-p\t\tPad image to valid size\n\t\t\tPads to 32/64/128/256/512kB as appropriate\n"); + printf("\t-r\t\ttRuncate image to valid size\n\t\t\tTruncates to 32/64/128/256/512kB as appropriate\n"); printf("\t-t\tChange cartridge title field (16 characters)\n"); - printf - ("\t-v\t\tValidate header\n\t\t\tCorrects - Nintendo Character Area (0x0104)\n\t\t\t\t - ROM type (0x0147)\n\t\t\t\t - ROM size (0x0148)\n\t\t\t\t - Checksums (0x014D-0x014F)\n"); + printf("\t-v\t\tValidate header\n\t\t\tCorrects - Nintendo Character Area (0x0104)\n\t\t\t\t - ROM type (0x0147)\n\t\t\t\t - ROM size (0x0148)\n\t\t\t\t - Checksums (0x014D-0x014F)\n"); + exit(0); } @@ -136,267 +135,267 @@ int main(int argc, char *argv[]) if (!FileExists(filename)) strcat(filename, ".gb"); - if ((f = fopen(filename, "rb+")) != NULL) { - /* - * -d (Debug) option code - * - */ + f = fopen(filename, "rb+"); + if (!f) + FatalError("Unable to open file"); - if (ulOptions & OPTF_DEBUG) { - printf("-d (Debug) option enabled...\n"); - } + /* + * -d (Debug) option code + * + */ + + if (ulOptions & OPTF_DEBUG) { + printf("-d (Debug) option enabled...\n"); + } + + /* + * -p (Pad) option code + * + */ + + if (ulOptions & OPTF_PAD) { + long size, padto; + long bytesadded = 0; + + size = FileSize(f); + padto = 0x8000L; + while (size > padto) + padto *= 2; + + printf("Padding to %ldkB:\n", padto / 1024); /* - * -p (Pad) option code - * - */ - - if (ulOptions & OPTF_PAD) { - long size, padto; - long bytesadded = 0; - - size = FileSize(f); - padto = 0x8000L; - while (size > padto) - padto *= 2; - - printf("Padding to %ldkB:\n", padto / 1024); - -/* - if( padto<=0x80000L ) - { - */ - if (size != padto) { - fflush(stdout); - - fseek(f, 0, SEEK_END); - while (size < padto) { - size += 1; - if ((ulOptions & OPTF_DEBUG) == 0) - fputc(0, f); - bytesadded += 1; - } - fflush(f); - - printf("\tAdded %ld bytes\n", bytesadded); - } else - printf("\tNo padding needed\n"); - /* - } - else - FatalError( "Image size exceeds 512kB" ); - */ - } - - /* - * -r (Truncate) option code - * - */ - - if (ulOptions & OPTF_TRUNCATE) { - long size, padto; - char tempfile[512]; - FILE *tf; - - size = FileSize(f); - padto = 256 * 32768; - while (size < padto) - padto /= 2; - - printf("Truncating to %ldkB:\n", padto / 1024); - - tmpnam(tempfile); - - if ((ulOptions & OPTF_DEBUG) == 0) { - if ((tf = fopen(tempfile, "wb")) != NULL) { - fseek(f, 0, SEEK_SET); - while (padto--) { - fputc(fgetc(f), tf); - } - fclose(f); - fclose(tf); - remove(filename); - rename(tempfile, filename); - f = fopen(filename, "rb+"); - } - } - } - - /* - * -t (Set carttitle) option code - * - */ - - if (ulOptions & OPTF_TITLE) { - printf("Setting cartridge title:\n"); - if ((ulOptions & OPTF_DEBUG) == 0) { - fflush(f); - fseek(f, 0x0134L, SEEK_SET); - fwrite(cartname, 16, 1, f); - fflush(f); - } - printf("\tTitle set to %s\n", cartname); - } - - /* - * -v (Validate header) option code - * - */ - - if (ulOptions & OPTF_VALIDATE) { - long i, byteschanged = 0; - long cartromsize, calcromsize = 0, filesize; - long carttype; - unsigned short cartchecksum = 0, calcchecksum = 0; - unsigned char cartcompchecksum = 0, calccompchecksum = - 0; - int ch; - - printf("Validating header:\n"); + if( padto<=0x80000L ) + { + */ + if (size != padto) { fflush(stdout); - /* Nintendo Character Area */ - - fflush(f); - fseek(f, 0x0104L, SEEK_SET); - - for (i = 0; i < 48; i += 1) { - int ch; - - ch = fgetc(f); - if (ch == EOF) - ch = 0x00; - if (ch != NintendoChar[i]) { - byteschanged += 1; - - if ((ulOptions & OPTF_DEBUG) == 0) { - fseek(f, -1, SEEK_CUR); - fputc(NintendoChar[i], f); - fflush(f); - } - } + fseek(f, 0, SEEK_END); + while (size < padto) { + size += 1; + if ((ulOptions & OPTF_DEBUG) == 0) + fputc(0, f); + bytesadded += 1; } - fflush(f); - if (byteschanged) - printf - ("\tChanged %ld bytes in the Nintendo Character Area\n", - byteschanged); - else - printf("\tNintendo Character Area is OK\n"); + printf("\tAdded %ld bytes\n", bytesadded); + } else + printf("\tNo padding needed\n"); + /* + } + else + FatalError( "Image size exceeds 512kB" ); + */ + } - /* ROM size */ + /* + * -r (Truncate) option code + * + */ + if (ulOptions & OPTF_TRUNCATE) { + long size, padto; + char tempfile[] = "/tmp/rgbfix-XXXXXX"; + FILE *tf; + + size = FileSize(f); + padto = 256 * 32768; + while (size < padto) + padto /= 2; + + printf("Truncating to %ldkB:\n", padto / 1024); + + mkstemp(tempfile); + + if ((ulOptions & OPTF_DEBUG) == 0) { + if ((tf = fopen(tempfile, "wb")) != NULL) { + fseek(f, 0, SEEK_SET); + while (padto--) { + fputc(fgetc(f), tf); + } + fclose(f); + fclose(tf); + remove(filename); + rename(tempfile, filename); + f = fopen(filename, "rb+"); + } + } + } + + /* + * -t (Set carttitle) option code + * + */ + + if (ulOptions & OPTF_TITLE) { + printf("Setting cartridge title:\n"); + if ((ulOptions & OPTF_DEBUG) == 0) { fflush(f); - fseek(f, 0x0148L, SEEK_SET); - cartromsize = fgetc(f); - if (cartromsize == EOF) - cartromsize = 0x00; - filesize = FileSize(f); - while (filesize > (0x8000L << calcromsize)) - calcromsize += 1; + fseek(f, 0x0134L, SEEK_SET); + fwrite(cartname, 16, 1, f); + fflush(f); + } + printf("\tTitle set to %s\n", cartname); + } + + /* + * -v (Validate header) option code + * + */ + + if (ulOptions & OPTF_VALIDATE) { + long i, byteschanged = 0; + long cartromsize, calcromsize = 0, filesize; + long carttype; + unsigned short cartchecksum = 0, calcchecksum = 0; + unsigned char cartcompchecksum = 0, calccompchecksum = + 0; + int ch; + + printf("Validating header:\n"); + fflush(stdout); + + /* Nintendo Character Area */ + + fflush(f); + fseek(f, 0x0104L, SEEK_SET); + + for (i = 0; i < 48; i += 1) { + int ch; + + ch = fgetc(f); + if (ch == EOF) + ch = 0x00; + if (ch != NintendoChar[i]) { + byteschanged += 1; - if (calcromsize != cartromsize) { if ((ulOptions & OPTF_DEBUG) == 0) { fseek(f, -1, SEEK_CUR); - fputc(calcromsize, f); + fputc(NintendoChar[i], f); + fflush(f); + } + } + } + + fflush(f); + + if (byteschanged) + printf + ("\tChanged %ld bytes in the Nintendo Character Area\n", + byteschanged); + else + printf("\tNintendo Character Area is OK\n"); + + /* ROM size */ + + fflush(f); + fseek(f, 0x0148L, SEEK_SET); + cartromsize = fgetc(f); + if (cartromsize == EOF) + cartromsize = 0x00; + filesize = FileSize(f); + while (filesize > (0x8000L << calcromsize)) + calcromsize += 1; + + if (calcromsize != cartromsize) { + if ((ulOptions & OPTF_DEBUG) == 0) { + fseek(f, -1, SEEK_CUR); + fputc(calcromsize, f); + fflush(f); + } + printf("\tChanged ROM size byte from 0x%02lX (%ldkB) to 0x%02lX (%ldkB)\n", + cartromsize, + (0x8000L << cartromsize) / 1024, + calcromsize, + (0x8000L << calcromsize) / 1024); + } else + printf("\tROM size byte is OK\n"); + + /* Cartridge type */ + + fflush(f); + fseek(f, 0x0147L, SEEK_SET); + carttype = fgetc(f); + if (carttype == EOF) + carttype = 0x00; + + if (FileSize(f) > 0x8000L) { + /* carttype byte must != 0x00 */ + if (carttype == 0x00) { + if ((ulOptions & OPTF_DEBUG) == 0) { + fseek(f, -1, SEEK_CUR); + fputc(0x01, f); fflush(f); } printf - ("\tChanged ROM size byte from 0x%02lX (%ldkB) to 0x%02lX (%ldkB)\n", - cartromsize, - (0x8000L << cartromsize) / 1024, - calcromsize, - (0x8000L << calcromsize) / 1024); + ("\tCartridge type byte changed to 0x01\n"); } else - printf("\tROM size byte is OK\n"); - - /* Cartridge type */ - - fflush(f); - fseek(f, 0x0147L, SEEK_SET); - carttype = fgetc(f); - if (carttype == EOF) - carttype = 0x00; - - if (FileSize(f) > 0x8000L) { - /* carttype byte must != 0x00 */ - if (carttype == 0x00) { - if ((ulOptions & OPTF_DEBUG) == 0) { - fseek(f, -1, SEEK_CUR); - fputc(0x01, f); - fflush(f); - } - printf - ("\tCartridge type byte changed to 0x01\n"); - } else - printf("\tCartridge type byte is OK\n"); - } else { - /* carttype byte can be anything? */ printf("\tCartridge type byte is OK\n"); - } - - /* Checksum */ - - fflush(f); - fseek(f, 0, SEEK_SET); - - for (i = 0; i < (0x8000L << calcromsize); i += 1) { - ch = fgetc(f); - if (ch == EOF) - ch = 0; - - if (i < 0x0134L) - calcchecksum += ch; - else if (i < 0x014DL) { - calccompchecksum += ch; - calcchecksum += ch; - } else if (i == 0x014DL) - cartcompchecksum = ch; - else if (i == 0x014EL) - cartchecksum = ch << 8; - else if (i == 0x014FL) - cartchecksum |= ch; - else - calcchecksum += ch; - } - - calccompchecksum = 0xE7 - calccompchecksum; - calcchecksum += calccompchecksum; - - if (cartchecksum != calcchecksum) { - fflush(f); - fseek(f, 0x014EL, SEEK_SET); - if ((ulOptions & OPTF_DEBUG) == 0) { - fputc(calcchecksum >> 8, f); - fputc(calcchecksum & 0xFF, f); - } - fflush(f); - printf - ("\tChecksum changed from 0x%04lX to 0x%04lX\n", - (long)cartchecksum, (long)calcchecksum); - } else - printf("\tChecksum is OK\n"); - - if (cartcompchecksum != calccompchecksum) { - fflush(f); - fseek(f, 0x014DL, SEEK_SET); - if ((ulOptions & OPTF_DEBUG) == 0) - fputc(calccompchecksum, f); - fflush(f); - printf - ("\tCompChecksum changed from 0x%02lX to 0x%02lX\n", - (long)cartcompchecksum, - (long)calccompchecksum); - } else - printf("\tCompChecksum is OK\n"); - + } else { + /* carttype byte can be anything? */ + printf("\tCartridge type byte is OK\n"); } - fclose(f); - } else { - FatalError("Unable to open file"); + + /* Checksum */ + + fflush(f); + fseek(f, 0, SEEK_SET); + + for (i = 0; i < (0x8000L << calcromsize); i += 1) { + ch = fgetc(f); + if (ch == EOF) + ch = 0; + + if (i < 0x0134L) + calcchecksum += ch; + else if (i < 0x014DL) { + calccompchecksum += ch; + calcchecksum += ch; + } else if (i == 0x014DL) + cartcompchecksum = ch; + else if (i == 0x014EL) + cartchecksum = ch << 8; + else if (i == 0x014FL) + cartchecksum |= ch; + else + calcchecksum += ch; + } + + calccompchecksum = 0xE7 - calccompchecksum; + calcchecksum += calccompchecksum; + + if (cartchecksum != calcchecksum) { + fflush(f); + fseek(f, 0x014EL, SEEK_SET); + if ((ulOptions & OPTF_DEBUG) == 0) { + fputc(calcchecksum >> 8, f); + fputc(calcchecksum & 0xFF, f); + } + fflush(f); + printf + ("\tChecksum changed from 0x%04lX to 0x%04lX\n", + (long)cartchecksum, (long)calcchecksum); + } else + printf("\tChecksum is OK\n"); + + if (cartcompchecksum != calccompchecksum) { + fflush(f); + fseek(f, 0x014DL, SEEK_SET); + if ((ulOptions & OPTF_DEBUG) == 0) + fputc(calccompchecksum, f); + fflush(f); + printf + ("\tCompChecksum changed from 0x%02lX to 0x%02lX\n", + (long)cartcompchecksum, + (long)calccompchecksum); + } else + printf("\tCompChecksum is OK\n"); + } + fclose(f); + return (0); }