add assert support to pokeemerald.

This commit is contained in:
ProjectRevoTPP 2018-01-06 21:12:42 -05:00
parent 601ec28721
commit 7be61cfb1a
7 changed files with 175 additions and 176 deletions

View File

@ -32,6 +32,8 @@ OBJCOPY := $(DEVKITARM)/bin/arm-none-eabi-objcopy
LIBGCC := tools/agbcc/lib/libgcc.a LIBGCC := tools/agbcc/lib/libgcc.a
LIBC := tools/agbcc/lib/libc.a
SHA1 := sha1sum -c SHA1 := sha1sum -c
GFX := tools/gbagfx/gbagfx 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 cd $(OBJ_DIR) && sed -f ../../ld_script.sed ../../$< | sed "s#tools/#../../tools/#g" > ld_script.ld
$(ELF): $(OBJ_DIR)/ld_script.ld $(OBJS) $(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) $(ROM): $(ELF)
$(OBJCOPY) -O binary --gap-fill 0xFF --pad-to 0x9000000 $< $@ $(OBJCOPY) -O binary --gap-fill 0xFF --pad-to 0x9000000 $< $@

43
include/assert.h Executable file
View File

@ -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

View File

@ -1,6 +1,16 @@
#ifndef GUARD_CONFIG_H #ifndef GUARD_CONFIG_H
#define 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 #define ENGLISH
#ifdef ENGLISH #ifdef ENGLISH

View File

@ -3,6 +3,7 @@
#include "gba/gba.h" #include "gba/gba.h"
#include "config.h" #include "config.h"
#include "assert.h"
// Prevent cross-jump optimization. // Prevent cross-jump optimization.
#define BLOCK_CROSS_JUMP asm(""); #define BLOCK_CROSS_JUMP asm("");

View File

@ -15,6 +15,44 @@ SECTIONS {
<EWRAM> <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; . = 0x40000;
} }
@ -28,10 +66,12 @@ SECTIONS {
/* .bss.code starts at 0x3001AA8 */ /* .bss.code starts at 0x3001AA8 */
src/m4a_2.o(.bss.code); src/m4a_2.o(.bss.code);
tools/agbcc/lib/libc.a:syscalls.o(.bss);
/* COMMON starts at 0x30022A8 */ /* COMMON starts at 0x30022A8 */
<COMMON> <COMMON>
tools/agbcc/lib/libc.a:sbrkr.o(COMMON);
end = .;
. = 0x8000; . = 0x8000;
} }
@ -325,7 +365,42 @@ 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);
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 } =0
.rodata : .rodata :
@ -1059,6 +1134,10 @@ SECTIONS {
data/librfu_rodata.o(.rodata); data/librfu_rodata.o(.rodata);
tools/agbcc/lib/libgcc.a:_divdi3.o(.rodata); tools/agbcc/lib/libgcc.a:_divdi3.o(.rodata);
tools/agbcc/lib/libgcc.a:_udivdi3.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 } =0
other_data : other_data :

View File

@ -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;
}

View File

@ -198,3 +198,40 @@ gUnknown_03001300: @ 3001300
.include "src/siirtc.o" .include "src/siirtc.o"
.include "tools/agbcc/lib/libgcc.a:dp-bit.o" .include "tools/agbcc/lib/libgcc.a:dp-bit.o"
.include "tools/agbcc/lib/libgcc.a:fp-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"