diff --git a/Makefile.ctr b/Makefile.ctr index d5ad185560..1005e50642 100644 --- a/Makefile.ctr +++ b/Makefile.ctr @@ -1,42 +1,34 @@ TARGET := retroarch_3ds LIBRETRO = -DEBUG = 0 -GRIFFIN_BUILD = 1 -WHOLE_ARCHIVE_LINK = 0 -BIG_STACK = 0 -BUILD_3DSX = 1 -BUILD_3DS = 1 -BUILD_CIA = 1 +DEBUG = 0 +GRIFFIN_BUILD = 1 +WHOLE_ARCHIVE_LINK = 0 +BUILD_3DSX = 1 +BUILD_3DS = 1 +BUILD_CIA = 1 -APP_TITLE = Retroarch 3DS -APP_DESCRIPTION = Retroarch 3DS -APP_AUTHOR = Team Libretro -APP_PRODUCT_CODE = RETROARCH-3DS -APP_UNIQUE_ID = 0xBAC00 -APP_ICON = ctr/default.png -APP_BANNER = ctr/libretro_banner.png -APP_AUDIO = ctr/silent.wav -APP_RSF = ctr/tools/template.rsf -APP_SYSTEM_MODE = 64MB -APP_SYSTEM_MODE_EXT = 124MB - - -ifeq ($(BIG_STACK),1) -CTR_STACK_SIZE = 0x400000 -else -CTR_STACK_SIZE = 0x100000 -endif -CTR_LINEAR_HEAP_SIZE = 0x600000 -CTR_MAX_HEAP_SIZE = 0x6000000 +APP_TITLE = Retroarch 3DS +APP_DESCRIPTION = Retroarch 3DS +APP_AUTHOR = Team Libretro +APP_PRODUCT_CODE = RETROARCH-3DS +APP_UNIQUE_ID = 0xBAC00 +APP_ICON = ctr/default.png +APP_BANNER = ctr/libretro_banner.png +APP_AUDIO = ctr/silent.wav +APP_RSF = ctr/tools/template.rsf +APP_SYSTEM_MODE = 64MB +APP_SYSTEM_MODE_EXT = 124MB include ctr/Makefile.cores -CONFIG_OBJECT = ctr/ctr_config_$(CTR_STACK_SIZE)_$(CTR_LINEAR_HEAP_SIZE)_$(CTR_MAX_HEAP_SIZE).o - OBJS := OBJS += gfx/drivers/ctr_sprite.o -OBJS += $(CONFIG_OBJECT) +OBJS += ctr/stack_adjust.o +OBJS += ctr/ctr_system.o +OBJS += ctr/ctr_memory.o +OBJS += ctr/ctr_linear.o + ifeq ($(GRIFFIN_BUILD), 1) OBJS += griffin/griffin.o else @@ -270,6 +262,7 @@ ARCH := -march=armv6k -mtune=mpcore -mfloat-abi=hard -marm -mfpu=vfp CFLAGS += -mword-relocations \ -fomit-frame-pointer -ffast-math \ + -Werror=implicit-function-declaration \ $(ARCH) #CFLAGS += -Wall @@ -286,19 +279,6 @@ ifeq ($(WHOLE_ARCHIVE_LINK), 1) WHOLE_END := -Wl,--no-whole-archive endif -ifneq ($(CTR_STACK_SIZE),) - CFLAGS += -DCTR_STACK_SIZE=$(CTR_STACK_SIZE) -endif - -ifneq ($(CTR_LINEAR_HEAP_SIZE),) - CFLAGS += -DCTR_LINEAR_HEAP_SIZE=$(CTR_LINEAR_HEAP_SIZE) -endif - -ifneq ($(CTR_MAX_HEAP_SIZE),) - CFLAGS += -DCTR_MAX_HEAP_SIZE=$(CTR_MAX_HEAP_SIZE) -endif - - CFLAGS += -I. -Ideps/zlib -Ideps/7zip -Ilibretro-common/include CFLAGS += -DRARCH_INTERNAL -DRARCH_CONSOLE -DSINC_LOWEST_QUALITY @@ -365,11 +345,6 @@ else BANNERTOOL = ctr/tools/bannertool.exe endif - -$(CONFIG_OBJECT): ctr/ctr_config.c - rm -f ctr/ctr_config_*.o - $(CC) -c -o $@ $< $(CFLAGS) $(INCDIRS) - %.o: %.shader python $(AEMSTRO)/aemstro_as.py $< $(notdir $<).shbin $(DEVKITARM)/bin/bin2s $(notdir $<).shbin | $(PREFIX)as -o $@ @@ -425,6 +400,7 @@ clean: rm -f $(TARGET).elf rm -f $(TARGET).3ds rm -f $(TARGET).cia + rm -f $(TARGET).smdh rm -f $(TARGET).bnr rm -f $(TARGET).icn rm -f *_shader_shbin.h diff --git a/ctr/Makefile.cores b/ctr/Makefile.cores index be1ce7ec33..2845421068 100644 --- a/ctr/Makefile.cores +++ b/ctr/Makefile.cores @@ -9,9 +9,6 @@ ifeq ($(LIBRETRO), gambatte) APP_ICON = ctr/gambatte.png #APP_BANNER = ctr/libretro_banner.png #APP_AUDIO = ctr/silent.wav - #APP_SYSTEM_MODE = 64MB - #APP_SYSTEM_MODE_EXT = Legacy - #CTR_LINEAR_HEAP_SIZE = 0x600000 else ifeq ($(LIBRETRO), gpsp) APP_TITLE = gpSP Libretro @@ -22,9 +19,6 @@ else ifeq ($(LIBRETRO), gpsp) APP_ICON = ctr/gpsp.png #APP_BANNER = ctr/libretro_banner.png #APP_AUDIO = ctr/silent.wav - #APP_SYSTEM_MODE = 64MB - #APP_SYSTEM_MODE_EXT = Legacy - #CTR_LINEAR_HEAP_SIZE = 0x600000 else ifeq ($(LIBRETRO), fceumm) APP_TITLE = FCeumm Libretro @@ -35,9 +29,6 @@ else ifeq ($(LIBRETRO), fceumm) APP_ICON = ctr/fceumm.png #APP_BANNER = ctr/libretro_banner.png #APP_AUDIO = ctr/silent.wav - #APP_SYSTEM_MODE = 64MB - #APP_SYSTEM_MODE_EXT = Legacy - #CTR_LINEAR_HEAP_SIZE = 0x600000 else ifeq ($(LIBRETRO), nestopia) APP_TITLE = Nestopia Libretro @@ -48,9 +39,6 @@ else ifeq ($(LIBRETRO), nestopia) APP_ICON = ctr/nestopia.png #APP_BANNER = ctr/libretro_banner.png #APP_AUDIO = ctr/silent.wav - #APP_SYSTEM_MODE = 64MB - #APP_SYSTEM_MODE_EXT = Legacy - CTR_LINEAR_HEAP_SIZE = 0xE00000 else ifeq ($(LIBRETRO), nxengine) APP_TITLE = NXengine Libretro @@ -61,9 +49,6 @@ else ifeq ($(LIBRETRO), nxengine) APP_ICON = ctr/nxengine.png #APP_BANNER = ctr/libretro_banner.png #APP_AUDIO = ctr/silent.wav - #APP_SYSTEM_MODE = 64MB - #APP_SYSTEM_MODE_EXT = Legacy - #CTR_LINEAR_HEAP_SIZE = 0x600000 else ifeq ($(LIBRETRO), genesis_plus_gx) APP_TITLE = Genesis Plus GX Libretro @@ -74,9 +59,6 @@ else ifeq ($(LIBRETRO), genesis_plus_gx) APP_ICON = ctr/genesis_plus_gx.png #APP_BANNER = ctr/libretro_banner.png #APP_AUDIO = ctr/silent.wav - #APP_SYSTEM_MODE = 64MB - #APP_SYSTEM_MODE_EXT = Legacy - CTR_LINEAR_HEAP_SIZE = 0xE00000 else ifeq ($(LIBRETRO), catsfc) APP_TITLE = CATSFC Libretro @@ -87,9 +69,6 @@ else ifeq ($(LIBRETRO), catsfc) APP_ICON = ctr/catsfc.png #APP_BANNER = ctr/libretro_banner.png #APP_AUDIO = ctr/silent.wav - #APP_SYSTEM_MODE = 64MB - #APP_SYSTEM_MODE_EXT = Legacy - #CTR_LINEAR_HEAP_SIZE = 0x600000 else ifeq ($(LIBRETRO), mednafen_wswan) APP_TITLE = Mednafen wswan Libretro @@ -100,9 +79,6 @@ else ifeq ($(LIBRETRO), mednafen_wswan) APP_ICON = ctr/mednafen_wswan.png #APP_BANNER = ctr/libretro_banner.png #APP_AUDIO = ctr/silent.wav - #APP_SYSTEM_MODE = 64MB - #APP_SYSTEM_MODE_EXT = Legacy - CTR_LINEAR_HEAP_SIZE = 0xE00000 else ifeq ($(LIBRETRO), mednafen_vb) APP_TITLE = Mednafen VB Libretro @@ -113,9 +89,6 @@ else ifeq ($(LIBRETRO), mednafen_vb) APP_ICON = ctr/mednafen_vb.png #APP_BANNER = ctr/libretro_banner.png #APP_AUDIO = ctr/silent.wav - #APP_SYSTEM_MODE = 64MB - #APP_SYSTEM_MODE_EXT = Legacy - CTR_LINEAR_HEAP_SIZE = 0xE00000 else ifeq ($(LIBRETRO), mednafen_ngp) APP_TITLE = Mednafen NGP Libretro @@ -126,9 +99,6 @@ else ifeq ($(LIBRETRO), mednafen_ngp) APP_ICON = ctr/mednafen_ngp.png #APP_BANNER = ctr/libretro_banner.png #APP_AUDIO = ctr/silent.wav - #APP_SYSTEM_MODE = 64MB - #APP_SYSTEM_MODE_EXT = Legacy - CTR_LINEAR_HEAP_SIZE = 0xE00000 else ifeq ($(LIBRETRO), 2048) APP_TITLE = 2048 Libretro @@ -139,9 +109,6 @@ else ifeq ($(LIBRETRO), 2048) APP_ICON = ctr/2048.png #APP_BANNER = ctr/libretro_banner.png #APP_AUDIO = ctr/silent.wav - #APP_SYSTEM_MODE = 64MB - #APP_SYSTEM_MODE_EXT = Legacy - CTR_LINEAR_HEAP_SIZE = 0xE00000 else ifeq ($(LIBRETRO), picodrive) APP_TITLE = Picodrive Libretro @@ -152,9 +119,6 @@ else ifeq ($(LIBRETRO), picodrive) APP_ICON = ctr/picodrive.png #APP_BANNER = ctr/libretro_banner.png #APP_AUDIO = ctr/silent.wav - #APP_SYSTEM_MODE = 64MB - #APP_SYSTEM_MODE_EXT = Legacy - #CTR_LINEAR_HEAP_SIZE = 0x600000 else ifeq ($(LIBRETRO), snes9x_next) APP_TITLE = Snes9x Next Libretro @@ -165,9 +129,6 @@ else ifeq ($(LIBRETRO), snes9x_next) APP_ICON = ctr/snes9x_next.png #APP_BANNER = ctr/libretro_banner.png #APP_AUDIO = ctr/silent.wav - #APP_SYSTEM_MODE = 64MB - #APP_SYSTEM_MODE_EXT = Legacy - #CTR_LINEAR_HEAP_SIZE = 0x600000 else ifeq ($(LIBRETRO), mgba) APP_TITLE = mGBA Libretro @@ -178,9 +139,6 @@ else ifeq ($(LIBRETRO), mgba) APP_ICON = ctr/mgba.png #APP_BANNER = ctr/libretro_banner.png #APP_AUDIO = ctr/silent.wav - #APP_SYSTEM_MODE = 64MB - #APP_SYSTEM_MODE_EXT = Legacy - #CTR_LINEAR_HEAP_SIZE = 0x600000 else ifeq ($(LIBRETRO), quicknes) APP_TITLE = QuickNES Libretro @@ -191,9 +149,6 @@ else ifeq ($(LIBRETRO), quicknes) APP_ICON = ctr/quicknes.png #APP_BANNER = ctr/libretro_banner.png #APP_AUDIO = ctr/silent.wav - #APP_SYSTEM_MODE = 64MB - #APP_SYSTEM_MODE_EXT = Legacy - #CTR_LINEAR_HEAP_SIZE = 0x600000 else ifeq ($(LIBRETRO), fb_alpha_neo) APP_TITLE = Neo Geo (FB Alpha) @@ -205,9 +160,6 @@ else ifeq ($(LIBRETRO), fb_alpha_neo) #APP_BANNER = ctr/libretro_banner.png #APP_AUDIO = ctr/silent.wav APP_SYSTEM_MODE = 80MB - #APP_SYSTEM_MODE_EXT = Legacy - CTR_LINEAR_HEAP_SIZE = 0x3A0000 - CTR_MAX_HEAP_SIZE = 0xC00000 else ifeq ($(LIBRETRO), fb_alpha_cps1) APP_TITLE = Final Burn Alpha - CPS-1 @@ -218,9 +170,6 @@ else ifeq ($(LIBRETRO), fb_alpha_cps1) APP_ICON = ctr/fb_alpha_cps1.png #APP_BANNER = ctr/libretro_banner.png #APP_AUDIO = ctr/silent.wav - #APP_SYSTEM_MODE = 64MB - #APP_SYSTEM_MODE_EXT = Legacy - #CTR_LINEAR_HEAP_SIZE = 0x600000 else ifeq ($(LIBRETRO), fb_alpha_cps2) APP_TITLE = Final Burn Alpha - CPS-2 @@ -232,8 +181,6 @@ else ifeq ($(LIBRETRO), fb_alpha_cps2) #APP_BANNER = ctr/libretro_banner.png #APP_AUDIO = ctr/silent.wav APP_SYSTEM_MODE = 80MB - #APP_SYSTEM_MODE_EXT = Legacy - #CTR_LINEAR_HEAP_SIZE = 0x600000 else ifeq ($(LIBRETRO), catsfc_plus) APP_TITLE = CATSFC Plus Libretro @@ -244,9 +191,6 @@ else ifeq ($(LIBRETRO), catsfc_plus) APP_ICON = ctr/catsfc_plus.png #APP_BANNER = ctr/libretro_banner.png #APP_AUDIO = ctr/silent.wav - #APP_SYSTEM_MODE = 64MB - #APP_SYSTEM_MODE_EXT = Legacy - #CTR_LINEAR_HEAP_SIZE = 0x600000 else ifeq ($(LIBRETRO), mednafen_pce_fast) APP_TITLE = Mednafen/Beetle PCE FAST @@ -257,9 +201,6 @@ else ifeq ($(LIBRETRO), mednafen_pce_fast) APP_ICON = ctr/mednafen_pce_fast.png #APP_BANNER = ctr/libretro_banner.png #APP_AUDIO = ctr/silent.wav - #APP_SYSTEM_MODE = 64MB - #APP_SYSTEM_MODE_EXT = Legacy - #CTR_LINEAR_HEAP_SIZE = 0x600000 else ifeq ($(LIBRETRO), pcsx_rearmed) APP_TITLE = PCSX ReARMed @@ -270,9 +211,6 @@ else ifeq ($(LIBRETRO), pcsx_rearmed) APP_ICON = ctr/pcsx_rearmed.png #APP_BANNER = ctr/libretro_banner.png #APP_AUDIO = ctr/silent.wav - #APP_SYSTEM_MODE = 64MB - #APP_SYSTEM_MODE_EXT = Legacy - CTR_LINEAR_HEAP_SIZE = 0xE00000 else ifeq ($(LIBRETRO), fmsx) APP_TITLE = fMSX @@ -283,8 +221,5 @@ else ifeq ($(LIBRETRO), fmsx) APP_ICON = ctr/fmsx.png #APP_BANNER = ctr/libretro_banner.png #APP_AUDIO = ctr/silent.wav - #APP_SYSTEM_MODE = 64MB - #APP_SYSTEM_MODE_EXT = Legacy - CTR_LINEAR_HEAP_SIZE = 0x1000000 endif diff --git a/ctr/ctr_config.c b/ctr/ctr_config.c deleted file mode 100644 index 21cc60022d..0000000000 --- a/ctr/ctr_config.c +++ /dev/null @@ -1,18 +0,0 @@ - - -#ifndef CTR_STACK_SIZE -#define CTR_STACK_SIZE 0x100000 -#endif - -#ifndef CTR_LINEAR_HEAP_SIZE -#define CTR_LINEAR_HEAP_SIZE 0x600000 -#endif - -#ifndef CTR_MAX_HEAP_SIZE -#define CTR_MAX_HEAP_SIZE 0x6000000 -#endif - - -int __stacksize__ = CTR_STACK_SIZE; -unsigned int __linear_heap_size = CTR_LINEAR_HEAP_SIZE; -unsigned int __heap_size = CTR_MAX_HEAP_SIZE + CTR_STACK_SIZE; diff --git a/ctr/ctr_debug.h b/ctr/ctr_debug.h new file mode 100644 index 0000000000..02dc35eb8c --- /dev/null +++ b/ctr/ctr_debug.h @@ -0,0 +1,23 @@ +#ifndef _CTR_DEBUG_H__ +#define _CTR_DEBUG_H__ + +#include + +#ifdef __cplusplus +extern "C" { +#endif +void wait_for_input(void); +void dump_result_value(Result val); +#ifdef __cplusplus +} +#endif + +#define DEBUG_HOLD() do{printf("%s@%s:%d.\n",__FUNCTION__, __FILE__, __LINE__);fflush(stdout);wait_for_input();}while(0) +#define DEBUG_STR(X) printf( "%s: %s\n", #X, (char*)(X)) +#define DEBUG_VAR(X) printf( "%-20s: 0x%08X\n", #X, (u32)(X)) +#define DEBUG_VAR64(X) printf( #X"\r\t\t\t\t : 0x%016llX\n", (u64)(X)) +#define DEBUG_ERROR(X) do{if(X)dump_result_value(X)}while(0) +#define PRINTFPOS(X,Y) "\x1b["#X";"#Y"H" +#define PRINTFPOS_STR(X,Y) "\x1b["X";"Y"H" + +#endif //_CTR_DEBUG_H__ diff --git a/ctr/ctr_linear.cpp b/ctr/ctr_linear.cpp new file mode 100644 index 0000000000..6afa03324a --- /dev/null +++ b/ctr/ctr_linear.cpp @@ -0,0 +1,273 @@ +/* from https://github.com/smealum/ctrulib + * modified to allow reducing __linear_heap_size at runtime */ + + +#include <3ds.h> +#include +#include <3ds/util/rbtree.h> +#include "ctr_debug.h" + +struct MemChunk +{ + u8* addr; + u32 size; +}; + +struct MemBlock +{ + MemBlock *prev, *next; + u8* base; + u32 size; + + static MemBlock* Create(u8* base, u32 size) + { + auto b = (MemBlock*)malloc(sizeof(MemBlock)); + if (!b) return nullptr; + b->prev = nullptr; + b->next = nullptr; + b->base = base; + b->size = size; + return b; + } +}; + +struct MemPool +{ + MemBlock *first, *last; + + bool Ready() { return first != nullptr; } + + void AddBlock(MemBlock* blk) + { + blk->prev = last; + if (last) last->next = blk; + if (!first) first = blk; + last = blk; + } + + void DelBlock(MemBlock* b) + { + auto prev = b->prev, &pNext = prev ? prev->next : first; + auto next = b->next, &nPrev = next ? next->prev : last; + pNext = next; + nPrev = prev; + free(b); + } + + void InsertBefore(MemBlock* b, MemBlock* p) + { + auto prev = b->prev, &pNext = prev ? prev->next : first; + b->prev = p; + p->next = b; + p->prev = prev; + pNext = p; + } + + void InsertAfter(MemBlock* b, MemBlock* n) + { + auto next = b->next, &nPrev = next ? next->prev : last; + b->next = n; + n->prev = b; + n->next = next; + nPrev = n; + } + + //void CoalesceLeft(MemBlock* b); + void CoalesceRight(MemBlock* b); + + bool Allocate(MemChunk& chunk, u32 size, int align); + void Deallocate(const MemChunk& chunk); + + void Destroy() + { + MemBlock* next = nullptr; + for (auto b = first; b; b = next) + { + next = b->next; + free(b); + } + first = nullptr; + last = nullptr; + } + + //void Dump(const char* title); + u32 GetFreeSpace(); +}; + +static rbtree_t sAddrMap; + +struct addrMapNode +{ + rbtree_node node; + MemChunk chunk; +}; + +#define getAddrMapNode(x) rbtree_item((x), addrMapNode, node) + +static int addrMapNodeComparator(const rbtree_node_t* _lhs, const rbtree_node_t* _rhs) +{ + auto lhs = getAddrMapNode(_lhs)->chunk.addr; + auto rhs = getAddrMapNode(_rhs)->chunk.addr; + if (lhs < rhs) + return -1; + if (lhs > rhs) + return 1; + return 0; +} + +static void addrMapNodeDestructor(rbtree_node_t* a) +{ + free(getAddrMapNode(a)); +} + +static addrMapNode* getNode(void* addr) +{ + addrMapNode n; + n.chunk.addr = (u8*)addr; + auto p = rbtree_find(&sAddrMap, &n.node); + return p ? getAddrMapNode(p) : nullptr; +} + +static addrMapNode* newNode(const MemChunk& chunk) +{ + auto p = (addrMapNode*)malloc(sizeof(addrMapNode)); + if (!p) return nullptr; + p->chunk = chunk; + return p; +} + +static void delNode(addrMapNode* node) +{ + rbtree_remove(&sAddrMap, &node->node, addrMapNodeDestructor); +} + +extern u32 __linear_heap, __linear_heap_size; + +static MemPool sLinearPool; +static u32 sLinearPool_maxaddr; + +static bool linearInit() +{ + auto blk = MemBlock::Create((u8*)__linear_heap, __linear_heap_size); + if (blk) + { + sLinearPool.AddBlock(blk); + sLinearPool_maxaddr = __linear_heap; + rbtree_init(&sAddrMap, addrMapNodeComparator); + return true; + } + return false; +} + +void* linearMemAlign(size_t size, size_t alignment) +{ + // Enforce minimum alignment + if (alignment < 16) + alignment = 16; + + // Convert alignment to shift amount + int shift; + for (shift = 4; shift < 32; shift ++) + { + if ((1U<node)); + + if (sLinearPool_maxaddr < (u32)sLinearPool.last->base) + sLinearPool_maxaddr = (u32)sLinearPool.last->base; + + return chunk.addr; +} + +void* linearAlloc(size_t size) +{ +// extern PrintConsole* currentConsole; +// if(currentConsole->consoleInitialised) +// { +// printf("linearAlloc : 0x%08X\n", size); +// DEBUG_HOLD(); +// } + return linearMemAlign(size, 0x80); +} + +void* linearRealloc(void* mem, size_t size) +{ + // TODO + return NULL; +} + +void linearFree(void* mem) +{ + auto node = getNode(mem); + if (!node) return; + + // Free the chunk + sLinearPool.Deallocate(node->chunk); + + // Free the node + delNode(node); +} + +u32 linearSpaceFree() +{ + return sLinearPool.GetFreeSpace(); +} + +extern "C" u32 ctr_get_linear_free(void) +{ + if(sLinearPool.last->base + sLinearPool.last->size != (u8*)__linear_heap + __linear_heap_size) + return 0; + return sLinearPool.last->size; +} + +extern "C" u32 ctr_get_linear_unused(void) +{ + return __linear_heap + __linear_heap_size - sLinearPool_maxaddr; +} + + +extern "C" void ctr_linear_free_pages(u32 pages) +{ + if(sLinearPool.last->base + sLinearPool.last->size != (u8*)__linear_heap + __linear_heap_size) + return; + + u32 size = pages << 12; + if(size > sLinearPool.last->size) + return; + + sLinearPool.last->size -= size; + __linear_heap_size -= size; + u32 tmp; + svcControlMemory(&tmp, __linear_heap + __linear_heap_size, 0x0, size, + MEMOP_FREE, (MemPerm)(MEMPERM_READ | MEMPERM_WRITE)); + +// printf("l:0x%08X-->0x%08X(-0x%08X) \n", sLinearPool.last->size + size, sLinearPool.last->size, size); +// DEBUG_HOLD(); +} + +extern "C" void ctr_linear_get_stats(void) +{ + printf("last:\n"); + printf("0x%08X --> 0x%08X (0x%08X) \n", sLinearPool.last->base, + sLinearPool.last->base + sLinearPool.last->size, sLinearPool.last->size); + printf("free: 0x%08X unused: 0x%08X \n", ctr_get_linear_unused(), ctr_get_linear_free()); +} diff --git a/ctr/ctr_memory.c b/ctr/ctr_memory.c new file mode 100644 index 0000000000..b210a9eb0f --- /dev/null +++ b/ctr/ctr_memory.c @@ -0,0 +1,151 @@ +#include <3ds.h> +#include +#include +#include + +#include "ctr_debug.h" + +//void* malloc(size_t nbytes) +//{ +// void* ret = _malloc_r (_REENT, nbytes); +// return ret; +//} + +//void free (void* aptr) +//{ +// _free_r (_REENT, aptr); +//} + +extern u32 __heapBase; +extern u32 __heap_size; +extern u32 __stack_bottom; +extern u32 __stack_size_extra; +extern u32 __stacksize__; + +u32 ctr_get_linear_free(void); +u32 ctr_get_linear_unused(void); + +u32 ctr_get_stack_free(void) +{ + extern u32 __stack_bottom; + + uint32_t* stack_bottom_current = (u32*)__stack_bottom; + while(*stack_bottom_current++ == 0xFCFCFCFC); + stack_bottom_current--; + + return ((u32)stack_bottom_current - __stack_bottom); +} + + +u32 ctr_get_stack_usage(void) +{ + extern u32 __stacksize__; + u32 stack_free = ctr_get_stack_free(); + + return __stacksize__ > stack_free? __stacksize__ - stack_free: 0; +} + +void ctr_linear_free_pages(u32 pages); + +void ctr_free_pages(u32 pages) +{ + if(!pages) + return; + + u32 linear_free_pages = ctr_get_linear_free() >> 12; + + if((ctr_get_linear_unused() >> 12) > pages + 0x100) + return ctr_linear_free_pages(pages); + +// if(linear_free_pages > pages + 0x400) +// return ctr_linear_free_pages(pages); + + u32 stack_free = ctr_get_stack_free(); + u32 stack_usage = __stacksize__ > stack_free? __stacksize__ - stack_free: 0; + + stack_free = stack_free > __stack_size_extra ? __stack_size_extra : stack_free; + + u32 stack_free_pages = stack_free >> 12; + + if(linear_free_pages + (stack_free_pages - (stack_usage >> 12)) > pages) + { + stack_free_pages -= (stack_usage >> 12); + stack_free_pages = stack_free_pages > pages ? pages : stack_free_pages; + linear_free_pages = pages - stack_free_pages; + } + else if(linear_free_pages + stack_free_pages > pages) + stack_free_pages = pages - linear_free_pages; + else + return; + + if(linear_free_pages) + ctr_linear_free_pages(linear_free_pages); + + if(stack_free_pages) + { + u32 tmp; + svcControlMemory(&tmp, __stack_bottom, + 0x0, + stack_free_pages << 12, + MEMOP_FREE, MEMPERM_READ | MEMPERM_WRITE); + __stack_bottom += stack_free_pages << 12; + __stack_size_extra -= stack_free_pages << 12; + __stacksize__ -= stack_free_pages << 12; +// printf("s:0x%08X-->0x%08X(-0x%08X) \n", stack_free, +// stack_free - (stack_free_pages << 12), stack_free_pages << 12); +// DEBUG_HOLD(); + } +} + +u32 ctr_get_free_space(void) +{ + u32 app_memory = *((u32*)0x1FF80040); + s64 mem_used; + svcGetSystemInfo(&mem_used, 0, 1); + return app_memory - (u32)mem_used; +} + +void ctr_request_free_pages(u32 pages) +{ + u32 free_pages = ctr_get_free_space() >> 12; + if (pages > free_pages) + { + ctr_free_pages(pages - free_pages); + free_pages = ctr_get_free_space() >> 12; + } +} + +void* _sbrk_r(struct _reent *ptr, ptrdiff_t incr) +{ + static u32 sbrk_top = 0; + + if (!sbrk_top) + sbrk_top = __heapBase; + + u32 tmp; + + int diff = ((sbrk_top + incr + 0xFFF) & ~0xFFF) + - (__heapBase + __heap_size); + + if (diff > 0) + { + ctr_request_free_pages(diff >> 12); + + if (svcControlMemory(&tmp, __heapBase + __heap_size, + 0x0, diff, MEMOP_ALLOC, MEMPERM_READ | MEMPERM_WRITE) < 0) + { + ptr->_errno = ENOMEM; + return (caddr_t) -1; + } + } + + __heap_size += diff; + + if (diff < 0) + svcControlMemory(&tmp, __heapBase + __heap_size, + 0x0, -diff, MEMOP_FREE, MEMPERM_READ | MEMPERM_WRITE); + + sbrk_top += incr; + + return (caddr_t)(sbrk_top - incr); +} diff --git a/ctr/ctr_system.c b/ctr/ctr_system.c new file mode 100644 index 0000000000..477246222e --- /dev/null +++ b/ctr/ctr_system.c @@ -0,0 +1,238 @@ + +#include <3ds.h> +#include +#include +#include +#include + +#define CTR_APPMEMALLOC_PTR ((u32*)0x1FF80040) + +u32 __stacksize__ = 0x00400000; +u32 __linear_heap_size = 0x01000000; + +u32 __heap_size; +u32 __linear_heap; +u32 __heapBase; + +extern u32 __linear_heap_size_hbl; +extern u32 __heap_size_hbl; + +extern void (*__system_retAddr)(void); + +void __destroy_handle_list(void); +void __appExit(); +void __libc_fini_array(void); + +void __libctru_init(void (*retAddr)(void)); +void __appInit(); +void __libc_init_array(void); + + +u32 __stack_bottom; +u32 __stack_size_extra; + +void __system_allocateHeaps() { + u32 tmp=0; + + MemInfo stack_memInfo; + PageInfo stack_pageInfo; + + register u32 sp_val __asm__("sp"); + + svcQueryMemory(&stack_memInfo, &stack_pageInfo, sp_val); + + __stacksize__ += 0xFFF; + __stacksize__ &= ~0xFFF; + __stack_size_extra = __stacksize__ > stack_memInfo.size ? __stacksize__ - stack_memInfo.size: 0; + __stack_bottom = stack_memInfo.base_addr - __stack_size_extra; + + if (__stack_size_extra) + { + svcControlMemory(&tmp, __stack_bottom, 0x0, __stack_size_extra, MEMOP_ALLOC, MEMPERM_READ | MEMPERM_WRITE); + memset((void*)__stack_bottom, 0xFC, __stack_size_extra); + } + + // setup the application heap + __heapBase = 0x08000000; + __heap_size = 0; + + // Allocate the linear heap + svcControlMemory(&__linear_heap, 0x0, 0x0, __linear_heap_size, MEMOP_ALLOC_LINEAR, MEMPERM_READ | MEMPERM_WRITE); + // Set up newlib heap + extern char* fake_heap_end; + fake_heap_end = 0x13F00000; + +} + +Result __sync_fini(void) __attribute__((weak)); + +extern char** __system_argv; +void __attribute__((noreturn)) __libctru_exit(int rc) +{ + u32 tmp=0; + + if(__system_argv) + free(__system_argv); + + // Unmap the linear heap + svcControlMemory(&tmp, __linear_heap, 0x0, __linear_heap_size, MEMOP_FREE, 0x0); + + // Unmap the application heap + svcControlMemory(&tmp, __heapBase, 0x0, __heap_size, MEMOP_FREE, 0x0); + + if (__stack_size_extra) + svcControlMemory(&tmp, __stack_bottom, 0x0, __stack_size_extra, MEMOP_FREE, 0x0); + + // Close some handles + __destroy_handle_list(); + + if (__sync_fini) + __sync_fini(); + + // Jump to the loader if it provided a callback + if (__system_retAddr) + __system_retAddr(); + + // Since above did not jump, end this process + svcExitProcess(); +} + +#include <3ds/types.h> + +#include + +// System globals we define here +int __system_argc; +char** __system_argv; +extern const char* __system_arglist; + +//extern char* fake_heap_start; +extern char* fake_heap_end; + +void __system_initArgv() +{ + int i; + const char* temp = __system_arglist; + + // Check if the argument list is present + if (!temp) + return; + + // Retrieve argc + __system_argc = *(u32*)temp; + temp += sizeof(u32); + + // Find the end of the argument data + for (i = 0; i < __system_argc; i ++) + { + for (; *temp; temp ++); + temp ++; + } + + // Reserve heap memory for argv data + u32 argSize = temp - __system_arglist - sizeof(u32); +// __system_argv = (char**)fake_heap_start; +// fake_heap_start += sizeof(char**)*(__system_argc + 1); +// char* argCopy = fake_heap_start; +// fake_heap_start += argSize; + + __system_argv = malloc(sizeof(char**)*(__system_argc + 1) + argSize); + char* argCopy = (char*)__system_argv + sizeof(char**)*(__system_argc + 1); + + + // Fill argv array + memcpy(argCopy, &__system_arglist[4], argSize); + temp = argCopy; + for (i = 0; i < __system_argc; i ++) + { + __system_argv[i] = (char*)temp; + for (; *temp; temp ++); + temp ++; + } + __system_argv[__system_argc] = NULL; +} + + +//void initSystem(void (*retAddr)(void)) +//{ +// __libctru_init(retAddr); +// __appInit(); +// __libc_init_array(); + +//} +//void __attribute__((noreturn)) __ctru_exit(int rc) +//{ +// __libc_fini_array(); +// __appExit(); +// __libctru_exit(rc); + + +//} + +typedef union{ + struct + { + unsigned description : 10; + unsigned module : 8; + unsigned : 3; + unsigned summary : 6; + unsigned level : 5; + }; + Result val; +}ctr_result_value; + +void dump_result_value(Result val) +{ + ctr_result_value res; + res.val = val; + printf("result : 0x%08X\n", val); + printf("description : %u\n", res.description); + printf("module : %u\n", res.module); + printf("summary : %u\n", res.summary); + printf("level : %u\n", res.level); +} + +bool select_pressed = false; + +void wait_for_input(void) +{ + printf("\n\nPress Start.\n\n"); + fflush(stdout); + + while(aptMainLoop()) + { + u32 kDown; + + hidScanInput(); + + kDown = hidKeysDown(); + + if (kDown & KEY_START) + break; + + if (kDown & KEY_SELECT) + exit(0); +#if 0 + select_pressed = true; +#endif + + svcSleepThread(1000000); + } +} + +int usleep (useconds_t us) +{ + svcSleepThread((int64_t)us * 1000); +} + +long sysconf(int name) +{ + switch(name) + { + case _SC_NPROCESSORS_ONLN: + return 2; + } + + return -1; +} + diff --git a/ctr/stack_adjust.s b/ctr/stack_adjust.s new file mode 100644 index 0000000000..f872b34a96 --- /dev/null +++ b/ctr/stack_adjust.s @@ -0,0 +1,49 @@ + + .arm + .align 2 + + .global initSystem + .type initSystem, %function + +initSystem: + ldr r2, =saved_stack + str sp, [r2] + str lr, [r2,#4] + + bics sp, sp, #7 + + bl __libctru_init + + bl __appInit + bl __libc_init_array + + ldr r2, =saved_stack + ldr lr, [r2,#4] + bx lr + + + .global __ctru_exit + .type __ctru_exit, %function + +__ctru_exit: + bl __libc_fini_array + bl __appExit + + + ldr r2, =saved_stack + ldr sp, [r2] + b __libctru_exit + + .data + .align 2 +__stacksize__: + .word 0x100000 + .weak __stacksize__ + + .bss + .align 2 +saved_stack: + .space 8 + + + diff --git a/ctr/tools/template.rsf b/ctr/tools/template.rsf index 7f3590ed8d..e3e9e77362 100644 --- a/ctr/tools/template.rsf +++ b/ctr/tools/template.rsf @@ -174,7 +174,7 @@ AccessControlInfo: SystemControlInfo: RemasterVersion: 2 - StackSize: 0x40000 + StackSize: 0x4000 # Modules that run services listed above should be included below # Maximum 48 dependencies # If a module is listed that isn't present on the 3DS, the title will get stuck at the logo (3ds waves) diff --git a/frontend/drivers/platform_ctr.c b/frontend/drivers/platform_ctr.c index f9ac12a0de..9b93a19bf0 100644 --- a/frontend/drivers/platform_ctr.c +++ b/frontend/drivers/platform_ctr.c @@ -16,7 +16,6 @@ #include #include #include -#include #include @@ -31,6 +30,8 @@ #include "retroarch.h" #include "audio/audio_driver.h" +#include "ctr/ctr_debug.h" + #ifdef IS_SALAMANDER #include "../../file_ext.h" #else @@ -39,90 +40,6 @@ const char* elf_path_cst = "sdmc:/retroarch/test.3dsx"; -#ifndef DEBUG_HOLD -void wait_for_input(void); -void dump_result_value(Result val); -#define DEBUG_HOLD() do{printf("%s@%s:%d.\n",__FUNCTION__, __FILE__, __LINE__);fflush(stdout);wait_for_input();}while(0) -#define DEBUG_VAR(X) printf( "%-20s: 0x%08X\n", #X, (u32)(X)) -#define DEBUG_VAR64(X) printf( #X"\r\t\t\t\t : 0x%016llX\n", (u64)(X)) -#define DEBUG_ERROR(X) do{if(X)dump_result_value(X)}while(0) -#define PRINTFPOS(X,Y) "\x1b["#X";"#Y"H" -#define PRINTFPOS_STR(X,Y) "\x1b["X";"Y"H" -#endif - -#define CTR_APPMEMALLOC_PTR ((u32*)0x1FF80040) - -extern char* fake_heap_start; -extern char* fake_heap_end; -u32 __linear_heap; -u32 __heapBase; -extern u32 __linear_heap_size; -extern u32 __heap_size; -extern u32 __linear_heap_size_hbl; -extern u32 __heap_size_hbl; - -extern void (*__system_retAddr)(void); - -void __destroy_handle_list(void); -void __appExit(); -void __libc_fini_array(void); - -void __system_allocateHeaps() { - extern unsigned int __service_ptr; - u32 tmp=0; - int64_t mem_used; - u32 mem_available; - u32 app_memory; - - svcGetSystemInfo(&mem_used, 0, 1); - - if(__service_ptr) - { - app_memory = mem_used + __linear_heap_size_hbl + __heap_size_hbl; - app_memory = app_memory < 0x04000000 ? 0x04000000 : app_memory; - } - else - app_memory = *CTR_APPMEMALLOC_PTR; - - mem_available = (app_memory - mem_used - __linear_heap_size - 0x10000) & 0xFFFFF000; - - __heap_size = __heap_size > mem_available ? mem_available : __heap_size; - __heap_size = __heap_size > 0x6000000 ? 0x6000000 : __heap_size; - -// __linear_heap_size = (app_memory - mem_used - __heap_size - 0x10000) & 0xFFFFF000; - - // Allocate the application heap - __heapBase = 0x08000000; - svcControlMemory(&tmp, __heapBase, 0x0, __heap_size, MEMOP_ALLOC, MEMPERM_READ | MEMPERM_WRITE); - - // Allocate the linear heap - svcControlMemory(&__linear_heap, 0x0, 0x0, __linear_heap_size, MEMOP_ALLOC_LINEAR, MEMPERM_READ | MEMPERM_WRITE); - // Set up newlib heap - fake_heap_start = (char*)__heapBase; - fake_heap_end = fake_heap_start + __heap_size; -} - -void __attribute__((noreturn)) __libctru_exit(int rc) -{ - u32 tmp=0; - - // Unmap the linear heap - svcControlMemory(&tmp, __linear_heap, 0x0, __linear_heap_size, MEMOP_FREE, 0x0); - - // Unmap the application heap - svcControlMemory(&tmp, __heapBase, 0x0, __heap_size, MEMOP_FREE, 0x0); - - // Close some handles - __destroy_handle_list(); - - // Jump to the loader if it provided a callback - if (__system_retAddr) - __system_retAddr(); - - // Since above did not jump, end this process - svcExitProcess(); -} - static void frontend_ctr_get_environment_settings(int *argc, char *argv[], void *args, void *params_data) { @@ -161,9 +78,15 @@ static void frontend_ctr_get_environment_settings(int *argc, char *argv[], fill_pathname_join(g_defaults.path.config, g_defaults.dir.port, "retroarch.cfg", sizeof(g_defaults.path.config)); - *argc = 0; +#if 0 + int i; + DEBUG_VAR(*argc); + for (i=0; i < *argc; i++) + DEBUG_STR(argv[i]); + DEBUG_HOLD(); +#endif - *argc=0; + *argc = 0; #ifndef IS_SALAMANDER #if 0 @@ -324,190 +247,6 @@ static int frontend_ctr_get_rating(void) return 3; } -bool select_pressed = false; - -typedef union{ - struct - { - unsigned description : 10; - unsigned module : 8; - unsigned : 3; - unsigned summary : 6; - unsigned level : 5; - }; - Result val; -}ctr_result_value; - -void dump_result_value(Result val) -{ - ctr_result_value res; - res.val = val; - printf("result : 0x%08X\n", val); - printf("description : %u\n", res.description); - printf("module : %u\n", res.module); - printf("summary : %u\n", res.summary); - printf("level : %u\n", res.level); -} -#if 0 -static void ctr_crawl_memory(uint32_t* total_size, uint32_t size) -{ - void* tmp = malloc(size); - if(tmp) - *total_size += size; - else - size >>= 1; - - if (size > 4) - ctr_crawl_memory(total_size, size); - - free(tmp); -} - -void ctr_get_memory_info(uint32_t* available, uint32_t* max_block) -{ - *available = 0; - - ctr_crawl_memory(available, 1<<27); - - void* tmp; - *max_block = 0; - int i; - for (i=27; i>2; i--) - { - tmp = malloc(*max_block + (1 << i)); - if(tmp) - { - *max_block += 1 << i; - free(tmp); - } - } - - -} - -uint32_t malloc_calls = 0; -uint32_t min_malloc_addr = 0xFFFFFFFF; -uint32_t max_malloc_addr = 0x0; - -void* malloc(size_t nbytes) -{ - void* ret = _malloc_r (_REENT, nbytes); - - if (ret) - { - if(max_malloc_addr < ((uint32_t)ret + nbytes)) - max_malloc_addr = ((uint32_t)ret + nbytes); - - if(min_malloc_addr > (uint32_t)ret) - min_malloc_addr = (uint32_t)ret; - } - - malloc_calls++; - return ret; -} - -void free (void* aptr) -{ - _free_r (_REENT, aptr); -} - -uint32_t sbrk_calls = 0; -uint32_t sbrk_max_incr = 0; -uint32_t sbrk_total_incr = 0; -uint32_t sbrk_heap_start = 0; -uint32_t sbrk_heap_end = 0; - -#include "errno.h" -extern char *fake_heap_end; -extern char *fake_heap_start; - -/* Register name faking - works in collusion with the linker. */ -register char * stack_ptr asm ("sp"); - -void * _sbrk_r (struct _reent *ptr, ptrdiff_t incr) { - extern char end asm ("__end__"); /* Defined by the linker. */ - static char * heap_start; - - char * prev_heap_start; - char * heap_end; - - if (heap_start == NULL) { - if (fake_heap_start == NULL) { - heap_start = &end; - } else { - heap_start = fake_heap_start; - } - } - - prev_heap_start = heap_start; - - if (fake_heap_end == NULL) { - heap_end = stack_ptr; - } else { - heap_end = fake_heap_end; - } - - if (heap_start + incr > heap_end) { - ptr->_errno = ENOMEM; - return (caddr_t) -1; - } - - heap_start += incr; - - sbrk_calls++; - if ((incr > 0) && (sbrk_max_incr < incr)) - sbrk_max_incr = incr; - sbrk_total_incr += incr; - sbrk_heap_start = (uint32_t) heap_start; - sbrk_heap_end = (uint32_t) heap_end; - - return (caddr_t) prev_heap_start; -} -#endif - -void wait_for_input(void) -{ - printf("\n\nPress Start.\n\n"); - fflush(stdout); - - while(aptMainLoop()) - { - u32 kDown; - - hidScanInput(); - - kDown = hidKeysDown(); - - if (kDown & KEY_START) - break; - - if (kDown & KEY_SELECT) - exit(0); -#if 0 - select_pressed = true; -#endif - - retro_sleep(1); - } -} - -int usleep (useconds_t us) -{ - svcSleepThread((int64_t)us * 1000); -} - -long sysconf(int name) -{ - switch(name) - { - case _SC_NPROCESSORS_ONLN: - return 2; - } - - return -1; -} - - enum frontend_architecture frontend_ctr_get_architecture(void) { return FRONTEND_ARCH_ARM; diff --git a/gfx/drivers/ctr_gfx.c b/gfx/drivers/ctr_gfx.c index 24a6ff03ad..342025926d 100644 --- a/gfx/drivers/ctr_gfx.c +++ b/gfx/drivers/ctr_gfx.c @@ -461,30 +461,56 @@ static bool ctr_frame(void* data, const void* frame, frames = 0; } -#if 0 -// extern u32 gpuCmdBufOffset; -// if(!(frames & 0x3F)) -// { -// u32 available,max_block; -// void ctr_get_memory_info(u32* available, u32* max_block); - -// ctr_get_memory_info(&available, &max_block); -// printf(PRINTFPOS(28,0)"u:0x%08X f:0x%08X b:0x%08X\n", __heap_size - available, available, max_block); -// } +//#define CTR_INSPECT_MEMORY_USAGE +#ifdef CTR_INSPECT_MEMORY_USAGE + uint32_t ctr_get_stack_usage(void); + void ctr_linear_get_stats(void); extern u32 __linear_heap_size; extern u32 __heap_size; - extern uint32_t sbrk_calls, sbrk_max_incr, sbrk_total_incr, sbrk_heap_start, sbrk_heap_end; - printf(PRINTFPOS(25,0)"c:0x%08X m:0x%08X c:0x%08X\n", sbrk_calls, sbrk_max_incr, sbrk_total_incr); - printf(PRINTFPOS(26,0)"s:0x%08X e:0x%08X \n", sbrk_heap_start, sbrk_heap_end); - extern uint32_t malloc_calls, min_malloc_addr, max_malloc_addr; - printf(PRINTFPOS(27,0)"n:0x%08X l:0x%08X h:0x%08X\n", malloc_calls, min_malloc_addr, max_malloc_addr); - printf(PRINTFPOS(28,0)"0x%08X 0x%08X 0x%08X\r", __heap_size, gpuCmdBufOffset, (__linear_heap_size - linearSpaceFree() +0x3FF) & ~0x3FF); -#endif -// printf(PRINTFPOS(29,0)"fps: %8.4f frames: %i (%X)\r", fps, total_frames++, (__linear_heap_size - linearSpaceFree())); + MemInfo mem_info; + PageInfo page_info; + u32 query_addr = 0x08000000; + printf(PRINTFPOS(0,0)); + while (query_addr < 0x40000000) + { + svcQueryMemory(&mem_info, &page_info, query_addr); + printf("0x%08X --> 0x%08X (0x%08X) \n", mem_info.base_addr, mem_info.base_addr + mem_info.size, mem_info.size); + query_addr = mem_info.base_addr + mem_info.size; + if(query_addr == 0x1F000000) + query_addr = 0x30000000; + } +// static u32* dummy_pointer; +// if(total_frames == 500) +// dummy_pointer = malloc(0x2000000); +// if(total_frames == 1000) +// free(dummy_pointer); + + + printf("========================================"); + printf("0x%08X 0x%08X 0x%08X\n", __heap_size, gpuCmdBufOffset, (__linear_heap_size - linearSpaceFree())); + printf("fps: %8.4f frames: %i (%X)\n", fps, total_frames++, (__linear_heap_size - linearSpaceFree())); + printf("========================================"); + u32 app_memory = *((u32*)0x1FF80040); + u64 mem_used; + svcGetSystemInfo(&mem_used, 0, 1); + printf("total mem : 0x%08X \n", app_memory); + printf("used: 0x%08X free: 0x%08X \n", (u32)mem_used, app_memory - (u32)mem_used); + static u32 stack_usage = 0; + extern u32 __stack_bottom; + if(!(total_frames & 0x3F)) + stack_usage = ctr_get_stack_usage(); + printf("stack total:0x%08X used: 0x%08X\n", 0x10000000 - __stack_bottom, stack_usage); + + printf("========================================"); + ctr_linear_get_stats(); + printf("========================================"); + +#else printf(PRINTFPOS(29,0)"fps: %8.4f frames: %i\r", fps, total_frames++); +#endif fflush(stdout); rarch_perf_init(&ctrframe_f, "ctrframe_f"); diff --git a/gfx/drivers/ctr_gu.h b/gfx/drivers/ctr_gu.h index 6eea2c3b87..4680aecdaf 100644 --- a/gfx/drivers/ctr_gu.h +++ b/gfx/drivers/ctr_gu.h @@ -31,14 +31,6 @@ #define CTRGU_SIZE(W,H) (((u32)(W)&0xFFFF)|((u32)(H)<<16)) - -/* from ctrulib/great-refactor */ -#define GPU_TEVOP_RGB_SRC_G 0x8 -#define GPU_TEVOP_RGB_SRC_B 0xC -#define GPU_TEVOP_RGB_SRC_ALPHA 0x2 -#define GPU_MULTIPLY_ADD 0x8 -/*******************************/ - /* DMA flags */ #define CTRGU_DMA_VFLIP (1 << 0) #define CTRGU_DMA_L_TO_T (1 << 1) @@ -62,6 +54,7 @@ #ifndef DEBUG_HOLD void wait_for_input(void); #define PRINTFPOS(X,Y) "\x1b["#X";"#Y"H" +#define PRINTF_LINE(X) "\x1b["X";0H" #define DEBUG_HOLD() do{printf("%s@%s:%d.\n",__FUNCTION__, __FILE__, __LINE__);fflush(stdout);wait_for_input();}while(0) #define DEBUG_VAR(X) printf( "%-20s: 0x%08X\n", #X, (u32)(X)) #define DEBUG_VAR64(X) printf( #X"\r\t\t\t\t : 0x%016llX\n", (u64)(X))