mirror of
https://github.com/gbdev/rgbds.git
synced 2025-11-20 18:22:07 +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)
|
||||
{
|
||||
printf(
|
||||
"usage: rgbfix [-CcjsVv] [-i game_id] [-k licensee_str] [-l licensee_id]\n"
|
||||
" [-m mbc_type] [-n rom_version] [-p pad_value] [-r ram_size]\n"
|
||||
" [-t title_str] file\n");
|
||||
"usage: rgbfix [-CcjsVv] [-f fix_spec] [-i game_id] [-k licensee_str]\n"
|
||||
" [-l licensee_id] [-m mbc_type] [-n rom_version] [-p pad_value]\n"
|
||||
" [-r ram_size] [-t title_str] file\n");
|
||||
exit(1);
|
||||
}
|
||||
|
||||
@@ -37,7 +37,12 @@ int main(int argc, char *argv[])
|
||||
*/
|
||||
|
||||
/* 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 setid = false;
|
||||
bool colorcompatible = false;
|
||||
@@ -61,7 +66,7 @@ int main(int argc, char *argv[])
|
||||
int version = 0; /* mask ROM version number */
|
||||
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) {
|
||||
case 'C':
|
||||
coloronly = true;
|
||||
@@ -69,6 +74,14 @@ int main(int argc, char *argv[])
|
||||
case 'c':
|
||||
colorcompatible = true;
|
||||
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':
|
||||
setid = true;
|
||||
|
||||
@@ -168,7 +181,9 @@ int main(int argc, char *argv[])
|
||||
printf("rgbfix %s\n", get_package_version_string());
|
||||
exit(0);
|
||||
case 'v':
|
||||
validate = true;
|
||||
fixlogo = true;
|
||||
fixheadsum = true;
|
||||
fixglobalsum = true;
|
||||
break;
|
||||
default:
|
||||
print_usage();
|
||||
@@ -195,7 +210,7 @@ int main(int argc, char *argv[])
|
||||
* Write changes to ROM
|
||||
*/
|
||||
|
||||
if (validate) {
|
||||
if (fixlogo || trashlogo) {
|
||||
/*
|
||||
* Offset 0x104–0x133: Nintendo Logo
|
||||
* 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
|
||||
* 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] = {
|
||||
@@ -217,6 +232,10 @@ int main(int argc, char *argv[])
|
||||
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);
|
||||
fwrite(ninlogo, 1, 48, rom);
|
||||
}
|
||||
@@ -415,7 +434,7 @@ int main(int argc, char *argv[])
|
||||
fputc(version, rom);
|
||||
}
|
||||
|
||||
if (validate) {
|
||||
if (fixheadsum || trashheadsum) {
|
||||
/*
|
||||
* Offset 0x14D: Header Checksum
|
||||
*/
|
||||
@@ -426,9 +445,14 @@ int main(int argc, char *argv[])
|
||||
for (int i = 0; i < (0x14D - 0x134); ++i)
|
||||
headcksum = headcksum - fgetc(rom) - 1;
|
||||
|
||||
if (trashheadsum)
|
||||
headcksum = ~headcksum;
|
||||
|
||||
fseek(rom, 0x14D, SEEK_SET);
|
||||
fputc(headcksum, rom);
|
||||
}
|
||||
|
||||
if (fixglobalsum || trashglobalsum) {
|
||||
/*
|
||||
* Offset 0x14E–0x14F: Global Checksum
|
||||
*/
|
||||
@@ -445,6 +469,9 @@ int main(int argc, char *argv[])
|
||||
while ((byte = fgetc(rom)) != EOF)
|
||||
globalcksum += byte;
|
||||
|
||||
if (trashglobalsum)
|
||||
globalcksum = ~globalcksum;
|
||||
|
||||
fseek(rom, 0x14E, SEEK_SET);
|
||||
fputc(globalcksum >> 8, rom);
|
||||
fputc(globalcksum & 0xFF, rom);
|
||||
|
||||
@@ -14,6 +14,7 @@
|
||||
.Sh SYNOPSIS
|
||||
.Nm rgbfix
|
||||
.Op Fl CcjsVv
|
||||
.Op Fl f Ar fix_spec
|
||||
.Op Fl i Ar game_id
|
||||
.Op Fl k Ar licensee_str
|
||||
.Op Fl l Ar licensee_id
|
||||
@@ -46,6 +47,30 @@ If both this and the
|
||||
flag are set,
|
||||
.Fl C
|
||||
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
|
||||
Set the game ID string
|
||||
.Pq Ad 0x13F Ns \(en Ns Ad 0x142
|
||||
@@ -104,12 +129,8 @@ overlapping portion of the title.
|
||||
.It Fl V
|
||||
Print the version of the program and exit.
|
||||
.It Fl v
|
||||
Validate the header and fix checksums: the Nintendo character area
|
||||
.Pq Ad 0x104 Ns \(en Ns Ad 0x133 ,
|
||||
the header checksum
|
||||
.Pq Ad 0x14D ,
|
||||
and the global checksum
|
||||
.Pq Ad 0x14E Ns \(en Ns Ad 0x14F .
|
||||
Equivalent to
|
||||
.Fl f Cm lhg .
|
||||
.El
|
||||
.Sh EXAMPLES
|
||||
Most values in the ROM header are only cosmetic.
|
||||
|
||||
Reference in New Issue
Block a user