added ds crtls

This commit is contained in:
Dave Murphy 2005-03-12 21:01:40 +00:00
parent 37b80cd1dd
commit 1454653b4e
10 changed files with 1351 additions and 0 deletions

293
dka-crtls/ds_arm7.ld Normal file
View File

@ -0,0 +1,293 @@
/* Linker Script Original v1.3 by Jeff Frohwein */
/* v1.0 - Original release */
/* v1.1 - Added proper .data section support */
/* v1.2 - Added support for c++ & iwram overlays */
/* - Major contributions by Jason Wilkins. */
/* v1.3 - .ewram section now can be used when */
/* compiling for MULTIBOOT mode. This fixes */
/* malloc() in DevKitAdvance which depends */
/* on __eheap_start instead of end to define*/
/* the starting location of heap space. */
/* External global variable __gba_iwram_heap*/
/* support added to allow labels end, _end, */
/* & __end__ to point to end of iwram or */
/* the end of ewram. */
/* */
/* Additions by WinterMute */
/* v1.4 - .sbss section added for unitialised */
/* data in ewram */
/* v1.5 - padding section added to stop EZF */
/* stripping important data */
/* Additions by Joat: */
/* v1.6 - Adapted for the DS */
/* This file is released into the public domain */
/* for commercial or non-commercial use with no */
/* restrictions placed upon it. */
/* NOTE!!!: This linker script defines the RAM & */
/* ROM start addresses. In order for it to work */
/* properly, remove -Ttext and -Tbss linker */
/* options from your makefile if they are */
/* present. */
/* You can use the following to view section */
/* addresses in your .elf file: */
/* objdump -h file.elf */
/* Please note that empty sections may incorrectly*/
/* list the lma address as the vma address for */
/* some versions of objdump. */
OUTPUT_FORMAT("elf32-littlearm", "elf32-bigarm", "elf32-littlearm")
OUTPUT_ARCH(arm)
ENTRY(_start)
/* SEARCH_DIR(/bin/arm); */
/* The linker script function "var1 += var2;" sometimes */
/* reports incorrect values in the *.map file but the */
/* actual value it calculates is usually, if not always, */
/* correct. If you leave out the ". = ALIGN(4);" at the */
/* end of each section then the return value of SIZEOF() */
/* is sometimes incorrect and "var1 += var2;" appears to */
/* not work as well. "var1 += var2" style functions are */
/* avoided below as a result. */
/* The linker script MEMORY directive is not used here due */
/* to the fact that __text_start is not always a fixed value. */
__ewram_start = 0x03800000;
/*__ewram_start = 0x023C0000;*/
__text_start = 0x02380000;
__eheap_end = 0x03810000 - 0x1000;
/*__eheap_end = 0x02400000;*/
__iwram_start = 0x03810000 - 0x800;/* tiny, error */
__iheap_end = 0x03810000 - 0x400;
__sp_usr = 0x03810000 - 0x140;
__sp_irq = 0x03810000 - 0x60;
__sp_usr_offset = __sp_usr - __iwram_start;
SECTIONS
{
. = __text_start;
.init :
{
KEEP (*(.init))
. = ALIGN(4);
} =0xff
.plt :
{
*(.plt)
. = ALIGN(4); /* REQUIRED. LD is flaky without it. */
}
.text : /* ALIGN (4): */
{
*(EXCLUDE_FILE (*.iwram*) .text)
*(.text.*)
*(.stub)
/* .gnu.warning sections are handled specially by elf32.em. */
*(.gnu.warning)
*(.gnu.linkonce.t*)
*(.glue_7)
*(.glue_7t)
. = ALIGN(4); /* REQUIRED. LD is flaky without it. */
} = 0xff
__text_end = .;
.fini :
{
KEEP (*(.fini))
. = ALIGN(4); /* REQUIRED. LD is flaky without it. */
} =0
.rodata :
{
*(.rodata)
*all.rodata*(*)
*(.roda)
*(.rodata.*)
*(.gnu.linkonce.r*)
SORT(CONSTRUCTORS)
. = ALIGN(4); /* REQUIRED. LD is flaky without it. */
} = 0xff
.ctors :
{
/* gcc uses crtbegin.o to find the start of the constructors, so
we make sure it is first. Because this is a wildcard, it
doesn't matter if the user does not actually link against
crtbegin.o; the linker won't look for a file to match a
wildcard. The wildcard also means that it doesn't matter which
directory crtbegin.o is in. */
KEEP (*crtbegin.o(.ctors))
KEEP (*(EXCLUDE_FILE (*crtend.o) .ctors))
KEEP (*(SORT(.ctors.*)))
KEEP (*(.ctors))
. = ALIGN(4); /* REQUIRED. LD is flaky without it. */
} = 0
.dtors :
{
KEEP (*crtbegin.o(.dtors))
KEEP (*(EXCLUDE_FILE (*crtend.o) .dtors))
KEEP (*(SORT(.dtors.*)))
KEEP (*(.dtors))
. = ALIGN(4); /* REQUIRED. LD is flaky without it. */
} = 0
.jcr : { KEEP (*(.jcr)) }
/* laddr = ADDR(.init) + SIZEOF(.init) + SIZEOF(.text) + SIZEOF(.fini) + SIZEOF(.rodata) + SIZEOF(.ctors) + SIZEOF(.dtors);
*/
.eh_frame :
{
KEEP (*(.eh_frame))
. = ALIGN(4); /* REQUIRED. LD is flaky without it. */
} = 0
.gcc_except_table :
{
*(.gcc_except_table)
. = ALIGN(4); /* REQUIRED. LD is flaky without it. */
} = 0
__iwram_lma = .;
.iwram __iwram_start : AT (__iwram_lma)
{
__iwram_start = ABSOLUTE(.) ;
*(.iwram)
*iwram.*(.text)
. = ALIGN(4); /* REQUIRED. LD is flaky without it. */
} = 0xff
__data_lma = __iwram_lma + SIZEOF(.iwram) ;
__iwram_end = . ;
.bss ALIGN(4) :
{
__bss_start = ABSOLUTE(.);
__bss_start__ = ABSOLUTE(.);
*(.dynbss)
*(.gnu.linkonce.b*)
*(COMMON)
. = ALIGN(4); /* REQUIRED. LD is flaky without it. */
}
__bss_end = . ;
__bss_end__ = . ;
.data ALIGN(4) : AT (__data_lma)
{
__data_start = ABSOLUTE(.);
*(.data)
*(.data.*)
*(.gnu.linkonce.d*)
CONSTRUCTORS
} = 0xff
__iwram_overlay_lma = __data_lma + SIZEOF(.data);
__data_end = .;
PROVIDE (edata = .);
__iwram_overlay_start = . ;
OVERLAY : NOCROSSREFS AT (__iwram_overlay_lma)
{
.iwram0 { *(.iwram0) . = ALIGN(4);}
.iwram1 { *(.iwram1) . = ALIGN(4);}
.iwram2 { *(.iwram2) . = ALIGN(4);}
.iwram3 { *(.iwram3) . = ALIGN(4);}
.iwram4 { *(.iwram4) . = ALIGN(4);}
.iwram5 { *(.iwram5) . = ALIGN(4);}
.iwram6 { *(.iwram6) . = ALIGN(4);}
.iwram7 { *(.iwram7) . = ALIGN(4);}
.iwram8 { *(.iwram8) . = ALIGN(4);}
.iwram9 { *(.iwram9) . = ALIGN(4);}
} = 0xff
__ewram_lma = LOADADDR(.iwram0) + SIZEOF(.iwram0)+SIZEOF(.iwram1)+SIZEOF(.iwram2)+SIZEOF(.iwram3)+SIZEOF(.iwram4)+SIZEOF(.iwram5)+SIZEOF(.iwram6)+SIZEOF(.iwram7)+SIZEOF(.iwram8)+SIZEOF(.iwram9);
__iwram_overlay_end = . ;
__iheap_start = . ;
.ewram __ewram_start : AT (__ewram_lma)
{
*(.ewram)
. = ALIGN(4); /* REQUIRED. LD is flaky without it. */
} = 0xff
__ewram_overlay_lma = __ewram_lma + SIZEOF(.ewram);
.sbss ALIGN(4):
{
*(.sbss)
. = ALIGN(4);
}
__ewram_end = . ;
__ewram_overlay_start = . ;
OVERLAY ALIGN(4): NOCROSSREFS AT (__ewram_overlay_lma)
{
.ewram0 { *(.ewram0) . = ALIGN(4);}
.ewram1 { *(.ewram1) . = ALIGN(4);}
.ewram2 { *(.ewram2) . = ALIGN(4);}
.ewram3 { *(.ewram3) . = ALIGN(4);}
.ewram4 { *(.ewram4) . = ALIGN(4);}
.ewram5 { *(.ewram5) . = ALIGN(4);}
.ewram6 { *(.ewram6) . = ALIGN(4);}
.ewram7 { *(.ewram7) . = ALIGN(4);}
.ewram8 { *(.ewram8) . = ALIGN(4);}
.ewram9 { *(.ewram9) . = ALIGN(4);}
} = 0xff
__pad_lma = LOADADDR(.ewram0) + SIZEOF(.ewram0)+SIZEOF(.ewram1)+SIZEOF(.ewram2)+SIZEOF(.ewram3)+SIZEOF(.ewram4)+SIZEOF(.ewram5)+SIZEOF(.ewram6)+SIZEOF(.ewram7)+SIZEOF(.ewram8)+SIZEOF(.ewram9);
/* EZF Advance strips trailing 0xff bytes, add a pad section so nothing important is removed */
.pad ALIGN(4) : AT (__pad_lma)
{
LONG(0x52416b64)
LONG(0x4d)
. = ALIGN(4); /* REQUIRED. LD is flaky without it. */
} = 0xff
__ewram_overlay_end = . ;
__eheap_start = . ;
_end = .;
__end__ = _end ; /* v1.3 */
PROVIDE (end = _end); /* v1.3 */
/* Stabs debugging sections. */
.stab 0 : { *(.stab) }
.stabstr 0 : { *(.stabstr) }
.stab.excl 0 : { *(.stab.excl) }
.stab.exclstr 0 : { *(.stab.exclstr) }
.stab.index 0 : { *(.stab.index) }
.stab.indexstr 0 : { *(.stab.indexstr) }
.comment 0 : { *(.comment) }
/* DWARF debug sections.
Symbols in the DWARF debugging sections are relative to the beginning
of the section so we begin them at 0. */
/* DWARF 1 */
.debug 0 : { *(.debug) }
.line 0 : { *(.line) }
/* GNU DWARF 1 extensions */
.debug_srcinfo 0 : { *(.debug_srcinfo) }
.debug_sfnames 0 : { *(.debug_sfnames) }
/* DWARF 1.1 and DWARF 2 */
.debug_aranges 0 : { *(.debug_aranges) }
.debug_pubnames 0 : { *(.debug_pubnames) }
/* DWARF 2 */
.debug_info 0 : { *(.debug_info) }
.debug_abbrev 0 : { *(.debug_abbrev) }
.debug_line 0 : { *(.debug_line) }
.debug_frame 0 : { *(.debug_frame) }
.debug_str 0 : { *(.debug_str) }
.debug_loc 0 : { *(.debug_loc) }
.debug_macinfo 0 : { *(.debug_macinfo) }
/* SGI/MIPS DWARF 2 extensions */
.debug_weaknames 0 : { *(.debug_weaknames) }
.debug_funcnames 0 : { *(.debug_funcnames) }
.debug_typenames 0 : { *(.debug_typenames) }
.debug_varnames 0 : { *(.debug_varnames) }
.stack 0x80000 : { _stack = .; *(.stack) }
/* These must appear regardless of . */
}

