Making some TRK progress (#564)
This commit is contained in:
parent
64f087c2c9
commit
66a9a044fa
|
|
@ -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
|
||||
|
|
|
|||
15
configure.py
15
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(
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
|
|
|
|||
|
|
@ -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(); }
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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)
|
||||
{
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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
|
||||
}
|
||||
|
|
@ -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;
|
||||
}
|
||||
|
|
@ -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) { }
|
||||
|
|
|
|||
Loading…
Reference in New Issue