gbadev.org forum archive

This is a read-only mirror of the content originally found on forum.gbadev.org (now offline), salvaged from Wayback machine copies. A new forum can be found here.

ASM > Automatic GBA Header code for GNU Assembler

#11900 - ace - Thu Oct 23, 2003 11:55 am

This is sort of a followup to my previous post. Cleaned up, and expanded.

The following obsoletes all header fixup utilities (if you are using GNU Assembler).

It contains logic that the assembler interprets to create ALL the required fields for a header for a ROM or Multiboot Image.

The source does not contain anything that is copyright Nintendo (As far as I know).

Yet if you assemble this header as the startup of your rom/multiboot image, you will not need a header fixup utility.

Note, the following was assembled using the C-Preprocessor, as a pre-processor. It is for more civilised this way, so if using plain gas, it might not assemble, try using GCC to assemble it.

Anyway, Im interested in what you think about this, if it is useful or not.

BTW, this is not all original, it is a seriously modified header I pulled from HAM. It could easily be re-incorporated back into HAM if anyone was interested. HAM currently requires a header fixup utility.

Header code follows:

Code:
/********************************************************************
 * startup.S - Gameboy Advance ARM Startup file                     *
 ********************************************************************/
    .TEXT

    .GLOBAL     _start
_start:
    .ALIGN
    .ARM
    // Start Vector - Entry point from GBA Bios
    b    rom_header_end

    // Nintendo Logo Character Data goes here (8000004h)
    // Note, some people argue that inserting the logo here
    // would breach Nintendo Copyright, or other IP rights.
    // This is arguable, however, the following works as good
    // as the real logo, on a real GameboyAdvance.
    // *** This is not the official Nintendo Logo Data ***
    // The following code sequence is public domain, and may
    // be used for any purpose.
    // 0x800009C = 0xA5 for debug rom.
    .set   header_data, 0x80
    .irp   param,0xA4,0xA3,0x51,0xA2,0x0B,0xA5,0x47,0x68, \
                 0xA5,0x29,0xAB,0xB5,0x39,0x1D,0x26,0xD3, \
                 0xE4,0x08,0x93,0x2B,0xEB,0x6C,0xEB,0x0C, \
                 0xAF,0x01,0xBF,0xD8,0x6B,0x74,0x42,0x62, \
                 0x72,0xB8,0x02,0x4C,0x44,0x6B,0x9C,0x88, \
                 0xE0,0xA7,0x8F,0xC2,0x44,0x27,0xF5,0xB4, \
                 0x39,0x2D,0x0C,0xA0,0x6E,0xB9,0xC2,0x83, \
                 0x17,0x6D,0xF7,0xB7,0xCA,0x3C,0xE3,0xDF, \
                 0x7E,0x02,0x4F,0xC2,0x65,0x2F,0xC9,0x2A, \
                 0x82,0x19,0xBC,0xE3,0xDF,0xE2,0x7A,0xF0, \
                 0x13,0x30,0xF7,0x58,0x5B,0x5F,0x0D,0x63, \
                 0x22,0x5A,0xDE,0xDE,0x1E,0xC5,0xD3,0xD0, \
                 0xCF,0x21,0x1F,0x22,0x91,0x26,0x56,0x47, \
                 0xDE,0xD9,0x99,0x1E,0x7E,0x54,0xD4,0xF9, \
                 0xA2,0x05,0xC3,0xC6,0xC7,0x15,0x4D,0x2F, \
                 0x28,0xCA,0xFE,0xFD,0xB8,0xF6,0xF9,0x3D, \
                 0xB5,0xB5,0x45,0x10,0x98,0xA9,0xE3,0x77, \
                 0xDC,0x9C,0x18,0x7B,0x02,0xF2,0x2E,0xDD, \
                 0xB3,0xD8,0xBC,0x47,0x7F,0x89,0x35,0xA7, \
                 0xC8,0x9C,0x94,0x9B
    .set   char, \param
    .byte  ((char - header_data) & 0xFF)
    .set   header_data, char
    .endr

    // Nifty autogenerate header checksum
    //.set    checksum, 0
    .set    checksum, 0xE7
    // ROM Header information, strings/data as follows :
    // Game Title - Must be 12 characters (80000A0h)
    // Game Code - might ned to set to 'M','B',' ',' ' for some emulators - 4 characters (80000ACh)
    // Maker Code - 2 characters (80000B0h)
    // Fixed Value 0x96      (80000B2h)
    // Main Unit Code        (80000B3h)
    // Device Type           (80000B4h)
    // Unused Data - 7 Bytes (80000B5h)
    // Software Version No   (80000BCh)
    .irp   param,'I','n','s','e','r','t',' ','T','i','t','l','e', \
                 '0','0','0','0', \
                 '0','0', \
                 0x96, \
                 0x00, \
                 0x00, \
                 0x00,0x00,0x00,0x00,0x00,0x00,0x00, \
                 0x00
    .set   char, \param
    .byte  char
    .set   checksum, checksum - char
    .endr
    // On FIQ or Invalid Instruction
    // Call 09fe2000 if MS Bit of 0x080000B4 set   and 0x800009C = 0xA5 for debug rom.
    // Call 09ffc000 if MS Bit of 0x080000B4 clear and 0x800009C = 0xA5 for debug rom.

    // Complement Check (80000BDh)
    // Is auto generated thus (only for GNU Assembler) :
    // 1) Seed Checksum with 0xE7
    // 2) Subtract all values from ROM locations $a0 to (and including) $bc.
    // 3) Save the least significant byte of the result to ROM location $bd.
    .byte  (checksum & 0xFF)

    // Reserved - 2 bytes (80000BEh) -- Needs to be zero ??? (does it??)
    .byte   0x00,0x00

    .ALIGN
    .ARM                           

