ソースを参照

* GBA port updated

git-svn-id: trunk@42201 -
Legolas 6 年 前
コミット
4239742b35

+ 109 - 120
compiler/systems/t_gba.pas

@@ -244,15 +244,16 @@ begin
       add('/*         support added to allow labels end, _end, */');
       add('/*         & __end__ to point to end of iwram or    */');
       add('/*         the end of ewram.                        */');
-      add('/*	Additions by WinterMute				*/');
-      add('/* v1.4 -	.sbss section added for unitialised	*/');
-      add('/*		    data in ewram 			*/');
-      add('/* v1.5 -	padding section added to stop EZF 	*/');
-      add('/*		    stripping important data		*/');
+      add('/*	Additions by WinterMute	               	*/');
+      add('/* v1.4 -	.sbss section added for unitialised		*/');
+      add('/*		    data in ewram 							*/');
+      add('/* v1.5 -	padding section added to stop EZF 		*/');
+      add('/*		    stripping important data				*/');
+      add('/* v1.6 -	added memory sections			 		*/');
       add('');
       add('/* This file is released into the public domain		*/');
       add('/* for commercial or non-commercial use with no		*/');
-      add('/* restrictions placed upon it.				*/');
+      add('/* restrictions placed upon it.						*/');
       add('');
       add('/* NOTE!!!: This linker script defines the RAM &  */');
       add('/*   ROM start addresses. In order for it to work */');
@@ -270,16 +271,6 @@ begin
       add('OUTPUT_FORMAT("elf32-littlearm", "elf32-bigarm", "elf32-littlearm")');
       add('OUTPUT_ARCH(arm)');
       add('ENTRY(_start)');
-      add('/* SEARCH_DIR(/bin/arm); */');
-      add('');
-      add('/* The linker script function "var1 += var2;" sometimes    */');
-      add('/* reports incorrect values in the *.map file but the      */');
-      add('/* actual value it calculates is usually, if not always,   */');
-      add('/* correct. If you leave out the ". = ALIGN(4);" at the    */');
-      add('/* end of each section then the return value of SIZEOF()   */');
-      add('/* is sometimes incorrect and "var1 += var2;" appears to   */');
-      add('/* not work as well. "var1 += var2" style functions are    */');
-      add('/* avoided below as a result.                              */');
       add('');
       add('MEMORY {');
       add('');
@@ -288,10 +279,13 @@ begin
       add('	ewram	: ORIGIN = 0x02000000, LENGTH = 256K');
       add('}');
       add('');
-      add('__text_start	=	ORIGIN(rom);');
+      add('');
+      add('');
+      add('__text_start	=	ORIGIN(ewram);');
       add('__eheap_end	=	ORIGIN(ewram) + LENGTH(ewram);');
       add('__iwram_start	=	ORIGIN(iwram);');
       add('__iwram_top	=	ORIGIN(iwram) + LENGTH(iwram);;');
+      add('');
       add('__sp_irq	=	__iwram_top - 0x060;');
       add('__sp_usr	=	__sp_irq - 0x0a0;');
       add('__irq_flags	=	0x03007ff8;');
@@ -299,19 +293,26 @@ begin
       add('SECTIONS');
       add('{');
       add('	. = __text_start;');
-      add('	.init :');
+      add('	. = __text_start;');
+      add('	.crt0 :');
       add('	{');
-      add('		KEEP (*(.init))');
+      add('		KEEP (*(.crt0))');
       add('		. = ALIGN(4);');
-      add('	} >rom =0xff');
+      add('	} >ewram =0xff');
+      add('');
+      add('	.init :');
+      add('	{');
+      add('		KEEP (*(SORT_NONE(.init)))');
+      add('	} >ewram');
       add('');
       add('	.plt :');
       add('	{');
       add('		*(.plt)');
       add('		. = ALIGN(4);   /* REQUIRED. LD is flaky without it. */');
-      add('	} >rom');
+      add('	} >ewram');
       add('');