8
dka-crtls/ds_arm7.specs Normal file
View File

@ -0,0 +1,8 @@
%rename link old_link
*link:
%(old_link) -T ds_arm7.ld%s
*startfile:
ds_arm7_crt0%O%s crti%O%s crtbegin%O%s

130
dka-crtls/ds_arm7_crt0.S Normal file
View File

@ -0,0 +1,130 @@
.section ".init"
.global _start
@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
.align 4
.arm
_start:
mov r0, #0x04000000 @ IME = 0;
add r0, r0, #0x208
strh r0, [r0]
mov r0, #0x12 @ Switch to IRQ Mode
msr cpsr, r0
ldr sp, =__sp_irq @ Set IRQ stack
mov r0, #0x1F @ Switch to System Mode
msr cpsr, r0
ldr sp, =__sp_usr @ Set user stack
ldr r0, =__bss_start @ Clear BSS section to 0x00
ldr r1, =__bss_end
sub r1, r1, r0
bl ClearMem
ldr r1, =__data_lma @ Copy initialized data (data section) from LMA to VMA (ROM to RAM)
ldr r2, =__data_start
ldr r4, =__data_end
bl CopyMemCheck
ldr r1, =__iwram_lma @ Copy internal work ram (iwram section) from LMA to VMA (ROM to RAM)
ldr r2, =__iwram_start
ldr r4, =__iwram_end
bl CopyMemCheck
ldr r2, =__load_stop_iwram0 @ Copy internal work ram overlay 0 (iwram0 section) from LMA to VMA (ROM to RAM)
ldr r1, =__load_start_iwram0
subs r3, r2, r1 @ Is there any data to copy?
beq CIW0Skip @ no
ldr r2, =__iwram_overlay_start
bl CopyMem
CIW0Skip:
ldr r1, =__ewram_lma @ Copy external work ram (ewram section) from LMA to VMA (ROM to RAM)
ldr r2, =__ewram_start
ldr r4, =__ewram_end
bl CopyMemCheck
ldr r2, =__load_stop_ewram0 @ @ Copy external work ram overlay 0 (ewram0 section) from LMA to VMA (ROM to RAM)
ldr r1, =__load_start_ewram0
subs r3, r2, r1 @ Is there any data to copy?
beq CEW0Skip @ no
ldr r2, =__ewram_overlay_start
bl CopyMem
CEW0Skip:
ldr r1, =fake_heap_end @ set heap end
ldr r0, =__eheap_end
str r0, [r1]
ldr r3, =_init @ global constructors
bl _call_via_r3
mov r0, #0 @ int argc
mov r1, #0 @ char *argv[]
ldr r3, =main
bl _call_via_r3 @ jump to user code
@ If the user ever returns, return to flash cartridge
mov r0, #0x08000000
bx r0
@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
@
@ Clear memory to 0x00 if length != 0
@ r0 = Start Address
@ r1 = Length
@
@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
ClearMem: mov r2, #3 @ Round down to nearest word boundary
add r1, r1, r2 @ Shouldn't be needed
bics r1, r1, r2 @ Clear 2 LSB (and set Z)
bxeq lr @ Quit if copy size is 0
mov r2, #0
ClrLoop: stmia r0!, {r2}
subs r1, r1, #4
bne ClrLoop
bx lr
@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
@
@ Copy memory if length != 0
@ r1 = Source Address
@ r2 = Dest Address
@ r4 = Dest Address + Length
@
@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
CopyMemCheck:
sub r3, r4, r2 @ Is there any data to copy?
@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
@
@ Copy memory
@ r1 = Source Address
@ r2 = Dest Address
@ r3 = Length
@
@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
CopyMem: mov r0, #3 @ These commands are used in cases where
add r3, r3, r0 @ the length is not a multiple of 4,
bics r3, r3, r0 @ even though it should be.
bxeq lr @ Length is zero, so exit
CIDLoop: ldmia r1!, {r0}
stmia r2!, {r0}
subs r3, r3, #4
bne CIDLoop
bx lr
@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
.align
.pool
.end

