From 7be61cfb1a55feb9ab30cfda9e78ed33c74eb097 Mon Sep 17 00:00:00 2001 From: ProjectRevoTPP Date: Sat, 6 Jan 2018 21:12:42 -0500 Subject: [PATCH 01/12] add assert support to pokeemerald. --- Makefile | 4 +- include/assert.h | 43 ++++++++++++ include/config.h | 10 +++ include/global.h | 1 + ld_script.txt | 83 ++++++++++++++++++++++- src/libc.c | 173 ----------------------------------------------- sym_bss.txt | 37 ++++++++++ 7 files changed, 175 insertions(+), 176 deletions(-) create mode 100755 include/assert.h delete mode 100644 src/libc.c 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 { + 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 */ - + 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 - -#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" From 8cf6da7a3b77bdceb38bbc4d9c1460028e8d9180 Mon Sep 17 00:00:00 2001 From: ProjectRevoTPP Date: Sat, 6 Jan 2018 21:13:18 -0500 Subject: [PATCH 02/12] don't forget to add the file dummy --- src/libisagbprn.c | 167 ++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 167 insertions(+) create mode 100755 src/libisagbprn.c diff --git a/src/libisagbprn.c b/src/libisagbprn.c new file mode 100755 index 000000000..867044217 --- /dev/null +++ b/src/libisagbprn.c @@ -0,0 +1,167 @@ +#include +#include +#include "gba/gba.h" +#include "config.h" +#include "assert.h" + +#define AGB_PRINT_FLUSH_ADDR 0x9FE209D +#define AGB_PRINT_STRUCT_ADDR 0x9FE20F8 +#define AGB_PRINT_PROTECT_ADDR 0x9FE2FFE +#define WSCNT_DATA (WAITCNT_PHI_OUT_16MHZ | WAITCNT_WS0_S_2 | WAITCNT_WS0_N_4) + +// TODO: make no$gba support not shit + +// for auto no$gba support, the string "no$gba" should be at this address. +#define NOGBAIDADDR 0x4FFFA00 +#define NOGBAPRINTADDR 0x4FFFA14 + +struct AGBPrintStruct +{ + u16 m_nRequest; + u16 m_nBank; + u16 m_nGet; + u16 m_nPut; +}; + +typedef void (*LPFN_PRINT_FLUSH)(void); + +#ifndef NOAGBPRN +void AGBPrintFlush1Block(void); + +void AGBPrintInit(void) +{ + volatile struct AGBPrintStruct *pPrint = (struct AGBPrintStruct *)AGB_PRINT_STRUCT_ADDR; + u16 *pWSCNT = (u16 *)REG_ADDR_WAITCNT; + u16 *pProtect = (u16 *)AGB_PRINT_PROTECT_ADDR; + u16 nOldWSCNT = *pWSCNT; + *pWSCNT = WSCNT_DATA; + *pProtect = 0x20; + pPrint->m_nRequest = pPrint->m_nGet = pPrint->m_nPut = 0; + pPrint->m_nBank = 0xFD; + *pProtect = 0; + *pWSCNT = nOldWSCNT; +} + +static void AGBPutcInternal(const char cChr) +{ + volatile struct AGBPrintStruct *pPrint = (struct AGBPrintStruct *)AGB_PRINT_STRUCT_ADDR; + u16 *pPrintBuf = (u16 *)(0x8000000 + (pPrint->m_nBank << 16)); + u16 *pProtect = (u16 *)AGB_PRINT_PROTECT_ADDR; + u16 nData = pPrintBuf[pPrint->m_nPut / 2]; + *pProtect = 0x20; + nData = (pPrint->m_nPut & 1) ? (nData & 0xFF) | (cChr << 8) : (nData & 0xFF00) | cChr; + pPrintBuf[pPrint->m_nPut / 2] = nData; + pPrint->m_nPut++; + *pProtect = 0; +} + +void AGBPutc(const char cChr) +{ + u16 *pWSCNT = (u16 *)REG_ADDR_WAITCNT; + u16 nOldWSCNT = *pWSCNT; + volatile struct AGBPrintStruct *pPrint; + *pWSCNT = WSCNT_DATA; + AGBPutcInternal(cChr); + *pWSCNT = nOldWSCNT; + pPrint = (struct AGBPrintStruct *)AGB_PRINT_STRUCT_ADDR; + if (pPrint->m_nPut == ((pPrint->m_nGet - 1) & 0xFFFF)) + AGBPrintFlush1Block(); +} + +void AGBPrint(const char *pBuf) +{ + volatile struct AGBPrintStruct *pPrint = (struct AGBPrintStruct *)AGB_PRINT_STRUCT_ADDR; + u16 *pWSCNT = (u16 *)REG_ADDR_WAITCNT; + u16 nOldWSCNT = *pWSCNT; + *pWSCNT = WSCNT_DATA; + while (*pBuf) + { + AGBPutc(*pBuf); + pBuf++; + } + *pWSCNT = nOldWSCNT; +} + +void AGBPrintf(const char *pBuf, ...) +{ + char bufPrint[0x100]; + va_list vArgv; + va_start(vArgv, pBuf); + vsprintf(bufPrint, pBuf, vArgv); + va_end(vArgv); + AGBPrint(bufPrint); +} + +static void AGBPrintTransferDataInternal(u32 bAllData) +{ + LPFN_PRINT_FLUSH lpfnFuncFlush; + u16 *pIME; + u16 nIME; + u16 *pWSCNT; + u16 nOldWSCNT; + u16 *pProtect; + volatile struct AGBPrintStruct *pPrint; + + pProtect = (u16 *)AGB_PRINT_PROTECT_ADDR; + pPrint = (struct AGBPrintStruct *)AGB_PRINT_STRUCT_ADDR; + lpfnFuncFlush = (LPFN_PRINT_FLUSH)AGB_PRINT_FLUSH_ADDR; + pIME = (u16 *)REG_ADDR_IME; + nIME = *pIME; + pWSCNT = (u16 *)REG_ADDR_WAITCNT; + nOldWSCNT = *pWSCNT; + *pIME = nIME & ~1; + *pWSCNT = WSCNT_DATA; + + if (bAllData) + { + while (pPrint->m_nPut != pPrint->m_nGet) + { + *pProtect = 0x20; + lpfnFuncFlush(); + *pProtect = 0; + } + } + else if (pPrint->m_nPut != pPrint->m_nGet) + { + *pProtect = 0x20; + lpfnFuncFlush(); + *pProtect = 0; + } + + *pWSCNT = nOldWSCNT; + *pIME = nIME; +} + +void AGBPrintFlush1Block(void) +{ + AGBPrintTransferDataInternal(FALSE); +} + +void AGBPrintFlush(void) +{ + AGBPrintTransferDataInternal(TRUE); +} + +void AGBAssert(const char *pFile, int nLine, const char *pExpression, int nStopProgram) +{ + if (nStopProgram) + { + AGBPrintf("ASSERTION FAILED FILE=[%s] LINE=[%d] EXP=[%s] \n", pFile, nLine, pExpression); + AGBPrintFlush(); + asm(".hword 0xEFFF"); + } + else + { + AGBPrintf("WARING FILE=[%s] LINE=[%d] EXP=[%s] \n", pFile, nLine, pExpression); + } +} + +// TODO: Find a way to seamlessly support no$gba without shit hack defines +// nogba print function +/* +void NOGBAPrint(const char *pBuf) +{ + *(volatile u32*)NOGBAPRINTADDR = (u32)pBuf; +}*/ + +#endif From 419e6d885baa060506489a947718b8610173b450 Mon Sep 17 00:00:00 2001 From: ProjectRevoTPP Date: Sat, 6 Jan 2018 21:38:34 -0500 Subject: [PATCH 03/12] use firered isagbprint header. --- include/assert.h | 43 ---------------------------------- include/gba/gba.h | 1 + include/gba/isagbprint.h | 50 ++++++++++++++++++++++++++++++++++++++++ 3 files changed, 51 insertions(+), 43 deletions(-) delete mode 100755 include/assert.h create mode 100755 include/gba/isagbprint.h diff --git a/include/assert.h b/include/assert.h deleted file mode 100755 index 0c1e5bf77..000000000 --- a/include/assert.h +++ /dev/null @@ -1,43 +0,0 @@ -#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/gba/gba.h b/include/gba/gba.h index 42ae3cdde..349344031 100644 --- a/include/gba/gba.h +++ b/include/gba/gba.h @@ -7,5 +7,6 @@ #include "gba/multiboot.h" #include "gba/syscall.h" #include "gba/macro.h" +#include "gba/isagbprint.h" #endif // GUARD_GBA_GBA_H diff --git a/include/gba/isagbprint.h b/include/gba/isagbprint.h new file mode 100755 index 000000000..c5eb456c3 --- /dev/null +++ b/include/gba/isagbprint.h @@ -0,0 +1,50 @@ +#ifndef GUARD_GBA_ISAGBPRINT_H +#define GUARD_GBA_ISAGBPRINT_H + +#ifdef NDEBUG +#define AGBPrintInit() +#define AGBPutc(cChr) +#define AGBPrint(pBuf) +#define AGBPrintf(pBuf, ...) +#define AGBPrintFlush1Block() +#define AGBPrintFlush() +#define AGBAssert(pFile, nLine, pExpression, nStopProgram) +#else +void AGBPrintInit(void); +void AGBPutc(const char cChr); +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 + +#undef AGB_ASSERT +#ifdef NDEBUG +#define AGB_ASSERT(exp) +#else +#define AGB_ASSERT(exp) (exp) ? ((void*)0) : AGBAssert(__FILE__, __LINE__, #exp, 1); +#endif + +#undef AGB_WARNING +#ifdef NDEBUG +#define AGB_WARNING(exp) +#else +#define AGB_WARNING(exp) (exp) ? ((void*)0) : AGBAssert(__FILE__, __LINE__, #exp, 0); +#endif + +// for matching purposes + +#ifdef NDEBUG +#define AGB_ASSERT_EX(exp, file, line) +#else +#define AGB_ASSERT_EX(exp, file, line) (exp) ? ((void*)0) : AGBAssert(file, line, #exp, 1); +#endif + +#ifdef NDEBUG +#define AGB_WARNING_EX(exp, file, line) +#else +#define AGB_WARNING_EX(exp, file, line) (exp) ? ((void*)0) : AGBAssert(file, line, #exp, 0); +#endif + +#endif // GUARD_GBA_ISAGBPRINT_H From 10ddfac7abab614d2c4488244cee35054ed06fa8 Mon Sep 17 00:00:00 2001 From: ProjectRevoTPP Date: Sat, 6 Jan 2018 22:00:08 -0500 Subject: [PATCH 04/12] consistency --- include/config.h | 4 ++-- include/global.h | 3 +-- src/libisagbprn.c | 3 +-- 3 files changed, 4 insertions(+), 6 deletions(-) diff --git a/include/config.h b/include/config.h index ce8e4ae74..7ee4503c7 100644 --- a/include/config.h +++ b/include/config.h @@ -4,10 +4,10 @@ // 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 +// to define NDEBUG 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 +#define NDEBUG // NOTE: Don't try to enable assert right now as many pointers // still exist in defines and WILL likely result in a broken ROM. diff --git a/include/global.h b/include/global.h index 1d0962cf6..3e260fd2a 100644 --- a/include/global.h +++ b/include/global.h @@ -1,9 +1,8 @@ #ifndef GUARD_GLOBAL_H #define GUARD_GLOBAL_H +#include "config.h" // we need to define config before gba headers as print stuff needs the functions nulled before defines. #include "gba/gba.h" -#include "config.h" -#include "assert.h" // Prevent cross-jump optimization. #define BLOCK_CROSS_JUMP asm(""); diff --git a/src/libisagbprn.c b/src/libisagbprn.c index 867044217..f056be5d2 100755 --- a/src/libisagbprn.c +++ b/src/libisagbprn.c @@ -2,7 +2,6 @@ #include #include "gba/gba.h" #include "config.h" -#include "assert.h" #define AGB_PRINT_FLUSH_ADDR 0x9FE209D #define AGB_PRINT_STRUCT_ADDR 0x9FE20F8 @@ -25,7 +24,7 @@ struct AGBPrintStruct typedef void (*LPFN_PRINT_FLUSH)(void); -#ifndef NOAGBPRN +#ifndef NDEBUG void AGBPrintFlush1Block(void); void AGBPrintInit(void) From d98c14444ade7e975585e991ef89c7597295f1b4 Mon Sep 17 00:00:00 2001 From: ProjectRevoTPP Date: Sun, 7 Jan 2018 23:46:35 -0500 Subject: [PATCH 05/12] NDEBUG which is supposed to be NDEBUG... --- include/config.h | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/include/config.h b/include/config.h index 7ee4503c7..53502c6c2 100644 --- a/include/config.h +++ b/include/config.h @@ -4,9 +4,8 @@ // 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 NDEBUG 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. +// to define NDEBUG before release, however this has been changed as +// Ruby's actual debug build does not use the AGBPrint features. #define NDEBUG // NOTE: Don't try to enable assert right now as many pointers // still exist in defines and WILL likely result in a broken ROM. From 7d501c8b13de92f8fc26c283e745fd1ea37e9b27 Mon Sep 17 00:00:00 2001 From: ProjectRevoTPP Date: Mon, 8 Jan 2018 17:03:28 -0500 Subject: [PATCH 06/12] let the user deal with nogbaprint, forget this --- src/libisagbprn.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/libisagbprn.c b/src/libisagbprn.c index f056be5d2..a0eb09c8a 100755 --- a/src/libisagbprn.c +++ b/src/libisagbprn.c @@ -8,9 +8,8 @@ #define AGB_PRINT_PROTECT_ADDR 0x9FE2FFE #define WSCNT_DATA (WAITCNT_PHI_OUT_16MHZ | WAITCNT_WS0_S_2 | WAITCNT_WS0_N_4) -// TODO: make no$gba support not shit - // for auto no$gba support, the string "no$gba" should be at this address. +// except it's not, blame Martin, hence I'm letting the user deal with this nonsense. #define NOGBAIDADDR 0x4FFFA00 #define NOGBAPRINTADDR 0x4FFFA14 @@ -25,6 +24,7 @@ struct AGBPrintStruct typedef void (*LPFN_PRINT_FLUSH)(void); #ifndef NDEBUG + void AGBPrintFlush1Block(void); void AGBPrintInit(void) From d215fcc78ea590ed897f83f5d1b3855e0f99fc51 Mon Sep 17 00:00:00 2001 From: ProjectRevoTPP Date: Mon, 8 Jan 2018 17:05:26 -0500 Subject: [PATCH 07/12] actually change NOGBAPrint, stupid --- src/libisagbprn.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/libisagbprn.c b/src/libisagbprn.c index a0eb09c8a..c066a41a0 100755 --- a/src/libisagbprn.c +++ b/src/libisagbprn.c @@ -155,12 +155,12 @@ void AGBAssert(const char *pFile, int nLine, const char *pExpression, int nStopP } } -// TODO: Find a way to seamlessly support no$gba without shit hack defines -// nogba print function +// nogba print function, uncomment to use /* void NOGBAPrint(const char *pBuf) { *(volatile u32*)NOGBAPRINTADDR = (u32)pBuf; -}*/ +} +*/ #endif From ba1eb6d952bfbeacd9345629997b3bdc18befde3 Mon Sep 17 00:00:00 2001 From: ProjectRevoTPP Date: Mon, 8 Jan 2018 21:39:07 -0500 Subject: [PATCH 08/12] nogba to nocashgba --- src/libisagbprn.c | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/src/libisagbprn.c b/src/libisagbprn.c index c066a41a0..007f90bb7 100755 --- a/src/libisagbprn.c +++ b/src/libisagbprn.c @@ -10,8 +10,8 @@ // for auto no$gba support, the string "no$gba" should be at this address. // except it's not, blame Martin, hence I'm letting the user deal with this nonsense. -#define NOGBAIDADDR 0x4FFFA00 -#define NOGBAPRINTADDR 0x4FFFA14 +#define NOCASHGBAIDADDR 0x4FFFA00 +#define NOCASHGBAPRINTADDR 0x4FFFA14 struct AGBPrintStruct { @@ -155,11 +155,11 @@ void AGBAssert(const char *pFile, int nLine, const char *pExpression, int nStopP } } -// nogba print function, uncomment to use +// no$gba print function, uncomment to use /* -void NOGBAPrint(const char *pBuf) +void NoCashGBAPrint(const char *pBuf) { - *(volatile u32*)NOGBAPRINTADDR = (u32)pBuf; + *(volatile u32*)NOCASHGBAPRINTADDR = (u32)pBuf; } */ From 0bf530da12f671c678f7e524b4318213d49b30e0 Mon Sep 17 00:00:00 2001 From: ProjectRevoTPP Date: Mon, 8 Jan 2018 22:03:07 -0500 Subject: [PATCH 09/12] nocashgba printf --- include/config.h | 8 ++++++++ src/libisagbprn.c | 12 +++++++++++- 2 files changed, 19 insertions(+), 1 deletion(-) diff --git a/include/config.h b/include/config.h index 53502c6c2..318ed39d8 100644 --- a/include/config.h +++ b/include/config.h @@ -7,6 +7,14 @@ // to define NDEBUG before release, however this has been changed as // Ruby's actual debug build does not use the AGBPrint features. #define NDEBUG + +// To enable print debugging, comment out "#define NDEBUG". This allows +// the various AGBPrint functions to be used. (See include/gba/isagbprint.h). +// Some emulators support a debug console window: uncomment NoCashGBAPrint() +// and NoCashGBAPrintf() in libisagbprn.c to use no$gba's own proprietary +// printing system. Use NoCashGBAPrint() and NoCashGBAPrintf() like you +// would normally use AGBPrint() and AGBPrintf(). + // NOTE: Don't try to enable assert right now as many pointers // still exist in defines and WILL likely result in a broken ROM. diff --git a/src/libisagbprn.c b/src/libisagbprn.c index 007f90bb7..a9656f3c5 100755 --- a/src/libisagbprn.c +++ b/src/libisagbprn.c @@ -155,12 +155,22 @@ void AGBAssert(const char *pFile, int nLine, const char *pExpression, int nStopP } } -// no$gba print function, uncomment to use +// no$gba print functions, uncomment to use /* void NoCashGBAPrint(const char *pBuf) { *(volatile u32*)NOCASHGBAPRINTADDR = (u32)pBuf; } + +void NoCashGBAPrintf(const char *pBuf, ...) +{ + char bufPrint[0x100]; + va_list vArgv; + va_start(vArgv, pBuf); + vsprintf(bufPrint, pBuf, vArgv); + va_end(vArgv); + NoCashGBAPrint(bufPrint); +} */ #endif From e19c51cd108c4daa230760ac3a92ca8f1e16a34f Mon Sep 17 00:00:00 2001 From: ProjectRevoTPP Date: Tue, 9 Jan 2018 01:26:27 -0500 Subject: [PATCH 10/12] scrub ld_script for bloat --- ld_script.txt | 39 --------------------------------------- sym_bss.txt | 36 ------------------------------------ 2 files changed, 75 deletions(-) diff --git a/ld_script.txt b/ld_script.txt index 0618bcc55..ae8dd057d 100644 --- a/ld_script.txt +++ b/ld_script.txt @@ -15,44 +15,6 @@ SECTIONS { - 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; } @@ -66,7 +28,6 @@ SECTIONS { /* .bss.code starts at 0x3001AA8 */ src/m4a_2.o(.bss.code); - tools/agbcc/lib/libc.a:syscalls.o(.bss); /* COMMON starts at 0x30022A8 */ diff --git a/sym_bss.txt b/sym_bss.txt index 97a987c62..9a474a733 100644 --- a/sym_bss.txt +++ b/sym_bss.txt @@ -198,40 +198,4 @@ 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" From ecc2408cd5165da34fdc5966af1ad903ba09032d Mon Sep 17 00:00:00 2001 From: ProjectRevoTPP Date: Tue, 9 Jan 2018 19:28:32 -0500 Subject: [PATCH 11/12] comment --- src/libisagbprn.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/libisagbprn.c b/src/libisagbprn.c index a9656f3c5..98231dcf5 100755 --- a/src/libisagbprn.c +++ b/src/libisagbprn.c @@ -8,8 +8,8 @@ #define AGB_PRINT_PROTECT_ADDR 0x9FE2FFE #define WSCNT_DATA (WAITCNT_PHI_OUT_16MHZ | WAITCNT_WS0_S_2 | WAITCNT_WS0_N_4) -// for auto no$gba support, the string "no$gba" should be at this address. -// except it's not, blame Martin, hence I'm letting the user deal with this nonsense. +// originally for auto no$gba support, the string "no$gba" should be at this address, +// the user needs to read this string out as the memory viewer won't show it. #define NOCASHGBAIDADDR 0x4FFFA00 #define NOCASHGBAPRINTADDR 0x4FFFA14 From e1801885a0619724860cb322ba1cb8dba2b2c0f3 Mon Sep 17 00:00:00 2001 From: ProjectRevoTPP Date: Tue, 9 Jan 2018 19:39:51 -0500 Subject: [PATCH 12/12] both print defines for nocashgba --- src/libisagbprn.c | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/src/libisagbprn.c b/src/libisagbprn.c index 98231dcf5..e0e979e95 100755 --- a/src/libisagbprn.c +++ b/src/libisagbprn.c @@ -11,7 +11,8 @@ // originally for auto no$gba support, the string "no$gba" should be at this address, // the user needs to read this string out as the memory viewer won't show it. #define NOCASHGBAIDADDR 0x4FFFA00 -#define NOCASHGBAPRINTADDR 0x4FFFA14 +#define NOCASHGBAPRINTADDR1 0x4FFFA10 // automatically adds a newline after the string has finished +#define NOCASHGBAPRINTADDR2 0x4FFFA14 // does not automatically add the newline. by default, NOCASHGBAPRINTADDR2 is used. this is used to keep strings consistent between no$gba and VBA-RR, but a user can choose to forgo this. struct AGBPrintStruct { @@ -159,7 +160,7 @@ void AGBAssert(const char *pFile, int nLine, const char *pExpression, int nStopP /* void NoCashGBAPrint(const char *pBuf) { - *(volatile u32*)NOCASHGBAPRINTADDR = (u32)pBuf; + *(volatile u32*)NOCASHGBAPRINTADDR2 = (u32)pBuf; } void NoCashGBAPrintf(const char *pBuf, ...)