-      add('	.text  :   /* ALIGN (4): */');
+      add('');
+      add('	.text  ALIGN (4):');
       add('	{');
       add('		*(EXCLUDE_FILE (*.iwram*) .text)');
       add('		*(.text .stub .text.* .gnu.linkonce.t.*)');
@@ -320,14 +321,14 @@ begin
       add('		*(.gnu.warning)');
       add('		*(.glue_7t) *(.glue_7) *(.vfp11_veneer)');
       add('		. = ALIGN(4);  /* REQUIRED. LD is flaky without it. */');
-      add('	} >rom = 0xff');
+      add('	} >ewram = 0xff');
       add('');
       add('	__text_end = .;');
       add('	.fini           :');
       add('	{');
       add('		KEEP (*(.fini))');
-      add('		. = ALIGN(4);  /* REQUIRED. LD is flaky without it. */');
-      add('	} >rom =0');
+      add('		. = ALIGN(4);   /* REQUIRED. LD is flaky without it. */');
+      add('	} >ewram =0');
       add('');
       add('	.rodata :');
       add('	{');
@@ -338,12 +339,26 @@ begin
       add('		*(.gnu.linkonce.r*)');
       add('		SORT(CONSTRUCTORS)');
       add('		. = ALIGN(4);   /* REQUIRED. LD is flaky without it. */');
-      add('	} >rom = 0xff');
-      add('  .ARM.extab   : { *(.ARM.extab* .gnu.linkonce.armextab.*) } >rom');
+      add('	} >ewram = 0xff');
+      add('');
+      add('  .ARM.extab   : { *(.ARM.extab* .gnu.linkonce.armextab.*) } >ewram');
       add('   __exidx_start = .;');
-      add('  .ARM.exidx   : { *(.ARM.exidx* .gnu.linkonce.armexidx.*) } >rom');
+      add('  .ARM.exidx   : { *(.ARM.exidx* .gnu.linkonce.armexidx.*) } >ewram');
       add('   __exidx_end = .;');
-      add('');
+      add('  /* Ensure the __preinit_array_start label is properly aligned.  We');
+      add('     could instead move the label definition inside the section, but');
+      add('     the linker would then create the section even if it turns out to');
+      add('     be empty, which isn''t pretty.  */');
+      add('  . = ALIGN(32 / 8);');
+      add('  PROVIDE (__preinit_array_start = .);');
+      add('  .preinit_array     : { KEEP (*(.preinit_array)) } >ewram = 0xff');
+      add('  PROVIDE (__preinit_array_end = .);');
+      add('  PROVIDE (__init_array_start = .);');
+      add('  .init_array     : { KEEP (*(.init_array)) } >ewram = 0xff');
+      add('  PROVIDE (__init_array_end = .);');
+      add('  PROVIDE (__fini_array_start = .);');
+      add('  .fini_array     : { KEEP (*(.fini_array)) } >ewram = 0xff');
+      add('  PROVIDE (__fini_array_end = .);');
       add('	.ctors :');
       add('	{');
       add('		/*	gcc uses crtbegin.o to find the start of the constructors, so');
@@ -357,7 +372,7 @@ begin
       add('		KEEP (*(SORT(.ctors.*)))');
       add('		KEEP (*(.ctors))');
       add('		. = ALIGN(4);   /* REQUIRED. LD is flaky without it. */');
-      add('	} >rom = 0');
+      add('	} >ewram = 0');
       add('');
       add('	.dtors :');
       add('	{');
@@ -366,144 +381,121 @@ begin
       add('		KEEP (*(SORT(.dtors.*)))');
       add('		KEEP (*(.dtors))');
       add('		. = ALIGN(4);   /* REQUIRED. LD is flaky without it. */');
-      add('	} >rom = 0');
-      add('');
+      add('	} >ewram = 0');
       add('');
+      add('	.jcr            : { KEEP (*(.jcr)) } >ewram');
       add('	.eh_frame :');
       add('	{');
       add('		KEEP (*(.eh_frame))');
