ref: 8e3abc0cce6d52ebf9195ea277a6dbd92ba497a1
dir: /sys/src/games/aout2gba.c/
#include <u.h> #include <libc.h> #include <bio.h> #include <mach.h> static char cart[] = { /* entry point */ 0x00, 0x00, 0x00, 0x00, /* nintendo logo */ 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, /* title */ 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, /* game code */ 'A', 'P', '9', 'E', /* maker code */ 'P', '9', /* fixed */ 0x96,0x00,0x00, 0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* version */ 0x00, /* compliment */ 0x00, /* reserved */ 0x00, 0x00, }; static int infd, outfd; static void io(ulong count) { static char buf[8192]; long n, n2; do { n2 = count > sizeof buf ? sizeof buf : count; n = read(infd, buf, n2); if(n <= 0) sysfatal("read: %r"); if(write(outfd, buf, n) != n) sysfatal("write: %r"); count -= n; } while(count != 0); } static void usage(void) { fprint(2, "usage: %s a.out\n", argv0); exits("usage"); } void main(int argc, char **argv) { Fhdr fhdr; u32int rzero; ulong ep; char *ofile, *iname; char *p, *e; int n; char c; ofile = nil; rzero = 0x08000000; ARGBEGIN { case 'Z': rzero = strtoull(EARGF(usage()), 0, 0); break; case 'o': ofile = strdup(EARGF(usage())); break; default: usage(); } ARGEND; if(argc != 1) usage(); infd = open(argv[0], OREAD); if(infd < 0) sysfatal("infd: %r"); if(crackhdr(infd, &fhdr) == 0) sysfatal("crackhdr: %r"); if(fhdr.type != FARM && fhdr.type != FARMB) sysfatal("not an arm32 a.out"); iname = strrchr(argv[0], '/'); if(iname != nil) iname++; else iname = argv[0]; if(ofile == nil) ofile = smprint("%s.gba", iname); outfd = create(ofile, OWRITE|OTRUNC, 0666); if(outfd < 0) sysfatal("create: %r"); ep = 0xea000000; //B main ep += (fhdr.entry - rzero - 8)/4; cart[3] = ep>>24; cart[2] = ep>>16; cart[1] = ep>>8; cart[0] = ep; p = cart + 0xA0; n = strlen(iname); if(n > 12) sysfatal("title too long"); memcpy(p, iname, n); //no null e = cart + 0xBD; for(c = 0; p < e; p++) c += *p; *p = -(0x19+c); if(write(outfd, cart, sizeof cart) != sizeof cart) sysfatal("write: %r"); seek(infd, fhdr.txtoff, 0); io(fhdr.txtsz); /* allignment */ assert(fhdr.datoff >= fhdr.txtoff + fhdr.txtsz); seek(outfd, fhdr.datoff - (fhdr.txtoff + fhdr.txtsz), 1); seek(infd, fhdr.datoff, 0); io(fhdr.datsz); exits(nil); }