[debug] add support for mgba printf
* adds support for mgba printf debugging as well as adding support for switching between debugging configuration * adds `mini_printf` as an alternative to libc printf as well as switches to choose a pretty printing handler * adds a pretty printing format to `mini_printf` to print preproc encoded strings
This commit is contained in:
+129
-5
@@ -2,6 +2,8 @@
|
||||
#include <stdio.h>
|
||||
#include "gba/gba.h"
|
||||
#include "config.h"
|
||||
#include "malloc.h"
|
||||
#include "mini_printf.h"
|
||||
|
||||
#define AGB_PRINT_FLUSH_ADDR 0x9FE209D
|
||||
#define AGB_PRINT_STRUCT_ADDR 0x9FE20F8
|
||||
@@ -14,6 +16,11 @@
|
||||
#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.
|
||||
|
||||
// hardware extensions for LOG_HANDLER_MGBA_PRINT
|
||||
#define REG_DEBUG_ENABLE ((vu16*) (0x4FFF780)) // handshake: (w)[0xC0DE] -> (r)[0x1DEA]
|
||||
#define REG_DEBUG_FLAGS ((vu16*) (0x4FFF700))
|
||||
#define REG_DEBUG_STRING ((char*) (0x4FFF600))
|
||||
|
||||
struct AGBPrintStruct
|
||||
{
|
||||
u16 m_nRequest;
|
||||
@@ -26,6 +33,8 @@ typedef void (*LPFN_PRINT_FLUSH)(void);
|
||||
|
||||
#ifndef NDEBUG
|
||||
|
||||
// AGBPrint print functions
|
||||
#if (LOG_HANDLER == LOG_HANDLER_AGB_PRINT)
|
||||
void AGBPrintFlush1Block(void);
|
||||
|
||||
void AGBPrintInit(void)
|
||||
@@ -87,7 +96,13 @@ void AGBPrintf(const char *pBuf, ...)
|
||||
char bufPrint[0x100];
|
||||
va_list vArgv;
|
||||
va_start(vArgv, pBuf);
|
||||
vsprintf(bufPrint, pBuf, vArgv);
|
||||
#if (PRETTY_PRINT_HANDLER == PRETTY_PRINT_MINI_PRINTF)
|
||||
mini_vsnprintf(bufPrint, 0x100, pBuf, vArgv);
|
||||
#elif (PRETTY_PRINT_HANDLER == PRETTY_PRINT_LIBC)
|
||||
vsnprintf(bufPrint, 0x100, pBuf, vArgv);
|
||||
#else
|
||||
#error "unspecified pretty printing handler."
|
||||
#endif
|
||||
va_end(vArgv);
|
||||
AGBPrint(bufPrint);
|
||||
}
|
||||
@@ -155,9 +170,10 @@ void AGBAssert(const char *pFile, int nLine, const char *pExpression, int nStopP
|
||||
AGBPrintf("WARING FILE=[%s] LINE=[%d] EXP=[%s] \n", pFile, nLine, pExpression);
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
// no$gba print functions, uncomment to use
|
||||
/*
|
||||
// no$gba print functions
|
||||
#if (LOG_HANDLER == LOG_HANDLER_NOCASH_PRINT)
|
||||
void NoCashGBAPrint(const char *pBuf)
|
||||
{
|
||||
*(volatile u32 *)NOCASHGBAPRINTADDR2 = (u32)pBuf;
|
||||
@@ -168,10 +184,118 @@ void NoCashGBAPrintf(const char *pBuf, ...)
|
||||
char bufPrint[0x100];
|
||||
va_list vArgv;
|
||||
va_start(vArgv, pBuf);
|
||||
vsprintf(bufPrint, pBuf, vArgv);
|
||||
#if (PRETTY_PRINT_HANDLER == PRETTY_PRINT_MINI_PRINTF)
|
||||
mini_vsnprintf(bufPrint, 0x100, pBuf, vArgv);
|
||||
#elif (PRETTY_PRINT_HANDLER == PRETTY_PRINT_LIBC)
|
||||
vsnprintf(bufPrint, 0x100, pBuf, vArgv);
|
||||
#else
|
||||
#error "unspecified pretty printing handler."
|
||||
#endif
|
||||
va_end(vArgv);
|
||||
NoCashGBAPrint(bufPrint);
|
||||
}
|
||||
*/
|
||||
|
||||
void NoCashGBAAssert(const char *pFile, s32 nLine, const char *pExpression, bool32 nStopProgram)
|
||||
{
|
||||
if (nStopProgram)
|
||||
{
|
||||
NoCashGBAPrintf("ASSERTION FAILED FILE=[%s] LINE=[%d] EXP=[%s]", pFile, nLine, pExpression);
|
||||
asm(".hword 0xEFFF");
|
||||
}
|
||||
else
|
||||
{
|
||||
NoCashGBAPrintf("WARING FILE=[%s] LINE=[%d] EXP=[%s]", pFile, nLine, pExpression);
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
// mgba print functions
|
||||
#if (LOG_HANDLER == LOG_HANDLER_MGBA_PRINT)
|
||||
#define MGBA_PRINTF_BUFFER_SIZE (4096)
|
||||
|
||||
#define MGBA_LOG_FATAL (0)
|
||||
#define MGBA_LOG_ERROR (1)
|
||||
#define MGBA_LOG_WARN (2)
|
||||
#define MGBA_LOG_INFO (3)
|
||||
#define MGBA_LOG_DEBUG (4)
|
||||
|
||||
#define MGBA_REG_DEBUG_MAX (256)
|
||||
|
||||
bool32 MgbaOpen(void)
|
||||
{
|
||||
*REG_DEBUG_ENABLE = 0xC0DE;
|
||||
return *REG_DEBUG_ENABLE == 0x1DEA;
|
||||
}
|
||||
|
||||
void MgbaClose(void)
|
||||
{
|
||||
*REG_DEBUG_ENABLE = 0;
|
||||
}
|
||||
|
||||
static void MgbaPrintfBounded(s32 level, const char* ptr, ...)
|
||||
{
|
||||
va_list args;
|
||||
|
||||
level &= 0x7;
|
||||
va_start(args, ptr);
|
||||
#if (PRETTY_PRINT_HANDLER == PRETTY_PRINT_MINI_PRINTF)
|
||||
mini_vsnprintf(REG_DEBUG_STRING, MGBA_REG_DEBUG_MAX, ptr, args);
|
||||
#elif (PRETTY_PRINT_HANDLER == PRETTY_PRINT_LIBC)
|
||||
vsnprintf(REG_DEBUG_STRING, MGBA_REG_DEBUG_MAX, ptr, args);
|
||||
#else
|
||||
#error "unspecified pretty printing handler."
|
||||
#endif
|
||||
va_end(args);
|
||||
*REG_DEBUG_FLAGS = level | 0x100;
|
||||
}
|
||||
|
||||
void MgbaPrintf(const char* ptr, ...)
|
||||
{
|
||||
va_list args;
|
||||
u32 offset = 0;
|
||||
u32 n = 0;
|
||||
u32 i;
|
||||
char *buffer = Alloc(MGBA_PRINTF_BUFFER_SIZE);
|
||||
AGB_ASSERT(buffer != NULL);
|
||||
|
||||
va_start(args, ptr);
|
||||
#if (PRETTY_PRINT_HANDLER == PRETTY_PRINT_MINI_PRINTF)
|
||||
n = mini_vsnprintf(buffer, MGBA_PRINTF_BUFFER_SIZE, ptr, args);
|
||||
#elif (PRETTY_PRINT_HANDLER == PRETTY_PRINT_LIBC)
|
||||
n = vsnprintf(buffer, MGBA_PRINTF_BUFFER_SIZE, ptr, args);
|
||||
#else
|
||||
#error "unspecified pretty printing handler."
|
||||
#endif
|
||||
va_end(args);
|
||||
|
||||
AGB_ASSERT(n < MGBA_PRINTF_BUFFER_SIZE);
|
||||
|
||||
do
|
||||
{
|
||||
for (i = 0; i < MGBA_REG_DEBUG_MAX; ++i)
|
||||
{
|
||||
REG_DEBUG_STRING[i] = buffer[offset + i];
|
||||
if (buffer[offset + i] == 0)
|
||||
break;
|
||||
}
|
||||
offset += i;
|
||||
*REG_DEBUG_FLAGS = MGBA_LOG_INFO | 0x100;
|
||||
} while ((i == MGBA_REG_DEBUG_MAX) && (buffer[offset] != '\0'));
|
||||
|
||||
Free(buffer);
|
||||
}
|
||||
|
||||
void MgbaAssert(const char *pFile, s32 nLine, const char *pExpression, bool32 nStopProgram)
|
||||
{
|
||||
if (nStopProgram)
|
||||
{
|
||||
MgbaPrintfBounded(MGBA_LOG_ERROR, "ASSERTION FAILED FILE=[%s] LINE=[%d] EXP=[%s]", pFile, nLine, pExpression);
|
||||
asm(".hword 0xEFFF");
|
||||
}
|
||||
else
|
||||
{
|
||||
MgbaPrintfBounded(MGBA_LOG_WARN, "WARING FILE=[%s] LINE=[%d] EXP=[%s]", pFile, nLine, pExpression);
|
||||
}
|
||||
}
|
||||
#endif
|
||||
#endif
|
||||
|
||||
Reference in New Issue
Block a user