-      add('		. = ALIGN(4);   /* REQUIRED. LD is flaky without it. */');
-      add('	} >rom = 0');
+      add('	. = ALIGN(4);   /* REQUIRED. LD is flaky without it. */');
+      add('	} >ewram = 0');
       add('');
       add('	.gcc_except_table :');
       add('	{');
       add('		*(.gcc_except_table)');
       add('		. = ALIGN(4);   /* REQUIRED. LD is flaky without it. */');
-      add('	} >rom = 0');
+      add('	} >ewram = 0');
       add('');
       add('	__iwram_lma = .;');
       add('');
       add('	.iwram __iwram_start : AT (__iwram_lma)');
       add('	{');
-      add('		__iwram_start = ABSOLUTE(.) ;');
+      add('		__iwram_start__ = ABSOLUTE(.) ;');
       add('		*(.iwram)');
       add('		*iwram.*(.text)');
       add('		. = ALIGN(4);   /* REQUIRED. LD is flaky without it. */');
-      add('		__iwram_end = ABSOLUTE(.) ;');
+      add('		__iwram_end__ = ABSOLUTE(.) ;');
       add('	} >iwram = 0xff');
       add('');
       add('	__data_lma = __iwram_lma + SIZEOF(.iwram) ;');
       add('');
-      add('	.bss ALIGN(4) (NOLOAD) :');
+      add('	.bss ALIGN(4) (NOLOAD):');
       add('	{');
-      add('		__bss_start = ABSOLUTE(.);');
       add('		__bss_start__ = ABSOLUTE(.);');
       add('		*(.dynbss)');
       add('		*(.gnu.linkonce.b*)');
       add('		*(.bss*)');
       add('		*(COMMON)');
       add('		. = ALIGN(4);    /* REQUIRED. LD is flaky without it. */');
-      add('		__bss_end = ABSOLUTE(.) ;');
-      add('');
-      add('	} AT>iwram');
-      add('');
-      add('	__bss_end__ = __bss_end ;');
+      add('		__bss_end__ = ABSOLUTE(.) ;');
+      add('	}');
       add('');
       add('	.data ALIGN(4) : AT (__data_lma)');
       add('	{');
-      add('		__data_start = ABSOLUTE(.);');
+      add('		__data_start__ = ABSOLUTE(.);');
       add('		*(.data)');
       add('		*(.data.*)');
       add('		*(.gnu.linkonce.d*)');
-      add('		*(.fpc*)');
       add('		CONSTRUCTORS');
-      add('		. = ALIGN(4);');
+      add('		. = ALIGN(4);  /* REQUIRED. LD is flaky without it. */');
+      add('		__data_end__  =  ABSOLUTE(.);');
       add('	} >iwram = 0xff');
       add('');
-      add('	__preinit_lma = __data_lma + SIZEOF(.data);');
-      add('');
-      add('	PROVIDE (__preinit_array_start = .);');
-      add('	.preinit_array     : AT (__preinit_lma) { KEEP (*(.preinit_array)) } >iwram');
-      add('	PROVIDE (__preinit_array_end = .);');
+      add('	__iwram_overlay_lma = __data_lma + SIZEOF(.data);');
       add('');
-      add('	__init_lma = __preinit_lma + SIZEOF(.preinit_array);');
+      add('	PROVIDE (edata = .);');
+      add('	__iwram_overlay_start = . ;');
       add('');
-      add('	PROVIDE (__init_array_start = .);');
-      add('	.init_array     : AT (__init_lma)');
+      add('	OVERLAY ALIGN(4) : NOCROSSREFS AT (__iwram_overlay_lma)');
       add('	{');