rom_header_end:
     b       start_vector   // This branch must be here for proper
                            // positioning of the following header.
                            // DO NOT REMOVE IT.

/********************************************************************
 * The following reserved bytes are used if the code is compiled for
 * multiboot mode. It does not hurt anything to leave this header in
 * even if the code is not compiled for multiboot. The GBA BIOS will
 * auto-patch the first two bytes with 0x03 and 0x01, respectively,
 * before running any code if it is executed as multiboot.
 * The following two bytes are included even for non-multiboot supporting
 * builds to guarantee that any generic library code that depends on them
 * will still be functional.
 ********************************************************************/
    .GLOBAL     __boot_method, __slave_number

__boot_method:
        .byte   0       // boot method (0=ROM boot, 3=Multiplay boot)
__slave_number:
        .byte   0       // slave # (1=slave#1, 2=slave#2, 3=slave#3)

        // Dont know if these need to be reserved for a multiboot image
        .byte   0       // reserved
        .byte   0       // reserved
        .word   0       // reserved
        .word   0       // reserved
        .word   0       // reserved
        .word   0       // reserved
        .word   0       // reserved
        .word   0       // reserved
/********************************************************************/


/********************************************************************
 *
 * Reset
 *
 ********************************************************************/

    .GLOBAL     start_vector
    .ALIGN
    .ARM
start_vector:
     // stick your startup code here, following is just an example...

        mov     r0, #0x12               // Set Switch to IRQ Mode
        msr     cpsr, r0                // Switch to IRQ Mode Here.
        ldr     sp,=IRQ_STACK_TOP       // Set SP_irq

        mov     r0, #0x11               // Set Switch to FIQ Mode
        msr     cpsr, r0                // Switch to FIQ Mode Here.
        ldr     sp,=IRQ_STACK_TOP       // Set SP_irq

        mov     r0, #0x1f               // Set Switch to System Mode
        msr     cpsr, r0                // Switch to System Mode here
        ldr     sp,=PGM_STACK_TOP       // Set SP_usr

        // Enter Thumb mode - conserves program space
        add    r0,pc,#1                 // r0 = address after following bx - thumb mode.
        bx     r0

        .THUMB
        // Copy Initialised data - program code to IWRAM

        // Jump to User Program
        ldr     r3,=start_vector
        mov     lr,r3            @ Set start_vector as return address

        ldr     r3,=GBA_Main
        bx      r3

        .ALIGN
        .POOL

    .END

#11911 - tepples - Thu Oct 23, 2003 7:28 pm

