From 23b7af3bc59782cc0d4120e3fa994caaa1c583ea Mon Sep 17 00:00:00 2001 From: mrshigure Date: Mon, 10 Feb 2025 19:49:23 -0800 Subject: [PATCH] TRK: matched serpoll and support; and making more progress (#565) --- configure.py | 4 +- .../MetroTRK/Portable/support.h | 8 +- .../ppc/Generic/mpc_7xx_603e.h | 2 +- src/TRK_MINNOW_DOLPHIN/mpc_7xx_603e.c | 2 +- src/TRK_MINNOW_DOLPHIN/serpoll.c | 161 +- src/TRK_MINNOW_DOLPHIN/support.c | 113 +- src/TRK_MINNOW_DOLPHIN/targimpl.c | 1622 +++++++++-------- 7 files changed, 1053 insertions(+), 859 deletions(-) diff --git a/configure.py b/configure.py index bcccf9c6..dfc33f8c 100644 --- a/configure.py +++ b/configure.py @@ -743,11 +743,11 @@ config.libs = [ Object(MatchingFor("GMPE01_00", "GMPE01_01"), "TRK_MINNOW_DOLPHIN/nubinit.c"), Object(MatchingFor("GMPE01_00", "GMPE01_01"), "TRK_MINNOW_DOLPHIN/msg.c"), Object(MatchingFor("GMPE01_00", "GMPE01_01"), "TRK_MINNOW_DOLPHIN/msgbuf.c"), - Object(NonMatching, "TRK_MINNOW_DOLPHIN/serpoll.c"), + Object(MatchingFor("GMPE01_00", "GMPE01_01"), "TRK_MINNOW_DOLPHIN/serpoll.c"), Object(MatchingFor("GMPE01_00", "GMPE01_01"), "TRK_MINNOW_DOLPHIN/usr_put.c"), Object(NonMatching, "TRK_MINNOW_DOLPHIN/dispatch.c"), Object(MatchingFor("GMPE01_00", "GMPE01_01"), "TRK_MINNOW_DOLPHIN/msghndlr.c"), - Object(NonMatching, "TRK_MINNOW_DOLPHIN/support.c"), + Object(MatchingFor("GMPE01_00", "GMPE01_01"), "TRK_MINNOW_DOLPHIN/support.c"), Object(MatchingFor("GMPE01_00", "GMPE01_01"), "TRK_MINNOW_DOLPHIN/mutex_TRK.c"), Object(NonMatching, "TRK_MINNOW_DOLPHIN/notify.c"), Object(MatchingFor("GMPE01_00", "GMPE01_01"), "TRK_MINNOW_DOLPHIN/flush_cache.c"), diff --git a/include/TRK_MINNOW_DOLPHIN/MetroTRK/Portable/support.h b/include/TRK_MINNOW_DOLPHIN/MetroTRK/Portable/support.h index 5f8e9fbc..f2b2913d 100644 --- a/include/TRK_MINNOW_DOLPHIN/MetroTRK/Portable/support.h +++ b/include/TRK_MINNOW_DOLPHIN/MetroTRK/Portable/support.h @@ -15,12 +15,12 @@ DSError TRKRequestSend(TRKBuffer* msgBuf, int* bufferId, u32 p1, u32 p2, int p3); DSError HandleOpenFileSupportRequest(const char* path, u8 replyError, - u32* param_3, DSIOResult* ioResult); + u32* param_3, u8* ioResult); -DSError HandleCloseFileSupportRequest(int replyError, DSIOResult* ioResult); +DSError HandleCloseFileSupportRequest(int replyError, u8* ioResult); -DSError HandlePositionFileSupportRequest(DSReplyError replyErr, u32* param_2, - u8 param_3, DSIOResult* ioResult); +DSError HandlePositionFileSupportRequest(u32 replyErr, u32* param_2, + u8 param_3, u8* ioResult); #ifdef __cplusplus } diff --git a/include/TRK_MINNOW_DOLPHIN/ppc/Generic/mpc_7xx_603e.h b/include/TRK_MINNOW_DOLPHIN/ppc/Generic/mpc_7xx_603e.h index ec764776..e29725fb 100644 --- a/include/TRK_MINNOW_DOLPHIN/ppc/Generic/mpc_7xx_603e.h +++ b/include/TRK_MINNOW_DOLPHIN/ppc/Generic/mpc_7xx_603e.h @@ -7,7 +7,7 @@ extern "C" { #endif -u32 TRKTargetCPUMinorType(void); +u8 TRKTargetCPUMinorType(void); #ifdef __cplusplus } diff --git a/src/TRK_MINNOW_DOLPHIN/mpc_7xx_603e.c b/src/TRK_MINNOW_DOLPHIN/mpc_7xx_603e.c index 04d4d3a9..921aa79d 100644 --- a/src/TRK_MINNOW_DOLPHIN/mpc_7xx_603e.c +++ b/src/TRK_MINNOW_DOLPHIN/mpc_7xx_603e.c @@ -245,4 +245,4 @@ lbl_8037149C: #endif // clang-format on } -u32 TRKTargetCPUMinorType(void) { return 0x54; } +u8 TRKTargetCPUMinorType(void) { return 0x54; } diff --git a/src/TRK_MINNOW_DOLPHIN/serpoll.c b/src/TRK_MINNOW_DOLPHIN/serpoll.c index 831644fa..c21fde38 100644 --- a/src/TRK_MINNOW_DOLPHIN/serpoll.c +++ b/src/TRK_MINNOW_DOLPHIN/serpoll.c @@ -9,74 +9,133 @@ static TRKFramingState gTRKFramingState; void* gTRKInputPendingPtr; -MessageBufferID TRKTestForPacket() -{ - int bytes; - int batch; - int err; - TRKBuffer* b; - int id; +static inline BOOL serpoll_inline_00(TRKBuffer* buffer) { + if (buffer->length < 2) { + TRKStandardACK(buffer, DSMSG_ReplyNAK, DSREPLY_PacketSizeError); + if (gTRKFramingState.msgBufID != -1) { + TRKReleaseBuffer(gTRKFramingState.msgBufID); + gTRKFramingState.msgBufID = -1; + } + gTRKFramingState.buffer = NULL; + gTRKFramingState.receiveState = DSRECV_Wait; + return FALSE; + } + buffer->position = 0; + buffer->length--; + return TRUE; +} - bytes = TRKPollUART(); - if (bytes > 0) { - TRKGetFreeBuffer(&id, &b); - if (bytes > TRKMSGBUF_SIZE) { - for (; bytes > 0; bytes -= batch) { - batch = bytes > TRKMSGBUF_SIZE ? TRKMSGBUF_SIZE : bytes; - TRKReadUARTN(b->data, batch); - } - TRKStandardACK(b, 0xff, 6); - } else { - err = TRKReadUARTN(b->data, bytes); - if (err == 0) { - b->length = bytes; - return id; - } - } - } - if (id != -1) { - TRKReleaseBuffer(id); - } - return -1; +MessageBufferID TRKTestForPacket(void) { + s32 var_r29; + s32 var_r3; + s8 sp8; + s32 temp_r3; + + var_r29 = 0; + var_r3 = TRKReadUARTPoll(&sp8); + while (var_r3 == 0 && var_r29 == 0) { + if (gTRKFramingState.receiveState != DSRECV_InFrame) { + gTRKFramingState.isEscape = FALSE; + } + switch (gTRKFramingState.receiveState) { + case DSRECV_Wait: + if (sp8 == 0x7E) { + var_r29 = TRKGetFreeBuffer(&gTRKFramingState.msgBufID, &gTRKFramingState.buffer); + gTRKFramingState.fcsType = 0; + gTRKFramingState.receiveState = DSRECV_Found; + } + break; + case DSRECV_Found: + if (sp8 == 0x7E) { + break; + } + gTRKFramingState.receiveState = DSRECV_InFrame; + /* fallthrough */ + case DSRECV_InFrame: + if (sp8 == 0x7E) { + if (gTRKFramingState.isEscape) { + TRKStandardACK(gTRKFramingState.buffer, DSMSG_ReplyNAK, DSREPLY_EscapeError); + if (gTRKFramingState.msgBufID != -1) { + TRKReleaseBuffer(gTRKFramingState.msgBufID); + gTRKFramingState.msgBufID = -1; + } + gTRKFramingState.buffer = NULL; + gTRKFramingState.receiveState = DSRECV_Wait; + break; + } + if (serpoll_inline_00(gTRKFramingState.buffer)) { + temp_r3 = gTRKFramingState.msgBufID; + gTRKFramingState.msgBufID = -1; + gTRKFramingState.buffer = NULL; + gTRKFramingState.receiveState = DSRECV_Wait; + return temp_r3; + } + gTRKFramingState.receiveState = DSRECV_Wait; + } else { + if (gTRKFramingState.isEscape) { + sp8 ^= 0x20; + gTRKFramingState.isEscape = FALSE; + } else if (sp8 == 0x7D) { + gTRKFramingState.isEscape = TRUE; + break; + } + var_r29 = TRKAppendBuffer1_ui8(gTRKFramingState.buffer, sp8); + gTRKFramingState.fcsType += sp8; + } + break; + case DSRECV_FrameOverflow: + if (sp8 == 0x7E) { + if (gTRKFramingState.msgBufID != -1) { + TRKReleaseBuffer(gTRKFramingState.msgBufID); + gTRKFramingState.msgBufID = -1; + } + gTRKFramingState.buffer = NULL; + gTRKFramingState.receiveState = DSRECV_Wait; + } + break; + } + var_r3 = TRKReadUARTPoll(&sp8); + } + return -1; } void TRKGetInput(void) { - MessageBufferID id; - TRKBuffer* msgBuffer; - u8 command; + TRKBuffer* msgBuffer; + MessageBufferID id; + u8 command; - id = TRKTestForPacket(); - if (id == -1) - return; + id = TRKTestForPacket(); + if (id == -1) + return; - msgBuffer = TRKGetBuffer(id); - TRKSetBufferPosition(msgBuffer, 0); - TRKReadBuffer1_ui8(msgBuffer, &command); - if (command < DSMSG_ReplyACK) { - TRKProcessInput(id); - } else { - TRKReleaseBuffer(id); - } + msgBuffer = TRKGetBuffer(id); + TRKSetBufferPosition(msgBuffer, 0); + TRKReadBuffer1_ui8(msgBuffer, &command); + if (command < DSMSG_ReplyACK) { + TRKProcessInput(id); + } else { + TRKReleaseBuffer(id); + } } void TRKProcessInput(int bufferIdx) { - TRKEvent event; + TRKEvent event; - TRKConstructEvent(&event, NUBEVENT_Request); - gTRKFramingState.msgBufID = -1; - event.msgBufID = bufferIdx; - TRKPostEvent(&event); + TRKConstructEvent(&event, NUBEVENT_Request); + gTRKFramingState.msgBufID = -1; + event.msgBufID = bufferIdx; + TRKPostEvent(&event); } DSError TRKInitializeSerialHandler(void) { - gTRKFramingState.msgBufID = -1; - gTRKFramingState.receiveState = DSRECV_Wait; - gTRKFramingState.isEscape = FALSE; + gTRKFramingState.msgBufID = -1; + gTRKFramingState.receiveState = DSRECV_Wait; + gTRKFramingState.isEscape = FALSE; - return DS_NoError; + return DS_NoError; } DSError TRKTerminateSerialHandler(void) { return DS_NoError; } diff --git a/src/TRK_MINNOW_DOLPHIN/support.c b/src/TRK_MINNOW_DOLPHIN/support.c index 0d31ca10..3f1e54c1 100644 --- a/src/TRK_MINNOW_DOLPHIN/support.c +++ b/src/TRK_MINNOW_DOLPHIN/support.c @@ -28,7 +28,7 @@ DSError TRKSuppAccessFile(u32 file_handle, u8* data, size_t* count, *io_result = DS_IONoError; done = 0; error = DS_NoError; - while (!exit && done < *count && error == DS_NoError && *io_result == 0) { + while (!exit && done < *count && error == DS_NoError && *io_result == DS_IONoError) { if (*count - done > 0x800) { length = 0x800; } else { @@ -175,3 +175,114 @@ DSError TRKRequestSend(TRKBuffer* msgBuf, int* bufferId, u32 p1, u32 p2, int p3) return error; } + +DSError HandleOpenFileSupportRequest(const char* path, u8 replyError, u32* param_3, u8* ioResult) { + int sp10; + int spC; + TRKBuffer* sp8; + TRKBuffer* var_r31; + DSError var_r26; + + *param_3 = 0; + var_r26 = TRKGetFreeBuffer(&spC, &sp8); + if (var_r26 == DS_NoError) { + var_r26 = TRKAppendBuffer1_ui8(sp8, 0xD2); + } + if (var_r26 == DS_NoError) { + var_r26 = TRKAppendBuffer1_ui8(sp8, replyError); + } + if (var_r26 == DS_NoError) { + var_r26 = TRKAppendBuffer1_ui16(sp8, strlen(path) + 1); + } + if (var_r26 == DS_NoError) { + var_r26 = TRKAppendBuffer_ui8(sp8, (u8*) path, strlen(path) + 1); + } + if (var_r26 == DS_NoError) { + *ioResult = 0; + var_r26 = TRKRequestSend(sp8, &sp10, 7, 3, 0); + if (var_r26 == DS_NoError) { + var_r31 = TRKGetBuffer(sp10); + TRKSetBufferPosition(var_r31, 2); + } + if (var_r26 == DS_NoError) { + var_r26 = TRKReadBuffer1_ui8(var_r31, ioResult); + } + if (var_r26 == DS_NoError) { + var_r26 = TRKReadBuffer1_ui32(var_r31, param_3); + } + TRKReleaseBuffer(sp10); + } + TRKReleaseBuffer(spC); + return var_r26; +} + +DSError HandleCloseFileSupportRequest(int replyError, u8* ioResult) { + int sp10; + int spC; + DSError var_r31; + TRKBuffer* sp8; + TRKBuffer* var_r30; + + var_r31 = TRKGetFreeBuffer(&spC, &sp8); + if (var_r31 == DS_NoError) { + var_r31 = TRKAppendBuffer1_ui8(sp8, 0xD3); + } + if (var_r31 == DS_NoError) { + var_r31 = TRKAppendBuffer1_ui32(sp8, replyError); + } + if (var_r31 == DS_NoError) { + *ioResult = DS_IONoError; + var_r31 = TRKRequestSend(sp8, &sp10, 3, 3, 0); + if (var_r31 == DS_NoError) { + var_r30 = TRKGetBuffer(sp10); + TRKSetBufferPosition(var_r30, 2); + } + if (var_r31 == DS_NoError) { + var_r31 = TRKReadBuffer1_ui8(var_r30, ioResult); + } + TRKReleaseBuffer(sp10); + } + TRKReleaseBuffer(spC); + return var_r31; +} + +DSError HandlePositionFileSupportRequest(u32 replyErr, u32* param_2, u8 param_3, u8* ioResult) { + int sp10; + int spC; + TRKBuffer* sp8; + TRKBuffer* var_r31; + DSError var_r27; + + var_r27 = TRKGetFreeBuffer(&spC, &sp8); + if (var_r27 == DS_NoError) { + var_r27 = TRKAppendBuffer1_ui8(sp8, 0xD4); + } + if (var_r27 == DS_NoError) { + var_r27 = TRKAppendBuffer1_ui32(sp8, replyErr); + } + if (var_r27 == DS_NoError) { + var_r27 = TRKAppendBuffer1_ui32(sp8, *param_2); + } + if (var_r27 == DS_NoError) { + var_r27 = TRKAppendBuffer1_ui8(sp8, param_3); + } + if (var_r27 == DS_NoError) { + *ioResult = DS_IONoError; + var_r27 = TRKRequestSend(sp8, &sp10, 3, 3, 0); + if (var_r27 == DS_NoError) { + var_r31 = TRKGetBuffer(sp10); + TRKSetBufferPosition(var_r31, 2); + } + if (var_r27 == DS_NoError) { + var_r27 = TRKReadBuffer1_ui8(var_r31, ioResult); + } + if (var_r27 == DS_NoError) { + var_r27 = TRKReadBuffer1_ui32(var_r31, param_2); + } else { + *param_2 = -1; + } + TRKReleaseBuffer(sp10); + } + TRKReleaseBuffer(spC); + return var_r27; +} diff --git a/src/TRK_MINNOW_DOLPHIN/targimpl.c b/src/TRK_MINNOW_DOLPHIN/targimpl.c index 858024a5..c25b33d4 100644 --- a/src/TRK_MINNOW_DOLPHIN/targimpl.c +++ b/src/TRK_MINNOW_DOLPHIN/targimpl.c @@ -9,32 +9,32 @@ #include "string.h" typedef struct memRange { - u8* start; - u8* end; - BOOL readable; - BOOL writeable; + u8* start; + u8* end; + BOOL readable; + BOOL writeable; } memRange; const memRange gTRKMemMap[1] = { { (u8*)0, (u8*)-1, TRUE, TRUE } }; typedef struct StopInfo_PPC { - u32 PC; - u32 PCInstruction; - u16 exceptionID; + u32 PC; + u32 PCInstruction; + u16 exceptionID; } StopInfo_PPC; typedef struct TRKExceptionStatus { - StopInfo_PPC exceptionInfo; - u8 inTRK; - u8 exceptionDetected; + StopInfo_PPC exceptionInfo; + u8 inTRK; + u8 exceptionDetected; } TRKExceptionStatus; typedef struct TRKStepStatus { - BOOL active; // 0x0 - DSMessageStepOptions type; // 0x4 - u32 count; // 0x8 - u32 rangeStart; // 0xC - u32 rangeEnd; // 0x10 + BOOL active; // 0x0 + DSMessageStepOptions type; // 0x4 + u32 count; // 0x8 + u32 rangeStart; // 0xC + u32 rangeEnd; // 0x10 } TRKStepStatus; ProcessorRestoreFlags_PPC gTRKRestoreFlags = { FALSE, FALSE }; @@ -56,24 +56,24 @@ Default_PPC gTRKSaveState; #define INSTR_NOP 0x60000000 #define INSTR_BLR 0x4E800020 #define INSTR_PSQ_ST(psr, offset, rDest, w, gqr) \ - (0xF0000000 | (psr << 21) | (rDest << 16) | (w << 15) | (gqr << 12) \ - | offset) + (0xF0000000 | (psr << 21) | (rDest << 16) | (w << 15) | (gqr << 12) \ + | offset) #define INSTR_PSQ_L(psr, offset, rSrc, w, gqr) \ - (0xE0000000 | (psr << 21) | (rSrc << 16) | (w << 15) | (gqr << 12) | offset) + (0xE0000000 | (psr << 21) | (rSrc << 16) | (w << 15) | (gqr << 12) | offset) #define INSTR_STW(rSrc, offset, rDest) \ - (0x90000000 | (rSrc << 21) | (rDest << 16) | offset) + (0x90000000 | (rSrc << 21) | (rDest << 16) | offset) #define INSTR_LWZ(rDest, offset, rSrc) \ - (0x80000000 | (rDest << 21) | (rSrc << 16) | offset) + (0x80000000 | (rDest << 21) | (rSrc << 16) | offset) #define INSTR_STFD(fprSrc, offset, rDest) \ - (0xD8000000 | (fprSrc << 21) | (rDest << 16) | offset) + (0xD8000000 | (fprSrc << 21) | (rDest << 16) | offset) #define INSTR_LFD(fprDest, offset, rSrc) \ - (0xC8000000 | (fprDest << 21) | (rSrc << 16) | offset) + (0xC8000000 | (fprDest << 21) | (rSrc << 16) | offset) #define INSTR_MFSPR(rDest, spr) \ - (0x7C000000 | (rDest << 21) | ((spr & 0xFE0) << 6) | ((spr & 0x1F) << 16) \ - | 0x2A6) + (0x7C000000 | (rDest << 21) | ((spr & 0xFE0) << 6) | ((spr & 0x1F) << 16) \ + | 0x2A6) #define INSTR_MTSPR(spr, rSrc) \ - (0x7C000000 | (rSrc << 21) | ((spr & 0xFE0) << 6) | ((spr & 0x1F) << 16) \ - | 0x3A6) + (0x7C000000 | (rSrc << 21) | ((spr & 0xFE0) << 6) | ((spr & 0x1F) << 16) \ + | 0x3A6) #define DSFetch_u32(_p_) (*((u32*)_p_)) #define DSFetch_u64(_p_) (*((u64*)_p_)) @@ -100,113 +100,115 @@ static BOOL TRKTargetCheckStep(); asm u32 __TRK_get_MSR() { #ifdef __MWERKS__ // clang-format off - nofralloc - mfmsr r3 - blr + nofralloc + mfmsr r3 + blr #endif // clang-format on } asm void __TRK_set_MSR(register u32 msr) { #ifdef __MWERKS__ // clang-format off - nofralloc - mtmsr msr - blr + nofralloc + mtmsr msr + blr #endif // clang-format on } +#pragma dont_inline on DSError TRKValidMemory32(const void* addr, size_t length, ValidMemoryOptions readWriteable) { - DSError err = DS_InvalidMemory; /* assume range is invalid */ + DSError err = DS_InvalidMemory; /* assume range is invalid */ - const u8* start; - const u8* end; + const u8* start; + const u8* end; - s32 i; + s32 i; - /* - ** Get start and end addresses for the memory range and - ** verify that they are reasonable. - */ + /* + ** Get start and end addresses for the memory range and + ** verify that they are reasonable. + */ - start = (const u8*)addr; - end = ((const u8*)addr + (length - 1)); + start = (const u8*)addr; + end = ((const u8*)addr + (length - 1)); - if (end < start) - return DS_InvalidMemory; + if (end < start) + return DS_InvalidMemory; - /* - ** Iterate through the gTRKMemMap array to determine if the requested - ** range falls within the valid ranges in the map. - */ + /* + ** Iterate through the gTRKMemMap array to determine if the requested + ** range falls within the valid ranges in the map. + */ - for (i = 0; (i < (s32)(sizeof(gTRKMemMap) / sizeof(memRange))); i++) { - /* - ** If the requested range is not completely above - ** the valid range AND it is not completely below - ** the valid range then it must overlap somewhere. - ** If the requested range overlaps with one of the - ** valid ranges, do some additional checking. - ** - */ + for (i = 0; (i < (s32)(sizeof(gTRKMemMap) / sizeof(memRange))); i++) { + /* + ** If the requested range is not completely above + ** the valid range AND it is not completely below + ** the valid range then it must overlap somewhere. + ** If the requested range overlaps with one of the + ** valid ranges, do some additional checking. + ** + */ - if ((start <= (const u8*)gTRKMemMap[i].end) - && (end >= (const u8*)gTRKMemMap[i].start)) { - /* - ** First, verify that the read/write attributes are - ** acceptable. If so, then recursively check any - ** part of the requested range that falls before or - ** after the valid range. - */ + if ((start <= (const u8*)gTRKMemMap[i].end) + && (end >= (const u8*)gTRKMemMap[i].start)) { + /* + ** First, verify that the read/write attributes are + ** acceptable. If so, then recursively check any + ** part of the requested range that falls before or + ** after the valid range. + */ - if (((readWriteable == VALIDMEM_Readable) - && !gTRKMemMap[i].readable) - || ((readWriteable == VALIDMEM_Writeable) - && !gTRKMemMap[i].writeable)) { - err = DS_InvalidMemory; - } else { - err = DS_NoError; + if (((readWriteable == VALIDMEM_Readable) + && !gTRKMemMap[i].readable) + || ((readWriteable == VALIDMEM_Writeable) + && !gTRKMemMap[i].writeable)) { + err = DS_InvalidMemory; + } else { + err = DS_NoError; - /* - ** If a portion of the requested range falls before - ** the current valid range, then recursively - ** check it. - */ + /* + ** If a portion of the requested range falls before + ** the current valid range, then recursively + ** check it. + */ - if (start < (const u8*)gTRKMemMap[i].start) - err = TRKValidMemory32( - start, (u32)((const u8*)gTRKMemMap[i].start - start), - readWriteable); + if (start < (const u8*)gTRKMemMap[i].start) + err = TRKValidMemory32( + start, (u32)((const u8*)gTRKMemMap[i].start - start), + readWriteable); - /* - ** If a portion of the requested range falls after - ** the current valid range, then recursively - ** check it. - ** Note: Only do this step if the previous check - ** did not detect invalid access. - */ + /* + ** If a portion of the requested range falls after + ** the current valid range, then recursively + ** check it. + ** Note: Only do this step if the previous check + ** did not detect invalid access. + */ - if ((err == DS_NoError) && (end > (const u8*)gTRKMemMap[i].end)) - err = TRKValidMemory32( - (const u8*)gTRKMemMap[i].end, - (u32)(end - (const u8*)gTRKMemMap[i].end), - readWriteable); - } + if ((err == DS_NoError) && (end > (const u8*)gTRKMemMap[i].end)) + err = TRKValidMemory32( + (const u8*)gTRKMemMap[i].end, + (u32)(end - (const u8*)gTRKMemMap[i].end), + readWriteable); + } - break; - } - } + break; + } + } - return err; + return err; } +#pragma dont_inline reset static asm void TRK_ppc_memcpy(register void* dest, register const void* src, register int n, register u32 param_4, register u32 param_5) { #ifdef __MWERKS__ // clang-format off -#define msr r8 -#define byte r9 -#define count r10 +#define msr r8 +#define byte r9 +#define count r10 nofralloc mfmsr msr @@ -240,938 +242,960 @@ out_loop: #endif // clang-format on } +#pragma dont_inline on DSError TRKTargetAccessMemory(void* data, u32 start, size_t* length, MemoryAccessOptions accessOptions, BOOL read) { - DSError error; - u32 target_msr; - void* addr; - u32 trk_msr; - TRKExceptionStatus tempExceptionStatus = gTRKExceptionStatus; - gTRKExceptionStatus.exceptionDetected = FALSE; + DSError error; + u32 target_msr; + void* addr; + u32 trk_msr; + TRKExceptionStatus tempExceptionStatus = gTRKExceptionStatus; + gTRKExceptionStatus.exceptionDetected = FALSE; - addr = (void*)TRKTargetTranslate(start); - error = TRKValidMemory32(addr, *length, - read ? VALIDMEM_Readable : VALIDMEM_Writeable); + addr = (void*)TRKTargetTranslate(start); + error = TRKValidMemory32(addr, *length, + read ? VALIDMEM_Readable : VALIDMEM_Writeable); - if (error != DS_NoError) { - *length = 0; - } else { - target_msr = __TRK_get_MSR(); - trk_msr = target_msr | gTRKCPUState.Extended1.MSR & 0x10; + if (error != DS_NoError) { + *length = 0; + } else { + target_msr = __TRK_get_MSR(); + trk_msr = target_msr | gTRKCPUState.Extended1.MSR & 0x10; - if (read) { - TRK_ppc_memcpy(data, addr, *length, target_msr, trk_msr); - } else { - TRK_ppc_memcpy(addr, data, *length, trk_msr, target_msr); - TRK_flush_cache(addr, *length); - if ((void*)start != addr) { - TRK_flush_cache((void*)start, *length); - } - } - } + if (read) { + TRK_ppc_memcpy(data, addr, *length, target_msr, trk_msr); + } else { + TRK_ppc_memcpy(addr, data, *length, trk_msr, target_msr); + TRK_flush_cache(addr, *length); + if ((void*)start != addr) { + TRK_flush_cache((void*)start, *length); + } + } + } - if (gTRKExceptionStatus.exceptionDetected) { - *length = 0; - error = DS_CWDSException; - } + if (gTRKExceptionStatus.exceptionDetected) { + *length = 0; + error = DS_CWDSException; + } - gTRKExceptionStatus = tempExceptionStatus; - return error; + gTRKExceptionStatus = tempExceptionStatus; + return error; } +#pragma dont_inline reset DSError TRKTargetReadInstruction(void* data, u32 start) { - DSError error; - size_t registersLength = 4; + DSError error; + size_t registersLength = 4; - error = TRKTargetAccessMemory(data, start, ®istersLength, - MEMACCESS_UserMemory, TRUE); + error = TRKTargetAccessMemory(data, start, ®istersLength, + MEMACCESS_UserMemory, TRUE); - if (error == DS_NoError && registersLength != 4) { - error = DS_InvalidMemory; - } + if (error == DS_NoError && registersLength != 4) { + error = DS_InvalidMemory; + } - return error; + return error; } DSError TRKTargetAccessDefault(u32 firstRegister, u32 lastRegister, TRKBuffer* b, size_t* registersLengthPtr, BOOL read) { - DSError error; - u32 count; - u32* data; - TRKExceptionStatus tempExceptionStatus; + DSError error; + u32 count; + u32* data; + TRKExceptionStatus tempExceptionStatus; - if (lastRegister > 0x24) { - return DS_InvalidRegister; - } + if (lastRegister > 0x24) { + return DS_InvalidRegister; + } - tempExceptionStatus = gTRKExceptionStatus; + tempExceptionStatus = gTRKExceptionStatus; - data = gTRKCPUState.Default.GPR + firstRegister; + gTRKExceptionStatus.exceptionDetected = FALSE; - count = (lastRegister - firstRegister) + 1; + data = gTRKCPUState.Default.GPR + firstRegister; - gTRKExceptionStatus.exceptionDetected = FALSE; + count = (lastRegister - firstRegister) + 1; - *registersLengthPtr = count * sizeof(u32); + *registersLengthPtr = count * sizeof(u32); - if (read) { - error = TRKAppendBuffer_ui32(b, data, count); - } else { - error = TRKReadBuffer_ui32(b, data, count); - } + if (read) { + error = TRKAppendBuffer_ui32(b, data, count); + } else { + error = TRKReadBuffer_ui32(b, data, count); + } - if (gTRKExceptionStatus.exceptionDetected) { - *registersLengthPtr = 0; - error = DS_CWDSException; - } + if (gTRKExceptionStatus.exceptionDetected) { + *registersLengthPtr = 0; + error = DS_CWDSException; + } - gTRKExceptionStatus = tempExceptionStatus; - return error; + gTRKExceptionStatus = tempExceptionStatus; + return error; } DSError TRKTargetAccessFP(u32 firstRegister, u32 lastRegister, TRKBuffer* b, size_t* registersLengthPtr, BOOL read) { - u64 temp; - DSError error; - TRKExceptionStatus tempExceptionStatus; - u32 current; + u64 temp; + DSError error; + TRKExceptionStatus tempExceptionStatus; + u32 current; - if (lastRegister > 0x21) { - return DS_InvalidRegister; - } + if (lastRegister > 0x21) { + return DS_InvalidRegister; + } - tempExceptionStatus = gTRKExceptionStatus; - gTRKExceptionStatus.exceptionDetected = FALSE; + tempExceptionStatus = gTRKExceptionStatus; + gTRKExceptionStatus.exceptionDetected = FALSE; - __TRK_set_MSR(__TRK_get_MSR() | 0x2000); + __TRK_set_MSR(__TRK_get_MSR() | 0x2000); - *registersLengthPtr = 0; - error = DS_NoError; + *registersLengthPtr = 0; + error = DS_NoError; - for (current = firstRegister; - (current <= lastRegister) && (error == DS_NoError); - current++, *registersLengthPtr += sizeof(f64)) { - if (read) { - TRKPPCAccessFPRegister(&temp, current, read); - error = TRKAppendBuffer1_ui64(b, temp); - } else { - TRKReadBuffer1_ui64(b, &temp); - error = TRKPPCAccessFPRegister(&temp, current, read); - } - } + for (current = firstRegister; + (current <= lastRegister) && (error == DS_NoError); + current++, *registersLengthPtr += sizeof(f64)) { + if (read) { + TRKPPCAccessFPRegister(&temp, current, read); + error = TRKAppendBuffer1_ui64(b, temp); + } else { + TRKReadBuffer1_ui64(b, &temp); + error = TRKPPCAccessFPRegister(&temp, current, read); + } + } - if (gTRKExceptionStatus.exceptionDetected) { - *registersLengthPtr = 0; - error = DS_CWDSException; - } + if (gTRKExceptionStatus.exceptionDetected) { + *registersLengthPtr = 0; + error = DS_CWDSException; + } - gTRKExceptionStatus = tempExceptionStatus; - return error; + gTRKExceptionStatus = tempExceptionStatus; + return error; } DSError TRKTargetAccessExtended1(u32 firstRegister, u32 lastRegister, TRKBuffer* b, size_t* registersLengthPtr, BOOL read) { - TRKExceptionStatus tempExceptionStatus; - int error; - u32* data; - int count; + TRKExceptionStatus tempExceptionStatus; + int error; + u32* data; + int count; - if (lastRegister > 0x60) { - return DS_InvalidRegister; - } + if (lastRegister > 0x60) { + return DS_InvalidRegister; + } - tempExceptionStatus = gTRKExceptionStatus; - gTRKExceptionStatus.exceptionDetected = FALSE; + tempExceptionStatus = gTRKExceptionStatus; + gTRKExceptionStatus.exceptionDetected = FALSE; - *registersLengthPtr = 0; + *registersLengthPtr = 0; - if (firstRegister <= lastRegister) { - data = (u32*)&gTRKCPUState.Extended1 + firstRegister; - count = lastRegister - firstRegister + 1; - *registersLengthPtr += count * sizeof(u32); + if (firstRegister <= lastRegister) { + data = (u32*)&gTRKCPUState.Extended1 + firstRegister; + count = lastRegister - firstRegister + 1; + *registersLengthPtr += count * sizeof(u32); - if (read) { - error = TRKAppendBuffer_ui32(b, data, count); - } else { - if (data <= &gTRKCPUState.Extended1.TBU - && (data + count - 1) >= &gTRKCPUState.Extended1.TBL) { - gTRKRestoreFlags.TBR = 1; - } + if (read) { + error = TRKAppendBuffer_ui32(b, data, count); + } else { + if (data <= &gTRKCPUState.Extended1.TBU + && (data + count - 1) >= &gTRKCPUState.Extended1.TBL) { + gTRKRestoreFlags.TBR = 1; + } - if (data <= &gTRKCPUState.Extended1.DEC - && (data + count - 1) >= &gTRKCPUState.Extended1.DEC) { - gTRKRestoreFlags.DEC = 1; - } - error = TRKReadBuffer_ui32(b, data, count); - } - } - if (gTRKExceptionStatus.exceptionDetected) { - *registersLengthPtr = 0; - error = DS_CWDSException; - } + if (data <= &gTRKCPUState.Extended1.DEC + && (data + count - 1) >= &gTRKCPUState.Extended1.DEC) { + gTRKRestoreFlags.DEC = 1; + } + error = TRKReadBuffer_ui32(b, data, count); + } + } + if (gTRKExceptionStatus.exceptionDetected) { + *registersLengthPtr = 0; + error = DS_CWDSException; + } - gTRKExceptionStatus = tempExceptionStatus; - return error; + gTRKExceptionStatus = tempExceptionStatus; + return error; } DSError TRKTargetAccessExtended2(u32 firstRegister, u32 lastRegister, TRKBuffer* b, size_t* registerStorageSize, BOOL read) { - TRKExceptionStatus savedException; - u32 i; - u32 value_buf0[1]; - u32 value_buf[2]; - DSError err; - u32 access_func[10]; + TRKExceptionStatus savedException; + u32 i; + u32 value_buf0[1]; + u32 value_buf[2]; + DSError err; + u32 access_func[10]; - if (lastRegister > 0x1f) - return DS_InvalidRegister; + if (lastRegister > 0x1f) + return DS_InvalidRegister; - /* - ** Save any existing exception status and clear the exception flag. - ** This allows detection of exceptions that occur ONLY within this - ** function. - */ + /* + ** Save any existing exception status and clear the exception flag. + ** This allows detection of exceptions that occur ONLY within this + ** function. + */ - savedException = gTRKExceptionStatus; - gTRKExceptionStatus.exceptionDetected = FALSE; + savedException = gTRKExceptionStatus; + gTRKExceptionStatus.exceptionDetected = FALSE; - TRKPPCAccessSPR(value_buf0, SPR_HID2, TRUE); + TRKPPCAccessSPR(value_buf0, SPR_HID2, TRUE); - value_buf0[0] |= 0xA0000000; - TRKPPCAccessSPR(value_buf0, SPR_HID2, FALSE); + value_buf0[0] |= 0xA0000000; + TRKPPCAccessSPR(value_buf0, SPR_HID2, FALSE); - value_buf0[0] = 0; - TRKPPCAccessSPR(value_buf0, SPR_GQR0, FALSE); + value_buf0[0] = 0; + TRKPPCAccessSPR(value_buf0, SPR_GQR0, FALSE); - *registerStorageSize = 0; - err = DS_NoError; + *registerStorageSize = 0; + err = DS_NoError; - for (i = firstRegister; (i <= lastRegister) && (err == DS_NoError); i++) { - if (read) { - err = TRKPPCAccessPairedSingleRegister((u64*)value_buf, i, read); - err = TRKAppendBuffer1_ui64(b, *(u64*)value_buf); - } else { - err = TRKReadBuffer1_ui64(b, (u64*)value_buf); - err = TRKPPCAccessPairedSingleRegister((u64*)value_buf, i, read); - } + for (i = firstRegister; (i <= lastRegister) && (err == DS_NoError); i++) { + if (read) { + err = TRKPPCAccessPairedSingleRegister((u64*)value_buf, i, read); + err = TRKAppendBuffer1_ui64(b, *(u64*)value_buf); + } else { + err = TRKReadBuffer1_ui64(b, (u64*)value_buf); + err = TRKPPCAccessPairedSingleRegister((u64*)value_buf, i, read); + } - *registerStorageSize += sizeof(u64); - } + *registerStorageSize += sizeof(u64); + } - if (gTRKExceptionStatus.exceptionDetected) { - *registerStorageSize = 0; - err = DS_CWDSException; - } + if (gTRKExceptionStatus.exceptionDetected) { + *registerStorageSize = 0; + err = DS_CWDSException; + } - gTRKExceptionStatus = savedException; + gTRKExceptionStatus = savedException; - return err; + return err; } DSError TRKTargetVersions(DSVersions* versions) { - versions->kernelMajor = 0; - versions->kernelMinor = 8; - versions->protocolMajor = 1; - versions->protocolMinor = 10; - return DS_NoError; + versions->kernelMajor = 0; + versions->kernelMinor = 10; + versions->protocolMajor = 1; + versions->protocolMinor = 10; + return DS_NoError; } DSError TRKTargetSupportMask(u8 mask[32]) { - mask[0] = 0x7a; - mask[1] = 0; - mask[2] = 0x4f; - mask[3] = 7; - mask[4] = 0; - mask[5] = 0; - mask[6] = 0; - mask[7] = 0; - mask[8] = 0; - mask[9] = 0; - mask[10] = 0; - mask[0xb] = 0; - mask[0xc] = 0; - mask[0xd] = 0; - mask[0xe] = 0; - mask[0xf] = 0; - mask[0x10] = 1; - mask[0x11] = 0; - mask[0x12] = 3; - mask[0x13] = 0; - mask[0x14] = 0; - mask[0x15] = 0; - mask[0x16] = 0; - mask[0x17] = 0; - mask[0x18] = 0; - mask[0x19] = 0; - mask[0x1a] = 3; - mask[0x1b] = 0; - mask[0x1c] = 0; - mask[0x1d] = 0; - mask[0x1e] = 0; - mask[0x1f] = 0x80; - return DS_NoError; + mask[0] = 0x7a; + mask[1] = 0; + mask[2] = 0x4f; + mask[3] = 7; + mask[4] = 0; + mask[5] = 0; + mask[6] = 0; + mask[7] = 0; + mask[8] = 0; + mask[9] = 0; + mask[10] = 0; + mask[0xb] = 0; + mask[0xc] = 0; + mask[0xd] = 0; + mask[0xe] = 0; + mask[0xf] = 0; + mask[0x10] = 1; + mask[0x11] = 0; + mask[0x12] = 3; + mask[0x13] = 0; + mask[0x14] = 0; + mask[0x15] = 0; + mask[0x16] = 0; + mask[0x17] = 0; + mask[0x18] = 0; + mask[0x19] = 0; + mask[0x1a] = 3; + mask[0x1b] = 0; + mask[0x1c] = 0; + mask[0x1d] = 0; + mask[0x1e] = 0; + mask[0x1f] = 0x80; + return DS_NoError; } extern BOOL gTRKBigEndian; DSError TRKTargetCPUType(DSCPUType* cpuType) { - cpuType->cpuMajor = 0; - cpuType->cpuMinor = TRKTargetCPUMinorType(); - cpuType->bigEndian = gTRKBigEndian; - cpuType->defaultTypeSize = 4; - cpuType->fpTypeSize = 8; - cpuType->extended1TypeSize = 4; - cpuType->extended2TypeSize = 8; - return DS_NoError; + cpuType->cpuMajor = 0; + cpuType->cpuMinor = TRKTargetCPUMinorType(); + cpuType->bigEndian = gTRKBigEndian; + cpuType->defaultTypeSize = 4; + cpuType->fpTypeSize = 8; + cpuType->extended1TypeSize = 4; + cpuType->extended2TypeSize = 8; + return DS_NoError; } asm void TRKInterruptHandler() { #ifdef __MWERKS__ // clang-format off - nofralloc - mtsrr0 r2 - mtsrr1 r4 - mfsprg r4, 3 - mfcr r2 - mtsprg 3, r2 - lis r2, gTRKState@h - ori r2, r2, gTRKState@l - lwz r2, TRKState_PPC.MSR(r2) - ori r2, r2, 0x8002 - xori r2, r2, 0x8002 - sync - mtmsr r2 - sync - lis r2, TRK_saved_exceptionID@h - ori r2, r2, TRK_saved_exceptionID@l - sth r3, 0(r2) - cmpwi r3, 0x500 - bne L_802CF694 - lis r2, gTRKCPUState@h - ori r2, r2, gTRKCPUState@l - mflr r3 - stw r3, ProcessorState_PPC.transport_handler_saved_ra(r2) - bl TRKUARTInterruptHandler - lis r2, gTRKCPUState@h - ori r2, r2, gTRKCPUState@l - lwz r3, ProcessorState_PPC.transport_handler_saved_ra(r2) - mtlr r3 - lis r2, gTRKState@h - ori r2, r2, gTRKState@l - lwz r2, TRKState_PPC.inputPendingPtr(r2) - lbz r2, TRKState_PPC.GPR[0](r2) - cmpwi r2, 0 - beq L_802CF678 - lis r2, gTRKExceptionStatus@h - ori r2, r2, gTRKExceptionStatus@l - lbz r2, TRKExceptionStatus.inTRK(r2) - cmpwi r2, 1 - beq L_802CF678 - lis r2, gTRKState@h - ori r2, r2, gTRKState@l - li r3, 1 - stb r3, TRKState_PPC.inputActivated(r2) - b L_802CF694 + nofralloc + mtsrr0 r2 + mtsrr1 r4 + mfsprg r4, 3 + mfcr r2 + mtsprg 3, r2 + lis r2, gTRKState@h + ori r2, r2, gTRKState@l + lwz r2, TRKState_PPC.MSR(r2) + ori r2, r2, 0x8002 + xori r2, r2, 0x8002 + sync + mtmsr r2 + sync + lis r2, TRK_saved_exceptionID@h + ori r2, r2, TRK_saved_exceptionID@l + sth r3, 0(r2) + cmpwi r3, 0x500 + bne L_802CF694 + lis r2, gTRKCPUState@h + ori r2, r2, gTRKCPUState@l + mflr r3 + stw r3, ProcessorState_PPC.transport_handler_saved_ra(r2) + bl TRKUARTInterruptHandler + lis r2, gTRKCPUState@h + ori r2, r2, gTRKCPUState@l + lwz r3, ProcessorState_PPC.transport_handler_saved_ra(r2) + mtlr r3 + lis r2, gTRKState@h + ori r2, r2, gTRKState@l + lwz r2, TRKState_PPC.inputPendingPtr(r2) + lbz r2, TRKState_PPC.GPR[0](r2) + cmpwi r2, 0 + beq L_802CF678 + lis r2, gTRKExceptionStatus@h + ori r2, r2, gTRKExceptionStatus@l + lbz r2, TRKExceptionStatus.inTRK(r2) + cmpwi r2, 1 + beq L_802CF678 + lis r2, gTRKState@h + ori r2, r2, gTRKState@l + li r3, 1 + stb r3, TRKState_PPC.inputActivated(r2) + b L_802CF694 L_802CF678: - lis r2, gTRKSaveState@h - ori r2, r2, gTRKSaveState@l - lwz r3, Default_PPC.CR(r2) - mtcrf 0xff, r3 - lwz r3, Default_PPC.GPR[3](r2) - lwz r2, Default_PPC.GPR[2](r2) - rfi + lis r2, gTRKSaveState@h + ori r2, r2, gTRKSaveState@l + lwz r3, Default_PPC.CR(r2) + mtcrf 0xff, r3 + lwz r3, Default_PPC.GPR[3](r2) + lwz r2, Default_PPC.GPR[2](r2) + rfi L_802CF694: - lis r2, TRK_saved_exceptionID@h - ori r2, r2, TRK_saved_exceptionID@l - lhz r3, 0(r2) - lis r2, gTRKExceptionStatus@h - ori r2, r2, gTRKExceptionStatus@l - lbz r2, TRKExceptionStatus.inTRK(r2) - cmpwi r2, 0 - bne TRKExceptionHandler - lis r2, gTRKCPUState@h - ori r2, r2, gTRKCPUState@l - stw r0, ProcessorState_PPC.Default.GPR[0](r2) - stw r1, ProcessorState_PPC.Default.GPR[1](r2) - mfsprg r0, 1 - stw r0, ProcessorState_PPC.Default.GPR[2](r2) - sth r3, ProcessorState_PPC.Extended1.exceptionID(r2) - sth r3, (ProcessorState_PPC.Extended1.exceptionID + 2)(r2) - mfsprg r0, 2 - stw r0, ProcessorState_PPC.Default.GPR[3](r2) - stmw r4, ProcessorState_PPC.Default.GPR[4](r2) - mfsrr0 r27 - mflr r28 - mfsprg r29, 3 - mfctr r30 - mfxer r31 - stmw r27, ProcessorState_PPC.Default.PC(r2) - bl TRKSaveExtended1Block - lis r2, gTRKExceptionStatus@h - ori r2, r2, gTRKExceptionStatus@l - li r3, 1 - stb r3, TRKExceptionStatus.inTRK(r2) - lis r2, gTRKState@h - ori r2, r2, gTRKState@l - lwz r0, TRKState_PPC.MSR(r2) - sync - mtmsr r0 - sync - lwz r0, TRKState_PPC.LR(r2) - mtlr r0 - lwz r0, TRKState_PPC.CTR(r2) - mtctr r0 - lwz r0, TRKState_PPC.XER(r2) - mtxer r0 - lwz r0, TRKState_PPC.DSISR(r2) - mtdsisr r0 - lwz r0, TRKState_PPC.DAR(r2) - mtdar r0 - lmw r3, TRKState_PPC.GPR[3](r2) - lwz r0, TRKState_PPC.GPR[0](r2) - lwz r1, TRKState_PPC.GPR[1](r2) - lwz r2, TRKState_PPC.GPR[2](r2) - b TRKPostInterruptEvent + lis r2, TRK_saved_exceptionID@h + ori r2, r2, TRK_saved_exceptionID@l + lhz r3, 0(r2) + lis r2, gTRKExceptionStatus@h + ori r2, r2, gTRKExceptionStatus@l + lbz r2, TRKExceptionStatus.inTRK(r2) + cmpwi r2, 0 + bne TRKExceptionHandler + lis r2, gTRKCPUState@h + ori r2, r2, gTRKCPUState@l + stw r0, ProcessorState_PPC.Default.GPR[0](r2) + stw r1, ProcessorState_PPC.Default.GPR[1](r2) + mfsprg r0, 1 + stw r0, ProcessorState_PPC.Default.GPR[2](r2) + sth r3, ProcessorState_PPC.Extended1.exceptionID(r2) + sth r3, (ProcessorState_PPC.Extended1.exceptionID + 2)(r2) + mfsprg r0, 2 + stw r0, ProcessorState_PPC.Default.GPR[3](r2) + stmw r4, ProcessorState_PPC.Default.GPR[4](r2) + mfsrr0 r27 + mflr r28 + mfsprg r29, 3 + mfctr r30 + mfxer r31 + stmw r27, ProcessorState_PPC.Default.PC(r2) + bl TRKSaveExtended1Block + lis r2, gTRKExceptionStatus@h + ori r2, r2, gTRKExceptionStatus@l + li r3, 1 + stb r3, TRKExceptionStatus.inTRK(r2) + lis r2, gTRKState@h + ori r2, r2, gTRKState@l + lwz r0, TRKState_PPC.MSR(r2) + sync + mtmsr r0 + sync + lwz r0, TRKState_PPC.LR(r2) + mtlr r0 + lwz r0, TRKState_PPC.CTR(r2) + mtctr r0 + lwz r0, TRKState_PPC.XER(r2) + mtxer r0 + lwz r0, TRKState_PPC.DSISR(r2) + mtdsisr r0 + lwz r0, TRKState_PPC.DAR(r2) + mtdar r0 + lmw r3, TRKState_PPC.GPR[3](r2) + lwz r0, TRKState_PPC.GPR[0](r2) + lwz r1, TRKState_PPC.GPR[1](r2) + lwz r2, TRKState_PPC.GPR[2](r2) + b TRKPostInterruptEvent #endif // clang-format on } static asm void TRKExceptionHandler(u16) { #ifdef __MWERKS__ // clang-format off - nofralloc - lis r2, gTRKExceptionStatus@h - ori r2, r2, gTRKExceptionStatus@l - sth r3, TRKExceptionStatus.exceptionInfo.exceptionID(r2) - mfsrr0 r3 - stw r3, TRKExceptionStatus.exceptionInfo.PC(r2) - lhz r3, TRKExceptionStatus.exceptionInfo.exceptionID(r2) - cmpwi r3, 0x200 - beq LAB_00010ba4 - cmpwi r3, 0x300 - beq LAB_00010ba4 - cmpwi r3, 0x400 - beq LAB_00010ba4 - cmpwi r3, 0x600 - beq LAB_00010ba4 - cmpwi r3, 0x700 - beq LAB_00010ba4 - cmpwi r3, 0x800 - beq LAB_00010ba4 - cmpwi r3, 0x1000 - beq LAB_00010ba4 - cmpwi r3, 0x1100 - beq LAB_00010ba4 - cmpwi r3, 0x1200 - beq LAB_00010ba4 - cmpwi r3, 0x1300 - beq LAB_00010ba4 - b LAB_00010bb0 + nofralloc + lis r2, gTRKExceptionStatus@h + ori r2, r2, gTRKExceptionStatus@l + sth r3, TRKExceptionStatus.exceptionInfo.exceptionID(r2) + mfsrr0 r3 + stw r3, TRKExceptionStatus.exceptionInfo.PC(r2) + lhz r3, TRKExceptionStatus.exceptionInfo.exceptionID(r2) + cmpwi r3, 0x200 + beq LAB_00010ba4 + cmpwi r3, 0x300 + beq LAB_00010ba4 + cmpwi r3, 0x400 + beq LAB_00010ba4 + cmpwi r3, 0x600 + beq LAB_00010ba4 + cmpwi r3, 0x700 + beq LAB_00010ba4 + cmpwi r3, 0x800 + beq LAB_00010ba4 + cmpwi r3, 0x1000 + beq LAB_00010ba4 + cmpwi r3, 0x1100 + beq LAB_00010ba4 + cmpwi r3, 0x1200 + beq LAB_00010ba4 + cmpwi r3, 0x1300 + beq LAB_00010ba4 + b LAB_00010bb0 LAB_00010ba4: - mfsrr0 r3 - addi r3, r3, 0x4 - mtsrr0 r3 + mfsrr0 r3 + addi r3, r3, 0x4 + mtsrr0 r3 LAB_00010bb0: - lis r2, gTRKExceptionStatus@h - ori r2, r2, gTRKExceptionStatus@l - li r3, 0x1 - stb r3, TRKExceptionStatus.exceptionDetected(r2) - mfsprg r3, 3 - mtcrf 0xff, r3 - mfsprg r2, 1 - mfsprg r3, 2 - rfi + lis r2, gTRKExceptionStatus@h + ori r2, r2, gTRKExceptionStatus@l + li r3, 0x1 + stb r3, TRKExceptionStatus.exceptionDetected(r2) + mfsprg r3, 3 + mtcrf 0xff, r3 + mfsprg r2, 1 + mfsprg r3, 2 + rfi #endif // clang-format on } void TRKPostInterruptEvent(void) { - NubEventType eventType; - u32 inst; - TRKEvent event; + NubEventType eventType; + u32 inst; + TRKEvent event; - if (gTRKState.inputActivated) { - gTRKState.inputActivated = FALSE; - } else { - switch (gTRKCPUState.Extended1.exceptionID & 0xFFFF) { - case 0xd00: - case 0x700: - TRKTargetReadInstruction(&inst, gTRKCPUState.Default.PC); + if (gTRKState.inputActivated) { + gTRKState.inputActivated = FALSE; + } else { + switch (gTRKCPUState.Extended1.exceptionID & 0xFFFF) { + case 0xd00: + case 0x700: + TRKTargetReadInstruction(&inst, gTRKCPUState.Default.PC); - if (inst == 0xfe00000) { - eventType = NUBEVENT_Support; - } else { - eventType = NUBEVENT_Breakpoint; - } - break; - default: - eventType = NUBEVENT_Exception; - break; - } + if (inst == 0xfe00000) { + eventType = NUBEVENT_Support; + } else { + eventType = NUBEVENT_Breakpoint; + } + break; + default: + eventType = NUBEVENT_Exception; + break; + } - TRKConstructEvent(&event, eventType); - TRKPostEvent(&event); - } + TRKConstructEvent(&event, eventType); + TRKPostEvent(&event); + } } asm void TRKSwapAndGo() { #ifdef __MWERKS__ // clang-format off - nofralloc - lis r3, gTRKState@h - ori r3, r3, gTRKState@l - stmw r0, TRKState_PPC.GPR[0](r3) - mfmsr r0 - stw r0, TRKState_PPC.MSR(r3) - mflr r0 - stw r0, TRKState_PPC.LR(r3) - mfctr r0 - stw r0, TRKState_PPC.CTR(r3) - mfxer r0 - stw r0, TRKState_PPC.XER(r3) - mfdsisr r0 - stw r0, TRKState_PPC.DSISR(r3) - mfdar r0 - stw r0, TRKState_PPC.DAR(r3) - li r1, -0x7ffe - nor r1, r1, r1 - mfmsr r3 - and r3, r3, r1 - mtmsr r3 - lis r2, gTRKState@h - ori r2, r2, gTRKState@l - lwz r2, TRKState_PPC.inputPendingPtr(r2) - lbz r2, TRKState_PPC.GPR[0](r2) - cmpwi r2, 0 - beq L_802CF930 - lis r2, gTRKState@h - ori r2, r2, gTRKState@l - li r3, 1 - stb r3, TRKState_PPC.inputActivated(r2) - b TRKInterruptHandlerEnableInterrupts + nofralloc + lis r3, gTRKState@h + ori r3, r3, gTRKState@l + stmw r0, TRKState_PPC.GPR[0](r3) + mfmsr r0 + stw r0, TRKState_PPC.MSR(r3) + mflr r0 + stw r0, TRKState_PPC.LR(r3) + mfctr r0 + stw r0, TRKState_PPC.CTR(r3) + mfxer r0 + stw r0, TRKState_PPC.XER(r3) + mfdsisr r0 + stw r0, TRKState_PPC.DSISR(r3) + mfdar r0 + stw r0, TRKState_PPC.DAR(r3) + li r1, -0x7ffe + nor r1, r1, r1 + mfmsr r3 + and r3, r3, r1 + mtmsr r3 + lis r2, gTRKState@h + ori r2, r2, gTRKState@l + lwz r2, TRKState_PPC.inputPendingPtr(r2) + lbz r2, TRKState_PPC.GPR[0](r2) + cmpwi r2, 0 + beq L_802CF930 + lis r2, gTRKState@h + ori r2, r2, gTRKState@l + li r3, 1 + stb r3, TRKState_PPC.inputActivated(r2) + b TRKInterruptHandlerEnableInterrupts L_802CF930: - lis r2, gTRKExceptionStatus@h - ori r2, r2, gTRKExceptionStatus@l - li r3, 0 - stb r3, 0xc(r2) - bl TRKRestoreExtended1Block - lis r2, gTRKCPUState@h - ori r2, r2, gTRKCPUState@l - lmw r27, ProcessorState_PPC.Default.PC(r2) - mtsrr0 r27 - mtlr r28 - mtcrf 0xff, r29 - mtctr r30 - mtxer r31 - lmw r3, ProcessorState_PPC.Default.GPR[3](r2) - lwz r0, ProcessorState_PPC.Default.GPR[0](r2) - lwz r1, ProcessorState_PPC.Default.GPR[1](r2) - lwz r2, ProcessorState_PPC.Default.GPR[2](r2) - rfi + lis r2, gTRKExceptionStatus@h + ori r2, r2, gTRKExceptionStatus@l + li r3, 0 + stb r3, 0xc(r2) + bl TRKRestoreExtended1Block + lis r2, gTRKCPUState@h + ori r2, r2, gTRKCPUState@l + lmw r27, ProcessorState_PPC.Default.PC(r2) + mtsrr0 r27 + mtlr r28 + mtcrf 0xff, r29 + mtctr r30 + mtxer r31 + lmw r3, ProcessorState_PPC.Default.GPR[3](r2) + lwz r0, ProcessorState_PPC.Default.GPR[0](r2) + lwz r1, ProcessorState_PPC.Default.GPR[1](r2) + lwz r2, ProcessorState_PPC.Default.GPR[2](r2) + rfi #endif // clang-format on } asm void TRKInterruptHandlerEnableInterrupts(void) { #ifdef __MWERKS__ // clang-format off - nofralloc; - lis r2, gTRKState@h - ori r2, r2, gTRKState@l - lwz r0, TRKState_PPC.MSR(r2) - sync - mtmsr r0 - sync - lwz r0, TRKState_PPC.LR(r2) - mtlr r0 - lwz r0, TRKState_PPC.CTR(r2) - mtctr r0 - lwz r0, TRKState_PPC.XER(r2) - mtxer r0 - lwz r0, TRKState_PPC.DSISR(r2) - mtdsisr r0 - lwz r0, TRKState_PPC.DAR(r2) - mtdar r0 - lmw r3, TRKState_PPC.GPR[3](r2) - lwz r0, TRKState_PPC.GPR[0](r2) - lwz r1, TRKState_PPC.GPR[1](r2) - lwz r2, TRKState_PPC.GPR[2](r2) - b TRKPostInterruptEvent + nofralloc; + lis r2, gTRKState@h + ori r2, r2, gTRKState@l + lwz r0, TRKState_PPC.MSR(r2) + sync + mtmsr r0 + sync + lwz r0, TRKState_PPC.LR(r2) + mtlr r0 + lwz r0, TRKState_PPC.CTR(r2) + mtctr r0 + lwz r0, TRKState_PPC.XER(r2) + mtxer r0 + lwz r0, TRKState_PPC.DSISR(r2) + mtdsisr r0 + lwz r0, TRKState_PPC.DAR(r2) + mtdar r0 + lmw r3, TRKState_PPC.GPR[3](r2) + lwz r0, TRKState_PPC.GPR[0](r2) + lwz r1, TRKState_PPC.GPR[1](r2) + lwz r2, TRKState_PPC.GPR[2](r2) + b TRKPostInterruptEvent #endif // clang-format on } DSError TRKTargetInterrupt(TRKEvent* event) { - DSError error = DS_NoError; - switch (event->eventType) { - case NUBEVENT_Breakpoint: - case NUBEVENT_Exception: - if (TRKTargetCheckStep() == FALSE) { - TRKTargetSetStopped(TRUE); - error = TRKDoNotifyStopped(DSMSG_NotifyStopped); - } - break; - default: - break; - } + DSError error = DS_NoError; + switch (event->eventType) { + case NUBEVENT_Breakpoint: + case NUBEVENT_Exception: + if (TRKTargetCheckStep() == FALSE) { + TRKTargetSetStopped(TRUE); + error = TRKDoNotifyStopped(DSMSG_NotifyStopped); + } + break; + default: + break; + } - return error; + return error; } DSError TRKTargetAddStopInfo(TRKBuffer* buffer) { - DSError error; - u32 instruction; + DSError error; + u32 instruction; + s32 i; - error = TRKAppendBuffer1_ui32(buffer, gTRKCPUState.Default.PC); - if (error == 0) { - error = TRKTargetReadInstruction(&instruction, gTRKCPUState.Default.PC); - } - if (error == 0) - error = TRKAppendBuffer1_ui32(buffer, instruction); - if (error == 0) - error - = TRKAppendBuffer1_ui16(buffer, gTRKCPUState.Extended1.exceptionID); - return error; + error = TRKAppendBuffer1_ui32(buffer, gTRKCPUState.Default.PC); + if (error == DS_NoError) { + error = TRKTargetReadInstruction(&instruction, gTRKCPUState.Default.PC); + } + if (error == DS_NoError) + error = TRKAppendBuffer1_ui32(buffer, instruction); + if (error == DS_NoError) + error = TRKAppendBuffer1_ui16(buffer, gTRKCPUState.Extended1.exceptionID); + + if (error == DS_NoError) { + for (i = 0; i < 32; i++) { + error = TRKAppendBuffer1_ui32(buffer, (u16) gTRKCPUState.Default.GPR[i]); + } + for (i = 0; i < 32; i++) { + error = TRKAppendBuffer1_ui64(buffer, (u16) gTRKCPUState.Float.FPR[i]); + } + } + + return error; } DSError TRKTargetAddExceptionInfo(TRKBuffer* buffer) { - DSError error; - u32 local_10; + DSError error; + u32 local_10; - error = TRKAppendBuffer1_ui32(buffer, gTRKExceptionStatus.exceptionInfo.PC); - if (error == 0) { - error = TRKTargetReadInstruction(&local_10, - gTRKExceptionStatus.exceptionInfo.PC); - } - if (error == 0) { - error = TRKAppendBuffer1_ui32(buffer, local_10); - } - if (error == 0) { - error = TRKAppendBuffer1_ui16( - buffer, gTRKExceptionStatus.exceptionInfo.exceptionID); - } + error = TRKAppendBuffer1_ui32(buffer, gTRKExceptionStatus.exceptionInfo.PC); + if (error == 0) { + error = TRKTargetReadInstruction(&local_10, + gTRKExceptionStatus.exceptionInfo.PC); + } + if (error == 0) { + error = TRKAppendBuffer1_ui32(buffer, local_10); + } + if (error == 0) { + error = TRKAppendBuffer1_ui16( + buffer, gTRKExceptionStatus.exceptionInfo.exceptionID); + } - return error; + return error; } static DSError TRKTargetEnableTrace(BOOL val) { - if (val) { - gTRKCPUState.Extended1.MSR = (gTRKCPUState.Extended1.MSR | 0x400); - } else { - gTRKCPUState.Extended1.MSR = (gTRKCPUState.Extended1.MSR & ~0x400); - } - return DS_NoError; + if (val) { + gTRKCPUState.Extended1.MSR = (gTRKCPUState.Extended1.MSR | 0x400); + } else { + gTRKCPUState.Extended1.MSR = (gTRKCPUState.Extended1.MSR & ~0x400); + } + return DS_NoError; } static BOOL TRKTargetStepDone() { - BOOL result = TRUE; + BOOL result = TRUE; - if (gTRKStepStatus.active - && ((u16)gTRKCPUState.Extended1.exceptionID) == PPC_Trace) { - switch (gTRKStepStatus.type) { - case DSSTEP_IntoCount: - if (gTRKStepStatus.count > 0) { - result = FALSE; - } - break; - case DSSTEP_IntoRange: - if (gTRKCPUState.Default.PC >= gTRKStepStatus.rangeStart - && gTRKCPUState.Default.PC <= gTRKStepStatus.rangeEnd) { - result = FALSE; - } - break; - default: - break; - } - } + if (gTRKStepStatus.active + && ((u16)gTRKCPUState.Extended1.exceptionID) == PPC_Trace) { + switch (gTRKStepStatus.type) { + case DSSTEP_IntoCount: + if (gTRKStepStatus.count > 0) { + result = FALSE; + } + break; + case DSSTEP_IntoRange: + if (gTRKCPUState.Default.PC >= gTRKStepStatus.rangeStart + && gTRKCPUState.Default.PC <= gTRKStepStatus.rangeEnd) { + result = FALSE; + } + break; + default: + break; + } + } - return result; + return result; } static DSError TRKTargetDoStep() { - gTRKStepStatus.active = TRUE; - TRKTargetEnableTrace(TRUE); + gTRKStepStatus.active = TRUE; + TRKTargetEnableTrace(TRUE); - if (gTRKStepStatus.type == DSSTEP_IntoCount - || gTRKStepStatus.type == DSSTEP_OverCount) { - gTRKStepStatus.count--; - } + if (gTRKStepStatus.type == DSSTEP_IntoCount + || gTRKStepStatus.type == DSSTEP_OverCount) { + gTRKStepStatus.count--; + } - TRKTargetSetStopped(FALSE); - return DS_NoError; + TRKTargetSetStopped(FALSE); + return DS_NoError; } static BOOL TRKTargetCheckStep() { - if (gTRKStepStatus.active) { - TRKTargetEnableTrace(FALSE); + if (gTRKStepStatus.active) { + TRKTargetEnableTrace(FALSE); - if (TRKTargetStepDone()) { - gTRKStepStatus.active = FALSE; - } else { - TRKTargetDoStep(); - } - } + if (TRKTargetStepDone()) { + gTRKStepStatus.active = FALSE; + } else { + TRKTargetDoStep(); + } + } - return gTRKStepStatus.active; + return gTRKStepStatus.active; } DSError TRKTargetSingleStep(u32 count, BOOL stepOver) { - DSError error = DS_NoError; + DSError error = DS_NoError; - if (stepOver) { - error = DS_UnsupportedError; - } else { - gTRKStepStatus.count = count; - gTRKStepStatus.type = DSSTEP_IntoCount; - error = TRKTargetDoStep(); - } + if (stepOver) { + error = DS_UnsupportedError; + } else { + gTRKStepStatus.type = DSSTEP_IntoCount; + gTRKStepStatus.count = count; + error = TRKTargetDoStep(); + } - return error; + return error; } DSError TRKTargetStepOutOfRange(u32 rangeStart, u32 rangeEnd, BOOL stepOver) { - DSError error = DS_NoError; + DSError error = DS_NoError; - if (stepOver) { - // Stepping over isn't supported for PowerPC - error = DS_UnsupportedError; - } else { - gTRKStepStatus.type = DSSTEP_IntoRange; - // gTRKStepStatus.active = TRUE; - gTRKStepStatus.rangeStart = rangeStart; - gTRKStepStatus.rangeEnd = rangeEnd; - error = TRKTargetDoStep(); - } + if (stepOver) { + // Stepping over isn't supported for PowerPC + error = DS_UnsupportedError; + } else { + gTRKStepStatus.type = DSSTEP_IntoRange; + // gTRKStepStatus.active = TRUE; + gTRKStepStatus.rangeStart = rangeStart; + gTRKStepStatus.rangeEnd = rangeEnd; + error = TRKTargetDoStep(); + } - return error; + return error; } u32 TRKTargetGetPC() { return gTRKCPUState.Default.PC; } -DSError TRKTargetSupportRequest() -{ - DSError error; - size_t* length; - DSIOResult ioResult; - MessageCommandID commandId; - TRKEvent event; +DSError TRKTargetSupportRequest(void) { + DSError error; + u32 spC; + size_t* length; + MessageCommandID commandId; + TRKEvent event; + u8 ioResult; - commandId = gTRKCPUState.Default.GPR[3]; - if (commandId != DSMSG_ReadFile && commandId != DSMSG_WriteFile) { - TRKConstructEvent(&event, 4); - TRKPostEvent(&event); - return DS_NoError; - } else { - length = (size_t*)gTRKCPUState.Default.GPR[5]; - error = TRKSuppAccessFile((u8)gTRKCPUState.Default.GPR[4], - (u8*)gTRKCPUState.Default.GPR[6], length, - &ioResult, TRUE, commandId == DSMSG_ReadFile); - - if (ioResult == DS_IONoError && error != DS_NoError) { - ioResult = DS_IOError; - } - - gTRKCPUState.Default.GPR[3] = ioResult; - - if (commandId == DSMSG_ReadFile) { - TRK_flush_cache((void*)gTRKCPUState.Default.GPR[6], *length); - } - } - - gTRKCPUState.Default.PC += 4; - return error; + commandId = (u8) gTRKCPUState.Default.GPR[3]; + if (commandId != DSMSG_ReadFile && commandId != DSMSG_WriteFile && commandId != DSMSG_OpenFile && commandId != DSMSG_CloseFile && commandId != DSMSG_PositionFile) { + TRKConstructEvent(&event, NUBEVENT_Exception); + TRKPostEvent(&event); + return DS_NoError; + } + if (commandId == DSMSG_OpenFile) { + error = HandleOpenFileSupportRequest((char*) gTRKCPUState.Default.GPR[4], gTRKCPUState.Default.GPR[5], (u32*) gTRKCPUState.Default.GPR[6], &ioResult); + if (ioResult == DS_IONoError && error != DS_NoError) { + ioResult = DS_IOError; + } + gTRKCPUState.Default.GPR[3] = ioResult; + } else if (commandId == DSMSG_CloseFile) { + error = HandleCloseFileSupportRequest(gTRKCPUState.Default.GPR[4], &ioResult); + if (ioResult == DS_IONoError && error != DS_NoError) { + ioResult = DS_IOError; + } + gTRKCPUState.Default.GPR[3] = ioResult; + } else if (commandId == DSMSG_PositionFile) { + spC = *((u32*) gTRKCPUState.Default.GPR[5]); + error = HandlePositionFileSupportRequest(gTRKCPUState.Default.GPR[4], &spC, gTRKCPUState.Default.GPR[6], &ioResult); + if (ioResult == DS_IONoError && error != DS_NoError) { + ioResult = DS_IOError; + } + gTRKCPUState.Default.GPR[3] = ioResult; + *((u32*) gTRKCPUState.Default.GPR[5]) = spC; + } else { + length = (size_t*) gTRKCPUState.Default.GPR[5]; + error = TRKSuppAccessFile((u8) gTRKCPUState.Default.GPR[4], (u8*) gTRKCPUState.Default.GPR[6], length, (DSIOResult*) &ioResult, TRUE, commandId == DSMSG_ReadFile); + if (ioResult == DS_IONoError && error != DS_NoError) { + ioResult = DS_IOError; + } + gTRKCPUState.Default.GPR[3] = ioResult; + if (commandId == DSMSG_ReadFile) { + TRK_flush_cache((void*) gTRKCPUState.Default.GPR[6], *length); + } + } + gTRKCPUState.Default.PC += 4; + return error; } DSError TRKTargetFlushCache(u8, void* start, void* end) { - if (start < end) { - TRK_flush_cache(start, (u8*)end - (u8*)start); - return DS_NoError; - } + if (start < end) { + TRK_flush_cache(start, (u8*)end - (u8*)start); + return DS_NoError; + } - return DS_InvalidMemory; + return DS_InvalidMemory; } BOOL TRKTargetStopped() { return gTRKState.isStopped; } void TRKTargetSetStopped(unsigned int stopped) { - gTRKState.isStopped = stopped; + gTRKState.isStopped = stopped; } u32 TRKTargetStop() { - TRKTargetSetStopped(1); - return 0; + TRKTargetSetStopped(1); + return 0; } DSError TRKPPCAccessSPR(void* value, u32 spr_register_num, BOOL read) { - /* Initialize instruction array with nop */ + /* Initialize instruction array with nop */ - u32 access_func[5] - = { INSTR_NOP, INSTR_NOP, INSTR_NOP, INSTR_NOP, INSTR_NOP }; - /* - ** Construct a small assembly function to perform the - ** requested access and call it. The read/write function - ** is in the form: - ** - ** read: - ** mfspr r4, spr_register_num - ** stw r4, 0(r3) - ** blr - ** - ** write: - ** lwz r4, 0(r3) - ** mtspr spr_register_num, r4 - ** blr - ** - */ + u32 access_func[10] = { + INSTR_NOP, INSTR_NOP, INSTR_NOP, INSTR_NOP, INSTR_NOP, + INSTR_NOP, INSTR_NOP, INSTR_NOP, INSTR_NOP, INSTR_NOP + }; + /* + ** Construct a small assembly function to perform the + ** requested access and call it. The read/write function + ** is in the form: + ** + ** read: + ** mfspr r4, spr_register_num + ** stw r4, 0(r3) + ** blr + ** + ** write: + ** lwz r4, 0(r3) + ** mtspr spr_register_num, r4 + ** blr + ** + */ - if (read) { - access_func[0] = INSTR_MFSPR(4, spr_register_num); - access_func[1] = (u32)INSTR_STW(4, 0, 3); - } else { - access_func[0] = (u32)INSTR_LWZ(4, 0, 3); - access_func[1] = INSTR_MTSPR(spr_register_num, 4); - } + if (read) { + access_func[0] = INSTR_MFSPR(4, spr_register_num); + access_func[1] = (u32)INSTR_STW(4, 0, 3); + } else { + access_func[0] = (u32)INSTR_LWZ(4, 0, 3); + access_func[1] = INSTR_MTSPR(spr_register_num, 4); + } - return TRKPPCAccessSpecialReg(value, access_func, read); + return TRKPPCAccessSpecialReg(value, access_func, read); } DSError TRKPPCAccessPairedSingleRegister(void* srcDestPtr, u32 psr, BOOL read) { - // all nop by default - u32 instructionData[] - = { INSTR_NOP, INSTR_NOP, INSTR_NOP, INSTR_NOP, INSTR_NOP }; + // all nop by default + u32 instructionData[] = { + INSTR_NOP, INSTR_NOP, INSTR_NOP, INSTR_NOP, INSTR_NOP, + INSTR_NOP, INSTR_NOP, INSTR_NOP, INSTR_NOP, INSTR_NOP + }; - if (read) { - instructionData[0] - = INSTR_PSQ_ST(psr, 0, 3, 0, 0); // psq_st psr, 0(r3), 0, 0 - } else { - instructionData[0] - = INSTR_PSQ_L(psr, 0, 3, 0, 0); // psq_l psr, 0(r3), 0, 0 - } + if (read) { + instructionData[0] + = INSTR_PSQ_ST(psr, 0, 3, 0, 0); // psq_st psr, 0(r3), 0, 0 + } else { + instructionData[0] + = INSTR_PSQ_L(psr, 0, 3, 0, 0); // psq_l psr, 0(r3), 0, 0 + } - return TRKPPCAccessSpecialReg(srcDestPtr, instructionData, read); + return TRKPPCAccessSpecialReg(srcDestPtr, instructionData, read); } +#pragma dont_inline on DSError TRKPPCAccessFPRegister(void* srcDestPtr, u32 fpr, BOOL read) { - DSError error = DS_NoError; - // all nop by default - u32 instructionData1[] - = { INSTR_NOP, INSTR_NOP, INSTR_NOP, INSTR_NOP, INSTR_NOP }; + DSError error = DS_NoError; + // all nop by default + u32 instructionData1[] = { + INSTR_NOP, INSTR_NOP, INSTR_NOP, INSTR_NOP, INSTR_NOP, + INSTR_NOP, INSTR_NOP, INSTR_NOP, INSTR_NOP, INSTR_NOP + }; - if (fpr < 0x20) { - if (read) { - instructionData1[0] = INSTR_STFD(fpr, 0, 3); // stfd fpr, 0(r3) - } else { - instructionData1[0] = INSTR_LFD(fpr, 0, 3); // lfd fpr, 0(r3) - } + if (fpr < 0x20) { + if (read) { + instructionData1[0] = INSTR_STFD(fpr, 0, 3); // stfd fpr, 0(r3) + } else { + instructionData1[0] = INSTR_LFD(fpr, 0, 3); // lfd fpr, 0(r3) + } - error = TRKPPCAccessSpecialReg(srcDestPtr, instructionData1, read); - } else if (fpr == 0x20) { - if (read) { - instructionData1[0] = INSTR_STFD(1, 0, 4); // stfd f1, 0(r4) - instructionData1[1] = 0xfc20048e; // mtfsf 0xff, f1 - instructionData1[2] = INSTR_STFD(1, 0, 3); // stfd f1, 0(r3) - instructionData1[3] = INSTR_LFD(1, 0, 4); // lfd f1, 0(r4) - } else { - instructionData1[0] = INSTR_STFD(1, 0, 4); // stfd f1, 0(r4) - instructionData1[1] = INSTR_LFD(1, 0, 3); // lfd f1, 0(r4) - instructionData1[2] = 0xfdfe0d8e; // mtfsf 0xff, f1 - instructionData1[3] = INSTR_LFD(1, 0, 4); // lfd f1, 0(r4) - } - error = TRKPPCAccessSpecialReg(srcDestPtr, instructionData1, read); - *(u64*)srcDestPtr &= 0xFFFFFFFF; - } else if (fpr == 0x21) { - if (!read) { - *(u32*)srcDestPtr = *((u32*)(srcDestPtr) + 1); - } + error = TRKPPCAccessSpecialReg(srcDestPtr, instructionData1, read); + } else if (fpr == 0x20) { + *(u64*)srcDestPtr &= 0xFFFFFFFF; + } else if (fpr == 0x21) { + if (!read) { + *(u32*)srcDestPtr = *((u32*)(srcDestPtr) + 1); + } + error = TRKPPCAccessSPR(srcDestPtr, 1022, read); + if (read) { + DSFetch_u64(srcDestPtr) = DSFetch_u32(srcDestPtr) & 0xffffffffLL; + } + } - error = TRKPPCAccessSPR(srcDestPtr, SPR_FPECR, read); - if (read) { - DSFetch_u64(srcDestPtr) = DSFetch_u32(srcDestPtr) & 0xffffffffLL; - } - } - - return error; + return error; } +#pragma dont_inline reset #define DEBUG_VECTORREG_ACCESS 0 DSError TRKPPCAccessSpecialReg(void* value, u32* access_func, BOOL read) { - typedef void (*asm_access_type)(void*, void*); + typedef void (*asm_access_type)(void*, void*); - asm_access_type asm_access; + asm_access_type asm_access; - /* - ** Construct a small assembly function to perform the - ** requested access and call it. The read/write function - ** is in the form: - ** - ** - ** blr - */ + /* + ** Construct a small assembly function to perform the + ** requested access and call it. The read/write function + ** is in the form: + ** + ** + ** blr + */ - /* - ** Put blr instruction at the end of access function (it should be - ** a 5-instruction array w/the last one empty). - */ + /* + ** Put blr instruction at the end of access function (it should be + ** a 5-instruction array w/the last one empty). + */ - access_func[9] = INSTR_BLR; + access_func[9] = INSTR_BLR; - /* - ** Now that the instruction array is built, get a function pointer to it. - */ + /* + ** Now that the instruction array is built, get a function pointer to it. + */ - asm_access = (asm_access_type)access_func; + asm_access = (asm_access_type)access_func; #if DEBUG_VECTORREG_ACCESS - __puts("\r\nasm_access: "); - __puthex8((u32)asm_access); - __puts(" access_func: "); - __puthex8((u32)access_func); + __puts("\r\nasm_access: "); + __puthex8((u32)asm_access); + __puts(" access_func: "); + __puthex8((u32)access_func); - for (i = 0; i < 10; i++) { - __puts("\r\ninst["); - __puthex2(i); - __puts("]: "); - __puthex8(access_func[i]); - __puts(" ; "); - __puthex8(*((u32*)asm_access + i)); - } + for (i = 0; i < 10; i++) { + __puts("\r\ninst["); + __puthex2(i); + __puts("]: "); + __puthex8(access_func[i]); + __puts(" ; "); + __puthex8(*((u32*)asm_access + i)); + } - __puts("\r\n"); + __puts("\r\n"); #endif - // Flush cache - TRK_flush_cache(access_func, (sizeof(access_func) * 10)); - (*asm_access)((u32*)value, (void*)&TRKvalue128_temp); + // Flush cache + TRK_flush_cache(access_func, (sizeof(access_func) * 10)); + (*asm_access)((u32*)value, (void*)&TRKvalue128_temp); - return DS_NoError; + return DS_NoError; } void TRKTargetSetInputPendingPtr(void* ptr) { gTRKState.inputPendingPtr = ptr; }