-      add('		KEEP (*(SORT(.init_array.*)))');
-      add('		KEEP (*(.init_array))');
-      add('	} >iwram');
-      add('	PROVIDE (__init_array_end = .);');
-      add('	PROVIDE (__fini_array_start = .);');
-      add('');
-      add('	__fini_lma = __init_lma + SIZEOF(.init_array);');
+      add('	   .iwram0 { *(.iwram0) . = ALIGN(4);}');
+      add('	   .iwram1 { *(.iwram1) . = ALIGN(4);}');
+      add('	   .iwram2 { *(.iwram2) . = ALIGN(4);}');
+      add('	   .iwram3 { *(.iwram3) . = ALIGN(4);}');
+      add('	   .iwram4 { *(.iwram4) . = ALIGN(4);}');
+      add('	   .iwram5 { *(.iwram5) . = ALIGN(4);}');
+      add('	   .iwram6 { *(.iwram6) . = ALIGN(4);}');
+      add('	   .iwram7 { *(.iwram7) . = ALIGN(4);}');
+      add('	   .iwram8 { *(.iwram8) . = ALIGN(4);}');
+      add('	   .iwram9 { *(.iwram9) . = ALIGN(4);}');
+      add('	} >iwram = 0xff');
       add('');
-      add('	.fini_array     : AT (__fini_lma)');
-      add('	{');
-      add('		KEEP (*(SORT(.fini_array.*)))');
-      add('		KEEP (*(.fini_array))');
-      add('	} >iwram');
-      add('  	PROVIDE (__fini_array_end = .);');
+      add('	__ewram_lma = LOADADDR(.iwram0) + SIZEOF(.iwram0)+SIZEOF(.iwram1)+SIZEOF(.iwram2)+SIZEOF(.iwram3)+SIZEOF(.iwram4)+SIZEOF(.iwram5)+SIZEOF(.iwram6)+SIZEOF(.iwram7)+SIZEOF(.iwram8)+SIZEOF(.iwram9);');
       add('');
-      add('	__jcr_lma = __fini_lma + SIZEOF(.fini_array);');
-      add('	.jcr            : AT (__jcr_lma) { KEEP (*(.jcr)) } >iwram');
+      add('	__iwram_overlay_end = __ewram_lma ;');
       add('');
-      add('	__data_end  =  ABSOLUTE(.);');
-      add('	__iwram_overlay_lma = __jcr_lma + SIZEOF(.jcr);');
+      add('	/* v1.3 */');
+      add('	__ewram_start =  __ewram_lma ;');
       add('');
-      add('	__iwram_overlay_start = . ;');
-      add('');
-      add('	OVERLAY ALIGN(4) : NOCROSSREFS AT (__iwram_overlay_lma)');
-      add('	{');
-      add('		.iwram0 { *(.iwram0) . = ALIGN(4);}');
-      add('		.iwram1 { *(.iwram1) . = ALIGN(4);}');
-      add('		.iwram2 { *(.iwram2) . = ALIGN(4);}');
-      add('		.iwram3 { *(.iwram3) . = ALIGN(4);}');
-      add('		.iwram4 { *(.iwram4) . = ALIGN(4);}');
-      add('		.iwram5 { *(.iwram5) . = ALIGN(4);}');
-      add('		.iwram6 { *(.iwram6) . = ALIGN(4);}');
-      add('		.iwram7 { *(.iwram7) . = ALIGN(4);}');
-      add('		.iwram8 { *(.iwram8) . = ALIGN(4);}');
-      add('		.iwram9 { *(.iwram9) . = ALIGN(4);}');
-      add('	}>iwram = 0xff');
-      add('');
-      add('	__iwram_overlay_end = . ;');
-      add('  __ewram_lma = __iwram_overlay_lma + (__iwram_overlay_end - __iwram_overlay_start) ;');
-      add('');
-      add('	__iheap_start = . ;');
-      add('');
-      add('	__ewram_start = ORIGIN(ewram);');
       add('	.ewram __ewram_start : AT (__ewram_lma)');
       add('	{');
       add('		*(.ewram)');
       add('		. = ALIGN(4);  /* REQUIRED. LD is flaky without it. */');
-      add('	}>ewram = 0xff');
+      add('		__ewram_end = ABSOLUTE(.);');
+      add('	} >ewram = 0xff');
       add('');
