summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorProjectRevoTPP <projectrevotpp@hotmail.com>2018-01-06 21:12:42 -0500
committerProjectRevoTPP <projectrevotpp@hotmail.com>2018-01-06 21:12:42 -0500
commit7be61cfb1a55feb9ab30cfda9e78ed33c74eb097 (patch)
tree813ee816afab86312307d67351dc4b13279557dd
parent601ec28721b250d74e7fd61300226ff07c8a710b (diff)
add assert support to pokeemerald.
-rw-r--r--Makefile4
-rwxr-xr-xinclude/assert.h43
-rw-r--r--include/config.h10
-rw-r--r--include/global.h1
-rw-r--r--ld_script.txt83
-rw-r--r--src/libc.c173
-rw-r--r--sym_bss.txt37
7 files changed, 175 insertions, 176 deletions
diff --git a/Makefile b/Makefile
index 382b69888..3b217013a 100644
--- a/Makefile
+++ b/Makefile
@@ -32,6 +32,8 @@ OBJCOPY := $(DEVKITARM)/bin/arm-none-eabi-objcopy
LIBGCC := tools/agbcc/lib/libgcc.a
+LIBC := tools/agbcc/lib/libc.a
+
SHA1 := sha1sum -c
GFX := tools/gbagfx/gbagfx
@@ -154,7 +156,7 @@ $(OBJ_DIR)/ld_script.ld: ld_script.txt $(OBJ_DIR)/sym_bss.ld $(OBJ_DIR)/sym_comm
cd $(OBJ_DIR) && sed -f ../../ld_script.sed ../../$< | sed "s#tools/#../../tools/#g" > ld_script.ld
$(ELF): $(OBJ_DIR)/ld_script.ld $(OBJS)
- cd $(OBJ_DIR) && $(LD) $(LDFLAGS) -T ld_script.ld -o ../../$@ $(OBJS_REL) ../../$(LIBGCC)
+ cd $(OBJ_DIR) && $(LD) $(LDFLAGS) -T ld_script.ld -o ../../$@ $(OBJS_REL) ../../$(LIBGCC) ../../$(LIBC)
$(ROM): $(ELF)
$(OBJCOPY) -O binary --gap-fill 0xFF --pad-to 0x9000000 $< $@
diff --git a/include/assert.h b/include/assert.h
new file mode 100755
index 000000000..0c1e5bf77
--- /dev/null
+++ b/include/assert.h
@@ -0,0 +1,43 @@
+#ifndef GUARD_GBASDKASSERT_H
+#define GUARD_GBASDKASSERT_H
+
+// this header is based on the
+// GBA SDK IsAgbAssert.h.
+
+#ifdef NOAGBPRN
+ #define AGBPrintInit()
+ #define AGBPutc(pBuf)
+ #define AGBPrint(pBuf)
+ #define AGBPrintf(...)
+ #define AGBPrintFlush1Block()
+ #define AGBPrintFlush()
+ #define AGBAssert(pFile, nLine, pExpression, nStopProgram)
+#else
+ // without NOAGBPRN defined, this enables asserts for usage
+ // on a standard GBA debugger unit or in emulators that
+ // support it.
+
+ void AGBPrintInit(void);
+ void AGBPutc(const char pBuf);
+ void AGBPrint(const char *pBuf);
+ void AGBPrintf(const char *pBuf, ...);
+ void AGBPrintFlush1Block(void);
+ void AGBPrintFlush(void);
+ void AGBAssert(const char *pFile, int nLine, const char *pExpression, int nStopProgram);
+#endif
+
+// when using AGB_WARNING, be sure to flush after as AGBAssert does not flush the string to console
+// immediately after usage.
+#ifdef NOAGBPRN
+ #define AGB_ASSERT(expression)
+#else
+ #define AGB_ASSERT(expression) (expression) ? ((void *)0) : AGBAssert(__FILE__, __LINE__, #expression, 1);
+#endif
+
+#ifdef NOAGBPRN
+ #define AGB_WARNING(expression)
+#else
+ #define AGB_WARNING(expression) (expression) ? ((void *)0) : AGBAssert(__FILE__, __LINE__, #expression, 0);
+#endif
+
+#endif
diff --git a/include/config.h b/include/config.h
index 162af3143..ce8e4ae74 100644
--- a/include/config.h
+++ b/include/config.h
@@ -1,6 +1,16 @@
#ifndef GUARD_CONFIG_H
#define GUARD_CONFIG_H
+// In the Generation 3 games, Asserts were used in various debug builds.
+// Ruby/Sapphire and Emerald do not have these asserts while Fire Red
+// still has them in the ROM. This is because the developers forgot
+// to define NOAGBPRN before release, which is actually supposed to be
+// NDEBUG, however this has been changed as Ruby's actual debug build
+// does not use the AGBPrint features.
+#define NOAGBPRN
+// NOTE: Don't try to enable assert right now as many pointers
+// still exist in defines and WILL likely result in a broken ROM.
+
#define ENGLISH
#ifdef ENGLISH
diff --git a/include/global.h b/include/global.h
index 7943fc569..1d0962cf6 100644
--- a/include/global.h
+++ b/include/global.h
@@ -3,6 +3,7 @@
#include "gba/gba.h"
#include "config.h"
+#include "assert.h"
// Prevent cross-jump optimization.
#define BLOCK_CROSS_JUMP asm("");
diff --git a/ld_script.txt b/ld_script.txt
index b3551e328..f4492b499 100644
--- a/ld_script.txt
+++ b/ld_script.txt
@@ -15,6 +15,44 @@ SECTIONS {
<EWRAM>
+ tools/agbcc/lib/libc.a:memcpy.o(.data);
+ tools/agbcc/lib/libc.a:memset.o(.data);
+ tools/agbcc/lib/libc.a:strcmp.o(.data);
+ tools/agbcc/lib/libc.a:strcpy.o(.data);
+ tools/agbcc/lib/libc.a:impure.o(.data);
+ tools/agbcc/lib/libc.a:vsprintf.o(.data);
+ tools/agbcc/lib/libc.a:vfprintf.o(.data);
+ tools/agbcc/lib/libc.a:wsetup.o(.data);
+ tools/agbcc/lib/libc.a:dtoa.o(.data);
+ tools/agbcc/lib/libc.a:fflush.o(.data);
+ tools/agbcc/lib/libc.a:findfp.o(.data);
+ tools/agbcc/lib/libc.a:freer.o(.data);
+ tools/agbcc/lib/libc.a:mtrim.o(.data);
+ tools/agbcc/lib/libc.a:fvwrite.o(.data);
+ tools/agbcc/lib/libc.a:fwalk.o(.data);
+ tools/agbcc/lib/libc.a:locale.o(.data);
+ tools/agbcc/lib/libc.a:makebuf.o(.data);
+ tools/agbcc/lib/libc.a:mallocr.o(.data);
+ tools/agbcc/lib/libc.a:mbtowc_r.o(.data);
+ tools/agbcc/lib/libc.a:memchr.o(.data);
+ tools/agbcc/lib/libc.a:memmove.o(.data);
+ tools/agbcc/lib/libc.a:mlock.o(.data);
+ tools/agbcc/lib/libc.a:mprec.o(.data);
+ tools/agbcc/lib/libc.a:s_isinf.o(.data);
+ tools/agbcc/lib/libc.a:s_isnan.o(.data);
+ tools/agbcc/lib/libc.a:sbrkr.o(.data);
+ tools/agbcc/lib/libc.a:stdio.o(.data);
+ tools/agbcc/lib/libc.a:strlen.o(.data);
+ tools/agbcc/lib/libc.a:syscalls.o(.data);
+ tools/agbcc/lib/libc.a:writer.o(.data);
+ tools/agbcc/lib/libc.a:callocr.o(.data);
+ tools/agbcc/lib/libc.a:closer.o(.data);
+ tools/agbcc/lib/libc.a:errno.o(.data);
+ tools/agbcc/lib/libc.a:fstatr.o(.data);
+ tools/agbcc/lib/libc.a:libcfunc.o(.data);
+ tools/agbcc/lib/libc.a:lseekr.o(.data);
+ tools/agbcc/lib/libc.a:readr.o(.data);
+
. = 0x40000;
}
@@ -28,10 +66,12 @@ SECTIONS {
/* .bss.code starts at 0x3001AA8 */
src/m4a_2.o(.bss.code);
+ tools/agbcc/lib/libc.a:syscalls.o(.bss);
/* COMMON starts at 0x30022A8 */
<COMMON>
-
+ tools/agbcc/lib/libc.a:sbrkr.o(COMMON);
+ end = .;
. = 0x8000;
}
@@ -325,7 +365,42 @@ SECTIONS {
tools/agbcc/lib/libgcc.a:fp-bit.o(.text);
tools/agbcc/lib/libgcc.a:_lshrdi3.o(.text);
tools/agbcc/lib/libgcc.a:_negdi2.o(.text);
- src/libc.o(.text);
+ tools/agbcc/lib/libc.a:memcpy.o(.text);
+ tools/agbcc/lib/libc.a:memset.o(.text);
+ tools/agbcc/lib/libc.a:strcmp.o(.text);
+ tools/agbcc/lib/libc.a:strcpy.o(.text);
+ tools/agbcc/lib/libc.a:vfprintf.o(.text);
+ tools/agbcc/lib/libc.a:vsprintf.o(.text);
+ tools/agbcc/lib/libc.a:fvwrite.o(.text);
+ tools/agbcc/lib/libc.a:locale.o(.text);
+ tools/agbcc/lib/libc.a:findfp.o(.text);
+ tools/agbcc/lib/libc.a:fflush.o(.text);
+ tools/agbcc/lib/libc.a:wsetup.o(.text);
+ tools/agbcc/lib/libc.a:mbtowc_r.o(.text);
+ tools/agbcc/lib/libc.a:s_isinf.o(.text);
+ tools/agbcc/lib/libc.a:s_isnan.o(.text);
+ tools/agbcc/lib/libc.a:memchr.o(.text);
+ tools/agbcc/lib/libc.a:strlen.o(.text);
+ tools/agbcc/lib/libc.a:dtoa.o(.text);
+ tools/agbcc/lib/libc.a:memmove.o(.text);
+ tools/agbcc/lib/libc.a:stdio.o(.text);
+ tools/agbcc/lib/libc.a:mprec.o(.text);
+ tools/agbcc/lib/libc.a:mallocr.o(.text);
+ tools/agbcc/lib/libc.a:fwalk.o(.text);
+ tools/agbcc/lib/libc.a:freer.o(.text);
+ tools/agbcc/lib/libc.a:makebuf.o(.text);
+ tools/agbcc/lib/libc.a:readr.o(.text);
+ tools/agbcc/lib/libc.a:writer.o(.text);
+ tools/agbcc/lib/libc.a:lseekr.o(.text);
+ tools/agbcc/lib/libc.a:closer.o(.text);
+ tools/agbcc/lib/libc.a:callocr.o(.text);
+ tools/agbcc/lib/libc.a:sbrkr.o(.text);
+ tools/agbcc/lib/libc.a:mlock.o(.text);
+ tools/agbcc/lib/libc.a:fstatr.o(.text);
+ tools/agbcc/lib/libc.a:libcfunc.o(.text);
+ tools/agbcc/lib/libc.a:syscalls.o(.text);
+ tools/agbcc/lib/libc.a:errno.o(.text);
+ src/libisagbprn.o(.text);
} =0
.rodata :
@@ -1059,6 +1134,10 @@ SECTIONS {
data/librfu_rodata.o(.rodata);
tools/agbcc/lib/libgcc.a:_divdi3.o(.rodata);
tools/agbcc/lib/libgcc.a:_udivdi3.o(.rodata);
+ tools/agbcc/lib/libc.a(.rodata);
+ tools/agbcc/lib/libc.a(.data);
+ tools/agbcc/lib/libc.a:syscalls.o(.rodata);
+ src/libisagbprn.o(.rodata);
} =0
other_data :
diff --git a/src/libc.c b/src/libc.c
deleted file mode 100644
index 1f457957b..000000000
--- a/src/libc.c
+++ /dev/null
@@ -1,173 +0,0 @@
-#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;
-}
-
diff --git a/sym_bss.txt b/sym_bss.txt
index de452b2e7..97a987c62 100644
--- a/sym_bss.txt
+++ b/sym_bss.txt
@@ -198,3 +198,40 @@ gUnknown_03001300: @ 3001300
.include "src/siirtc.o"
.include "tools/agbcc/lib/libgcc.a:dp-bit.o"
.include "tools/agbcc/lib/libgcc.a:fp-bit.o"
+ .include "tools/agbcc/lib/libc.a:memcpy.o"
+ .include "tools/agbcc/lib/libc.a:memset.o"
+ .include "tools/agbcc/lib/libc.a:strcmp.o"
+ .include "tools/agbcc/lib/libc.a:strcpy.o"
+ .include "tools/agbcc/lib/libc.a:impure.o"
+ .include "tools/agbcc/lib/libc.a:vsprintf.o"
+ .include "tools/agbcc/lib/libc.a:vfprintf.o"
+ .include "tools/agbcc/lib/libc.a:wsetup.o"
+ .include "tools/agbcc/lib/libc.a:dtoa.o"
+ .include "tools/agbcc/lib/libc.a:fflush.o"
+ .include "tools/agbcc/lib/libc.a:findfp.o"
+ .include "tools/agbcc/lib/libc.a:freer.o"
+ .include "tools/agbcc/lib/libc.a:mtrim.o"
+ .include "tools/agbcc/lib/libc.a:fvwrite.o"
+ .include "tools/agbcc/lib/libc.a:fwalk.o"
+ .include "tools/agbcc/lib/libc.a:locale.o"
+ .include "tools/agbcc/lib/libc.a:makebuf.o"
+ .include "tools/agbcc/lib/libc.a:mallocr.o"
+ .include "tools/agbcc/lib/libc.a:mbtowc_r.o"
+ .include "tools/agbcc/lib/libc.a:memchr.o"
+ .include "tools/agbcc/lib/libc.a:memmove.o"
+ .include "tools/agbcc/lib/libc.a:mlock.o"
+ .include "tools/agbcc/lib/libc.a:mprec.o"
+ .include "tools/agbcc/lib/libc.a:s_isinf.o"
+ .include "tools/agbcc/lib/libc.a:s_isnan.o"
+ .include "tools/agbcc/lib/libc.a:sbrkr.o"
+ .include "tools/agbcc/lib/libc.a:stdio.o"
+ .include "tools/agbcc/lib/libc.a:strlen.o"
+ .include "tools/agbcc/lib/libc.a:syscalls.o"
+ .include "tools/agbcc/lib/libc.a:writer.o"
+ .include "tools/agbcc/lib/libc.a:callocr.o"
+ .include "tools/agbcc/lib/libc.a:closer.o"
+ .include "tools/agbcc/lib/libc.a:errno.o"
+ .include "tools/agbcc/lib/libc.a:fstatr.o"
+ .include "tools/agbcc/lib/libc.a:libcfunc.o"
+ .include "tools/agbcc/lib/libc.a:lseekr.o"
+ .include "tools/agbcc/lib/libc.a:readr.o"