summaryrefslogtreecommitdiff
path: root/source
diff options
context:
space:
mode:
Diffstat (limited to 'source')
-rw-r--r--source/checkParams.c133
-rw-r--r--source/copyright.c49
-rw-r--r--source/exit.c36
-rw-r--r--source/getSum.c40
-rw-r--r--source/help.c46
-rw-r--r--source/initData.c36
-rw-r--r--source/main.c65
-rw-r--r--source/open.c40
-rw-r--r--source/patch.c38
-rw-r--r--source/read.c42
10 files changed, 525 insertions, 0 deletions
diff --git a/source/checkParams.c b/source/checkParams.c
new file mode 100644
index 0000000..47bdeef
--- /dev/null
+++ b/source/checkParams.c
@@ -0,0 +1,133 @@
+/*
+ Copyright 2022-2023 Gabriel Bjørnager Jensen.
+
+ This file is part of agbsum.
+
+ agbsum is free software: you can redistribute it
+ and/or modify it under the terms of the GNU
+ Affero General Public License as published by
+ the Free Software Foundation, either version 3
+ of the License, or (at your option) any later
+ version.
+
+ agbsum is distributed in the hope that it will
+ be useful, but WITHOUT ANY WARRANTY; without
+ even the implied warranty of MERCHANTABILITY
+ or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU Affero General Public License for more
+ details.
+
+ You should have received a copy of the GNU
+ Affero General Public License along with agbsum.
+ If not, see <https://www.gnu.org/licenses/>.
+*/
+
+#include <agbsum.h>
+
+#include <inttypes.h>
+#include <stddef.h>
+#include <stdio.h>
+#include <string.h>
+
+noreturn static void
+agb_expectedParamValue (char const charParam)
+{
+ fprintf (stderr, "Expected value for character parameter '%c'\n", charParam);
+ agb_exit (agb_Cnd_Error, NULL);
+}
+
+static bool
+agb_checkCharParam (struct agb_Data* const restrict data, char const* const restrict param)
+{
+ // Returns true if the rest of the parameter is
+ // used as a value.
+
+ char const charParam = param[0x0];
+ if (charParam == '\x0') {return true;}
+
+ char const* const restrict paramval = &param[0x1];
+
+ switch (charParam) {
+ default:
+ fprintf (stderr, "Invalid character parameter '%c'\n", charParam);
+ agb_exit (agb_Cnd_Error, NULL);
+
+ case 'h':
+ agb_help ();
+ agb_exit (agb_Cnd_Ok, NULL);
+
+ case 'i':
+ {
+ if (paramval[0x0] == '\x0') {agb_expectedParamValue (charParam);}
+ data->path = paramval;
+ }
+ return true;
+
+ case 'p':
+ data->doPatch = true;
+ return false;
+
+ case 's':
+ data->silent = true;
+ return false;
+ }
+}
+
+void
+agb_checkParams (struct agb_Data* const restrict data, int const argc, char const* const* const argv) {
+ if (argc < 0x2) {
+ agb_help ();
+ agb_exit (agb_Cnd_Ok, NULL);
+ }
+
+ size_t const numParams = argc; // Prettier.
+
+ for (ptrdiff_t index = 0x1; index < (ptrdiff_t)numParams; ++index) {
+ // Iterate over the parameters. One hyphen denotes character parameters (-h) whilst two denote long paramters (--help).
+
+ char const* const param = argv[index];
+ if (param[0x0] == '-') {
+ if (param[0x1] == '-') {
+ char const* const longParam = &param[0x2];
+
+ // Check long parameters.
+
+ if (longParam[0x0] == '\x0') {
+ fputs ("Missing long parameter after '--' sequence\n", stderr);
+ agb_exit (agb_Cnd_Error, NULL);
+ }
+
+ if (!strcmp (longParam, "help")) {
+ agb_help ();
+ agb_exit (agb_Cnd_Ok, NULL);
+ }
+
+ if (!strcmp (longParam, "version")) {
+ agb_copyright();
+ agb_exit (agb_Cnd_Ok, NULL);
+ }
+
+ fprintf (stderr, "Invalid long parameter \"%s\"\n", longParam);
+ agb_exit (agb_Cnd_Error, NULL);
+ }
+
+ if (param[0x1] == '\x0') {
+ fputs ("Missing character parameter after '-'\n", stderr);
+ agb_exit (agb_Cnd_Error, NULL);
+ }
+
+ // Check character parameters.
+
+ for (char const* charIndex = &param[0x1];; ++charIndex) { if (agb_checkCharParam (data, charIndex)) { break; } }
+
+ continue;
+ }
+
+ // We did not find the 'i' parameter, so we don't know where the ROM is.
+
+ if (data->path == NULL) {
+ fputs ("ROM not set (missing character parameter 'i')\n", stderr);
+ agb_exit (agb_Cnd_Error, NULL);
+ }
+ }
+}
diff --git a/source/copyright.c b/source/copyright.c
new file mode 100644
index 0000000..14a64a5
--- /dev/null
+++ b/source/copyright.c
@@ -0,0 +1,49 @@
+/*
+ Copyright 2022-2023 Gabriel Bjørnager Jensen.
+
+ This file is part of agbsum.
+
+ agbsum is free software: you can redistribute it
+ and/or modify it under the terms of the GNU
+ Affero General Public License as published by
+ the Free Software Foundation, either version 3
+ of the License, or (at your option) any later
+ version.
+
+ agbsum is distributed in the hope that it will
+ be useful, but WITHOUT ANY WARRANTY; without
+ even the implied warranty of MERCHANTABILITY
+ or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU Affero General Public License for more
+ details.
+
+ You should have received a copy of the GNU
+ Affero General Public License along with agbsum.
+ If not, see <https://www.gnu.org/licenses/>.
+*/
+
+#include <agbsum.h>
+
+#include <inttypes.h>
+#include <stdio.h>
+
+void
+agb_copyright (void)
+{
+ printf (
+ "agbsum #%" PRIX64 " - Copyright 2022-2023 Gabriel Bj\u00F8rnager Jensen.\n"
+ "\n"
+ "This program is free software: you can redistribute it and/or modify it under\n"
+ "the terms of the GNU General Public License as published by the Free Software\n"
+ "Foundation, either version 3 of the License, or (at your option) any later\n"
+ "version.\n"
+ "\n"
+ "This program is distributed in the hope that it will be useful, but WITHOUT ANY\n"
+ "WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A\n"
+ "PARTICULAR PURPOSE. See the GNU General Public License for more details.\n"
+ "\n"
+ "You should have received a copy of the GNU General Public License along with\n"
+ "this program. If not, see <https://www.gnu.org/licenses/>.\n",
+ agb_release
+ );
+}
diff --git a/source/exit.c b/source/exit.c
new file mode 100644
index 0000000..b34d91c
--- /dev/null
+++ b/source/exit.c
@@ -0,0 +1,36 @@
+/*
+ Copyright 2022-2023 Gabriel Bjørnager Jensen.
+
+ This file is part of agbsum.
+
+ agbsum is free software: you can redistribute it
+ and/or modify it under the terms of the GNU
+ Affero General Public License as published by
+ the Free Software Foundation, either version 3
+ of the License, or (at your option) any later
+ version.
+
+ agbsum is distributed in the hope that it will
+ be useful, but WITHOUT ANY WARRANTY; without
+ even the implied warranty of MERCHANTABILITY
+ or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU Affero General Public License for more
+ details.
+
+ You should have received a copy of the GNU
+ Affero General Public License along with agbsum.
+ If not, see <https://www.gnu.org/licenses/>.
+*/
+
+#include <agbsum.h>
+
+#include <stdio.h>
+#include <stdlib.h>
+
+noreturn void
+agb_exit (enum agb_Condition const condition, FILE* restrict image)
+{
+ if (image != NULL) { fclose (image); }
+
+ exit (condition == agb_Cnd_Ok ? EXIT_SUCCESS : EXIT_FAILURE);
+}
diff --git a/source/getSum.c b/source/getSum.c
new file mode 100644
index 0000000..6d600ae
--- /dev/null
+++ b/source/getSum.c
@@ -0,0 +1,40 @@
+/*
+ Copyright 2022-2023 Gabriel Bjørnager Jensen.
+
+ This file is part of agbsum.
+
+ agbsum is free software: you can redistribute it
+ and/or modify it under the terms of the GNU
+ Affero General Public License as published by
+ the Free Software Foundation, either version 3
+ of the License, or (at your option) any later
+ version.
+
+ agbsum is distributed in the hope that it will
+ be useful, but WITHOUT ANY WARRANTY; without
+ even the implied warranty of MERCHANTABILITY
+ or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU Affero General Public License for more
+ details.
+
+ You should have received a copy of the GNU
+ Affero General Public License along with agbsum.
+ If not, see <https://www.gnu.org/licenses/>.
+*/
+
+#include <agbsum.h>
+
+#include <stdint.h>
+
+uint8_t
+agb_getSum (void const* const restrict imagePtr)
+{
+ uint8_t const* restrict image = imagePtr;
+ uint8_t sum = UINT8_C(0x0);
+
+ for (char unsigned const* restrict position = image; position != image + agb_sumOffset; ++position) { sum += *position; }
+
+ sum = -(UINT8_C(0x19) + sum);
+
+ return sum;
+}
diff --git a/source/help.c b/source/help.c
new file mode 100644
index 0000000..3686af9
--- /dev/null
+++ b/source/help.c
@@ -0,0 +1,46 @@
+/*
+ Copyright 2022-2023 Gabriel Bjørnager Jensen.
+
+ This file is part of agbsum.
+
+ agbsum is free software: you can redistribute it
+ and/or modify it under the terms of the GNU
+ Affero General Public License as published by
+ the Free Software Foundation, either version 3
+ of the License, or (at your option) any later
+ version.
+
+ agbsum is distributed in the hope that it will
+ be useful, but WITHOUT ANY WARRANTY; without
+ even the implied warranty of MERCHANTABILITY
+ or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU Affero General Public License for more
+ details.
+
+ You should have received a copy of the GNU
+ Affero General Public License along with agbsum.
+ If not, see <https://www.gnu.org/licenses/>.
+*/
+
+#include <agbsum.h>
+
+#include <inttypes.h>
+#include <stdio.h>
+
+void
+agb_help (void)
+{
+ fputs (
+ "agbsum - Patch AGB image header checksums.\n"
+ "\n"
+ "Usage: agbsum [options] <image>\n"
+ "Options:\n"
+ " --help -h Print the help screen\n"
+ " -p Patch the image file\n"
+ " -s Don't print results\n"
+ " --version Print the version number\n"
+ "\n",
+ stdout
+ );
+ agb_copyright ();
+}
diff --git a/source/initData.c b/source/initData.c
new file mode 100644
index 0000000..f9baea3
--- /dev/null
+++ b/source/initData.c
@@ -0,0 +1,36 @@
+/*
+ Copyright 2022-2023 Gabriel Bjørnager Jensen.
+
+ This file is part of agbsum.
+
+ agbsum is free software: you can redistribute it
+ and/or modify it under the terms of the GNU
+ Affero General Public License as published by
+ the Free Software Foundation, either version 3
+ of the License, or (at your option) any later
+ version.
+
+ agbsum is distributed in the hope that it will
+ be useful, but WITHOUT ANY WARRANTY; without
+ even the implied warranty of MERCHANTABILITY
+ or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU Affero General Public License for more
+ details.
+
+ You should have received a copy of the GNU
+ Affero General Public License along with agbsum.
+ If not, see <https://www.gnu.org/licenses/>.
+*/
+
+#include <agbsum.h>
+
+#include <stddef.h>
+
+void
+agb_initdata (struct agb_Data* const restrict data)
+{
+ data->doPatch = false;
+ data->path = NULL;
+ data->silent = false;
+ data->image = NULL;
+}
diff --git a/source/main.c b/source/main.c
new file mode 100644
index 0000000..4583eb5
--- /dev/null
+++ b/source/main.c
@@ -0,0 +1,65 @@
+/*
+ Copyright 2022-2023 Gabriel Bjørnager Jensen.
+
+ This file is part of agbsum.
+
+ agbsum is free software: you can redistribute it
+ and/or modify it under the terms of the GNU
+ Affero General Public License as published by
+ the Free Software Foundation, either version 3
+ of the License, or (at your option) any later
+ version.
+
+ agbsum is distributed in the hope that it will
+ be useful, but WITHOUT ANY WARRANTY; without
+ even the implied warranty of MERCHANTABILITY
+ or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU Affero General Public License for more
+ details.
+
+ You should have received a copy of the GNU
+ Affero General Public License along with agbsum.
+ If not, see <https://www.gnu.org/licenses/>.
+*/
+
+#include <agbsum.h>
+
+#include <limits.h>
+#include <stdint.h>
+#include <stdio.h>
+
+#if CHAR_BIT != 0x8
+#error "agbsum only support 8-bit byte systems"
+#endif
+
+int main (int const argc, char const* const* const argv)
+{
+ struct agb_Data data;
+ agb_initdata (&data);
+ agb_checkParams (&data, argc, argv);
+
+ data.image = agb_open (data.path);
+
+ char unsigned buffer[agb_sumOffset + 0x1];
+
+ agb_read (buffer, data.image);
+
+ {
+ char unsigned const sum = agb_getSum (buffer);
+ char unsigned const imageSum = buffer[agb_sumOffset];
+
+ if (imageSum == sum || !data.doPatch) {
+ // Don't patch the ROM if it's already okay or we're not allowed to.
+ if (!data.silent) {printf ("\"%s\": %hhX (%hhX in file)\n", data.path, sum, imageSum);}
+ agb_exit (agb_Cnd_Ok, data.image);
+ }
+
+ agb_patch (data.image, sum);
+
+ // If we aren't supposed to print anything then
+ // don't.
+ if (!data.silent) { printf ("\"%s\" @ %zX: %hhX => %hhX\n", data.path, agb_sumDataStart + agb_sumOffset, imageSum, sum); }
+ }
+
+ agb_exit (agb_Cnd_Ok, data.image);
+}
diff --git a/source/open.c b/source/open.c
new file mode 100644
index 0000000..415e589
--- /dev/null
+++ b/source/open.c
@@ -0,0 +1,40 @@
+/*
+ Copyright 2022-2023 Gabriel Bjørnager Jensen.
+
+ This file is part of agbsum.
+
+ agbsum is free software: you can redistribute it
+ and/or modify it under the terms of the GNU
+ Affero General Public License as published by
+ the Free Software Foundation, either version 3
+ of the License, or (at your option) any later
+ version.
+
+ agbsum is distributed in the hope that it will
+ be useful, but WITHOUT ANY WARRANTY; without
+ even the implied warranty of MERCHANTABILITY
+ or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU Affero General Public License for more
+ details.
+
+ You should have received a copy of the GNU
+ Affero General Public License along with agbsum.
+ If not, see <https://www.gnu.org/licenses/>.
+*/
+
+#include <agbsum.h>
+
+#include <stdio.h>
+
+FILE*
+agb_open (char const* const restrict path)
+{
+ FILE* image = fopen (path, "r+");
+
+ if (image == NULL) {
+ fputs ("Unable to open ROM\n", stderr);
+ agb_exit (agb_Cnd_Error, NULL);
+ }
+
+ return image;
+}
diff --git a/source/patch.c b/source/patch.c
new file mode 100644
index 0000000..78d2531
--- /dev/null
+++ b/source/patch.c
@@ -0,0 +1,38 @@
+/*
+ Copyright 2022-2023 Gabriel Bjørnager Jensen.
+
+ This file is part of agbsum.
+
+ agbsum is free software: you can redistribute it
+ and/or modify it under the terms of the GNU
+ Affero General Public License as published by
+ the Free Software Foundation, either version 3
+ of the License, or (at your option) any later
+ version.
+
+ agbsum is distributed in the hope that it will
+ be useful, but WITHOUT ANY WARRANTY; without
+ even the implied warranty of MERCHANTABILITY
+ or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU Affero General Public License for more
+ details.
+
+ You should have received a copy of the GNU
+ Affero General Public License along with agbsum.
+ If not, see <https://www.gnu.org/licenses/>.
+*/
+
+#include <agbsum.h>
+
+#include <stdio.h>
+
+void
+agb_patch (FILE* const restrict image, char unsigned sum)
+{
+ fseek (image, (long)(agb_sumDataStart + agb_sumOffset), SEEK_SET);
+
+ if (fwrite (&sum, 0x1u, 0x1u, image) != 0x1u) {
+ fputs ("Unable to patch ROM\n", stderr);
+ agb_exit (agb_Cnd_Error, image);
+ }
+}
diff --git a/source/read.c b/source/read.c
new file mode 100644
index 0000000..0ed3808
--- /dev/null
+++ b/source/read.c
@@ -0,0 +1,42 @@
+/*
+ Copyright 2022-2023 Gabriel Bjørnager Jensen.
+
+ This file is part of agbsum.
+
+ agbsum is free software: you can redistribute it
+ and/or modify it under the terms of the GNU
+ Affero General Public License as published by
+ the Free Software Foundation, either version 3
+ of the License, or (at your option) any later
+ version.
+
+ agbsum is distributed in the hope that it will
+ be useful, but WITHOUT ANY WARRANTY; without
+ even the implied warranty of MERCHANTABILITY
+ or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU Affero General Public License for more
+ details.
+
+ You should have received a copy of the GNU
+ Affero General Public License along with agbsum.
+ If not, see <https://www.gnu.org/licenses/>.
+*/
+
+#include <agbsum.h>
+
+#include <stdio.h>
+
+void
+agb_read (void* const restrict buffer, FILE* restrict image)
+{
+ // We only need to read the part of the image
+ // that is used for the checksum.
+ fseek (image, agb_sumDataStart, SEEK_SET);
+
+ size_t const count = agb_sumOffset + 0x1u;
+
+ if (fread (buffer, 0x1u, count, image) != count) {
+ fputs ("Unable to read ROM\n", stderr);
+ agb_exit (agb_Cnd_Error, image);
+ }
+}