-      add('	__pad_lma = __ewram_lma + SIZEOF(.ewram);');
+      add('	__ewram_overlay_lma = __ewram_lma + SIZEOF(.ewram);');
       add('');
       add('	.sbss ALIGN(4)(NOLOAD):');
       add(' 	{');
-      add('		__sbss_start = ABSOLUTE(.);');
-      add(' 		*(.sbss)');
-      add(' 		. = ALIGN(4);');
-      add('		__sbss_end  = ABSOLUTE(.);');
-      add(' 	} AT>ewram');
-      add('');
-      add('');
-      add('	__ewram_end = __sbss_end ;');
-      add('	__eheap_start = __sbss_end;');
-      add('	__end__ = __sbss_end;');
+      add('		__sbss_start__ = ABSOLUTE(.);');
+      add('		*(.sbss)');
+      add('		. = ALIGN(4);');
+      add('		__sbss_end__  = ABSOLUTE(.);');
+      add('		__end__ = ABSOLUTE(.);');
+      add('		__eheap_start = ABSOLUTE(.);');
+      add('	}');
       add('');
-      add('	/* EZF Advance strips trailing 0xff bytes, add a pad section so nothing important is removed */');
-      add('	.pad ALIGN(4) : AT (__pad_lma)');
+      add('	OVERLAY ALIGN(4): NOCROSSREFS AT (__ewram_overlay_lma)');
       add('	{');
-      add('		LONG(0x52416b64)');
-      add('		LONG(0x4d)');
-      add('		. = ALIGN(4);  /* REQUIRED. LD is flaky without it. */');
-      add('	} = 0xff');
-      add('	__rom_end__ = __pad_lma + SIZEOF(.pad);');
-      add('');
+      add('		.ewram0 { *(.ewram0) . = ALIGN(4);}');
+      add('		.ewram1 { *(.ewram1) . = ALIGN(4);}');
+      add('		.ewram2 { *(.ewram2) . = ALIGN(4);}');
+      add('		.ewram3 { *(.ewram3) . = ALIGN(4);}');
+      add('		.ewram4 { *(.ewram4) . = ALIGN(4);}');
+      add('		.ewram5 { *(.ewram5) . = ALIGN(4);}');
+      add('		.ewram6 { *(.ewram6) . = ALIGN(4);}');
+      add('		.ewram7 { *(.ewram7) . = ALIGN(4);}');
+      add('		.ewram8 { *(.ewram8) . = ALIGN(4);}');
+      add('		.ewram9 { *(.ewram9) . = ALIGN(4);}');
+      add('	} >ewram = 0xff');
+      add('	__ewram_overlay_end  = ABSOLUTE(.);');
+      add('');
+      add('	__eheap_start = __ewram_overlay_end ;');
+      add('');
+      add('	_end = __ewram_overlay_end;');
+      add('	__end__ = __ewram_overlay_end;');
+      add('	__rom_end__ = __ewram_overlay_end;');
       add('');
       add('	/* Stabs debugging sections.  */');
       add('	.stab 0 : { *(.stab) }');
@@ -513,9 +505,9 @@ begin
       add('	.stab.index 0 : { *(.stab.index) }');
       add('	.stab.indexstr 0 : { *(.stab.indexstr) }');
       add('	.comment 0 : { *(.comment) }');
-      add('	/*	DWARF debug sections.');
-      add('		Symbols in the DWARF debugging sections are relative to the beginning');
-      add('		of the section so we begin them at 0.  */');
+      add('	/* DWARF debug sections.');
+      add('	   Symbols in the DWARF debugging sections are relative to the beginning');
+      add('	   of the section so we begin them at 0.  */');
       add('	/* DWARF 1 */');
       add('	.debug          0 : { *(.debug) }');
       add('	.line           0 : { *(.line) }');
@@ -540,9 +532,6 @@ begin
       add('	.debug_varnames  0 : { *(.debug_varnames) }');
       add('	.stack 0x80000 : { _stack = .; *(.stack) }');
       add('	/* These must appear regardless of  .  */');
