shithub: riscv

Download patch

ref: 633bac1e917fe558b35846ffcc729ec2d47d4c99
parent: 4fc2780a5a3e6f6e79cc2bfd7d53516cecdc54ab
author: Jacob Moody <moody@posixcafe.org>
date: Sun Mar 5 02:47:21 EST 2023

/sys/src/games/^(aout2gba gba/rom): basic gba toolkit

--- /dev/null
+++ b/sys/src/games/aout2gba.c
@@ -1,0 +1,152 @@
+#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)
+		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);
+}
--- /dev/null
+++ b/sys/src/games/gba/rom/l.s
@@ -1,0 +1,52 @@
+/*		MOVW PC, R1		ADD 5, R1		BX R1 */
+#define THUMB	WORD $0xE1A0100F;	WORD $0xE2811005;	WORD $0xE12FFF11
+
+TEXT _main(SB), 1, $-4
+	THUMB
+TEXT _maint(SB), 4, $-4
+	MOVW	$setR12(SB), R1	/* load the SB */
+	MOVW	R1,R12
+	B	,main(SB)
+
+TEXT _isr(SB), 1, $-4
+	THUMB
+TEXT _isrt(SB), 4, $-4
+	SUB	$36,SP
+	WORD	$0x4672		/* MOV LR,R2 */
+	MOVW	R2,0(SP)
+
+	MOVW	R4,4(SP)
+	MOVW	R5,8(SP)
+	MOVW	R6,12(SP)
+	MOVW	R7,16(SP)
+
+	MOVW	R8,R2
+	MOVW	R2,20(SP)
+	MOVW	R9,R2
+	MOVW	R2,24(SP)
+	MOVW	R10,R2
+	MOVW	R2,28(SP)
+	MOVW	R11,R2
+	MOVW	R2,32(SP)
+
+	BL	,isr(SB)
+
+	MOVW	0(SP),R2
+	WORD	$0x4696		/* MOV R2,LR */
+	
+	MOVW	4(SP),R4
+	MOVW	8(SP),R5
+	MOVW	12(SP),R6
+	MOVW	16(SP),R7
+
+	MOVW	20(SP),R2
+	MOVW	R2,R8
+	MOVW	24(SP),R2
+	MOVW	R2,R9
+	MOVW	28(SP),R2
+	MOVW	R2,R10
+	MOVW	32(SP),R2
+	MOVW	R2,R11
+
+	ADD	$36,SP
+	WORD	$0x4770		/* BX LR */
--- /dev/null
+++ b/sys/src/games/gba/rom/mkfile
@@ -1,0 +1,7 @@
+</sys/src/mkfile.proto
+
+CC=tc
+LD=tl
+LDFLAGS=-T 0x080000C0 -R 0x4
+O=t
+AS=5a
--- /dev/null
+++ b/sys/src/games/gba/rom/mkone
@@ -1,0 +1,30 @@
+BIN=/sys/games/lib/gba
+
+default:V:	$TARG.gba
+
+all:V:	$TARG.gba
+
+$TARG.gba:	$O.out
+	games/aout2gba -o $target $prereq
+
+$O.out:	l.5 $OFILES $LIB
+	$LD $LDFLAGS -o $target $prereq
+
+%.$O:	$HFILES
+
+l.5:	/sys/src/games/gba/rom/l.s
+	$AS $AFLAGS $prereq
+
+%.$O:	%.c
+	$CC $CFLAGS $stem.c
+
+%.$O:	%.s
+	$AS $AFLAGS $stem.s
+
+install:V:	$BIN/$TARG.gba
+
+$BIN/$TARG.gba:	$TARG.gba
+	cp $prereq $target
+
+clean:V:
+	rm -f *.[$OS] [$OS].out y.tab.? lex.yy.c y.debug y.output $TARG.gba $CLEANFILES
--- a/sys/src/games/mkfile
+++ b/sys/src/games/mkfile
@@ -3,6 +3,7 @@
 TARG=4s\
 	5s\
 	ana\
+	aout2gba\
 	catclock\
 	festoon\
 	geigerstats\