#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:
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 |