-      add('  .note.gnu.arm.ident 0 : { KEEP (*(.note.gnu.arm.ident)) }');
-      add('  .ARM.attributes 0 : { KEEP (*(.ARM.attributes)) }');
-      add('  /DISCARD/ : { *(.note.GNU-stack) }');
       add('}');
     end;
 

+ 1 - 1
packages/libgbafpc/Makefile.fpc.fpcmake

@@ -34,4 +34,4 @@ nortl=y
 [rules]
 .NOTPARALLEL:
 core_asm$(OEXT):src/gba/core_asm.as
-        $(AS) -o $(UNITTARGETDIRPREFIX)core_asm$(OEXT) src/gba/core_asm.as
+        $(AS) src/gba/core_asm.as -o $(UNITTARGETDIRPREFIX)core_asm$(OEXT) 

+ 2 - 2
packages/libgbafpc/src/gba/gba_sound.inc

@@ -180,7 +180,7 @@ const
   DMGSNDCTRL_LSQR1   = $0100;
   DMGSNDCTRL_LSQR2   = $0200;
   DMGSNDCTRL_LTRI    = $0400;
-  DMGSNTCTRL_LNOISE  = $0800;
+  DMGSNDCTRL_LNOISE  = $0800;
   DMGSNDCTRL_RSQR1   = $1000;
   DMGSNDCTRL_RSQR2   = $2000;
   DMGSNDCTRL_RTRI    = $4000;
@@ -219,7 +219,7 @@ const
 function DSOUNDCTRL_ATIMER(x: integer): integer; inline; 
   
 const
-  DSOUNDCTRL_ARESET    = $0400;
+  DSOUNDCTRL_ARESET    = $0800;
   DSOUNDCTRL_BR        = $1000;
   DSOUNDCTRL_BL        = $2000;
   

+ 14 - 12
rtl/gba/cprt0.as