ace wrote:
Code:

    // Nintendo Logo Character Data goes here (8000004h)
    // Note, some people argue that inserting the logo here
    // would breach Nintendo Copyright, or other IP rights.
    // This is arguable, however, the following works as good
    // as the real logo, on a real GameboyAdvance.
    // *** This is not the official Nintendo Logo Data ***
    // The following code sequence is public domain, and may
    // be used for any purpose.
    // 0x800009C = 0xA5 for debug rom.
    .set   header_data, 0x80
    .irp   param,0xA4,0xA3,0x51,0xA2,0x0B,0xA5,0x47,0x68, \
                 0xA5,0x29,0xAB,0xB5,0x39,0x1D,0x26,0xD3, \
                 0xE4,0x08,0x93,0x2B,0xEB,0x6C,0xEB,0x0C, \
                 0xAF,0x01,0xBF,0xD8,0x6B,0x74,0x42,0x62, \
                 0x72,0xB8,0x02,0x4C,0x44,0x6B,0x9C,0x88, \
                 0xE0,0xA7,0x8F,0xC2,0x44,0x27,0xF5,0xB4, \
                 0x39,0x2D,0x0C,0xA0,0x6E,0xB9,0xC2,0x83, \
                 0x17,0x6D,0xF7,0xB7,0xCA,0x3C,0xE3,0xDF, \
                 0x7E,0x02,0x4F,0xC2,0x65,0x2F,0xC9,0x2A, \
                 0x82,0x19,0xBC,0xE3,0xDF,0xE2,0x7A,0xF0, \
                 0x13,0x30,0xF7,0x58,0x5B,0x5F,0x0D,0x63, \
                 0x22,0x5A,0xDE,0xDE,0x1E,0xC5,0xD3,0xD0, \
                 0xCF,0x21,0x1F,0x22,0x91,0x26,0x56,0x47, \
                 0xDE,0xD9,0x99,0x1E,0x7E,0x54,0xD4,0xF9, \
                 0xA2,0x05,0xC3,0xC6,0xC7,0x15,0x4D,0x2F, \
                 0x28,0xCA,0xFE,0xFD,0xB8,0xF6,0xF9,0x3D, \
                 0xB5,0xB5,0x45,0x10,0x98,0xA9,0xE3,0x77, \
                 0xDC,0x9C,0x18,0x7B,0x02,0xF2,0x2E,0xDD, \
                 0xB3,0xD8,0xBC,0x47,0x7F,0x89,0x35,0xA7, \
                 0xC8,0x9C,0x94,0x9B
    .set   char, \param
    .byte  ((char - header_data) & 0xFF)
    .set   header_data, char
    .endr

This is just a lightly encrypted version of the real logo data, which the script expands into the real thing, right?
_________________
-- Where is he?
-- Who?
-- You know, the human.
-- I think he moved to Tilwick.

#11932 - ace - Fri Oct 24, 2003 1:13 pm

It is what it is.

Its useful or not.

#11933 - torne - Fri Oct 24, 2003 3:14 pm

The 'encrypted' version of the logo data, supplied with an automatic decryption function, has exactly the same legal status as distributing the real logo data. I am not a lawyer, so I can't tell you whether distributing the real logo is legal (the issue is complex), but if the real logo is not, then your file is not either; your file is a derived work and therefore has the same copyright status as the original.

It's analogous to typing out the new Harry Potter book backwards, and posting it online along with a program that reverses the file again.

I suggest this topic be edited to remove the 'encrypted' data.

#11935 - poslundc - Fri Oct 24, 2003 3:59 pm

torne wrote:
I suggest this topic be edited to remove the 'encrypted' data.


Okay, he might be wrong about the technical legality, but does it really make a difference in a practical sense? After all, no one here is getting published without Nintendo's blessing (either directly or indirectly through a Nintendo-licensed publisher) anyway, right?

Can someone fill me in on what the big taboo is here?

Thanks,

Dan.

#11936 - torne - Fri Oct 24, 2003 4:04 pm

The board as a whole goes to some lengths to avoid discussion of questionably legal topics. Most of us have flashcarts; nobody talks about commercial roms. Some people may have seen the official Nintendo SDK from a warez copy; nobody discloses that either. And so on. =)

It's not been proven one way or the other whether it's legal to distribute the logo data. To do so would require a court case, which it's unlikely that anyone here can afford.

I was simply pointing out that if it's not legal to distribute the logo data, it is equally not legal to distribute the data given above, and therefore it might be wise to err on the side of caution.

#11941 - tepples - Fri Oct 24, 2003 6:03 pm

torne wrote:
It's not been proven one way or the other whether it's legal to distribute the logo data. To do so would require a court case

Hasn't this court case already been fought and won by an independent console game publisher?
_________________
-- Where is he?
-- Who?
-- You know, the human.
-- I think he moved to Tilwick.

#11944 - Gopher - Fri Oct 24, 2003 7:06 pm

Quote:

Hasn't this court case already been fought and won by an independent console game publisher?


Interesting case, thanks for posting the link.
After reading it, I would say that while a liberal interpretation might apply the findings to the GBA copyright system, a close examination of the findings reveals some fundamental differences.

The judge found on the side of Accolade in part on the grounds that there was no other way but SEGA's way to create a program that worked on the Genesis III, as differentiated from a prior case involving the NES where it was found that there were endless variations of the algorithm which could have the same result of satisfying the NES' security. In this it is the same as the GBA situation, since as far as I know only nintendo's way will work. I imagine a court would agree with torne's evaluation that encrypting the data does not change the fact that it is still the same data, and therefore the encryption approach does not constitute a distinct and seperate way of activating the hardware.

