mirror of
https://github.com/gbdev/rgbds.git
synced 2025-11-21 02:32:06 +00:00
Add a new flag, -f, which allows independently fixing or trashing checksums.
This commit is contained in:
@@ -20,9 +20,9 @@
|
|||||||
static void print_usage(void)
|
static void print_usage(void)
|
||||||
{
|
{
|
||||||
printf(
|
printf(
|
||||||
"usage: rgbfix [-CcjsVv] [-i game_id] [-k licensee_str] [-l licensee_id]\n"
|
"usage: rgbfix [-CcjsVv] [-f fix_spec] [-i game_id] [-k licensee_str]\n"
|
||||||
" [-m mbc_type] [-n rom_version] [-p pad_value] [-r ram_size]\n"
|
" [-l licensee_id] [-m mbc_type] [-n rom_version] [-p pad_value]\n"
|
||||||
" [-t title_str] file\n");
|
" [-r ram_size] [-t title_str] file\n");
|
||||||
exit(1);
|
exit(1);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -37,7 +37,12 @@ int main(int argc, char *argv[])
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
/* all flags default to false unless options specify otherwise */
|
/* all flags default to false unless options specify otherwise */
|
||||||
bool validate = false;
|
bool fixlogo = false;
|
||||||
|
bool fixheadsum = false;
|
||||||
|
bool fixglobalsum = false;
|
||||||
|
bool trashlogo = false;
|
||||||
|
bool trashheadsum = false;
|
||||||
|
bool trashglobalsum = false;
|
||||||
bool settitle = false;
|
bool settitle = false;
|
||||||
bool setid = false;
|
bool setid = false;
|
||||||
bool colorcompatible = false;
|
bool colorcompatible = false;
|
||||||
@@ -61,7 +66,7 @@ int main(int argc, char *argv[])
|
|||||||
int version = 0; /* mask ROM version number */
|
int version = 0; /* mask ROM version number */
|
||||||
int padvalue = 0; /* to pad the rom with if it changes size */
|
int padvalue = 0; /* to pad the rom with if it changes size */
|
||||||
|
|
||||||
while ((ch = getopt(argc, argv, "Cci:jk:l:m:n:p:sr:t:Vv")) != -1) {
|
while ((ch = getopt(argc, argv, "Ccf:i:jk:l:m:n:p:sr:t:Vv")) != -1) {
|
||||||
switch (ch) {
|
switch (ch) {
|
||||||
case 'C':
|
case 'C':
|
||||||
coloronly = true;
|
coloronly = true;
|
||||||
@@ -69,6 +74,14 @@ int main(int argc, char *argv[])
|
|||||||
case 'c':
|
case 'c':
|
||||||
colorcompatible = true;
|
colorcompatible = true;
|
||||||
break;
|
break;
|
||||||
|
case 'f':
|
||||||
|
fixlogo = strchr(optarg, 'l');
|
||||||
|
fixheadsum = strchr(optarg, 'h');
|
||||||
|
fixglobalsum = strchr(optarg, 'g');
|
||||||
|
trashlogo = strchr(optarg, 'L');
|
||||||
|
trashheadsum = strchr(optarg, 'H');
|
||||||
|
trashglobalsum = strchr(optarg, 'G');
|
||||||
|
break;
|
||||||
case 'i':
|
case 'i':
|
||||||
setid = true;
|
setid = true;
|
||||||
|
|
||||||
@@ -168,7 +181,9 @@ int main(int argc, char *argv[])
|
|||||||
printf("rgbfix %s\n", get_package_version_string());
|
printf("rgbfix %s\n", get_package_version_string());
|
||||||
exit(0);
|
exit(0);
|
||||||
case 'v':
|
case 'v':
|
||||||
validate = true;
|
fixlogo = true;
|
||||||
|
fixheadsum = true;
|
||||||
|
fixglobalsum = true;
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
print_usage();
|
print_usage();
|
||||||
@@ -195,7 +210,7 @@ int main(int argc, char *argv[])
|
|||||||
* Write changes to ROM
|
* Write changes to ROM
|
||||||
*/
|
*/
|
||||||
|
|
||||||
if (validate) {
|
if (fixlogo || trashlogo) {
|
||||||
/*
|
/*
|
||||||
* Offset 0x104–0x133: Nintendo Logo
|
* Offset 0x104–0x133: Nintendo Logo
|
||||||
* This is a bitmap image that displays when the Game Boy is
|
* This is a bitmap image that displays when the Game Boy is
|
||||||
@@ -205,7 +220,7 @@ int main(int argc, char *argv[])
|
|||||||
/*
|
/*
|
||||||
* See also: global checksums at 0x14D–0x14F, They must
|
* See also: global checksums at 0x14D–0x14F, They must
|
||||||
* also be correct for the game to boot, so we fix them
|
* also be correct for the game to boot, so we fix them
|
||||||
* as well when the -v flag is set.
|
* as well when requested with the -f flag.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
uint8_t ninlogo[48] = {
|
uint8_t ninlogo[48] = {
|
||||||
@@ -217,6 +232,10 @@ int main(int argc, char *argv[])
|
|||||||
0xDD, 0xDC, 0x99, 0x9F, 0xBB, 0xB9, 0x33, 0x3E
|
0xDD, 0xDC, 0x99, 0x9F, 0xBB, 0xB9, 0x33, 0x3E
|
||||||
};
|
};
|
||||||
|
|
||||||
|
if (trashlogo)
|
||||||
|
for (int i = 0; i < sizeof(ninlogo); i++)
|
||||||
|
ninlogo[i] = ~ninlogo[i];
|
||||||
|
|
||||||
fseek(rom, 0x104, SEEK_SET);
|
fseek(rom, 0x104, SEEK_SET);
|
||||||
fwrite(ninlogo, 1, 48, rom);
|
fwrite(ninlogo, 1, 48, rom);
|
||||||
}
|
}
|
||||||
@@ -415,7 +434,7 @@ int main(int argc, char *argv[])
|
|||||||
fputc(version, rom);
|
fputc(version, rom);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (validate) {
|
if (fixheadsum || trashheadsum) {
|
||||||
/*
|
/*
|
||||||
* Offset 0x14D: Header Checksum
|
* Offset 0x14D: Header Checksum
|
||||||
*/
|
*/
|
||||||
@@ -426,9 +445,14 @@ int main(int argc, char *argv[])
|
|||||||
for (int i = 0; i < (0x14D - 0x134); ++i)
|
for (int i = 0; i < (0x14D - 0x134); ++i)
|
||||||
headcksum = headcksum - fgetc(rom) - 1;
|
headcksum = headcksum - fgetc(rom) - 1;
|
||||||
|
|
||||||
|
if (trashheadsum)
|
||||||
|
headcksum = ~headcksum;
|
||||||
|
|
||||||
fseek(rom, 0x14D, SEEK_SET);
|
fseek(rom, 0x14D, SEEK_SET);
|
||||||
fputc(headcksum, rom);
|
fputc(headcksum, rom);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (fixglobalsum || trashglobalsum) {
|
||||||
/*
|
/*
|
||||||
* Offset 0x14E–0x14F: Global Checksum
|
* Offset 0x14E–0x14F: Global Checksum
|
||||||
*/
|
*/
|
||||||
@@ -445,6 +469,9 @@ int main(int argc, char *argv[])
|
|||||||
while ((byte = fgetc(rom)) != EOF)
|
while ((byte = fgetc(rom)) != EOF)
|
||||||
globalcksum += byte;
|
globalcksum += byte;
|
||||||
|
|
||||||
|
if (trashglobalsum)
|
||||||
|
globalcksum = ~globalcksum;
|
||||||
|
|
||||||
fseek(rom, 0x14E, SEEK_SET);
|
fseek(rom, 0x14E, SEEK_SET);
|
||||||
fputc(globalcksum >> 8, rom);
|
fputc(globalcksum >> 8, rom);
|
||||||
fputc(globalcksum & 0xFF, rom);
|
fputc(globalcksum & 0xFF, rom);
|
||||||
|
|||||||
@@ -14,6 +14,7 @@
|
|||||||
.Sh SYNOPSIS
|
.Sh SYNOPSIS
|
||||||
.Nm rgbfix
|
.Nm rgbfix
|
||||||
.Op Fl CcjsVv
|
.Op Fl CcjsVv
|
||||||
|
.Op Fl f Ar fix_spec
|
||||||
.Op Fl i Ar game_id
|
.Op Fl i Ar game_id
|
||||||
.Op Fl k Ar licensee_str
|
.Op Fl k Ar licensee_str
|
||||||
.Op Fl l Ar licensee_id
|
.Op Fl l Ar licensee_id
|
||||||
@@ -46,6 +47,30 @@ If both this and the
|
|||||||
flag are set,
|
flag are set,
|
||||||
.Fl C
|
.Fl C
|
||||||
takes precedence.
|
takes precedence.
|
||||||
|
.It Fl f Ar fix_spec
|
||||||
|
Fix certain header values that the Game Boy checks for correctness.
|
||||||
|
Alternatively, intentionally trash these values by writing their binary inverse
|
||||||
|
instead.
|
||||||
|
.Ar fix_spec
|
||||||
|
is a string containing any combination of the following characters:
|
||||||
|
.Pp
|
||||||
|
.Bl -tag -compact -width xx
|
||||||
|
.It Cm l
|
||||||
|
Fix the Nintendo logo
|
||||||
|
.Pq Ad 0x104 Ns \(en Ns Ad 0x133 .
|
||||||
|
.It Cm L
|
||||||
|
Trash the Nintendo logo.
|
||||||
|
.It Cm h
|
||||||
|
Fix the header checksum
|
||||||
|
.Pq Ad 0x14D .
|
||||||
|
.It Cm H
|
||||||
|
Trash the header checksum.
|
||||||
|
.It Cm g
|
||||||
|
Fix the global checksum
|
||||||
|
.Pq Ad 0x14E Ns \(en Ns Ad 0x14F .
|
||||||
|
.It Cm G
|
||||||
|
Trash the global checksum.
|
||||||
|
.El
|
||||||
.It Fl i Ar game_id
|
.It Fl i Ar game_id
|
||||||
Set the game ID string
|
Set the game ID string
|
||||||
.Pq Ad 0x13F Ns \(en Ns Ad 0x142
|
.Pq Ad 0x13F Ns \(en Ns Ad 0x142
|
||||||
@@ -104,12 +129,8 @@ overlapping portion of the title.
|
|||||||
.It Fl V
|
.It Fl V
|
||||||
Print the version of the program and exit.
|
Print the version of the program and exit.
|
||||||
.It Fl v
|
.It Fl v
|
||||||
Validate the header and fix checksums: the Nintendo character area
|
Equivalent to
|
||||||
.Pq Ad 0x104 Ns \(en Ns Ad 0x133 ,
|
.Fl f Cm lhg .
|
||||||
the header checksum
|
|
||||||
.Pq Ad 0x14D ,
|
|
||||||
and the global checksum
|
|
||||||
.Pq Ad 0x14E Ns \(en Ns Ad 0x14F .
|
|
||||||
.El
|
.El
|
||||||
.Sh EXAMPLES
|
.Sh EXAMPLES
|
||||||
Most values in the ROM header are only cosmetic.
|
Most values in the ROM header are only cosmetic.
|
||||||
|
|||||||
Reference in New Issue
Block a user