@@ -1,10 +1,12 @@
 @ (c) 2006 by devkitPro (http://www.devkitpro.org)
 
-
-	.section	".init"
+	.section	".crt0","ax"
 	.global     _start
 	.align
+
 	.arm
+	.cpu arm7tdmi
+
 @---------------------------------------------------------------------------------
 _start:
 @---------------------------------------------------------------------------------
@@ -46,8 +48,8 @@ __slave_number:
 	.word   0    				@ reserved
 	.word   0    				@ reserved
 
-    .global     start_vector
-    .align
+	.global     start_vector
+	.align
 @---------------------------------------------------------------------------------
 start_vector:
 @---------------------------------------------------------------------------------
@@ -107,16 +109,16 @@ SkipEWRAMClear:					@ Clear Internal WRAM to 0x00
 @---------------------------------------------------------------------------------
 @ Clear BSS section to 0x00
 @---------------------------------------------------------------------------------
-	ldr	r0, =__bss_start
-	ldr	r1, =__bss_end
+	ldr	r0, =__bss_start__
+	ldr	r1, =__bss_end__
 	sub	r1, r0
 	bl	ClearMem
 
 @---------------------------------------------------------------------------------
 @ Clear SBSS section to 0x00
 @---------------------------------------------------------------------------------
-	ldr	r0, =__sbss_start
-	ldr	r1, =__sbss_end
+	ldr	r0, =__sbss_start__
+	ldr	r1, =__sbss_end__
 	sub	r1, r0
 	bl	ClearMem
 
@@ -124,16 +126,16 @@ SkipEWRAMClear:					@ Clear Internal WRAM to 0x00
 @ Copy initialized data (data section) from LMA to VMA (ROM to RAM)
 @---------------------------------------------------------------------------------
 	ldr	r1, =__data_lma
-	ldr	r2, =__data_start
-	ldr	r4, =__data_end
+	ldr	r2, =__data_start__
+	ldr	r4, =__data_end__
 	bl	CopyMemChk
 
 @---------------------------------------------------------------------------------
 @ Copy internal work ram (iwram section) from LMA to VMA (ROM to RAM)
 @---------------------------------------------------------------------------------
 	ldr	r1,= __iwram_lma
-	ldr	r2,= __iwram_start
-	ldr	r4,= __iwram_end
+	ldr	r2,= __iwram_start__
+	ldr	r4,= __iwram_end__
 	bl	CopyMemChk
 
 @---------------------------------------------------------------------------------

+ 21 - 19
rtl/gba/prt0.as

@@ -1,10 +1,11 @@
 @ (c) 2006 by devkitPro (http://www.devkitpro.org)
-
-
-	.section	".init"
+	.section	".crt0","ax"
 	.global     _start
 	.align
+
 	.arm
+	.cpu arm7tdmi
+
 @---------------------------------------------------------------------------------
 _start:
 @---------------------------------------------------------------------------------
@@ -46,8 +47,8 @@ __slave_number:
 	.word   0    				@ reserved
 	.word   0    				@ reserved
 
-    .global     start_vector
-    .align
+	.global     start_vector
+	.align
 @---------------------------------------------------------------------------------
 start_vector:
 @---------------------------------------------------------------------------------
@@ -107,16 +108,16 @@ SkipEWRAMClear:					@ Clear Internal WRAM to 0x00
 @---------------------------------------------------------------------------------
 @ Clear BSS section to 0x00
 @---------------------------------------------------------------------------------
-	ldr	r0, =__bss_start
-	ldr	r1, =__bss_end
+	ldr	r0, =__bss_start__
+	ldr	r1, =__bss_end__
 	sub	r1, r0
 	bl	ClearMem
 
 @---------------------------------------------------------------------------------
 @ Clear SBSS section to 0x00
 @---------------------------------------------------------------------------------
-	ldr	r0, =__sbss_start
-	ldr	r1, =__sbss_end
+	ldr	r0, =__sbss_start__
+	ldr	r1, =__sbss_end__
 	sub	r1, r0
 	bl	ClearMem
 
@@ -124,16 +125,16 @@ SkipEWRAMClear:					@ Clear Internal WRAM to 0x00
 @ Copy initialized data (data section) from LMA to VMA (ROM to RAM)
 @---------------------------------------------------------------------------------
 	ldr	r1, =__data_lma
-	ldr	r2, =__data_start
-	ldr	r4, =__data_end
+	ldr	r2, =__data_start__
+	ldr	r4, =__data_end__
 	bl	CopyMemChk
 
 @---------------------------------------------------------------------------------
 @ Copy internal work ram (iwram section) from LMA to VMA (ROM to RAM)
 @---------------------------------------------------------------------------------
 	ldr	r1,= __iwram_lma
-	ldr	r2,= __iwram_start
-	ldr	r4,= __iwram_end
+	ldr	r2,= __iwram_start__
+	ldr	r4,= __iwram_end__
 	bl	CopyMemChk
 
 @---------------------------------------------------------------------------------
@@ -165,16 +166,17 @@ CEW0Skip:
 	ldr	r0, =__eheap_end
 	str	r0, [r1]
 @---------------------------------------------------------------------------------
+@ global constructors
+@---------------------------------------------------------------------------------
+	ldr	r3, =__libc_init_array
+	bl	_blx_r3_stub
+@---------------------------------------------------------------------------------
 @ Jump to user code
 @---------------------------------------------------------------------------------
 	mov	r0, #0				@ int argc
 	mov	r1, #0				@ char	*argv[]
-	ldr     r3,=main
-	bl      _blx_r3_stub
-	nop								@ This nop is here to allow unmapped memory to be used as
-                    @ as a delay of almost 1 sec with a 1 cycle resolution.
-                    @ Read this for technical info:
-                    @  http://www.devrs.com/gba/files/gbadevfaqs.php#RepeatUses
+	ldr	r3, =main
+	bl	_blx_r3_stub
 @---------------------------------------------------------------------------------
 @ Clear memory to 0x00 if length != 0
 @---------------------------------------------------------------------------------