However, another point given some emphasis in this finding was that sega's method of bypassing the security was simply the presence of the 4 letters 'SEGA' in a particurlar memory location. Sega could not make the defense that this 4-letter sequence was copyrighted material, and was instead limited to arguing that disassembling the code to make this discovery was the crime, and that they were violating the copyright on Sega's code when they produced games using this knowledge. Nintendo, on the other hand, can additionally argue that including a copy of their trademarked logo is itself copyright infringement, independent of the arguments settled against Sega in the referenced case.

As for what a judge would decide if Nintendo were to file a claim against an unliscensed game release on those grounds, as far as I know that is an issue which is still untested in court.

[edit : Spelling, typos, grammar]
_________________
"Only two things are infinite: the universe, and human stupidity. The first is debatable." -Albert Einstein

#11951 - tepples - Fri Oct 24, 2003 8:40 pm

Gopher wrote:
The judge found on the side of Accolade in part on the grounds that there was no other way but SEGA's way to create a program that worked on the Genesis III, as differentiated from a prior case involving the NES where it was found that there were endless variations of the algorithm which could have the same result of satisfying the NES' security.

From my reading of Atari Games v. Nintendo, the issue that distinguished it from Sega was that Atari Games had defrauded the Copyright Office in asking for the source code to Nintendo's lockout chip implementation.

Quote:
Nintendo, on the other hand, can additionally argue that including a copy of their trademarked logo is itself copyright infringement, independent of the arguments settled against Sega in the referenced case.

The copyrighted work is not the Nintendo logo data. It is Super Mario Advance, the first published work that contained the Nintendo logo data. Super Mario Advance consists of 4194304 bytes of data, of which the Nintendo logo (156 bytes) makes up only 0.004 percent. I smell an "amount and substantiality" fair use argument here.

Quote:
As for what a judge would decide if Nintendo were to file a claim against an unliscensed game release on those grounds, as far as I know that is an issue which is still untested in court.

Get a good lawyer and you should be fine.
_________________
-- Where is he?
-- Who?
-- You know, the human.
-- I think he moved to Tilwick.

#11956 - ace - Fri Oct 24, 2003 11:56 pm

The "Logo" is not a logo at all. It is a series of bytes, a number. It becomes a Logo "in a sense" when the BIOS of the GBA messes with it and produces a "Logo" for printing on the screen. I have never seen the words "Nintendo" in the ascii data of the supposed logo data. And I only believe this is the case, because that is what people say. To me, it is a meaningles set of bytes, that have to be where they are for a rom or multiboot image to work on real hardware. It certainly doesnt look like any Logo ive ever seen before. I doubt 0x24,0xFF,0xAE...0xD4,0xF8,0x07 is the literal logo of the Nintendo company, It also doesn't appear to be a trademark. What the bios does with it is anyones guess. (unless they've reverse engineered the bios, which I havent.) Without doing that, how your supposed to know its a logo i dont know.

So on one argument, there is no Logo, until Nintendo Code (the bios of the GBA) creates the Logo (if thats what it does, which i dont know for a fact). In fact, all developers need the data for is so the bios can compare that data with data already contained in the bios (apparently).

To my mind it is less a copyright work and more like a signature. The issue is how did you get the signature. In my case I got it from a header changing utility that is freely available on the net. There was no Nintendo copyright notice in that.

I tried it and it worked. Great.

I know people are paranoid about this subject, but at the end of the day, what harm has anyone writing a bit of code at home done to nintendo.

The cat is well and truly out of the bag. I didn't release it. I made a bit of code, that makes it more convenient to write "play" stuff. Bit copying a rom was possible before anyone even knew about the header data requirement.

To my mind it is at best a storm in a teacup, and at worst, a flawed mechanism on the part of Nintendo to try and extort licences from developers that do not get any assistance from Nintendo.

If someone was to publish a game, without Nintendo's blessing, I actually wonder who they could sue. All the information is freely available on the web to do so. If the game developer was not responsible for putting it there in the first place, they are not responsible for the damage that does nintendo.

I would have been more scared of the register programming specs being out there, but no they are there, and Nintendo has done nothing obvious to enforce whatever rights it has (if any, which is not admitted :) in those reverse-engineered/re-typed specs, (or even in this header data which is freely available on the net for anyone who cares to look). No one seems to have any problem with the existence of these specs.

But, without those specs, no one would be able to do anything, whether they copied the header from a commercial rom or not.

