This makes 5l capable of spitting out valid .gba files. With this I was able to get a basic rom working. To give this a try: ; hget http://okturing.com/src/15122/body > sprite.c ; 5c sprite.c ; 5l -H8 -Emain sprite.5 ; games/gba 5.out diff e6c6217b35c319127f0200fdb28ec86e1b774a4f uncommitted --- a/sys/src/cmd/5l/asm.c +++ b/sys/src/cmd/5l/asm.c @@ -81,6 +81,7 @@ case 2: case 5: case 7: + case 8: OFFSET = HEADR+textsize; seek(cout, OFFSET, 0); break; @@ -126,6 +127,7 @@ seek(cout, OFFSET, 0); break; case 7: + case 8: break; } if(!debug['s']) @@ -269,6 +271,9 @@ lput(0x04L); /* protections = R */ lput(0x04L); /* alignment code?? */ break; + case 8: /* GameBoy Advance */ + gbaheader(); + break; } cflush(); } @@ -1842,4 +1847,80 @@ return n; } return -1; +} + +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 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, + + /* game code */ + 'A', 'P', '9', 'E', + + /* maker code */ + 'P', '9', + + /* fixed */ + 0x96,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00, + + /* compliment */ + 0x00, + + /* reserved */ + 0x00, 0x00, +}; + +void +gbaheader(void) +{ + ulong ep; + char *p, *e; + char c; + + ep = 0xea000000; + ep += (entryvalue() - INITTEXT + HEADR - 8) / 4; + cart[3] = ep>>24; + cart[2] = ep>>16; + cart[1] = ep>>8; + cart[0] = ep; + + p = cart + 0xA0; + if(strlen(outfile) < 12) + strcpy(p, outfile); + + e = cart + 0xBD; + for(c = 0; p < e; p++) + c += *p; + *p = -(0x19+c); + + p = cart; + e = p + sizeof cart; + for(;p < e; p++) + cput(*p); } --- a/sys/src/cmd/5l/l.h +++ b/sys/src/cmd/5l/l.h @@ -343,6 +343,7 @@ int find1(long, int); char* findlib(char*); void follow(void); +void gbaheader(void); void histtoauto(void); double ieeedtod(Ieee*); long ieeedtof(Ieee*); --- a/sys/src/cmd/5l/obj.c +++ b/sys/src/cmd/5l/obj.c @@ -193,6 +193,15 @@ if(INITRND == -1) INITRND = 4; break; + case 8: /* GameBoy Advance */ + HEADR = 192L; + if(INITTEXT == -1) + INITTEXT = 0x08000000 + HEADR; + if(INITDAT == -1) + INITDAT = 0; + if(INITRND == -1) + INITRND = 4; + break; } if(INITDAT != 0 && INITRND != 0) print("warning: -D0x%lux is ignored because of -R0x%lux\n",
Jacob Moody <moody@mail.posixcafe.org> once said:
> This makes 5l capable of spitting out valid .gba files.
> With this I was able to get a basic rom working.
>
> To give this a try:
> ; hget http://okturing.com/src/15122/body > sprite.c
> ; 5c sprite.c
> ; 5l -H8 -Emain sprite.5
> ; games/gba 5.out
This should be a command that takes a 5.out and produces
a gba image. See
- aux/aout2uimage for the u-boot image format,
- aux/ms2 for the motorola s-record format,
- and xenbin for xen binary images
as examples. Putting the nintendo logo in the loader is
a bit much for my taste. Not to mention the prospect of
provoking ptyalism in the swamp creatures colloquially
referred to as intellectual property lawyers.
Cheers,
Anthony
On 3/2/23 04:15, Anthony Martin wrote: > Jacob Moody <moody@mail.posixcafe.org> once said: >> This makes 5l capable of spitting out valid .gba files. >> With this I was able to get a basic rom working. >> >> To give this a try: >> ; hget http://okturing.com/src/15122/body > sprite.c >> ; 5c sprite.c >> ; 5l -H8 -Emain sprite.5 >> ; games/gba 5.out > > This should be a command that takes a 5.out and produces > a gba image. See > > - aux/aout2uimage for the u-boot image format, > - aux/ms2 for the motorola s-record format, > - and xenbin for xen binary images > So you end up needing to pass -T to the linker anyway? I did it this way because -H8 is a bit more descriptive then just -T 0x08000000. Perhaps I am missing something and there is a way of making aout2gba work with any 5.out binary, without the need for specific linker flags. Or is the expectation that for those tools you do end up needing an explicit -T as well? I dont know; those tools dont have manuals. But it seems odd to me to have this as an external tool if it has assumptions about specific linker flags. > as examples. Putting the nintendo logo in the loader is > a bit much for my taste. Not to mention the prospect of > provoking ptyalism in the swamp creatures colloquially > referred to as intellectual property lawyers. > I know "look they're doing it too" is about as far as you can get from sound legal advice, but this has seemingly not been an issue for devkitpro which also ships with the hex code as part of their 'gbafix' program. Surely getting the only open source gba development kit taken off the web would have happened by now if the logo was all it took. Without the logo you can not build a rom that the bios will load. If it can't be anywhere in the tree then we can do nothing and are wasting our time. - moody
i dont think that a.out (arm) have relocatable code. aout2uimage does not relocate the image (abslute addresses are encoded inside instruction immediates) but only changes the header and handles some padding stuff. the load address (and entry point) all *MUST* stay the same no matter if it is wrapped in a.out or uimage. this is why you need the -T flag for the linker. theres no relocation info in a.out as far as i remember. so writing a external tool to convert an a.out to ???? requiering relocation will have a hard time. -- cinap
On 3/2/23 10:33, cinap_lenrek@felloff.net wrote:
> i dont think that a.out (arm) have relocatable code.
>
> aout2uimage does not relocate the image (abslute addresses
> are encoded inside instruction immediates) but only
> changes the header and handles some padding stuff.
>
> the load address (and entry point) all *MUST* stay the
> same no matter if it is wrapped in a.out or uimage.
>
> this is why you need the -T flag for the linker. theres
> no relocation info in a.out as far as i remember.
> so writing a external tool to convert an a.out to ????
> requiering relocation will have a hard time.
>
> --
> cinap
I dont want to do relocation, I just want to know
why external programs that only work under assumptions
of how the a.out was linked are preferable to just
having the linker output correct files.
I wrote it this way because there was some existing
precedent in 5l creating boot images for ipaq and ixp1200
in the code. If everyone else is in agreement that this kind of header
code should only be done in external programs, should that code also be moved
to be external or deleted?
> I dont want to do relocation, I just want to know > why external programs that only work under assumptions > of how the a.out was linked are preferable to just > having the linker output correct files. Sorry, then i must have misundersood you. > If everyone else is in agreement that this kind of header > code should only be done in external programs, should that > code also be moved to be external or deleted? I do not see a need to be dogmatic about this at all or force a decision. I do not have any skin in this game nor do i have a gameboy. Was just pointing out why an external tool would only solve half the problem in this case. But i think we agree here. A external tool made perfect sense for uimage as we want to generate both an a.out (for debugger and /dev/reboot) and a uimage for uboot. Linking is quite expensive compared to just writing out a header and copying some data out of a file and calculating a checksum. For the gameboy rom image problem, my first guess would be to just generate the header using the assembler and pass that as the first object to the linker and have the linker geneate headerless image. -- cinap
On 3/3/23 13:59, cinap_lenrek@felloff.net wrote:
>> I dont want to do relocation, I just want to know
>> why external programs that only work under assumptions
>> of how the a.out was linked are preferable to just
>> having the linker output correct files.
>
> Sorry, then i must have misundersood you.
>
>> If everyone else is in agreement that this kind of header
>> code should only be done in external programs, should that
>> code also be moved to be external or deleted?
>
> I do not see a need to be dogmatic about this at all
> or force a decision.
>
> I do not have any skin in this game nor do i have a gameboy.
>
> Was just pointing out why an external tool would only solve
> half the problem in this case. But i think we agree here.
>
> A external tool made perfect sense for uimage as we want to
> generate both an a.out (for debugger and /dev/reboot) and a
> uimage for uboot. Linking is quite expensive compared to just
> writing out a header and copying some data out of a file and
> calculating a checksum.
>
> For the gameboy rom image problem, my first guess would be to
> just generate the header using the assembler and pass that
> as the first object to the linker and have the linker geneate
> headerless image.
I ended up writing an aout2gba that does work as intended. I think
this may still be quite useful, I am considering teaching games/gba
how to load a gba a.out file (for debug info), so being able to
generate both may be useful.
In porting a more complicated rom, I realized that plan9 specific
init code is unavoidable anyway due to needing to setup R12:
MOVW $setR12(SB), R12 /* load the SB */
Somehow I had missed that this preamble would be needed. Given that
we need an l.s entrypoint for this anyway, I can just stuff the header
in there and encode the entry point manually to just jump down after the
header as we discussed. I am working on a /sys/src/cmd/mkone equivalent
and some plumbing, I'll post another diff soon.
Thanks,
moody
> In porting a more complicated rom, I realized that plan9 specific > init code is unavoidable anyway due to needing to setup R12: > MOVW $setR12(SB), R12 /* load the SB */ It is not plan9 specific really. It is just an address bias value for accessing the data section; generated by the linker. The idea is that you want to keep the offsets small becuse small offsets are more likely be encodable directly into a single instruction, while larger ones need multiple instructions. Also note this is a RISC thing; where you have usually a large number of general purpose registers. For 386 code, there is no such thing. -- cinap