294
dka-crtls/ds_arm7cart.ld Normal file
View File

@ -0,0 +1,294 @@
/* Linker Script Original v1.3 by Jeff Frohwein */
/* v1.0 - Original release */
/* v1.1 - Added proper .data section support */
/* v1.2 - Added support for c++ & iwram overlays */
/* - Major contributions by Jason Wilkins. */
/* v1.3 - .ewram section now can be used when */
/* compiling for MULTIBOOT mode. This fixes */
/* malloc() in DevKitAdvance which depends */
/* on __eheap_start instead of end to define*/
/* the starting location of heap space. */
/* External global variable __gba_iwram_heap*/
/* support added to allow labels end, _end, */
/* & __end__ to point to end of iwram or */
/* the end of ewram. */
/* */
/* Additions by WinterMute */
/* v1.4 - .sbss section added for unitialised */
/* data in ewram */
/* v1.5 - padding section added to stop EZF */
/* stripping important data */
/* Additions by Joat: */
/* v1.6 - Adapted for the DS */
/* This file is released into the public domain */
/* for commercial or non-commercial use with no */
/* restrictions placed upon it. */
/* NOTE!!!: This linker script defines the RAM & */
/* ROM start addresses. In order for it to work */
/* properly, remove -Ttext and -Tbss linker */
/* options from your makefile if they are */
/* present. */
/* You can use the following to view section */
/* addresses in your .elf file: */
/* objdump -h file.elf */
/* Please note that empty sections may incorrectly*/
/* list the lma address as the vma address for */
/* some versions of objdump. */
OUTPUT_FORMAT("elf32-littlearm", "elf32-bigarm", "elf32-littlearm")
OUTPUT_ARCH(arm)
ENTRY(_start)
/* SEARCH_DIR(/bin/arm); */
/* By default this linker script will generate code */
/* for flash carts located at 0x8000000. */
/* The linker script function "var1 += var2;" sometimes */
/* reports incorrect values in the *.map file but the */
/* actual value it calculates is usually, if not always, */
/* correct. If you leave out the ". = ALIGN(4);" at the */
/* end of each section then the return value of SIZEOF() */
/* is sometimes incorrect and "var1 += var2;" appears to */
/* not work as well. "var1 += var2" style functions are */
/* avoided below as a result. */
/* The linker script MEMORY directive is not used here due */
/* to the fact that __text_start is not always a fixed value. */
__text_start = 0x08000000;
__eheap_end = 0x03802000;
__ewram_start = 0x03800000;
__iwram_start = 0x03802000;
__iheap_end = 0x03810000 - 0x400;
__sp_usr = 0x03810000 - 0x100;
__sp_irq = 0x03810000 - 0x60;
__sp_usr_offset = __sp_usr - __iwram_start;
SECTIONS
{
. = __text_start;
.init :
{
KEEP (*(.init))
. = ALIGN(4);
} =0xff
.plt :
{
*(.plt)
. = ALIGN(4); /* REQUIRED. LD is flaky without it. */
}
.text : /* ALIGN (4): */
{
*(EXCLUDE_FILE (*.iwram*) .text)
*(.text.*)
*(.stub)
/* .gnu.warning sections are handled specially by elf32.em. */
*(.gnu.warning)
*(.gnu.linkonce.t*)
*(.glue_7)
*(.glue_7t)
. = ALIGN(4); /* REQUIRED. LD is flaky without it. */
} = 0xff
__text_end = .;
.fini :
{
KEEP (*(.fini))
. = ALIGN(4); /* REQUIRED. LD is flaky without it. */
} =0
.rodata :
{
*(.rodata)
*all.rodata*(*)
*(.roda)
*(.rodata.*)
*(.gnu.linkonce.r*)
SORT(CONSTRUCTORS)
. = ALIGN(4); /* REQUIRED. LD is flaky without it. */
} = 0xff
.ctors :
{
/* gcc uses crtbegin.o to find the start of the constructors, so
we make sure it is first. Because this is a wildcard, it
doesn't matter if the user does not actually link against
crtbegin.o; the linker won't look for a file to match a
wildcard. The wildcard also means that it doesn't matter which
directory crtbegin.o is in. */
KEEP (*crtbegin.o(.ctors))
KEEP (*(EXCLUDE_FILE (*crtend.o) .ctors))
KEEP (*(SORT(.ctors.*)))
KEEP (*(.ctors))
. = ALIGN(4); /* REQUIRED. LD is flaky without it. */
} = 0
.dtors :
{
KEEP (*crtbegin.o(.dtors))
KEEP (*(EXCLUDE_FILE (*crtend.o) .dtors))
KEEP (*(SORT(.dtors.*)))
KEEP (*(.dtors))
. = ALIGN(4); /* REQUIRED. LD is flaky without it. */
} = 0
.jcr : { KEEP (*(.jcr)) }
/* laddr = ADDR(.init) + SIZEOF(.init) + SIZEOF(.text) + SIZEOF(.fini) + SIZEOF(.rodata) + SIZEOF(.ctors) + SIZEOF(.dtors);
*/
.eh_frame :
{
KEEP (*(.eh_frame))
. = ALIGN(4); /* REQUIRED. LD is flaky without it. */
} = 0
.gcc_except_table :
{
*(.gcc_except_table)
. = ALIGN(4); /* REQUIRED. LD is flaky without it. */
} = 0
__iwram_lma = .;
.iwram __iwram_start : AT (__iwram_lma)
{
__iwram_start = ABSOLUTE(.) ;
*(.iwram)
*iwram.*(.text)
. = ALIGN(4); /* REQUIRED. LD is flaky without it. */
} = 0xff
__data_lma = __iwram_lma + SIZEOF(.iwram) ;
__iwram_end = . ;
.bss ALIGN(4) :
{
__bss_start = ABSOLUTE(.);
__bss_start__ = ABSOLUTE(.);
*(.dynbss)
*(.gnu.linkonce.b*)
*(COMMON)
. = ALIGN(4); /* REQUIRED. LD is flaky without it. */
}
__bss_end = . ;
__bss_end__ = . ;
.data ALIGN(4) : AT (__data_lma)
{
__data_start = ABSOLUTE(.);
*(.data)
*(.data.*)
*(.gnu.linkonce.d*)
CONSTRUCTORS
} = 0xff
__iwram_overlay_lma = __data_lma + SIZEOF(.data);
__data_end = .;
PROVIDE (edata = .);
__iwram_overlay_start = . ;
OVERLAY : NOCROSSREFS AT (__iwram_overlay_lma)
{
.iwram0 { *(.iwram0) . = ALIGN(4);}
.iwram1 { *(.iwram1) . = ALIGN(4);}
.iwram2 { *(.iwram2) . = ALIGN(4);}
.iwram3 { *(.iwram3) . = ALIGN(4);}
.iwram4 { *(.iwram4) . = ALIGN(4);}
.iwram5 { *(.iwram5) . = ALIGN(4);}
.iwram6 { *(.iwram6) . = ALIGN(4);}
.iwram7 { *(.iwram7) . = ALIGN(4);}
.iwram8 { *(.iwram8) . = ALIGN(4);}
.iwram9 { *(.iwram9) . = ALIGN(4);}
} = 0xff
__ewram_lma = LOADADDR(.iwram0) + SIZEOF(.iwram0)+SIZEOF(.iwram1)+SIZEOF(.iwram2)+SIZEOF(.iwram3)+SIZEOF(.iwram4)+SIZEOF(.iwram5)+SIZEOF(.iwram6)+SIZEOF(.iwram7)+SIZEOF(.iwram8)+SIZEOF(.iwram9);
__iwram_overlay_end = . ;
__iheap_start = . ;
.ewram __ewram_start : AT (__ewram_lma)
{
*(.ewram)
. = ALIGN(4); /* REQUIRED. LD is flaky without it. */
} = 0xff
__ewram_overlay_lma = __ewram_lma + SIZEOF(.ewram);
.sbss ALIGN(4):
{
*(.sbss)
. = ALIGN(4);
}
__ewram_end = . ;
__ewram_overlay_start = . ;
OVERLAY ALIGN(4): NOCROSSREFS AT (__ewram_overlay_lma)
{
.ewram0 { *(.ewram0) . = ALIGN(4);}
.ewram1 { *(.ewram1) . = ALIGN(4);}
.ewram2 { *(.ewram2) . = ALIGN(4);}
.ewram3 { *(.ewram3) . = ALIGN(4);}
.ewram4 { *(.ewram4) . = ALIGN(4);}
.ewram5 { *(.ewram5) . = ALIGN(4);}
.ewram6 { *(.ewram6) . = ALIGN(4);}
.ewram7 { *(.ewram7) . = ALIGN(4);}
.ewram8 { *(.ewram8) . = ALIGN(4);}
.ewram9 { *(.ewram9) . = ALIGN(4);}
} = 0xff
__pad_lma = LOADADDR(.ewram0) + SIZEOF(.ewram0)+SIZEOF(.ewram1)+SIZEOF(.ewram2)+SIZEOF(.ewram3)+SIZEOF(.ewram4)+SIZEOF(.ewram5)+SIZEOF(.ewram6)+SIZEOF(.ewram7)+SIZEOF(.ewram8)+SIZEOF(.ewram9);
/* EZF Advance strips trailing 0xff bytes, add a pad section so nothing important is removed */
.pad ALIGN(4) : AT (__pad_lma)
{
LONG(0x52416b64)
LONG(0x4d)
. = ALIGN(4); /* REQUIRED. LD is flaky without it. */
} = 0xff
__ewram_overlay_end = . ;
__eheap_start = . ;
_end = .;
__end__ = _end ; /* v1.3 */
PROVIDE (end = _end); /* v1.3 */
/* Stabs debugging sections. */
.stab 0 : { *(.stab) }
.stabstr 0 : { *(.stabstr) }
.stab.excl 0 : { *(.stab.excl) }
.stab.exclstr 0 : { *(.stab.exclstr) }
.stab.index 0 : { *(.stab.index) }
.stab.indexstr 0 : { *(.stab.indexstr) }
.comment 0 : { *(.comment) }
/* DWARF debug sections.
Symbols in the DWARF debugging sections are relative to the beginning
of the section so we begin them at 0. */
/* DWARF 1 */
.debug 0 : { *(.debug) }
.line 0 : { *(.line) }
/* GNU DWARF 1 extensions */
.debug_srcinfo 0 : { *(.debug_srcinfo) }
.debug_sfnames 0 : { *(.debug_sfnames) }
/* DWARF 1.1 and DWARF 2 */
.debug_aranges 0 : { *(.debug_aranges) }
.debug_pubnames 0 : { *(.debug_pubnames) }
/* DWARF 2 */
.debug_info 0 : { *(.debug_info) }
.debug_abbrev 0 : { *(.debug_abbrev) }
.debug_line 0 : { *(.debug_line) }
.debug_frame 0 : { *(.debug_frame) }
.debug_str 0 : { *(.debug_str) }
.debug_loc 0 : { *(.debug_loc) }
.debug_macinfo 0 : { *(.debug_macinfo) }
/* SGI/MIPS DWARF 2 extensions */
.debug_weaknames 0 : { *(.debug_weaknames) }
.debug_funcnames 0 : { *(.debug_funcnames) }
.debug_typenames 0 : { *(.debug_typenames) }
.debug_varnames 0 : { *(.debug_varnames) }
.stack 0x80000 : { _stack = .; *(.stack) }
/* These must appear regardless of . */
}

