mirror of
https://github.com/Ninjdai1/pokeemerald.git
synced 2024-12-26 19:54:21 +01:00
Ported libc from pokeruby
This commit is contained in:
parent
0f6ec6492c
commit
442002dada
6
Makefile
6
Makefile
@ -59,8 +59,7 @@ asm/libmks4agb.o \
|
|||||||
asm/libagbbackup.o \
|
asm/libagbbackup.o \
|
||||||
asm/librtc.o \
|
asm/librtc.o \
|
||||||
asm/librfu.o \
|
asm/librfu.o \
|
||||||
asm/libagbsyscall.o \
|
asm/libagbsyscall.o
|
||||||
asm/libc.o
|
|
||||||
|
|
||||||
DATA_ASM_OBJS := data/data2.o data/anim_mon_front_pics.o \
|
DATA_ASM_OBJS := data/data2.o data/anim_mon_front_pics.o \
|
||||||
data/graphics.o data/unknown_serial_data.o data/multiboot_berry_glitch_fix.o \
|
data/graphics.o data/unknown_serial_data.o data/multiboot_berry_glitch_fix.o \
|
||||||
@ -102,6 +101,9 @@ include graphics_file_rules.mk
|
|||||||
%.lz: % ; $(GFX) $< $@
|
%.lz: % ; $(GFX) $< $@
|
||||||
%.rl: % ; $(GFX) $< $@
|
%.rl: % ; $(GFX) $< $@
|
||||||
|
|
||||||
|
src/libc.o: CC1 := tools/agbcc/bin/old_agbcc
|
||||||
|
src/libc.o: CFLAGS := -O2
|
||||||
|
|
||||||
src/siirtc.o: CFLAGS := -mthumb-interwork
|
src/siirtc.o: CFLAGS := -mthumb-interwork
|
||||||
|
|
||||||
src/agb_flash.o: CFLAGS := -O -mthumb-interwork
|
src/agb_flash.o: CFLAGS := -O -mthumb-interwork
|
||||||
|
213
asm/libc.s
213
asm/libc.s
@ -1,213 +0,0 @@
|
|||||||
.include "asm/macros.s"
|
|
||||||
|
|
||||||
.syntax unified
|
|
||||||
|
|
||||||
.text
|
|
||||||
|
|
||||||
thumb_func_start memcpy
|
|
||||||
@ void *memcpy(void *dest, void *src, int size)
|
|
||||||
memcpy: @ 82E93D4
|
|
||||||
push {r4,r5,lr}
|
|
||||||
adds r5, r0, 0
|
|
||||||
adds r4, r5, 0
|
|
||||||
adds r3, r1, 0
|
|
||||||
cmp r2, 0xF
|
|
||||||
bls _082E9414
|
|
||||||
adds r0, r3, 0
|
|
||||||
orrs r0, r5
|
|
||||||
movs r1, 0x3
|
|
||||||
ands r0, r1
|
|
||||||
cmp r0, 0
|
|
||||||
bne _082E9414
|
|
||||||
adds r1, r5, 0
|
|
||||||
_082E93EE:
|
|
||||||
ldm r3!, {r0}
|
|
||||||
stm r1!, {r0}
|
|
||||||
ldm r3!, {r0}
|
|
||||||
stm r1!, {r0}
|
|
||||||
ldm r3!, {r0}
|
|
||||||
stm r1!, {r0}
|
|
||||||
ldm r3!, {r0}
|
|
||||||
stm r1!, {r0}
|
|
||||||
subs r2, 0x10
|
|
||||||
cmp r2, 0xF
|
|
||||||
bhi _082E93EE
|
|
||||||
cmp r2, 0x3
|
|
||||||
bls _082E9412
|
|
||||||
_082E9408:
|
|
||||||
ldm r3!, {r0}
|
|
||||||
stm r1!, {r0}
|
|
||||||
subs r2, 0x4
|
|
||||||
cmp r2, 0x3
|
|
||||||
bhi _082E9408
|
|
||||||
_082E9412:
|
|
||||||
adds r4, r1, 0
|
|
||||||
_082E9414:
|
|
||||||
subs r2, 0x1
|
|
||||||
movs r0, 0x1
|
|
||||||
negs r0, r0
|
|
||||||
cmp r2, r0
|
|
||||||
beq _082E942E
|
|
||||||
adds r1, r0, 0
|
|
||||||
_082E9420:
|
|
||||||
ldrb r0, [r3]
|
|
||||||
strb r0, [r4]
|
|
||||||
adds r3, 0x1
|
|
||||||
adds r4, 0x1
|
|
||||||
subs r2, 0x1
|
|
||||||
cmp r2, r1
|
|
||||||
bne _082E9420
|
|
||||||
_082E942E:
|
|
||||||
adds r0, r5, 0
|
|
||||||
pop {r4,r5,pc}
|
|
||||||
thumb_func_end memcpy
|
|
||||||
|
|
||||||
thumb_func_start memset
|
|
||||||
@ void *memset(void *dest, char c, int size)
|
|
||||||
memset: @ 82E9434
|
|
||||||
push {r4,r5,lr}
|
|
||||||
adds r5, r0, 0
|
|
||||||
adds r4, r1, 0
|
|
||||||
adds r3, r5, 0
|
|
||||||
cmp r2, 0x3
|
|
||||||
bls _082E947A
|
|
||||||
movs r0, 0x3
|
|
||||||
ands r0, r5
|
|
||||||
cmp r0, 0
|
|
||||||
bne _082E947A
|
|
||||||
adds r1, r5, 0
|
|
||||||
movs r0, 0xFF
|
|
||||||
ands r4, r0
|
|
||||||
lsls r3, r4, 8
|
|
||||||
orrs r3, r4
|
|
||||||
lsls r0, r3, 16
|
|
||||||
orrs r3, r0
|
|
||||||
cmp r2, 0xF
|
|
||||||
bls _082E946E
|
|
||||||
_082E945A:
|
|
||||||
stm r1!, {r3}
|
|
||||||
stm r1!, {r3}
|
|
||||||
stm r1!, {r3}
|
|
||||||
stm r1!, {r3}
|
|
||||||
subs r2, 0x10
|
|
||||||
cmp r2, 0xF
|
|
||||||
bhi _082E945A
|
|
||||||
b _082E946E
|
|
||||||
_082E946A:
|
|
||||||
stm r1!, {r3}
|
|
||||||
subs r2, 0x4
|
|
||||||
_082E946E:
|
|
||||||
cmp r2, 0x3
|
|
||||||
bhi _082E946A
|
|
||||||
adds r3, r1, 0
|
|
||||||
b _082E947A
|
|
||||||
_082E9476:
|
|
||||||
strb r4, [r3]
|
|
||||||
adds r3, 0x1
|
|
||||||
_082E947A:
|
|
||||||
adds r0, r2, 0
|
|
||||||
subs r2, 0x1
|
|
||||||
cmp r0, 0
|
|
||||||
bne _082E9476
|
|
||||||
adds r0, r5, 0
|
|
||||||
pop {r4,r5,pc}
|
|
||||||
thumb_func_end memset
|
|
||||||
|
|
||||||
thumb_func_start strcmp
|
|
||||||
@ int strcmp(char *s1, char *s2)
|
|
||||||
strcmp: @ 82E9488
|
|
||||||
push {r4,r5,lr}
|
|
||||||
adds r2, r0, 0
|
|
||||||
adds r3, r1, 0
|
|
||||||
orrs r0, r3
|
|
||||||
movs r1, 0x3
|
|
||||||
ands r0, r1
|
|
||||||
cmp r0, 0
|
|
||||||
bne _082E94CE
|
|
||||||
ldr r1, [r2]
|
|
||||||
ldr r0, [r3]
|
|
||||||
cmp r1, r0
|
|
||||||
bne _082E94CE
|
|
||||||
ldr r5, _082E94B4
|
|
||||||
ldr r4, _082E94B8
|
|
||||||
_082E94A4:
|
|
||||||
ldr r1, [r2]
|
|
||||||
adds r0, r1, r5
|
|
||||||
bics r0, r1
|
|
||||||
ands r0, r4
|
|
||||||
cmp r0, 0
|
|
||||||
beq _082E94BC
|
|
||||||
movs r0, 0
|
|
||||||
b _082E94E0
|
|
||||||
.align 2, 0
|
|
||||||
_082E94B4: .4byte 0xfefefeff
|
|
||||||
_082E94B8: .4byte 0x80808080
|
|
||||||
_082E94BC:
|
|
||||||
adds r2, 0x4
|
|
||||||
adds r3, 0x4
|
|
||||||
ldr r1, [r2]
|
|
||||||
ldr r0, [r3]
|
|
||||||
cmp r1, r0
|
|
||||||
beq _082E94A4
|
|
||||||
b _082E94CE
|
|
||||||
_082E94CA:
|
|
||||||
adds r2, 0x1
|
|
||||||
adds r3, 0x1
|
|
||||||
_082E94CE:
|
|
||||||
ldrb r0, [r2]
|
|
||||||
cmp r0, 0
|
|
||||||
beq _082E94DA
|
|
||||||
ldrb r1, [r3]
|
|
||||||
cmp r0, r1
|
|
||||||
beq _082E94CA
|
|
||||||
_082E94DA:
|
|
||||||
ldrb r2, [r2]
|
|
||||||
ldrb r3, [r3]
|
|
||||||
subs r0, r2, r3
|
|
||||||
_082E94E0:
|
|
||||||
pop {r4,r5,pc}
|
|
||||||
thumb_func_end strcmp
|
|
||||||
|
|
||||||
thumb_func_start strcat
|
|
||||||
strcat: @ 82E94E4
|
|
||||||
push {r4-r6,lr}
|
|
||||||
adds r6, r0, 0
|
|
||||||
adds r3, r6, 0
|
|
||||||
adds r2, r1, 0
|
|
||||||
adds r0, r2, 0
|
|
||||||
orrs r0, r6
|
|
||||||
movs r1, 0x3
|
|
||||||
ands r0, r1
|
|
||||||
cmp r0, 0
|
|
||||||
bne _082E951C
|
|
||||||
ldr r1, [r2]
|
|
||||||
ldr r5, _082E9504
|
|
||||||
adds r0, r1, r5
|
|
||||||
bics r0, r1
|
|
||||||
ldr r4, _082E9508
|
|
||||||
b _082E9516
|
|
||||||
.align 2, 0
|
|
||||||
_082E9504: .4byte 0xfefefeff
|
|
||||||
_082E9508: .4byte 0x80808080
|
|
||||||
_082E950C:
|
|
||||||
ldm r2!, {r0}
|
|
||||||
stm r3!, {r0}
|
|
||||||
ldr r1, [r2]
|
|
||||||
adds r0, r1, r5
|
|
||||||
bics r0, r1
|
|
||||||
_082E9516:
|
|
||||||
ands r0, r4
|
|
||||||
cmp r0, 0
|
|
||||||
beq _082E950C
|
|
||||||
_082E951C:
|
|
||||||
ldrb r0, [r2]
|
|
||||||
strb r0, [r3]
|
|
||||||
lsls r0, 24
|
|
||||||
adds r2, 0x1
|
|
||||||
adds r3, 0x1
|
|
||||||
cmp r0, 0
|
|
||||||
bne _082E951C
|
|
||||||
adds r0, r6, 0
|
|
||||||
pop {r4-r6,pc}
|
|
||||||
|
|
||||||
.align 2, 0 @ Don't pad with nop.
|
|
@ -2523,7 +2523,7 @@ task00_link_test: @ 800A850
|
|||||||
sub sp, 0x20
|
sub sp, 0x20
|
||||||
ldr r1, =gUnknown_082ED1E4
|
ldr r1, =gUnknown_082ED1E4
|
||||||
mov r0, sp
|
mov r0, sp
|
||||||
bl strcat
|
bl strcpy
|
||||||
mov r0, sp
|
mov r0, sp
|
||||||
movs r1, 0x5
|
movs r1, 0x5
|
||||||
movs r2, 0x2
|
movs r2, 0x2
|
||||||
|
@ -86,7 +86,7 @@ SECTIONS {
|
|||||||
tools/agbcc/lib/libgcc.a:fp-bit.o(.text);
|
tools/agbcc/lib/libgcc.a:fp-bit.o(.text);
|
||||||
tools/agbcc/lib/libgcc.a:_lshrdi3.o(.text);
|
tools/agbcc/lib/libgcc.a:_lshrdi3.o(.text);
|
||||||
tools/agbcc/lib/libgcc.a:_negdi2.o(.text);
|
tools/agbcc/lib/libgcc.a:_negdi2.o(.text);
|
||||||
asm/libc.o(.text);
|
src/libc.o(.text);
|
||||||
} =0
|
} =0
|
||||||
|
|
||||||
.rodata :
|
.rodata :
|
||||||
|
173
src/libc.c
Normal file
173
src/libc.c
Normal file
@ -0,0 +1,173 @@
|
|||||||
|
#include "global.h"
|
||||||
|
#include <stddef.h>
|
||||||
|
|
||||||
|
#define LBLOCKSIZE (sizeof(long))
|
||||||
|
|
||||||
|
// Nonzero if (long)X contains a NULL byte.
|
||||||
|
#define CONTAINSNULL(X) (((X) - 0x01010101) & ~(X) & 0x80808080)
|
||||||
|
|
||||||
|
// Nonzero if X is not aligned on a "long" boundary.
|
||||||
|
#define UNALIGNED(X) ((long)X & (LBLOCKSIZE - 1))
|
||||||
|
|
||||||
|
void *memcpy(void *dst0, const void *src0, size_t len0)
|
||||||
|
{
|
||||||
|
char *dst = dst0;
|
||||||
|
const char *src = src0;
|
||||||
|
long *aligned_dst;
|
||||||
|
const long *aligned_src;
|
||||||
|
unsigned int len = len0;
|
||||||
|
|
||||||
|
// If the size is small, or either src or dst is unaligned,
|
||||||
|
// then go to the byte copy loop. This should be rare.
|
||||||
|
if(len >= 16 && !(UNALIGNED(src) | UNALIGNED(dst)))
|
||||||
|
{
|
||||||
|
aligned_dst = (long *)dst;
|
||||||
|
aligned_src = (long *)src;
|
||||||
|
|
||||||
|
// Copy 4X long words at a time if possible.
|
||||||
|
while(len >= 16)
|
||||||
|
{
|
||||||
|
*aligned_dst++ = *aligned_src++;
|
||||||
|
*aligned_dst++ = *aligned_src++;
|
||||||
|
*aligned_dst++ = *aligned_src++;
|
||||||
|
*aligned_dst++ = *aligned_src++;
|
||||||
|
len -= 16;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Copy one long word at a time if possible
|
||||||
|
while(len >= 4)
|
||||||
|
{
|
||||||
|
*aligned_dst++ = *aligned_src++;
|
||||||
|
len -= 4;
|
||||||
|
}
|
||||||
|
|
||||||
|
dst = (char *)aligned_dst;
|
||||||
|
src = (char *)aligned_src;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Pick up any remaining bytes with a byte copier.
|
||||||
|
while(len--)
|
||||||
|
*dst++ = *src++;
|
||||||
|
|
||||||
|
return dst0;
|
||||||
|
}
|
||||||
|
|
||||||
|
void *memset(void *m, int c, size_t n)
|
||||||
|
{
|
||||||
|
char *s = (char *)m;
|
||||||
|
int count, i;
|
||||||
|
unsigned long buffer;
|
||||||
|
unsigned long *aligned_addr;
|
||||||
|
unsigned char *unaligned_addr;
|
||||||
|
|
||||||
|
// If the size is small or m is unaligned,
|
||||||
|
// then go to the byte copy loop. This should be rare.
|
||||||
|
if(n >= LBLOCKSIZE && !UNALIGNED(m))
|
||||||
|
{
|
||||||
|
// We know that n is large and m is word-aligned.
|
||||||
|
aligned_addr = (unsigned long *)m;
|
||||||
|
|
||||||
|
// Store C into each char sized location in buffer so that
|
||||||
|
// we can set large blocks quickly.
|
||||||
|
c &= 0xFF;
|
||||||
|
if(LBLOCKSIZE == 4)
|
||||||
|
{
|
||||||
|
buffer = (c << 8) | c;
|
||||||
|
buffer |= (buffer << 16);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
buffer = 0;
|
||||||
|
for(i = 0; i < LBLOCKSIZE; i++)
|
||||||
|
buffer = (buffer << 8) | c;
|
||||||
|
}
|
||||||
|
|
||||||
|
while(n >= LBLOCKSIZE * 4)
|
||||||
|
{
|
||||||
|
*aligned_addr++ = buffer;
|
||||||
|
*aligned_addr++ = buffer;
|
||||||
|
*aligned_addr++ = buffer;
|
||||||
|
*aligned_addr++ = buffer;
|
||||||
|
n -= LBLOCKSIZE * 4;
|
||||||
|
}
|
||||||
|
while(n >= LBLOCKSIZE)
|
||||||
|
{
|
||||||
|
*aligned_addr++ = buffer;
|
||||||
|
n -= LBLOCKSIZE;
|
||||||
|
}
|
||||||
|
|
||||||
|
s = (char *)aligned_addr;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Pick up the remainder with a bytewise loop.
|
||||||
|
while(n--)
|
||||||
|
*s++ = (char)c;
|
||||||
|
|
||||||
|
return m;
|
||||||
|
}
|
||||||
|
|
||||||
|
int strcmp(const char *s1, const char *s2)
|
||||||
|
{
|
||||||
|
unsigned long *a1;
|
||||||
|
unsigned long *a2;
|
||||||
|
|
||||||
|
// If s1 or s2 are unaligned, then skip this and compare bytes.
|
||||||
|
if(!(UNALIGNED(s1) | UNALIGNED(s2)))
|
||||||
|
{
|
||||||
|
// Compare them a word at a time.
|
||||||
|
a1 = (unsigned long *)s1;
|
||||||
|
a2 = (unsigned long *)s2;
|
||||||
|
while(*a1 == *a2)
|
||||||
|
{
|
||||||
|
// If *a1 == *a2, and we find a null in *a1,
|
||||||
|
// then the strings must be equal, so return zero.
|
||||||
|
if(CONTAINSNULL(*a1))
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
a1++;
|
||||||
|
a2++;
|
||||||
|
}
|
||||||
|
|
||||||
|
s1 = (char *)a1;
|
||||||
|
s2 = (char *)a2;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Check the remaining few bytes.
|
||||||
|
while(*s1 != '\0' && *s1 == *s2)
|
||||||
|
{
|
||||||
|
s1++;
|
||||||
|
s2++;
|
||||||
|
}
|
||||||
|
|
||||||
|
return (*(unsigned char *) s1) - (*(unsigned char *) s2);
|
||||||
|
}
|
||||||
|
|
||||||
|
char* strcpy(char *dst0, const char *src0)
|
||||||
|
{
|
||||||
|
char *dst = dst0;
|
||||||
|
const char *src = src0;
|
||||||
|
unsigned long *a1;
|
||||||
|
const unsigned long *a2;
|
||||||
|
|
||||||
|
/* If SRC or DEST is unaligned, then copy bytes. */
|
||||||
|
if(!(UNALIGNED(src) | UNALIGNED(dst)))
|
||||||
|
{
|
||||||
|
/* SRC and DEST are both "long int" aligned, try to do "long int"
|
||||||
|
sized copies. */
|
||||||
|
a1 = (unsigned long *)dst;
|
||||||
|
a2 = (unsigned long *)src;
|
||||||
|
while(!CONTAINSNULL(*a2))
|
||||||
|
{
|
||||||
|
*a1++ = *a2++;
|
||||||
|
}
|
||||||
|
|
||||||
|
dst = (char *)a1;
|
||||||
|
src = (char *)a2;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Copy the remaining few bytes.
|
||||||
|
while(*dst++ = *src++);
|
||||||
|
|
||||||
|
return dst0;
|
||||||
|
}
|
||||||
|
|
Loading…
Reference in New Issue
Block a user