They might not like it, but where's their case? For there to be a case, there has to be harm or damage that can be ameleiorated by a court. Further, the agrieved party can not have done anything to allow someone to think they were OK. Not asserting what rights you have, promptly and decisively, is taken in a lot of courts to be the same as condoning that action and therefore giving up those rights. You can not Approbate and Reprobate as it were. (or blow hot and cold)

But, without those specs, no one would be able to do anything, whether they copied the header from a commercial rom or not.

I would say the Genie is out of the bottle. Once it's out, it can't be put back in.

At the end of the day, we are talking about 156 Bytes.

The other point i'll make, is with the sequence i put up, it isn't anything until it's interpreted by the GNU Assembler. The act of doing that is creating the (allegedly) offending data. This is no worse than using a header fixup utility. If you don't do it it's not exposed. If you do do it, well you exposed it, because it wasn't that data when you started.

Without effort the "working header data" can not be extracted. If you do that work, you are complicit (if there is a case to answer, which I would argue there isn't).

What it wouldn't surprise me to find is this sequence is more of a stick against licenced developers. Used contractually to prevent them from refusing to pay royalties to Nintendo. They probably have a clause that goes, "to create a rom you have to insert this sequence "blah", you agree that every rom you create that has this sequence in it, you will pay us (Nintendo) $100,000.00. This clause survives termination of this agreement. You may not disclose this sequence to another third party without the prior written authorisation of Nintendo. blah blah blah."

So whatever its status is as a copyright work, a licenced developer has agreed that they will pay nintendo a licence for all roms containing it. In that case, it could be just 2 bytes, its probably longer, so that the chance of it coming up naturaly is remote.

If its too controversial, delete my post, it achieved what it was supposed to, cause a debate of the subject. I do notice with interest that the auto checksum code doesn't arrouse the same fear. It should, it would also be possible to argue, that calculating that checksum and putting it there in the image on those range of bytes breaches Nintendo's trade secrets. (I dont agree with this, and think they would loose if they ran a case on it, for a number of reasons.) But without it, a ROM wont run in a GBA, nor a multiboot image. The algorithm was either leaked, or reverse engineered. In the US, each is as bad as the other. In countries with more rational IP laws, reverse engineering is OK, so i dont know who came up with it, or how they did, but it is just as controversial. Seems however most don't think it is.

I wonder if instead of someone saying "Here is the nintendo logo" and it needs to be here in the rom. If they said, "Here is some random data, I dont know what it is, but if it isn't here in the rom it wont work" If everyone would have the same paranoia.

By using this header data we are not doing anything wrong. Wea re not harming nintendo in any way. We should stop acting like we are.

ACE.

#11957 - tepples - Sat Oct 25, 2003 12:21 am

ace wrote:
I doubt 0x24,0xFF,0xAE...0xD4,0xF8,0x07 is the literal logo of the Nintendo company

When run through a suitable Huffman decompressor, the 156 bytes of the Magic Cookie Data form a 1-bit image of the printed name Nintendo. Details

Quote:
They might not like it, but where's their case? For there to be a case, there has to be harm or damage that can be ameleiorated by a court.

How about "you're competing with us, and we have a bigger legal budget than you have"?

Quote:
Not asserting what rights you have, promptly and decisively, is taken in a lot of courts to be the same as condoning that action and therefore giving up those rights.

In other words, "estoppel" or "laches".

Quote:
[from conjectured NOA licensee NDA] "This clause survives termination of this agreement."

Disregarding the size of NOA, is this clearly enforceable?

Quote:
"You may not disclose this sequence to another third party without the prior written authorisation of Nintendo."

In that case, wouldn't having the game published (with Nintendo's authorization) count as "disclosing" the Magic Cookie Data to every GBA owner who buys the game?

Quote:
I wonder if instead of someone saying "Here is the nintendo logo" and it needs to be here in the rom. If they said, "Here is some random data, I dont know what it is, but if it isn't here in the rom it wont work" If everyone would have the same paranoia.

So why not just call it the "magic cookie data"?
_________________
-- Where is he?
-- Who?
-- You know, the human.
-- I think he moved to Tilwick.

#11973 - torne - Sat Oct 25, 2003 2:20 pm

Regardless of previous rulings, this case has not been tested.

Also, you seem to be missing the point. It is not vital or even particularly important that homebrew developers include the magic cookie in their roms, so why take a chance?

If you flash the game to a cart, then it will almost certainly have the header fixed anyway; logo, checksum, the lot. If you're going to play it over a multiboot cable, then you're probably technically competent enough to run a header fixup utility over it. =)

I'm not trying to detract from your clever code; the checksum calculation is nice. I just have no use for it personally.