View File

@ -0,0 +1,8 @@
%rename link old_link
*link:
%(old_link) -T ds_arm7cart.ld%s
*startfile:
ds_cart_crt0%O%s crti%O%s crtbegin%O%s

291
dka-crtls/ds_arm9.ld Normal file
View File

@ -0,0 +1,291 @@
/* Linker Script Original v1.3 by Jeff Frohwein */
/* v1.0 - Original release */
/* v1.1 - Added proper .data section support */
/* v1.2 - Added support for c++ & iwram overlays */
/* - Major contributions by Jason Wilkins. */
/* v1.3 - .ewram section now can be used when */
/* compiling for MULTIBOOT mode. This fixes */
/* malloc() in DevKitAdvance which depends */
/* on __eheap_start instead of end to define*/
/* the starting location of heap space. */
/* External global variable __gba_iwram_heap*/
/* support added to allow labels end, _end, */
/* & __end__ to point to end of iwram or */
/* the end of ewram. */
/* */
/* Additions by WinterMute */
/* v1.4 - .sbss section added for unitialised */
/* data in ewram */
/* v1.5 - padding section added to stop EZF */
/* stripping important data */
/* Additions by Joat: */
/* v1.6 - Adapted for the DS */
/* This file is released into the public domain */
/* for commercial or non-commercial use with no */
/* restrictions placed upon it. */
/* NOTE!!!: This linker script defines the RAM & */
/* ROM start addresses. In order for it to work */
/* properly, remove -Ttext and -Tbss linker */
/* options from your makefile if they are */
/* present. */
/* You can use the following to view section */
/* addresses in your .elf file: */
/* objdump -h file.elf */
/* Please note that empty sections may incorrectly*/
/* list the lma address as the vma address for */
/* some versions of objdump. */
OUTPUT_FORMAT("elf32-littlearm", "elf32-bigarm", "elf32-littlearm")
OUTPUT_ARCH(arm)
ENTRY(_start)
/* SEARCH_DIR(/bin/arm); */
/* The linker script function "var1 += var2;" sometimes */
/* reports incorrect values in the *.map file but the */
/* actual value it calculates is usually, if not always, */
/* correct. If you leave out the ". = ALIGN(4);" at the */
/* end of each section then the return value of SIZEOF() */
/* is sometimes incorrect and "var1 += var2;" appears to */
/* not work as well. "var1 += var2" style functions are */
/* avoided below as a result. */
/* The linker script MEMORY directive is not used here due */
/* to the fact that __text_start is not always a fixed value. */
__ewram_start = 0x02001000;
__text_start = 0x02004000;
__eheap_end = 0x02380000;
__iwram_start = 0x00800000;
__iheap_end = 0x00804000 - 0x400;
__sp_usr = 0x00804000 - 0x140;
__sp_irq = 0x00804000 - 0x60;
__sp_usr_offset = __sp_usr - __iwram_start;
SECTIONS
{
. = __text_start;
.init :
{
KEEP (*(.init))
. = ALIGN(4);
} =0xff
.plt :
{
*(.plt)
. = ALIGN(4); /* REQUIRED. LD is flaky without it. */
}
.text : /* ALIGN (4): */
{
*(EXCLUDE_FILE (*.iwram*) .text)
*(.text.*)
*(.stub)
/* .gnu.warning sections are handled specially by elf32.em. */
*(.gnu.warning)
*(.gnu.linkonce.t*)
*(.glue_7)
*(.glue_7t)
. = ALIGN(4); /* REQUIRED. LD is flaky without it. */
} = 0xff
__text_end = .;
.fini :
{
KEEP (*(.fini))
. = ALIGN(4); /* REQUIRED. LD is flaky without it. */
} =0
.rodata :
{
*(.rodata)
*all.rodata*(*)
*(.roda)
*(.rodata.*)
*(.gnu.linkonce.r*)
SORT(CONSTRUCTORS)
. = ALIGN(4); /* REQUIRED. LD is flaky without it. */
} = 0xff
.ctors :
{
/* gcc uses crtbegin.o to find the start of the constructors, so
we make sure it is first. Because this is a wildcard, it
doesn't matter if the user does not actually link against
crtbegin.o; the linker won't look for a file to match a
wildcard. The wildcard also means that it doesn't matter which
directory crtbegin.o is in. */
KEEP (*crtbegin.o(.ctors))
KEEP (*(EXCLUDE_FILE (*crtend.o) .ctors))
KEEP (*(SORT(.ctors.*)))
KEEP (*(.ctors))
. = ALIGN(4); /* REQUIRED. LD is flaky without it. */
} = 0
.dtors :
{
KEEP (*crtbegin.o(.dtors))
KEEP (*(EXCLUDE_FILE (*crtend.o) .dtors))
KEEP (*(SORT(.dtors.*)))
KEEP (*(.dtors))
. = ALIGN(4); /* REQUIRED. LD is flaky without it. */
} = 0
.jcr : { KEEP (*(.jcr)) }
/* laddr = ADDR(.init) + SIZEOF(.init) + SIZEOF(.text) + SIZEOF(.fini) + SIZEOF(.rodata) + SIZEOF(.ctors) + SIZEOF(.dtors);
*/
.eh_frame :
{
KEEP (*(.eh_frame))
. = ALIGN(4); /* REQUIRED. LD is flaky without it. */
} = 0
.gcc_except_table :
{
*(.gcc_except_table)
. = ALIGN(4); /* REQUIRED. LD is flaky without it. */
} = 0
__iwram_lma = .;
.iwram __iwram_start : AT (__iwram_lma)
{
__iwram_start = ABSOLUTE(.) ;
*(.iwram)
*iwram.*(.text)
. = ALIGN(4); /* REQUIRED. LD is flaky without it. */
} = 0xff
__data_lma = __iwram_lma + SIZEOF(.iwram) ;
__iwram_end = . ;
.bss ALIGN(4) :
{
__bss_start = ABSOLUTE(.);
__bss_start__ = ABSOLUTE(.);
*(.dynbss)
*(.gnu.linkonce.b*)
*(COMMON)
. = ALIGN(4); /* REQUIRED. LD is flaky without it. */
}
__bss_end = . ;
__bss_end__ = . ;
.data ALIGN(4) : AT (__data_lma)
{
__data_start = ABSOLUTE(.);
*(.data)
*(.data.*)
*(.gnu.linkonce.d*)
CONSTRUCTORS
} = 0xff
__iwram_overlay_lma = __data_lma + SIZEOF(.data);
__data_end = .;
PROVIDE (edata = .);
__iwram_overlay_start = . ;
OVERLAY : NOCROSSREFS AT (__iwram_overlay_lma)
{
.iwram0 { *(.iwram0) . = ALIGN(4);}
.iwram1 { *(.iwram1) . = ALIGN(4);}
.iwram2 { *(.iwram2) . = ALIGN(4);}
.iwram3 { *(.iwram3) . = ALIGN(4);}
.iwram4 { *(.iwram4) . = ALIGN(4);}
.iwram5 { *(.iwram5) . = ALIGN(4);}
.iwram6 { *(.iwram6) . = ALIGN(4);}
.iwram7 { *(.iwram7) . = ALIGN(4);}
.iwram8 { *(.iwram8) . = ALIGN(4);}
.iwram9 { *(.iwram9) . = ALIGN(4);}
} = 0xff
__ewram_lma = LOADADDR(.iwram0) + SIZEOF(.iwram0)+SIZEOF(.iwram1)+SIZEOF(.iwram2)+SIZEOF(.iwram3)+SIZEOF(.iwram4)+SIZEOF(.iwram5)+SIZEOF(.iwram6)+SIZEOF(.iwram7)+SIZEOF(.iwram8)+SIZEOF(.iwram9);
__iwram_overlay_end = . ;
__iheap_start = . ;
.ewram __ewram_start : AT (__ewram_lma)
{
*(.ewram)
. = ALIGN(4); /* REQUIRED. LD is flaky without it. */
} = 0xff
__ewram_overlay_lma = __ewram_lma + SIZEOF(.ewram);
.sbss ALIGN(4):
{
*(.sbss)
. = ALIGN(4);
}
__ewram_end = . ;
__ewram_overlay_start = . ;
OVERLAY ALIGN(4): NOCROSSREFS AT (__ewram_overlay_lma)
{
.ewram0 { *(.ewram0) . = ALIGN(4);}
.ewram1 { *(.ewram1) . = ALIGN(4);}
.ewram2 { *(.ewram2) . = ALIGN(4);}
.ewram3 { *(.ewram3) . = ALIGN(4);}
.ewram4 { *(.ewram4) . = ALIGN(4);}
.ewram5 { *(.ewram5) . = ALIGN(4);}
.ewram6 { *(.ewram6) . = ALIGN(4);}
.ewram7 { *(.ewram7) . = ALIGN(4);}
.ewram8 { *(.ewram8) . = ALIGN(4);}
.ewram9 { *(.ewram9) . = ALIGN(4);}
} = 0xff
__pad_lma = LOADADDR(.ewram0) + SIZEOF(.ewram0)+SIZEOF(.ewram1)+SIZEOF(.ewram2)+SIZEOF(.ewram3)+SIZEOF(.ewram4)+SIZEOF(.ewram5)+SIZEOF(.ewram6)+SIZEOF(.ewram7)+SIZEOF(.ewram8)+SIZEOF(.ewram9);
/* EZF Advance strips trailing 0xff bytes, add a pad section so nothing important is removed */
.pad ALIGN(4) : AT (__pad_lma)
{
LONG(0x52416b64)
LONG(0x4d)
. = ALIGN(4); /* REQUIRED. LD is flaky without it. */
} = 0xff
__ewram_overlay_end = . ;
__eheap_start = . ;
_end = .;
__end__ = _end ; /* v1.3 */
PROVIDE (end = _end); /* v1.3 */
/* Stabs debugging sections. */
.stab 0 : { *(.stab) }
.stabstr 0 : { *(.stabstr) }
.stab.excl 0 : { *(.stab.excl) }
.stab.exclstr 0 : { *(.stab.exclstr) }
.stab.index 0 : { *(.stab.index) }
.stab.indexstr 0 : { *(.stab.indexstr) }
.comment 0 : { *(.comment) }
/* DWARF debug sections.
Symbols in the DWARF debugging sections are relative to the beginning
of the section so we begin them at 0. */
/* DWARF 1 */
.debug 0 : { *(.debug) }
.line 0 : { *(.line) }
/* GNU DWARF 1 extensions */
.debug_srcinfo 0 : { *(.debug_srcinfo) }
.debug_sfnames 0 : { *(.debug_sfnames) }
/* DWARF 1.1 and DWARF 2 */
.debug_aranges 0 : { *(.debug_aranges) }
.debug_pubnames 0 : { *(.debug_pubnames) }
/* DWARF 2 */
.debug_info 0 : { *(.debug_info) }
.debug_abbrev 0 : { *(.debug_abbrev) }
.debug_line 0 : { *(.debug_line) }
.debug_frame 0 : { *(.debug_frame) }
.debug_str 0 : { *(.debug_str) }
.debug_loc 0 : { *(.debug_loc) }
.debug_macinfo 0 : { *(.debug_macinfo) }
/* SGI/MIPS DWARF 2 extensions */
.debug_weaknames 0 : { *(.debug_weaknames) }
.debug_funcnames 0 : { *(.debug_funcnames) }
.debug_typenames 0 : { *(.debug_typenames) }
.debug_varnames 0 : { *(.debug_varnames) }
.stack 0x80000 : { _stack = .; *(.stack) }
/* These must appear regardless of . */
}

