Making some TRK progress (#564)

This commit is contained in:
mrshigure 2025-02-07 06:48:22 -08:00 committed by GitHub
parent 64f087c2c9
commit 66a9a044fa
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
12 changed files with 434 additions and 139 deletions

View file

@ -3668,7 +3668,7 @@ atanhi = .rodata:0x8011E9B8; // type:object size:0x20 scope:local
atanlo = .rodata:0x8011E9D8; // type:object size:0x20 scope:local atanlo = .rodata:0x8011E9D8; // type:object size:0x20 scope:local
aT = .rodata:0x8011E9F8; // type:object size:0x58 scope:local aT = .rodata:0x8011E9F8; // type:object size:0x58 scope:local
@62 = .rodata:0x8011EA50; // type:object size:0x1C scope:local data:string @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 gTRKMemMap = .rodata:0x8011EA90; // type:object size:0x10 data:4byte
lbl_8011EAA0 = .rodata:0x8011EAA0; // type:object size:0x28 data:4byte lbl_8011EAA0 = .rodata:0x8011EAA0; // type:object size:0x28 data:4byte
lbl_8011EAC8 = .rodata:0x8011EAC8; // type:object size:0x28 data:4byte lbl_8011EAC8 = .rodata:0x8011EAC8; // type:object size:0x28 data:4byte

View file

@ -238,12 +238,11 @@ cflags_msl = [
cflags_trk = [ cflags_trk = [
*cflags_base, *cflags_base,
"-use_lmw_stmw on", "-use_lmw_stmw on",
"-str reuse,pool,readonly", "-str reuse,readonly",
"-common off", "-common off",
"-sdata 0", "-sdata 0",
"-sdata2 0", "-sdata2 0",
"-inline auto,deferred", "-inline auto,deferred",
"-pool off",
"-enum min", "-enum min",
"-sdatathreshold 0" "-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/mainloop.c"),
Object(MatchingFor("GMPE01_00", "GMPE01_01"), "TRK_MINNOW_DOLPHIN/nubevent.c"), Object(MatchingFor("GMPE01_00", "GMPE01_01"), "TRK_MINNOW_DOLPHIN/nubevent.c"),
Object(MatchingFor("GMPE01_00", "GMPE01_01"), "TRK_MINNOW_DOLPHIN/nubinit.c"), Object(MatchingFor("GMPE01_00", "GMPE01_01"), "TRK_MINNOW_DOLPHIN/nubinit.c"),
Object(NonMatching, "TRK_MINNOW_DOLPHIN/msg.c"), Object(MatchingFor("GMPE01_00", "GMPE01_01"), "TRK_MINNOW_DOLPHIN/msg.c"),
Object(NonMatching, "TRK_MINNOW_DOLPHIN/msgbuf.c"), Object(MatchingFor("GMPE01_00", "GMPE01_01"), "TRK_MINNOW_DOLPHIN/msgbuf.c"),
Object(NonMatching, "TRK_MINNOW_DOLPHIN/serpoll.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/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(NonMatching, "TRK_MINNOW_DOLPHIN/support.c"),
Object(MatchingFor("GMPE01_00", "GMPE01_01"), "TRK_MINNOW_DOLPHIN/mutex_TRK.c"), Object(MatchingFor("GMPE01_00", "GMPE01_01"), "TRK_MINNOW_DOLPHIN/mutex_TRK.c"),
Object(NonMatching, "TRK_MINNOW_DOLPHIN/notify.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(MatchingFor("GMPE01_00", "GMPE01_01"), "TRK_MINNOW_DOLPHIN/main_TRK.c"),
Object(NonMatching, "TRK_MINNOW_DOLPHIN/dolphin_trk_glue.c"), Object(NonMatching, "TRK_MINNOW_DOLPHIN/dolphin_trk_glue.c"),
Object(MatchingFor("GMPE01_00", "GMPE01_01"), "TRK_MINNOW_DOLPHIN/targcont.c"), Object(MatchingFor("GMPE01_00", "GMPE01_01"), "TRK_MINNOW_DOLPHIN/targcont.c"),
Object(NonMatching, "TRK_MINNOW_DOLPHIN/target_options.c"), Object(MatchingFor("GMPE01_00", "GMPE01_01"), "TRK_MINNOW_DOLPHIN/target_options.c"),
Object(NonMatching, "TRK_MINNOW_DOLPHIN/mslsupp.c"), Object(MatchingFor("GMPE01_00", "GMPE01_01"), "TRK_MINNOW_DOLPHIN/mslsupp.c"),
], ],
}, },
MusyX( MusyX(

View file

@ -254,6 +254,9 @@ typedef struct ProcessorRestoreFlags_PPC {
void TRKSaveExtended1Block(); void TRKSaveExtended1Block();
void SetUseSerialIO(u8);
u8 GetUseSerialIO(void);
#define SPR_XER 1 #define SPR_XER 1
#define SPR_LR 8 #define SPR_LR 8
#define SPR_CTR 9 #define SPR_CTR 9

View file

@ -8,7 +8,7 @@ typedef struct _TRK_Msg {
u8 _00[8]; u8 _00[8];
u32 m_msgLength; u32 m_msgLength;
u32 _0C; u32 _0C;
u32 m_msg; u8 m_msg[4]; // TODO: unknown array length
} TRK_Msg; } TRK_Msg;
#ifdef __cplusplus #ifdef __cplusplus

View file

@ -12,7 +12,7 @@ DSError TRKInitializeMessageBuffers(void);
DSError TRKSetBufferPosition(TRKBuffer* msg, u32 pos); DSError TRKSetBufferPosition(TRKBuffer* msg, u32 pos);
void* TRKGetBuffer(int); void* TRKGetBuffer(int);
void TRKResetBuffer(TRKBuffer* msg, BOOL keepData); void TRKResetBuffer(TRKBuffer* msg, u8 keepData);
void* TRKGetBuffer(int idx); void* TRKGetBuffer(int idx);
void TRKReleaseBuffer(int idx); void TRKReleaseBuffer(int idx);
DSError TRKGetFreeBuffer(int* msgID, TRKBuffer** outMsg); DSError TRKGetFreeBuffer(int* msgID, TRKBuffer** outMsg);

View file

@ -4,84 +4,95 @@
#include "amcstubs/AmcExi2Stubs.h" #include "amcstubs/AmcExi2Stubs.h"
#include "PowerPC_EABI_Support/MetroTRK/trk.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 = {}; DBCommTable gDBCommTable = {};
asm void TRKLoadContext(OSContext* ctx, u32) asm void TRKLoadContext(OSContext* ctx, u32)
{ {
#ifdef __MWERKS__ // clang-format off #ifdef __MWERKS__ // clang-format off
nofralloc nofralloc
lwz r0, OSContext.gpr[0](r3) lwz r0, OSContext.gpr[0](r3)
lwz r1, OSContext.gpr[1](r3) lwz r1, OSContext.gpr[1](r3)
lwz r2, OSContext.gpr[2](r3) lwz r2, OSContext.gpr[2](r3)
lhz r5, OSContext.state(r3) lhz r5, OSContext.state(r3)
rlwinm. r6, r5, 0, 0x1e, 0x1e rlwinm. r6, r5, 0, 0x1e, 0x1e
beq lbl_80371C1C beq lbl_80371C1C
rlwinm r5, r5, 0, 0x1f, 0x1d rlwinm r5, r5, 0, 0x1f, 0x1d
sth r5, OSContext.state(r3) sth r5, OSContext.state(r3)
lmw r5, OSContext.gpr[5](r3) lmw r5, OSContext.gpr[5](r3)
b lbl_80371C20 b lbl_80371C20
lbl_80371C1C: lbl_80371C1C:
lmw r13, OSContext.gpr[13](r3) lmw r13, OSContext.gpr[13](r3)
lbl_80371C20: lbl_80371C20:
mr r31, r3 mr r31, r3
mr r3, r4 mr r3, r4
lwz r4, OSContext.cr(r31) lwz r4, OSContext.cr(r31)
mtcrf 0xff, r4 mtcrf 0xff, r4
lwz r4, OSContext.lr(r31) lwz r4, OSContext.lr(r31)
mtlr r4 mtlr r4
lwz r4, OSContext.ctr(r31) lwz r4, OSContext.ctr(r31)
mtctr r4 mtctr r4
lwz r4, OSContext.xer(r31) lwz r4, OSContext.xer(r31)
mtxer r4 mtxer r4
mfmsr r4 mfmsr r4
rlwinm r4, r4, 0, 0x11, 0xf //Turn off external exceptions rlwinm r4, r4, 0, 0x11, 0xf //Turn off external exceptions
rlwinm r4, r4, 0, 0x1f, 0x1d //Turn off recoverable exception flag rlwinm r4, r4, 0, 0x1f, 0x1d //Turn off recoverable exception flag
mtmsr r4 mtmsr r4
mtsprg 1, r2 mtsprg 1, r2
lwz r4, OSContext.gpr[3](r31) lwz r4, OSContext.gpr[3](r31)
mtsprg 2, r4 mtsprg 2, r4
lwz r4, OSContext.gpr[4](r31) lwz r4, OSContext.gpr[4](r31)
mtsprg 3, r4 mtsprg 3, r4
lwz r2, OSContext.srr0(r31) lwz r2, OSContext.srr0(r31)
lwz r4, OSContext.srr1(r31) lwz r4, OSContext.srr1(r31)
lwz r31, OSContext.gpr[31](r31) lwz r31, OSContext.gpr[31](r31)
b TRKInterruptHandler b TRKInterruptHandler
#endif // clang-format on #endif // clang-format on
} }
void TRKEXICallBack(__OSInterrupt param_0, OSContext* ctx) void TRKEXICallBack(__OSInterrupt param_0, OSContext* ctx)
{ {
OSEnableScheduler(); OSEnableScheduler();
TRKLoadContext(ctx, 0x500); TRKLoadContext(ctx, 0x500);
} }
int InitMetroTRKCommTable(int hwId) int InitMetroTRKCommTable(int hwId)
{ {
int result; int result;
if (hwId == HARDWARE_GDEV) { if (hwId == HARDWARE_GDEV) {
result = Hu_IsStub(); OSReport("MetroTRK : Set to GDEV hardware\n");
result = Hu_IsStub();
gDBCommTable.initialize_func = DBInitComm; gDBCommTable.initialize_func = DBInitComm;
gDBCommTable.init_interrupts_func = DBInitInterrupts; gDBCommTable.init_interrupts_func = DBInitInterrupts;
gDBCommTable.peek_func = DBQueryData; gDBCommTable.peek_func = DBQueryData;
gDBCommTable.read_func = DBRead; gDBCommTable.read_func = DBRead;
gDBCommTable.write_func = DBWrite; gDBCommTable.write_func = DBWrite;
gDBCommTable.open_func = DBOpen; gDBCommTable.open_func = DBOpen;
gDBCommTable.close_func = DBClose; gDBCommTable.close_func = DBClose;
} else { } else {
result = AMC_IsStub(); OSReport("MetroTRK : Set to AMC DDH hardware\n");
result = AMC_IsStub();
gDBCommTable.initialize_func = EXI2_Init; gDBCommTable.initialize_func = EXI2_Init;
gDBCommTable.init_interrupts_func = EXI2_EnableInterrupts; gDBCommTable.init_interrupts_func = EXI2_EnableInterrupts;
gDBCommTable.peek_func = EXI2_Poll; gDBCommTable.peek_func = EXI2_Poll;
gDBCommTable.read_func = EXI2_ReadN; gDBCommTable.read_func = EXI2_ReadN;
gDBCommTable.write_func = EXI2_WriteN; gDBCommTable.write_func = EXI2_WriteN;
gDBCommTable.open_func = EXI2_Reserve; gDBCommTable.open_func = EXI2_Reserve;
gDBCommTable.close_func = EXI2_Unreserve; gDBCommTable.close_func = EXI2_Unreserve;
} }
return result; return result;
} }
void TRKUARTInterruptHandler() { } void TRKUARTInterruptHandler() { }
@ -89,8 +100,8 @@ void TRKUARTInterruptHandler() { }
DSError TRKInitializeIntDrivenUART(u32 param_0, u32 param_1, u32 param_2, DSError TRKInitializeIntDrivenUART(u32 param_0, u32 param_1, u32 param_2,
volatile u8** param_3) volatile u8** param_3)
{ {
gDBCommTable.initialize_func(param_3, TRKEXICallBack); gDBCommTable.initialize_func(param_3, TRKEXICallBack);
return DS_NoError; return DS_NoError;
} }
void EnableEXI2Interrupts(void) { gDBCommTable.init_interrupts_func(); } void EnableEXI2Interrupts(void) { gDBCommTable.init_interrupts_func(); }
@ -99,14 +110,59 @@ int TRKPollUART(void) { return gDBCommTable.peek_func(); }
UARTError TRKReadUARTN(void* bytes, u32 length) UARTError TRKReadUARTN(void* bytes, u32 length)
{ {
int readErr = gDBCommTable.read_func(bytes, length); int readErr = gDBCommTable.read_func(bytes, length);
return readErr == 0 ? 0 : -1; return readErr == 0 ? 0 : -1;
} }
UARTError TRKWriteUARTN(const void* bytes, u32 length) UARTError TRKWriteUARTN(const void* bytes, u32 length)
{ {
int writeErr = gDBCommTable.write_func(bytes, length); int writeErr = gDBCommTable.write_func(bytes, length);
return writeErr == 0 ? 0 : -1; 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(); } void ReserveEXI2Port(void) { gDBCommTable.open_func(); }

View file

@ -2,8 +2,60 @@
#include "TRK_MINNOW_DOLPHIN/Os/dolphin/dolphin_trk_glue.h" #include "TRK_MINNOW_DOLPHIN/Os/dolphin/dolphin_trk_glue.h"
#include "PowerPC_EABI_Support/MetroTRK/trk.h" #include "PowerPC_EABI_Support/MetroTRK/trk.h"
// Incorrect signature? Should be u8.
UARTError WriteUART1(s8 arg0);
DSError TRKMessageSend(TRK_Msg* msg) DSError TRKMessageSend(TRK_Msg* msg)
{ {
DSError write_err = TRKWriteUARTN(&msg->m_msg, msg->m_msgLength); u8 var_r30;
return DS_NoError; 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;
} }

View file

@ -34,7 +34,7 @@ DSError TRKGetFreeBuffer(int* msgID, TRKBuffer** outMsg)
TRKAcquireMutex(buf); TRKAcquireMutex(buf);
if (!buf->isInUse) { if (!buf->isInUse) {
TRKResetBuffer(buf, TRUE); TRKResetBuffer(buf, 1);
TRKSetBufferUsed(buf, TRUE); TRKSetBufferUsed(buf, TRUE);
error = DS_NoError; error = DS_NoError;
*outMsg = buf; *outMsg = buf;
@ -44,6 +44,10 @@ DSError TRKGetFreeBuffer(int* msgID, TRKBuffer** outMsg)
TRKReleaseMutex(buf); TRKReleaseMutex(buf);
} }
if (error == DS_NoMessageBufferAvailable) {
usr_puts_serial("ERROR : No buffer available\n");
}
return error; 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->length = 0;
msg->position = 0; msg->position = 0;
@ -96,6 +100,7 @@ DSError TRKSetBufferPosition(TRKBuffer* msg, u32 pos)
return error; return error;
} }
#pragma dont_inline on
DSError TRKAppendBuffer(TRKBuffer* msg, const void* data, size_t length) DSError TRKAppendBuffer(TRKBuffer* msg, const void* data, size_t length)
{ {
DSError error = DS_NoError; // r31 DSError error = DS_NoError; // r31
@ -129,6 +134,7 @@ DSError TRKAppendBuffer(TRKBuffer* msg, const void* data, size_t length)
return error; return error;
} }
#pragma dont_inline reset
DSError TRKReadBuffer(TRKBuffer* msg, void* data, size_t length) DSError TRKReadBuffer(TRKBuffer* msg, void* data, size_t length)
{ {

View file

@ -45,8 +45,7 @@ DSError TRKStandardACK(TRKBuffer* buffer, MessageCommandID commandID,
DSReplyError replyError) DSReplyError replyError)
{ {
TRKMessageIntoReply(buffer, commandID, replyError); TRKMessageIntoReply(buffer, commandID, replyError);
TRKSendACK(buffer); return TRKSendACK(buffer);
return;
} }
DSError TRKDoUnsupported(TRKBuffer* buffer) DSError TRKDoUnsupported(TRKBuffer* buffer)
@ -107,7 +106,6 @@ DSError TRKDoVersions(TRKBuffer* buffer)
else else
error = TRKSendACK(buffer); error = TRKSendACK(buffer);
} }
return error;
} }
DSError TRKDoSupportMask(TRKBuffer* buffer) DSError TRKDoSupportMask(TRKBuffer* buffer)
@ -140,7 +138,7 @@ DSError TRKDoCPUType(TRKBuffer* buffer)
if (buffer->length != 1) { if (buffer->length != 1) {
error = TRKStandardACK(buffer, DSMSG_ReplyACK, DSREPLY_PacketSizeError); error = TRKStandardACK(buffer, DSMSG_ReplyACK, DSREPLY_PacketSizeError);
return error; return;
} }
TRKMessageIntoReply(buffer, DSMSG_ReplyACK, DSREPLY_NoError); TRKMessageIntoReply(buffer, DSMSG_ReplyACK, DSREPLY_NoError);
@ -166,8 +164,6 @@ DSError TRKDoCPUType(TRKBuffer* buffer)
error = TRKStandardACK(buffer, DSMSG_ReplyACK, DSREPLY_CWDSError); error = TRKStandardACK(buffer, DSMSG_ReplyACK, DSREPLY_CWDSError);
else else
error = TRKSendACK(buffer); error = TRKSendACK(buffer);
return error;
} }
DSError TRKDoReadMemory(TRKBuffer* buffer) DSError TRKDoReadMemory(TRKBuffer* buffer)
@ -175,11 +171,11 @@ DSError TRKDoReadMemory(TRKBuffer* buffer)
DSError error; DSError error;
DSReplyError replyError; DSReplyError replyError;
u8 tempBuf[0x800]; u8 tempBuf[0x800];
u32 length;
u32 msg_start; u32 msg_start;
u32 length;
u16 msg_length; u16 msg_length;
u8 msg_options;
u8 msg_command; u8 msg_command;
u8 msg_options;
if (buffer->length != 8) { if (buffer->length != 8) {
error = TRKStandardACK(buffer, DSMSG_ReplyACK, DSREPLY_PacketSizeError); error = TRKStandardACK(buffer, DSMSG_ReplyACK, DSREPLY_PacketSizeError);
@ -257,11 +253,11 @@ DSError TRKDoWriteMemory(TRKBuffer* buffer)
DSError error; DSError error;
DSReplyError replyError; DSReplyError replyError;
u8 tmpBuffer[0x800]; u8 tmpBuffer[0x800];
u32 length;
u32 msg_start; u32 msg_start;
u32 length;
u16 msg_length; u16 msg_length;
u8 msg_options;
u8 msg_command; u8 msg_command;
u8 msg_options;
if (buffer->length <= 8) { if (buffer->length <= 8) {
error = TRKStandardACK(buffer, DSMSG_ReplyACK, DSREPLY_PacketSizeError); error = TRKStandardACK(buffer, DSMSG_ReplyACK, DSREPLY_PacketSizeError);
@ -343,14 +339,14 @@ DSError TRKDoReadRegisters(TRKBuffer* buffer)
DSReplyError replyError; DSReplyError replyError;
DSMessageRegisterOptions options; DSMessageRegisterOptions options;
u32 registerDataLength; u32 registerDataLength;
u16 msg_lastRegister;
u16 msg_firstRegister; u16 msg_firstRegister;
u8 msg_options; u16 msg_lastRegister;
u8 msg_command; u8 msg_command;
u8 msg_options;
if (buffer->length != 6) { if (buffer->length != 6) {
error = TRKStandardACK(buffer, DSMSG_ReplyACK, DSREPLY_PacketSizeError); error = TRKStandardACK(buffer, DSMSG_ReplyACK, DSREPLY_PacketSizeError);
return error; return;
} }
TRKSetBufferPosition(buffer, DSREPLY_NoError); TRKSetBufferPosition(buffer, DSREPLY_NoError);
error = TRKReadBuffer1_ui8(buffer, &msg_command); error = TRKReadBuffer1_ui8(buffer, &msg_command);
@ -366,13 +362,13 @@ DSError TRKDoReadRegisters(TRKBuffer* buffer)
if (msg_firstRegister > msg_lastRegister) { if (msg_firstRegister > msg_lastRegister) {
error = TRKStandardACK(buffer, DSMSG_ReplyACK, error = TRKStandardACK(buffer, DSMSG_ReplyACK,
DSREPLY_InvalidRegisterRange); DSREPLY_InvalidRegisterRange);
return error; return;
} }
if (error == DS_NoError) if (error == DS_NoError)
TRKMessageIntoReply(buffer, DSMSG_ReplyACK, DSREPLY_NoError); TRKMessageIntoReply(buffer, DSMSG_ReplyACK, DSREPLY_NoError);
options = (DSMessageRegisterOptions)msg_options; options = (DSMessageRegisterOptions)(msg_options & 7);
switch (options) { switch (options) {
case DSREG_Default: case DSREG_Default:
error = TRKTargetAccessDefault(msg_firstRegister, msg_lastRegister, error = TRKTargetAccessDefault(msg_firstRegister, msg_lastRegister,
@ -423,8 +419,6 @@ DSError TRKDoReadRegisters(TRKBuffer* buffer)
} else { } else {
error = TRKSendACK(buffer); error = TRKSendACK(buffer);
} }
return error;
} }
DSError TRKDoWriteRegisters(TRKBuffer* buffer) DSError TRKDoWriteRegisters(TRKBuffer* buffer)
@ -433,14 +427,14 @@ DSError TRKDoWriteRegisters(TRKBuffer* buffer)
DSReplyError replyError; DSReplyError replyError;
DSMessageRegisterOptions options; DSMessageRegisterOptions options;
u32 registerDataLength; u32 registerDataLength;
u16 msg_lastRegister;
u16 msg_firstRegister; u16 msg_firstRegister;
u8 msg_options; u16 msg_lastRegister;
u8 msg_command; u8 msg_command;
u8 msg_options;
if (buffer->length <= 6) { if (buffer->length <= 6) {
error = TRKStandardACK(buffer, DSMSG_ReplyACK, DSREPLY_PacketSizeError); error = TRKStandardACK(buffer, DSMSG_ReplyACK, DSREPLY_PacketSizeError);
return error; return;
} }
TRKSetBufferPosition(buffer, DSREPLY_NoError); TRKSetBufferPosition(buffer, DSREPLY_NoError);
error = TRKReadBuffer1_ui8(buffer, &msg_command); error = TRKReadBuffer1_ui8(buffer, &msg_command);
@ -456,7 +450,7 @@ DSError TRKDoWriteRegisters(TRKBuffer* buffer)
if (msg_firstRegister > msg_lastRegister) { if (msg_firstRegister > msg_lastRegister) {
error = TRKStandardACK(buffer, DSMSG_ReplyACK, error = TRKStandardACK(buffer, DSMSG_ReplyACK,
DSREPLY_InvalidRegisterRange); DSREPLY_InvalidRegisterRange);
return error; return;
} }
options = (DSMessageRegisterOptions)msg_options; options = (DSMessageRegisterOptions)msg_options;
@ -516,22 +510,20 @@ DSError TRKDoWriteRegisters(TRKBuffer* buffer)
} else { } else {
error = TRKSendACK(buffer); error = TRKSendACK(buffer);
} }
return error;
} }
DSError TRKDoFlushCache(TRKBuffer* buffer) DSError TRKDoFlushCache(TRKBuffer* buffer)
{ {
DSError error; DSError error;
DSReplyError replyErr; DSReplyError replyErr;
u32 msg_end;
u32 msg_start; u32 msg_start;
u8 msg_options; u32 msg_end;
u8 msg_command; u8 msg_command;
u8 msg_options;
if (buffer->length != 10) { if (buffer->length != 10) {
error = TRKStandardACK(buffer, DSMSG_ReplyACK, DSREPLY_PacketSizeError); error = TRKStandardACK(buffer, DSMSG_ReplyACK, DSREPLY_PacketSizeError);
return error; return;
} }
TRKSetBufferPosition(buffer, DSREPLY_NoError); TRKSetBufferPosition(buffer, DSREPLY_NoError);
@ -546,7 +538,7 @@ DSError TRKDoFlushCache(TRKBuffer* buffer)
if (msg_start > msg_end) { if (msg_start > msg_end) {
error = TRKStandardACK(buffer, DSMSG_ReplyACK, error = TRKStandardACK(buffer, DSMSG_ReplyACK,
DSREPLY_InvalidMemoryRange); DSREPLY_InvalidMemoryRange);
return error; return;
} }
if (error == DS_NoError) if (error == DS_NoError)
@ -570,8 +562,6 @@ DSError TRKDoFlushCache(TRKBuffer* buffer)
} else { } else {
error = TRKSendACK(buffer); error = TRKSendACK(buffer);
} }
return error;
} }
DSError TRKDoContinue(TRKBuffer* buffer) DSError TRKDoContinue(TRKBuffer* buffer)
@ -581,14 +571,12 @@ DSError TRKDoContinue(TRKBuffer* buffer)
error = TRKTargetStopped(); error = TRKTargetStopped();
if (error == DS_NoError) { if (error == DS_NoError) {
error = TRKStandardACK(buffer, DSMSG_ReplyACK, DSREPLY_NotStopped); error = TRKStandardACK(buffer, DSMSG_ReplyACK, DSREPLY_NotStopped);
return error; return;
} }
error = TRKStandardACK(buffer, DSMSG_ReplyACK, DSREPLY_NoError); error = TRKStandardACK(buffer, DSMSG_ReplyACK, DSREPLY_NoError);
if (error == DS_NoError) if (error == DS_NoError)
error = TRKTargetContinue(); error = TRKTargetContinue();
return error;
} }
DSError TRKDoStep(TRKBuffer* buffer) DSError TRKDoStep(TRKBuffer* buffer)
@ -601,8 +589,10 @@ DSError TRKDoStep(TRKBuffer* buffer)
u32 msg_rangeEnd; u32 msg_rangeEnd;
u32 pc; u32 pc;
if (buffer->length < 3) if (buffer->length < 3) {
return TRKStandardACK(buffer, DSMSG_ReplyACK, DSREPLY_PacketSizeError); TRKStandardACK(buffer, DSMSG_ReplyACK, DSREPLY_PacketSizeError);
return;
}
TRKSetBufferPosition(buffer, DSREPLY_NoError); TRKSetBufferPosition(buffer, DSREPLY_NoError);
@ -618,12 +608,14 @@ DSError TRKDoStep(TRKBuffer* buffer)
if (msg_count >= 1) { if (msg_count >= 1) {
break; break;
} }
return TRKStandardACK(buffer, DSMSG_ReplyACK, DSREPLY_ParameterError); TRKStandardACK(buffer, DSMSG_ReplyACK, DSREPLY_ParameterError);
return;
case DSSTEP_IntoRange: case DSSTEP_IntoRange:
case DSSTEP_OverRange: case DSSTEP_OverRange:
if (buffer->length != 10) if (buffer->length != 10) {
return TRKStandardACK(buffer, DSMSG_ReplyACK, TRKStandardACK(buffer, DSMSG_ReplyACK, DSREPLY_PacketSizeError);
DSREPLY_PacketSizeError); return;
}
if (error == DS_NoError) if (error == DS_NoError)
error = TRKReadBuffer1_ui32(buffer, &msg_rangeStart); error = TRKReadBuffer1_ui32(buffer, &msg_rangeStart);
@ -634,33 +626,33 @@ DSError TRKDoStep(TRKBuffer* buffer)
if (pc >= msg_rangeStart && pc <= msg_rangeEnd) { if (pc >= msg_rangeStart && pc <= msg_rangeEnd) {
break; break;
} }
return TRKStandardACK(buffer, DSMSG_ReplyACK, DSREPLY_ParameterError); TRKStandardACK(buffer, DSMSG_ReplyACK, DSREPLY_ParameterError);
return;
default: default:
return TRKStandardACK(buffer, DSMSG_ReplyACK, TRKStandardACK(buffer, DSMSG_ReplyACK, DSREPLY_UnsupportedOptionError);
DSREPLY_UnsupportedOptionError); return;
} }
if (!TRKTargetStopped()) { if (!TRKTargetStopped()) {
return TRKStandardACK(buffer, DSMSG_ReplyACK, DSREPLY_NotStopped); TRKStandardACK(buffer, DSMSG_ReplyACK, DSREPLY_NotStopped);
} else { 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;
}
return error;
} }
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) DSError TRKDoStop(TRKBuffer* b)
@ -687,3 +679,46 @@ DSError TRKDoStop(TRKBuffer* b)
return TRKStandardACK(b, DSMSG_ReplyACK, replyError); 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);
}

112
src/TRK_MINNOW_DOLPHIN/mslsupp.c Executable file
View file

@ -0,0 +1,112 @@
#include "PowerPC_EABI_Support/MetroTRK/trk.h"
#include <stddef.h>
// 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
}

View file

@ -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;
}

View file

@ -2,4 +2,25 @@
#include "TRK_MINNOW_DOLPHIN/MetroTRK/Portable/msghndlr.h" #include "TRK_MINNOW_DOLPHIN/MetroTRK/Portable/msghndlr.h"
#include "PowerPC_EABI_Support/MetroTRK/trk.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) { } void usr_put_initialize(void) { }