aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--gbafix.c124
-rw-r--r--readme3
2 files changed, 127 insertions, 0 deletions
diff --git a/gbafix.c b/gbafix.c
new file mode 100644
index 0000000..e1eb83d
--- /dev/null
+++ b/gbafix.c
@@ -0,0 +1,124 @@
+#include <u.h>
+#include <libc.h>
+
+enum {
+ AROM = 0x00,
+ ALOGO = 0x04,
+ ATITLE = 0xA0,
+ AGAME = 0xAC,
+ AMAKER = 0xB0,
+ AFIXED = 0xB2,
+ AUNIT = 0xB3,
+ ADEVTYPE = 0xB4,
+ ARES0 = 0xB5,
+ AVERSION = 0xBC,
+ ACKSUM = 0xBD,
+ ARES1 = 0xBE,
+ AEND = 0xC0
+};
+
+typedef struct Header Header;
+
+struct Header
+{
+ u32int start; /* ARM entry point branch opcode */
+ u8int logo[156]; /* the Nintendo logo */
+ u8int title[12];
+ u32int game;
+ u16int maker;
+ u8int fixed; /* 0x96 */
+ u8int unit;
+ u8int devtype;
+ u8int r0[7]; /* reserved area */
+ u8int version;
+ u8int cksum;
+ u8int r1[2]; /* reserved area */
+};
+
+u8int nintendō[156] = {
+ 0x24,0xFF,0xAE,0x51,0x69,0x9A,0xA2,0x21,0x3D,0x84,0x82,0x0A,0x84,0xE4,0x09,0xAD,
+ 0x11,0x24,0x8B,0x98,0xC0,0x81,0x7F,0x21,0xA3,0x52,0xBE,0x19,0x93,0x09,0xCE,0x20,
+ 0x10,0x46,0x4A,0x4A,0xF8,0x27,0x31,0xEC,0x58,0xC7,0xE8,0x33,0x82,0xE3,0xCE,0xBF,
+ 0x85,0xF4,0xDF,0x94,0xCE,0x4B,0x09,0xC1,0x94,0x56,0x8A,0xC0,0x13,0x72,0xA7,0xFC,
+ 0x9F,0x84,0x4D,0x73,0xA3,0xCA,0x9A,0x61,0x58,0x97,0xA3,0x27,0xFC,0x03,0x98,0x76,
+ 0x23,0x1D,0xC7,0x61,0x03,0x04,0xAE,0x56,0xBF,0x38,0x84,0x00,0x40,0xA7,0x0E,0xFD,
+ 0xFF,0x52,0xFE,0x03,0x6F,0x95,0x30,0xF1,0x97,0xFB,0xC0,0x85,0x60,0xD6,0x80,0x25,
+ 0xA9,0x63,0xBE,0x03,0x01,0x4E,0x38,0xE2,0xF9,0xA2,0x34,0xFF,0xBB,0x3E,0x03,0x44,
+ 0x78,0x00,0x90,0xCB,0x88,0x11,0x3A,0x94,0x65,0xC0,0x7C,0x63,0x87,0xF0,0x3C,0xAF,
+ 0xD6,0x25,0xE4,0x8B,0x38,0x0A,0xAC,0x72,0x21,0xD4,0xF8,0x07
+};
+
+char
+cksum(Header *h)
+{
+ int n;
+ char c, *p;
+
+ c = 0;
+ p = (char*)h;
+ p += ATITLE;
+ for(n = 0; n < ACKSUM-ATITLE; n++)
+ c += *p++;
+ return -(0x19+c);
+}
+
+void
+usage(void)
+{
+ fprint(2, "usage: %s [-t title] [-g gamecode] [-m makercode] [-v version] rom\n", argv0);
+ exits("usage");
+}
+
+void
+main(int argc, char *argv[])
+{
+ Header h;
+ char *title;
+ u32int gcode;
+ u16int mcode;
+ u8int vcode;
+ int fd;
+
+ title = nil;
+ gcode = mcode = vcode = 0;
+ ARGBEGIN{
+ case 't':
+ title = EARGF(usage());
+ break;
+ case 'g':
+ gcode = strtoul(EARGF(usage()), nil, 0);
+ break;
+ case 'm':
+ mcode = strtoul(EARGF(usage()), nil, 0);
+ break;
+ case 'v':
+ vcode = strtoul(EARGF(usage()), nil, 0);
+ break;
+ default: usage();
+ }ARGEND;
+ if(argc != 1)
+ usage();
+ fd = open(argv[0], ORDWR);
+ if(fd < 0)
+ sysfatal("open: %r");
+ memset(&h, 0, sizeof h);
+ if(readn(fd, &h, sizeof(Header)) != sizeof(Header))
+ sysfatal("readn: %r");
+ memmove(h.logo, nintendō, sizeof(nintendō));
+ if(title)
+ memmove(h.title, title, strlen(title) < sizeof(h.title)? strlen(title): sizeof(h.title));
+ if(gcode)
+ h.game = gcode;
+ if(mcode)
+ h.maker = mcode;
+ h.fixed = 0x96;
+ h.devtype = 0x00;
+ if(vcode)
+ h.version = vcode;
+ h.cksum = cksum(&h);
+ seek(fd, 0, 0);
+ if(write(fd, &h, sizeof(Header)) != sizeof(Header))
+ sysfatal("write: %r");
+ close(fd);
+ exits(0);
+}
diff --git a/readme b/readme
new file mode 100644
index 0000000..5e00a50
--- /dev/null
+++ b/readme
@@ -0,0 +1,3 @@
+Tools for GBA ROM development
+
+so far i've got gbafix(1). more should come later.