8
dka-crtls/ds_arm9.specs Normal file
View File

@ -0,0 +1,8 @@
%rename link old_link
*link:
%(old_link) -T ds_arm9.ld%s
*startfile:
ds_arm9_crt0%O%s crti%O%s crtbegin%O%s

143
dka-crtls/ds_arm9_crt0.S Normal file
View File

@ -0,0 +1,143 @@
.section ".init"
.global _start
@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
.align 4
.arm
_start:
mov r0, #0x04000000 @ IME = 0;
add r0, r0, #0x208
strh r0, [r0]
ldr r1, =0x00002078 @ disable DTCM and protection unit
mcr p15, 0, r1, c1, c0
ldr r0, =0x0080000A
mcr p15, 0, r0, c9, c1 @ TCM base = 0x00800*4096, size = 16 KB
mrc p15, 0, r0, c1, c0 @ throw-away read of cp15.c1
orr r1, r1, #0x10000
mcr p15, 0, r1, c1, c0 @ cp15.c1 = 0x00012078;
mov r0, #0x12 @ Switch to IRQ Mode
msr cpsr, r0
ldr sp, =__sp_irq @ Set IRQ stack
mov r0, #0x1F @ Switch to System Mode
msr cpsr, r0
ldr sp, =__sp_usr @ Set user stack
ldr r0, =__bss_start @ Clear BSS section to 0x00
ldr r1, =__bss_end
sub r1, r1, r0
bl ClearMem
ldr r1, =__data_lma @ Copy initialized data (data section) from LMA to VMA (ROM to RAM)
ldr r2, =__data_start
ldr r4, =__data_end
bl CopyMemCheck
ldr r1, =__iwram_lma @ Copy internal work ram (iwram section) from LMA to VMA (ROM to RAM)
ldr r2, =__iwram_start
ldr r4, =__iwram_end
bl CopyMemCheck
ldr r2, =__load_stop_iwram0 @ Copy internal work ram overlay 0 (iwram0 section) from LMA to VMA (ROM to RAM)
ldr r1, =__load_start_iwram0
subs r3, r2, r1 @ Is there any data to copy?
beq CIW0Skip @ no
ldr r2, =__iwram_overlay_start
bl CopyMem
CIW0Skip:
ldr r1, =__ewram_lma @ Copy external work ram (ewram section) from LMA to VMA (ROM to RAM)
ldr r2, =__ewram_start
ldr r4, =__ewram_end
bl CopyMemCheck
ldr r2, =__load_stop_ewram0 @ @ Copy external work ram overlay 0 (ewram0 section) from LMA to VMA (ROM to RAM)
ldr r1, =__load_start_ewram0
subs r3, r2, r1 @ Is there any data to copy?
beq CEW0Skip @ no
ldr r2, =__ewram_overlay_start
bl CopyMem
CEW0Skip:
ldr r1, =fake_heap_end @ set heap end
ldr r0, =__eheap_end
str r0, [r1]
ldr r3, =_init @ global constructors
bl _call_via_r3
mov r0, #0 @ int argc
mov r1, #0 @ char *argv[]
ldr r3, =main
bl _call_via_r3 @ jump to user code
@ If the user ever returns, go to an infinte loop
ldr r0, =ILoop
ldr r0, [r0]
ldr r1, =0x027FFE78
str r0, [r1]
bx r1
ILoop: b ILoop
@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
@
@ Clear memory to 0x00 if length != 0
@ r0 = Start Address
@ r1 = Length
@
@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
ClearMem: mov r2, #3 @ Round down to nearest word boundary
add r1, r1, r2 @ Shouldn't be needed
bics r1, r1, r2 @ Clear 2 LSB (and set Z)
bxeq lr @ Quit if copy size is 0
mov r2, #0
ClrLoop: stmia r0!, {r2}
subs r1, r1, #4
bne ClrLoop
bx lr
@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
@
@ Copy memory if length != 0
@ r1 = Source Address
@ r2 = Dest Address
@ r4 = Dest Address + Length
@
@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
CopyMemCheck:
sub r3, r4, r2 @ Is there any data to copy?
@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
@
@ Copy memory
@ r1 = Source Address
@ r2 = Dest Address
@ r3 = Length
@
@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
CopyMem: mov r0, #3 @ These commands are used in cases where
add r3, r3, r0 @ the length is not a multiple of 4,
bics r3, r3, r0 @ even though it should be.
bxeq lr @ Length is zero, so exit
CIDLoop: ldmia r1!, {r0}
stmia r2!, {r0}
subs r3, r3, #4
bne CIDLoop
bx lr
@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
.align
.pool
.end

