diff --git a/config/GMPE01_00/symbols.txt b/config/GMPE01_00/symbols.txt index 43ae5aae..d2b64397 100644 --- a/config/GMPE01_00/symbols.txt +++ b/config/GMPE01_00/symbols.txt @@ -3668,7 +3668,7 @@ atanhi = .rodata:0x8011E9B8; // type:object size:0x20 scope:local atanlo = .rodata:0x8011E9D8; // type:object size:0x20 scope:local aT = .rodata:0x8011E9F8; // type:object size:0x58 scope:local @62 = .rodata:0x8011EA50; // type:object size:0x1C scope:local data:string -lbl_8011EA70 = .rodata:0x8011EA70; // type:object size:0x20 +lbl_8011EA70 = .rodata:0x8011EA70; // type:object size:0x1D data:string gTRKMemMap = .rodata:0x8011EA90; // type:object size:0x10 data:4byte lbl_8011EAA0 = .rodata:0x8011EAA0; // type:object size:0x28 data:4byte lbl_8011EAC8 = .rodata:0x8011EAC8; // type:object size:0x28 data:4byte diff --git a/configure.py b/configure.py index 1e740726..bcccf9c6 100644 --- a/configure.py +++ b/configure.py @@ -238,12 +238,11 @@ cflags_msl = [ cflags_trk = [ *cflags_base, "-use_lmw_stmw on", - "-str reuse,pool,readonly", + "-str reuse,readonly", "-common off", "-sdata 0", "-sdata2 0", "-inline auto,deferred", - "-pool off", "-enum min", "-sdatathreshold 0" ] @@ -742,12 +741,12 @@ config.libs = [ Object(MatchingFor("GMPE01_00", "GMPE01_01"), "TRK_MINNOW_DOLPHIN/mainloop.c"), Object(MatchingFor("GMPE01_00", "GMPE01_01"), "TRK_MINNOW_DOLPHIN/nubevent.c"), Object(MatchingFor("GMPE01_00", "GMPE01_01"), "TRK_MINNOW_DOLPHIN/nubinit.c"), - Object(NonMatching, "TRK_MINNOW_DOLPHIN/msg.c"), - Object(NonMatching, "TRK_MINNOW_DOLPHIN/msgbuf.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(NonMatching, "TRK_MINNOW_DOLPHIN/usr_put.c"), + Object(MatchingFor("GMPE01_00", "GMPE01_01"), "TRK_MINNOW_DOLPHIN/usr_put.c"), Object(NonMatching, "TRK_MINNOW_DOLPHIN/dispatch.c"), - Object(NonMatching, "TRK_MINNOW_DOLPHIN/msghndlr.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/mutex_TRK.c"), Object(NonMatching, "TRK_MINNOW_DOLPHIN/notify.c"), @@ -761,8 +760,8 @@ config.libs = [ Object(MatchingFor("GMPE01_00", "GMPE01_01"), "TRK_MINNOW_DOLPHIN/main_TRK.c"), Object(NonMatching, "TRK_MINNOW_DOLPHIN/dolphin_trk_glue.c"), Object(MatchingFor("GMPE01_00", "GMPE01_01"), "TRK_MINNOW_DOLPHIN/targcont.c"), - Object(NonMatching, "TRK_MINNOW_DOLPHIN/target_options.c"), - Object(NonMatching, "TRK_MINNOW_DOLPHIN/mslsupp.c"), + Object(MatchingFor("GMPE01_00", "GMPE01_01"), "TRK_MINNOW_DOLPHIN/target_options.c"), + Object(MatchingFor("GMPE01_00", "GMPE01_01"), "TRK_MINNOW_DOLPHIN/mslsupp.c"), ], }, MusyX( diff --git a/include/PowerPC_EABI_Support/MetroTRK/trk.h b/include/PowerPC_EABI_Support/MetroTRK/trk.h index c8814672..66b36f3b 100644 --- a/include/PowerPC_EABI_Support/MetroTRK/trk.h +++ b/include/PowerPC_EABI_Support/MetroTRK/trk.h @@ -254,6 +254,9 @@ typedef struct ProcessorRestoreFlags_PPC { void TRKSaveExtended1Block(); +void SetUseSerialIO(u8); +u8 GetUseSerialIO(void); + #define SPR_XER 1 #define SPR_LR 8 #define SPR_CTR 9 diff --git a/include/TRK_MINNOW_DOLPHIN/MetroTRK/Portable/msg.h b/include/TRK_MINNOW_DOLPHIN/MetroTRK/Portable/msg.h index 8433ef8d..2dc2dff8 100644 --- a/include/TRK_MINNOW_DOLPHIN/MetroTRK/Portable/msg.h +++ b/include/TRK_MINNOW_DOLPHIN/MetroTRK/Portable/msg.h @@ -8,7 +8,7 @@ typedef struct _TRK_Msg { u8 _00[8]; u32 m_msgLength; u32 _0C; - u32 m_msg; + u8 m_msg[4]; // TODO: unknown array length } TRK_Msg; #ifdef __cplusplus diff --git a/include/TRK_MINNOW_DOLPHIN/MetroTRK/Portable/msgbuf.h b/include/TRK_MINNOW_DOLPHIN/MetroTRK/Portable/msgbuf.h index 770d3886..f16fe261 100644 --- a/include/TRK_MINNOW_DOLPHIN/MetroTRK/Portable/msgbuf.h +++ b/include/TRK_MINNOW_DOLPHIN/MetroTRK/Portable/msgbuf.h @@ -12,7 +12,7 @@ DSError TRKInitializeMessageBuffers(void); DSError TRKSetBufferPosition(TRKBuffer* msg, u32 pos); void* TRKGetBuffer(int); -void TRKResetBuffer(TRKBuffer* msg, BOOL keepData); +void TRKResetBuffer(TRKBuffer* msg, u8 keepData); void* TRKGetBuffer(int idx); void TRKReleaseBuffer(int idx); DSError TRKGetFreeBuffer(int* msgID, TRKBuffer** outMsg); diff --git a/src/TRK_MINNOW_DOLPHIN/dolphin_trk_glue.c b/src/TRK_MINNOW_DOLPHIN/dolphin_trk_glue.c index 9a55362b..9fbb6aeb 100644 --- a/src/TRK_MINNOW_DOLPHIN/dolphin_trk_glue.c +++ b/src/TRK_MINNOW_DOLPHIN/dolphin_trk_glue.c @@ -4,84 +4,95 @@ #include "amcstubs/AmcExi2Stubs.h" #include "PowerPC_EABI_Support/MetroTRK/trk.h" +#define BUFF_LEN 4362 + +u8 gWriteBuf[BUFF_LEN]; +u8 gReadBuf[BUFF_LEN]; +s32 _MetroTRK_Has_Framing; +s32 gReadCount; +s32 gReadPos; +s32 gWritePos; + DBCommTable gDBCommTable = {}; asm void TRKLoadContext(OSContext* ctx, u32) { #ifdef __MWERKS__ // clang-format off - nofralloc - lwz r0, OSContext.gpr[0](r3) - lwz r1, OSContext.gpr[1](r3) - lwz r2, OSContext.gpr[2](r3) - lhz r5, OSContext.state(r3) - rlwinm. r6, r5, 0, 0x1e, 0x1e - beq lbl_80371C1C - rlwinm r5, r5, 0, 0x1f, 0x1d - sth r5, OSContext.state(r3) - lmw r5, OSContext.gpr[5](r3) - b lbl_80371C20 + nofralloc + lwz r0, OSContext.gpr[0](r3) + lwz r1, OSContext.gpr[1](r3) + lwz r2, OSContext.gpr[2](r3) + lhz r5, OSContext.state(r3) + rlwinm. r6, r5, 0, 0x1e, 0x1e + beq lbl_80371C1C + rlwinm r5, r5, 0, 0x1f, 0x1d + sth r5, OSContext.state(r3) + lmw r5, OSContext.gpr[5](r3) + b lbl_80371C20 lbl_80371C1C: - lmw r13, OSContext.gpr[13](r3) + lmw r13, OSContext.gpr[13](r3) lbl_80371C20: - mr r31, r3 - mr r3, r4 - lwz r4, OSContext.cr(r31) - mtcrf 0xff, r4 - lwz r4, OSContext.lr(r31) - mtlr r4 - lwz r4, OSContext.ctr(r31) - mtctr r4 - lwz r4, OSContext.xer(r31) - mtxer r4 - mfmsr r4 - rlwinm r4, r4, 0, 0x11, 0xf //Turn off external exceptions - rlwinm r4, r4, 0, 0x1f, 0x1d //Turn off recoverable exception flag - mtmsr r4 - mtsprg 1, r2 - lwz r4, OSContext.gpr[3](r31) - mtsprg 2, r4 - lwz r4, OSContext.gpr[4](r31) - mtsprg 3, r4 - lwz r2, OSContext.srr0(r31) - lwz r4, OSContext.srr1(r31) - lwz r31, OSContext.gpr[31](r31) - b TRKInterruptHandler + mr r31, r3 + mr r3, r4 + lwz r4, OSContext.cr(r31) + mtcrf 0xff, r4 + lwz r4, OSContext.lr(r31) + mtlr r4 + lwz r4, OSContext.ctr(r31) + mtctr r4 + lwz r4, OSContext.xer(r31) + mtxer r4 + mfmsr r4 + rlwinm r4, r4, 0, 0x11, 0xf //Turn off external exceptions + rlwinm r4, r4, 0, 0x1f, 0x1d //Turn off recoverable exception flag + mtmsr r4 + mtsprg 1, r2 + lwz r4, OSContext.gpr[3](r31) + mtsprg 2, r4 + lwz r4, OSContext.gpr[4](r31) + mtsprg 3, r4 + lwz r2, OSContext.srr0(r31) + lwz r4, OSContext.srr1(r31) + lwz r31, OSContext.gpr[31](r31) + b TRKInterruptHandler #endif // clang-format on } void TRKEXICallBack(__OSInterrupt param_0, OSContext* ctx) { - OSEnableScheduler(); - TRKLoadContext(ctx, 0x500); + OSEnableScheduler(); + TRKLoadContext(ctx, 0x500); } int InitMetroTRKCommTable(int hwId) { - int result; + int result; - if (hwId == HARDWARE_GDEV) { - result = Hu_IsStub(); + if (hwId == HARDWARE_GDEV) { + OSReport("MetroTRK : Set to GDEV hardware\n"); + result = Hu_IsStub(); - gDBCommTable.initialize_func = DBInitComm; - gDBCommTable.init_interrupts_func = DBInitInterrupts; - gDBCommTable.peek_func = DBQueryData; - gDBCommTable.read_func = DBRead; - gDBCommTable.write_func = DBWrite; - gDBCommTable.open_func = DBOpen; - gDBCommTable.close_func = DBClose; - } else { - result = AMC_IsStub(); + gDBCommTable.initialize_func = DBInitComm; + gDBCommTable.init_interrupts_func = DBInitInterrupts; + gDBCommTable.peek_func = DBQueryData; + gDBCommTable.read_func = DBRead; + gDBCommTable.write_func = DBWrite; + gDBCommTable.open_func = DBOpen; + gDBCommTable.close_func = DBClose; + } else { + OSReport("MetroTRK : Set to AMC DDH hardware\n"); + result = AMC_IsStub(); - gDBCommTable.initialize_func = EXI2_Init; - gDBCommTable.init_interrupts_func = EXI2_EnableInterrupts; - gDBCommTable.peek_func = EXI2_Poll; - gDBCommTable.read_func = EXI2_ReadN; - gDBCommTable.write_func = EXI2_WriteN; - gDBCommTable.open_func = EXI2_Reserve; - gDBCommTable.close_func = EXI2_Unreserve; - } + gDBCommTable.initialize_func = EXI2_Init; + gDBCommTable.init_interrupts_func = EXI2_EnableInterrupts; + gDBCommTable.peek_func = EXI2_Poll; + gDBCommTable.read_func = EXI2_ReadN; + gDBCommTable.write_func = EXI2_WriteN; + gDBCommTable.open_func = EXI2_Reserve; + gDBCommTable.close_func = EXI2_Unreserve; + } - return result; + return result; } void TRKUARTInterruptHandler() { } @@ -89,8 +100,8 @@ void TRKUARTInterruptHandler() { } DSError TRKInitializeIntDrivenUART(u32 param_0, u32 param_1, u32 param_2, volatile u8** param_3) { - gDBCommTable.initialize_func(param_3, TRKEXICallBack); - return DS_NoError; + gDBCommTable.initialize_func(param_3, TRKEXICallBack); + return DS_NoError; } void EnableEXI2Interrupts(void) { gDBCommTable.init_interrupts_func(); } @@ -99,14 +110,59 @@ int TRKPollUART(void) { return gDBCommTable.peek_func(); } UARTError TRKReadUARTN(void* bytes, u32 length) { - int readErr = gDBCommTable.read_func(bytes, length); - return readErr == 0 ? 0 : -1; + int readErr = gDBCommTable.read_func(bytes, length); + return readErr == 0 ? 0 : -1; } UARTError TRKWriteUARTN(const void* bytes, u32 length) { - int writeErr = gDBCommTable.write_func(bytes, length); - return writeErr == 0 ? 0 : -1; + int writeErr = gDBCommTable.write_func(bytes, length); + return writeErr == 0 ? 0 : -1; +} + +UARTError WriteUARTFlush(void) +{ + UARTError readErr = 0; + + while (gWritePos < 0x800) { + gWriteBuf[gWritePos] = 0; + gWritePos++; + } + if (gWritePos != 0) { + readErr = TRKWriteUARTN(gWriteBuf, gWritePos); + gWritePos = 0; + } + return readErr; +} + +UARTError WriteUART1(u8 arg0) +{ + gWriteBuf[gWritePos++] = arg0; + return 0; +} + +UARTError TRKReadUARTPoll(u8* arg0) +{ + UARTError readErr = 4; + + if (gReadPos >= gReadCount) { + gReadPos = 0; + gReadCount = TRKPollUART(); + if (gReadCount > 0) { + if (gReadCount > BUFF_LEN) { + gReadCount = BUFF_LEN; + } + readErr = TRKReadUARTN(gReadBuf, gReadCount); + if (readErr != 0) { + gReadCount = 0; + } + } + } + if (gReadPos < gReadCount) { + *arg0 = gReadBuf[gReadPos++]; + readErr = 0; + } + return readErr; } void ReserveEXI2Port(void) { gDBCommTable.open_func(); } diff --git a/src/TRK_MINNOW_DOLPHIN/msg.c b/src/TRK_MINNOW_DOLPHIN/msg.c index 0ae376eb..09f5de11 100644 --- a/src/TRK_MINNOW_DOLPHIN/msg.c +++ b/src/TRK_MINNOW_DOLPHIN/msg.c @@ -2,8 +2,60 @@ #include "TRK_MINNOW_DOLPHIN/Os/dolphin/dolphin_trk_glue.h" #include "PowerPC_EABI_Support/MetroTRK/trk.h" +// Incorrect signature? Should be u8. +UARTError WriteUART1(s8 arg0); + DSError TRKMessageSend(TRK_Msg* msg) { - DSError write_err = TRKWriteUARTN(&msg->m_msg, msg->m_msgLength); - return DS_NoError; + u8 var_r30; + u8 var_r28; + u8 var_r28_2; + s32 var_r3; + s32 i; + + var_r30 = 0; + for (i = 0; i < msg->m_msgLength; i++) { + var_r30 = var_r30 + msg->m_msg[i]; + } + var_r30 = var_r30 ^ 0xFF; + var_r3 = WriteUART1(0x7E); + if (var_r3 == 0) { + for (i = 0; i < msg->m_msgLength; i++) { + var_r28 = msg->m_msg[i]; + if (var_r28 == 0x7E || var_r28 == 0x7D) { + var_r3 = WriteUART1(0x7D); + var_r28 ^= 0x20; + if (var_r3 != 0) { + break; + } + } + var_r3 = WriteUART1(var_r28); + if (var_r3 != 0) { + break; + } + } + } + if (var_r3 == 0) { + var_r28_2 = var_r30; + for (i = 0; i < 1; i++) { + if (var_r28_2 == 0x7E || var_r28_2 == 0x7D) { + var_r3 = WriteUART1(0x7D); + var_r28_2 ^= 0x20; + if (var_r3 != 0) { + break; + } + } + var_r3 = WriteUART1(var_r28_2); + if (var_r3 != 0) { + break; + } + } + } + if (var_r3 == 0) { + var_r3 = WriteUART1(0x7E); + } + if (var_r3 == 0) { + var_r3 = WriteUARTFlush(); + } + return var_r3; } diff --git a/src/TRK_MINNOW_DOLPHIN/msgbuf.c b/src/TRK_MINNOW_DOLPHIN/msgbuf.c index 8eb7031c..71702e8c 100644 --- a/src/TRK_MINNOW_DOLPHIN/msgbuf.c +++ b/src/TRK_MINNOW_DOLPHIN/msgbuf.c @@ -34,7 +34,7 @@ DSError TRKGetFreeBuffer(int* msgID, TRKBuffer** outMsg) TRKAcquireMutex(buf); if (!buf->isInUse) { - TRKResetBuffer(buf, TRUE); + TRKResetBuffer(buf, 1); TRKSetBufferUsed(buf, TRUE); error = DS_NoError; *outMsg = buf; @@ -44,6 +44,10 @@ DSError TRKGetFreeBuffer(int* msgID, TRKBuffer** outMsg) TRKReleaseMutex(buf); } + if (error == DS_NoMessageBufferAvailable) { + usr_puts_serial("ERROR : No buffer available\n"); + } + return error; } @@ -68,7 +72,7 @@ void TRKReleaseBuffer(int idx) } } -void TRKResetBuffer(TRKBuffer* msg, BOOL keepData) +void TRKResetBuffer(TRKBuffer* msg, u8 keepData) { msg->length = 0; msg->position = 0; @@ -96,6 +100,7 @@ DSError TRKSetBufferPosition(TRKBuffer* msg, u32 pos) return error; } +#pragma dont_inline on DSError TRKAppendBuffer(TRKBuffer* msg, const void* data, size_t length) { DSError error = DS_NoError; // r31 @@ -129,6 +134,7 @@ DSError TRKAppendBuffer(TRKBuffer* msg, const void* data, size_t length) return error; } +#pragma dont_inline reset DSError TRKReadBuffer(TRKBuffer* msg, void* data, size_t length) { diff --git a/src/TRK_MINNOW_DOLPHIN/msghndlr.c b/src/TRK_MINNOW_DOLPHIN/msghndlr.c index 35c91822..c8ede7e7 100644 --- a/src/TRK_MINNOW_DOLPHIN/msghndlr.c +++ b/src/TRK_MINNOW_DOLPHIN/msghndlr.c @@ -45,8 +45,7 @@ DSError TRKStandardACK(TRKBuffer* buffer, MessageCommandID commandID, DSReplyError replyError) { TRKMessageIntoReply(buffer, commandID, replyError); - TRKSendACK(buffer); - return; + return TRKSendACK(buffer); } DSError TRKDoUnsupported(TRKBuffer* buffer) @@ -107,7 +106,6 @@ DSError TRKDoVersions(TRKBuffer* buffer) else error = TRKSendACK(buffer); } - return error; } DSError TRKDoSupportMask(TRKBuffer* buffer) @@ -140,7 +138,7 @@ DSError TRKDoCPUType(TRKBuffer* buffer) if (buffer->length != 1) { error = TRKStandardACK(buffer, DSMSG_ReplyACK, DSREPLY_PacketSizeError); - return error; + return; } TRKMessageIntoReply(buffer, DSMSG_ReplyACK, DSREPLY_NoError); @@ -166,8 +164,6 @@ DSError TRKDoCPUType(TRKBuffer* buffer) error = TRKStandardACK(buffer, DSMSG_ReplyACK, DSREPLY_CWDSError); else error = TRKSendACK(buffer); - - return error; } DSError TRKDoReadMemory(TRKBuffer* buffer) @@ -175,11 +171,11 @@ DSError TRKDoReadMemory(TRKBuffer* buffer) DSError error; DSReplyError replyError; u8 tempBuf[0x800]; - u32 length; u32 msg_start; + u32 length; u16 msg_length; - u8 msg_options; u8 msg_command; + u8 msg_options; if (buffer->length != 8) { error = TRKStandardACK(buffer, DSMSG_ReplyACK, DSREPLY_PacketSizeError); @@ -257,11 +253,11 @@ DSError TRKDoWriteMemory(TRKBuffer* buffer) DSError error; DSReplyError replyError; u8 tmpBuffer[0x800]; - u32 length; u32 msg_start; + u32 length; u16 msg_length; - u8 msg_options; u8 msg_command; + u8 msg_options; if (buffer->length <= 8) { error = TRKStandardACK(buffer, DSMSG_ReplyACK, DSREPLY_PacketSizeError); @@ -343,14 +339,14 @@ DSError TRKDoReadRegisters(TRKBuffer* buffer) DSReplyError replyError; DSMessageRegisterOptions options; u32 registerDataLength; - u16 msg_lastRegister; u16 msg_firstRegister; - u8 msg_options; + u16 msg_lastRegister; u8 msg_command; + u8 msg_options; if (buffer->length != 6) { error = TRKStandardACK(buffer, DSMSG_ReplyACK, DSREPLY_PacketSizeError); - return error; + return; } TRKSetBufferPosition(buffer, DSREPLY_NoError); error = TRKReadBuffer1_ui8(buffer, &msg_command); @@ -366,13 +362,13 @@ DSError TRKDoReadRegisters(TRKBuffer* buffer) if (msg_firstRegister > msg_lastRegister) { error = TRKStandardACK(buffer, DSMSG_ReplyACK, DSREPLY_InvalidRegisterRange); - return error; + return; } if (error == DS_NoError) TRKMessageIntoReply(buffer, DSMSG_ReplyACK, DSREPLY_NoError); - options = (DSMessageRegisterOptions)msg_options; + options = (DSMessageRegisterOptions)(msg_options & 7); switch (options) { case DSREG_Default: error = TRKTargetAccessDefault(msg_firstRegister, msg_lastRegister, @@ -423,8 +419,6 @@ DSError TRKDoReadRegisters(TRKBuffer* buffer) } else { error = TRKSendACK(buffer); } - - return error; } DSError TRKDoWriteRegisters(TRKBuffer* buffer) @@ -433,14 +427,14 @@ DSError TRKDoWriteRegisters(TRKBuffer* buffer) DSReplyError replyError; DSMessageRegisterOptions options; u32 registerDataLength; - u16 msg_lastRegister; u16 msg_firstRegister; - u8 msg_options; + u16 msg_lastRegister; u8 msg_command; + u8 msg_options; if (buffer->length <= 6) { error = TRKStandardACK(buffer, DSMSG_ReplyACK, DSREPLY_PacketSizeError); - return error; + return; } TRKSetBufferPosition(buffer, DSREPLY_NoError); error = TRKReadBuffer1_ui8(buffer, &msg_command); @@ -456,7 +450,7 @@ DSError TRKDoWriteRegisters(TRKBuffer* buffer) if (msg_firstRegister > msg_lastRegister) { error = TRKStandardACK(buffer, DSMSG_ReplyACK, DSREPLY_InvalidRegisterRange); - return error; + return; } options = (DSMessageRegisterOptions)msg_options; @@ -516,22 +510,20 @@ DSError TRKDoWriteRegisters(TRKBuffer* buffer) } else { error = TRKSendACK(buffer); } - - return error; } DSError TRKDoFlushCache(TRKBuffer* buffer) { DSError error; DSReplyError replyErr; - u32 msg_end; u32 msg_start; - u8 msg_options; + u32 msg_end; u8 msg_command; + u8 msg_options; if (buffer->length != 10) { error = TRKStandardACK(buffer, DSMSG_ReplyACK, DSREPLY_PacketSizeError); - return error; + return; } TRKSetBufferPosition(buffer, DSREPLY_NoError); @@ -546,7 +538,7 @@ DSError TRKDoFlushCache(TRKBuffer* buffer) if (msg_start > msg_end) { error = TRKStandardACK(buffer, DSMSG_ReplyACK, DSREPLY_InvalidMemoryRange); - return error; + return; } if (error == DS_NoError) @@ -570,8 +562,6 @@ DSError TRKDoFlushCache(TRKBuffer* buffer) } else { error = TRKSendACK(buffer); } - - return error; } DSError TRKDoContinue(TRKBuffer* buffer) @@ -581,14 +571,12 @@ DSError TRKDoContinue(TRKBuffer* buffer) error = TRKTargetStopped(); if (error == DS_NoError) { error = TRKStandardACK(buffer, DSMSG_ReplyACK, DSREPLY_NotStopped); - return error; + return; } error = TRKStandardACK(buffer, DSMSG_ReplyACK, DSREPLY_NoError); if (error == DS_NoError) error = TRKTargetContinue(); - - return error; } DSError TRKDoStep(TRKBuffer* buffer) @@ -601,8 +589,10 @@ DSError TRKDoStep(TRKBuffer* buffer) u32 msg_rangeEnd; u32 pc; - if (buffer->length < 3) - return TRKStandardACK(buffer, DSMSG_ReplyACK, DSREPLY_PacketSizeError); + if (buffer->length < 3) { + TRKStandardACK(buffer, DSMSG_ReplyACK, DSREPLY_PacketSizeError); + return; + } TRKSetBufferPosition(buffer, DSREPLY_NoError); @@ -618,12 +608,14 @@ DSError TRKDoStep(TRKBuffer* buffer) if (msg_count >= 1) { break; } - return TRKStandardACK(buffer, DSMSG_ReplyACK, DSREPLY_ParameterError); + TRKStandardACK(buffer, DSMSG_ReplyACK, DSREPLY_ParameterError); + return; case DSSTEP_IntoRange: case DSSTEP_OverRange: - if (buffer->length != 10) - return TRKStandardACK(buffer, DSMSG_ReplyACK, - DSREPLY_PacketSizeError); + if (buffer->length != 10) { + TRKStandardACK(buffer, DSMSG_ReplyACK, DSREPLY_PacketSizeError); + return; + } if (error == DS_NoError) error = TRKReadBuffer1_ui32(buffer, &msg_rangeStart); @@ -634,33 +626,33 @@ DSError TRKDoStep(TRKBuffer* buffer) if (pc >= msg_rangeStart && pc <= msg_rangeEnd) { break; } - return TRKStandardACK(buffer, DSMSG_ReplyACK, DSREPLY_ParameterError); + TRKStandardACK(buffer, DSMSG_ReplyACK, DSREPLY_ParameterError); + return; default: - return TRKStandardACK(buffer, DSMSG_ReplyACK, - DSREPLY_UnsupportedOptionError); + TRKStandardACK(buffer, DSMSG_ReplyACK, DSREPLY_UnsupportedOptionError); + return; } if (!TRKTargetStopped()) { - return TRKStandardACK(buffer, DSMSG_ReplyACK, DSREPLY_NotStopped); - } else { - error = TRKStandardACK(buffer, DSMSG_ReplyACK, DSREPLY_NoError); - if (error == DS_NoError) - switch (msg_options) { - case DSSTEP_IntoCount: - case DSSTEP_OverCount: - error = TRKTargetSingleStep(msg_count, - (msg_options == DSSTEP_OverCount)); - break; - case DSSTEP_IntoRange: - case DSSTEP_OverRange: - error = TRKTargetStepOutOfRange( - msg_rangeStart, msg_rangeEnd, - (msg_options == DSSTEP_OverRange)); - break; - } - - return error; + TRKStandardACK(buffer, DSMSG_ReplyACK, DSREPLY_NotStopped); + return; } + + error = TRKStandardACK(buffer, DSMSG_ReplyACK, DSREPLY_NoError); + if (error == DS_NoError) + switch (msg_options) { + case DSSTEP_IntoCount: + case DSSTEP_OverCount: + error = TRKTargetSingleStep(msg_count, + (msg_options == DSSTEP_OverCount)); + break; + case DSSTEP_IntoRange: + case DSSTEP_OverRange: + error = TRKTargetStepOutOfRange( + msg_rangeStart, msg_rangeEnd, + (msg_options == DSSTEP_OverRange)); + break; + } } DSError TRKDoStop(TRKBuffer* b) @@ -687,3 +679,46 @@ DSError TRKDoStop(TRKBuffer* b) return TRKStandardACK(b, DSMSG_ReplyACK, replyError); } + +DSError TRKDoSetOption(TRKBuffer* buffer) { + DSError error; + u8 spA; + u8 sp9; + u8 sp8; + + spA = 0; + sp9 = 0; + sp8 = 0; + TRKSetBufferPosition(buffer, DSREPLY_NoError); + error = TRKReadBuffer1_ui8(buffer, &spA); + if (error == DS_NoError) { + error = TRKReadBuffer1_ui8(buffer, &sp9); + } + if (error == DS_NoError) { + error = TRKReadBuffer1_ui8(buffer, &sp8); + } + if (error != DS_NoError) { + TRKResetBuffer(buffer, 1); + if (buffer->position < 0x880) { + buffer->data[buffer->position++] = 0x80; + buffer->length++; + } + if (buffer->position < 0x880) { + buffer->data[buffer->position++] = 1; + buffer->length++; + } + TRKSendACK(buffer); + } else if (sp9 == 1) { + SetUseSerialIO(sp8); + } + TRKResetBuffer(buffer, 1); + if (buffer->position < 0x880) { + buffer->data[buffer->position++] = 0x80; + buffer->length++; + } + if (buffer->position < 0x880) { + buffer->data[buffer->position++] = 0; + buffer->length++; + } + return TRKSendACK(buffer); +} diff --git a/src/TRK_MINNOW_DOLPHIN/mslsupp.c b/src/TRK_MINNOW_DOLPHIN/mslsupp.c new file mode 100755 index 00000000..cbcfc85f --- /dev/null +++ b/src/TRK_MINNOW_DOLPHIN/mslsupp.c @@ -0,0 +1,112 @@ +#include "PowerPC_EABI_Support/MetroTRK/trk.h" +#include + +// forward declares +DSIOResult __read_file(u32 handle, u8* buffer, size_t* count, void* ref_con); +DSIOResult __write_file(u32 handle, u8* buffer, size_t* count, void* ref_con); +DSIOResult __access_file(u32 handle, u8* buffer, size_t* count, void* ref_con, MessageCommandID cmd); + +/** + * @note Address: 0x800C0B4C + * @note Size: 0xBC + */ +DSIOResult __read_console(u32 handle, u8* buffer, size_t* count, void* ref_con) +{ + if (GetUseSerialIO() == 0) { + return DS_IOError; + } + return __read_file(DS_Stdin, buffer, count, ref_con); +} + +/** + * @note Address: 0x800C0A90 + * @note Size: 0xBC + */ +DSIOResult __TRK_write_console(u32 handle, u8* buffer, size_t* count, void* ref_con) +{ + if (GetUseSerialIO() == 0) { + return DS_IOError; + } + return __write_file(DS_Stdout, buffer, count, ref_con); +} + +/** + * @note Address: N/A + * @note Size: 0xB4 + */ +DSIOResult __read_file(u32 handle, u8* buffer, size_t* count, void* ref_con) +{ + return __access_file(handle, buffer, count, ref_con, DSMSG_ReadFile); +} + +/** + * @note Address: N/A + * @note Size: 0xB4 + */ +DSIOResult __write_file(u32 handle, u8* buffer, size_t* count, void* ref_con) +{ + return __access_file(handle, buffer, count, ref_con, DSMSG_WriteFile); +} + +/** + * @note Address: N/A + * @note Size: 0x17C + */ +void __open_file(void) +{ + // UNUSED FUNCTION +} + +/** + * @note Address: N/A + * @note Size: 0xDC + */ +void __position_file(void) +{ + // UNUSED FUNCTION +} + +/** + * @note Address: N/A + * @note Size: 0xE0 + */ +void convertFileMode(void) +{ + // UNUSED FUNCTION +} + +/** + * @note Address: N/A + * @note Size: 0xC0 + */ +DSIOResult __access_file(u32 handle, u8* buffer, size_t* count, void* ref_con, MessageCommandID cmd) +{ + size_t countTemp; + u32 r0; + + if (GetTRKConnected() == DS_NoError) { + return DS_IOError; + } + + countTemp = *count; + r0 = TRKAccessFile(cmd, handle, &countTemp, buffer); + *count = countTemp; + + switch ((u8)r0) { + case DS_IONoError: + return DS_IONoError; + case DS_IOEOF: + return DS_IOEOF; + } + + return DS_IOError; +} + +/** + * @note Address: N/A + * @note Size: 0x1D0 + */ +void __open_temp_file(void) +{ + // UNUSED FUNCTION +} diff --git a/src/TRK_MINNOW_DOLPHIN/target_options.c b/src/TRK_MINNOW_DOLPHIN/target_options.c new file mode 100755 index 00000000..22cc3e98 --- /dev/null +++ b/src/TRK_MINNOW_DOLPHIN/target_options.c @@ -0,0 +1,11 @@ +#include "PowerPC_EABI_Support/MetroTRK/trk.h" + +static u8 bUseSerialIO; + +void SetUseSerialIO(u8 sio) { + bUseSerialIO = sio; +} + +u8 GetUseSerialIO(void) { + return bUseSerialIO; +} diff --git a/src/TRK_MINNOW_DOLPHIN/usr_put.c b/src/TRK_MINNOW_DOLPHIN/usr_put.c index eda11e06..7ba2dc21 100644 --- a/src/TRK_MINNOW_DOLPHIN/usr_put.c +++ b/src/TRK_MINNOW_DOLPHIN/usr_put.c @@ -2,4 +2,25 @@ #include "TRK_MINNOW_DOLPHIN/MetroTRK/Portable/msghndlr.h" #include "PowerPC_EABI_Support/MetroTRK/trk.h" +BOOL usr_puts_serial(const char* msg) +{ + BOOL connect_ = FALSE; + char c; + char buf[2]; + + while (!connect_ && (c = *msg++) != '\0') { + BOOL connect = GetTRKConnected(); + + buf[0] = c; + buf[1] = '\0'; + + SetTRKConnected(FALSE); + OSReport(buf); + + SetTRKConnected(connect); + connect_ = FALSE; + } + return connect_; +} + void usr_put_initialize(void) { }