173
dka-crtls/ds_cart_crt0.S Normal file
View File

@ -0,0 +1,173 @@
.section ".init"
.global _start
.align
@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
.arm
_start:
b rom_header_end
.fill 156,1,0 @ Nintendo Logo Character Data (8000004h)
.fill 16,1,0 @ Game Title
.byte 0x30,0x31 @ Maker Code (80000B0h)
.byte 0x96 @ Fixed Value (80000B2h)
.byte 0x00 @ Main Unit Code (80000B3h)
.byte 0x00 @ Device Type (80000B4h)
.fill 7,1,0 @ unused
.byte 0x00 @ Software Version No (80000BCh)
.byte 0xf0 @ Complement Check (80000BDh)
.byte 0x00,0x00 @ Checksum (80000BEh)
rom_header_end:
b start_vector @ This branch must be here for proper
@ positioning of the following header.
.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)
.byte 0 @ reserved
.byte 0 @ reserved
.word 0 @ reserved
.word 0 @ reserved
.word 0 @ reserved
.word 0 @ reserved
.word 0 @ reserved
.word 0 @ reserved
@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
.align 4
.arm
start_vector:
mov r0, #0x04000000 @ IME = 0;
add r0, r0, #0x208
strh r0, [r0]
mov r0, #0x12 @ Switch to IRQ Mode
msr cpsr, r0
ldr sp, =__sp_irq @ Set IRQ stack
mov r0, #0x1F @ Switch to System Mode
msr cpsr, r0
ldr sp, =__sp_usr @ Set user stack
mov r1, #0x42
strb r1, [r7], #1
mov r1, #0x35
strb r1, [r7], #1
mov r1, #0x2B
strb r1, [r7], #1
mov r1, #0x2B
strb r1, [r7], #1
ldr r0, =__bss_start @ Clear BSS section to 0x00
ldr r1, =__bss_end
sub r1, r1, r0
bl ClearMem
ldr r1, =__data_lma @ Copy initialized data (data section) from LMA to VMA (ROM to RAM)
ldr r2, =__data_start
ldr r4, =__data_end
bl CopyMemChk
ldr r1, =__iwram_lma @ Copy internal work ram (iwram section) from LMA to VMA (ROM to RAM)
ldr r2, =__iwram_start
ldr r4, =__iwram_end
bl CopyMemChk
ldr r2, =__load_stop_iwram0 @ Copy internal work ram overlay 0 (iwram0 section) from LMA to VMA (ROM to RAM)
ldr r1, =__load_start_iwram0
subs r3, r2, r1 @ Is there any data to copy?
beq CIW0Skip @ no
ldr r2, =__iwram_overlay_start
bl CopyMem
CIW0Skip:
ldr r1, =__ewram_lma @ Copy external work ram (ewram section) from LMA to VMA (ROM to RAM)
ldr r2, =__ewram_start
ldr r4, =__ewram_end
bl CopyMemChk
ldr r2, =__load_stop_ewram0 @ @ Copy external work ram overlay 0 (ewram0 section) from LMA to VMA (ROM to RAM)
ldr r1, =__load_start_ewram0
subs r3, r2, r1 @ Is there any data to copy?
beq CEW0Skip @ no
ldr r2, =__ewram_overlay_start
bl CopyMem
CEW0Skip:
ldr r1, =fake_heap_end @ set heap end
ldr r0, =__eheap_end
str r0, [r1]
ldr r3, =_init @ global constructors
bl _call_via_r3
mov r0, #0 @ int argc
mov r1, #0 @ char *argv[]
ldr r3, =main
bl _call_via_r3 @ jump to user code
@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
@
@ Clear memory to 0x00 if length != 0
@ r0 = Start Address
@ r1 = Length
@
@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
ClearMem: mov r2, #3 @ Round down to nearest word boundary
add r1, r1, r2 @ Shouldn't be needed
bics r1, r1, r2 @ Clear 2 LSB (and set Z)
bxeq lr @ Quit if copy size is 0
mov r2, #0
ClrLoop: stmia r0!, {r2}
subs r1, r1, #4
bne ClrLoop
bx lr
@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
@
@ Copy memory if length != 0
@ r1 = Source Address
@ r2 = Dest Address
@ r4 = Dest Address + Length
@
@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
CopyMemChk: sub r3, r4, r2 @ Is there any data to copy?
@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
@
@ Copy memory
@ r1 = Source Address
@ r2 = Dest Address
@ r3 = Length
@
@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
CopyMem: mov r0, #3 @ These commands are used in cases where
add r3, r3, r0 @ the length is not a multiple of 4,
bics r3, r3, r0 @ even though it should be.
bxeq lr @ Length is zero so exit
CIDLoop: ldmia r1!, {r0}
stmia r2!, {r0}
subs r3, r3, #4
bne CIDLoop
bx lr
@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
.align
.pool
.end

View File

@ -12,3 +12,6 @@ $MAKE CRT=gba_crt0
$MAKE CRT=gp32_crt0
$MAKE CRT=er_crt0
$MAKE CRT=gp32_gpsdk_crt0
$MAKE CRT=ds_arm7_crt0
$MAKE CRT=ds_arm9_crt0
$MAKE CRT=ds_cart_crt0