TRK: matched serpoll and support; and making more progress (#565)

This commit is contained in:
mrshigure 2025-02-10 19:49:23 -08:00 committed by GitHub
parent 66a9a044fa
commit 23b7af3bc5
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
7 changed files with 1053 additions and 859 deletions

View file

@ -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/nubinit.c"),
Object(MatchingFor("GMPE01_00", "GMPE01_01"), "TRK_MINNOW_DOLPHIN/msg.c"), Object(MatchingFor("GMPE01_00", "GMPE01_01"), "TRK_MINNOW_DOLPHIN/msg.c"),
Object(MatchingFor("GMPE01_00", "GMPE01_01"), "TRK_MINNOW_DOLPHIN/msgbuf.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(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(MatchingFor("GMPE01_00", "GMPE01_01"), "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/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"),
Object(MatchingFor("GMPE01_00", "GMPE01_01"), "TRK_MINNOW_DOLPHIN/flush_cache.c"), Object(MatchingFor("GMPE01_00", "GMPE01_01"), "TRK_MINNOW_DOLPHIN/flush_cache.c"),

View file

@ -15,12 +15,12 @@ DSError TRKRequestSend(TRKBuffer* msgBuf, int* bufferId, u32 p1, u32 p2,
int p3); int p3);
DSError HandleOpenFileSupportRequest(const char* path, u8 replyError, 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, DSError HandlePositionFileSupportRequest(u32 replyErr, u32* param_2,
u8 param_3, DSIOResult* ioResult); u8 param_3, u8* ioResult);
#ifdef __cplusplus #ifdef __cplusplus
} }

View file

@ -7,7 +7,7 @@
extern "C" { extern "C" {
#endif #endif
u32 TRKTargetCPUMinorType(void); u8 TRKTargetCPUMinorType(void);
#ifdef __cplusplus #ifdef __cplusplus
} }

View file

@ -245,4 +245,4 @@ lbl_8037149C:
#endif // clang-format on #endif // clang-format on
} }
u32 TRKTargetCPUMinorType(void) { return 0x54; } u8 TRKTargetCPUMinorType(void) { return 0x54; }

View file

@ -9,41 +9,100 @@ static TRKFramingState gTRKFramingState;
void* gTRKInputPendingPtr; void* gTRKInputPendingPtr;
MessageBufferID TRKTestForPacket() static inline BOOL serpoll_inline_00(TRKBuffer* buffer) {
{ if (buffer->length < 2) {
int bytes; TRKStandardACK(buffer, DSMSG_ReplyNAK, DSREPLY_PacketSizeError);
int batch; if (gTRKFramingState.msgBufID != -1) {
int err; TRKReleaseBuffer(gTRKFramingState.msgBufID);
TRKBuffer* b; gTRKFramingState.msgBufID = -1;
int id; }
gTRKFramingState.buffer = NULL;
gTRKFramingState.receiveState = DSRECV_Wait;
return FALSE;
}
buffer->position = 0;
buffer->length--;
return TRUE;
}
bytes = TRKPollUART(); MessageBufferID TRKTestForPacket(void) {
if (bytes > 0) { s32 var_r29;
TRKGetFreeBuffer(&id, &b); s32 var_r3;
if (bytes > TRKMSGBUF_SIZE) { s8 sp8;
for (; bytes > 0; bytes -= batch) { s32 temp_r3;
batch = bytes > TRKMSGBUF_SIZE ? TRKMSGBUF_SIZE : bytes;
TRKReadUARTN(b->data, batch); var_r29 = 0;
var_r3 = TRKReadUARTPoll(&sp8);
while (var_r3 == 0 && var_r29 == 0) {
if (gTRKFramingState.receiveState != DSRECV_InFrame) {
gTRKFramingState.isEscape = FALSE;
} }
TRKStandardACK(b, 0xff, 6); 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 { } else {
err = TRKReadUARTN(b->data, bytes); if (gTRKFramingState.isEscape) {
if (err == 0) { sp8 ^= 0x20;
b->length = bytes; gTRKFramingState.isEscape = FALSE;
return id; } 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;
} }
if (id != -1) { gTRKFramingState.buffer = NULL;
TRKReleaseBuffer(id); gTRKFramingState.receiveState = DSRECV_Wait;
}
break;
}
var_r3 = TRKReadUARTPoll(&sp8);
} }
return -1; return -1;
} }
void TRKGetInput(void) void TRKGetInput(void)
{ {
MessageBufferID id;
TRKBuffer* msgBuffer; TRKBuffer* msgBuffer;
MessageBufferID id;
u8 command; u8 command;
id = TRKTestForPacket(); id = TRKTestForPacket();

View file

@ -28,7 +28,7 @@ DSError TRKSuppAccessFile(u32 file_handle, u8* data, size_t* count,
*io_result = DS_IONoError; *io_result = DS_IONoError;
done = 0; done = 0;
error = DS_NoError; 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) { if (*count - done > 0x800) {
length = 0x800; length = 0x800;
} else { } else {
@ -175,3 +175,114 @@ DSError TRKRequestSend(TRKBuffer* msgBuf, int* bufferId, u32 p1, u32 p2, int p3)
return error; 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;
}

View file

@ -114,6 +114,7 @@ asm void __TRK_set_MSR(register u32 msr) {
#endif // clang-format on #endif // clang-format on
} }
#pragma dont_inline on
DSError TRKValidMemory32(const void* addr, size_t length, DSError TRKValidMemory32(const void* addr, size_t length,
ValidMemoryOptions readWriteable) ValidMemoryOptions readWriteable)
{ {
@ -199,6 +200,7 @@ DSError TRKValidMemory32(const void* addr, size_t length,
return err; return err;
} }
#pragma dont_inline reset
static asm void TRK_ppc_memcpy(register void* dest, register const void* src, static asm void TRK_ppc_memcpy(register void* dest, register const void* src,
register int n, register u32 param_4, register int n, register u32 param_4,
@ -240,6 +242,7 @@ out_loop:
#endif // clang-format on #endif // clang-format on
} }
#pragma dont_inline on
DSError TRKTargetAccessMemory(void* data, u32 start, size_t* length, DSError TRKTargetAccessMemory(void* data, u32 start, size_t* length,
MemoryAccessOptions accessOptions, BOOL read) MemoryAccessOptions accessOptions, BOOL read)
{ {
@ -279,6 +282,7 @@ DSError TRKTargetAccessMemory(void* data, u32 start, size_t* length,
gTRKExceptionStatus = tempExceptionStatus; gTRKExceptionStatus = tempExceptionStatus;
return error; return error;
} }
#pragma dont_inline reset
DSError TRKTargetReadInstruction(void* data, u32 start) DSError TRKTargetReadInstruction(void* data, u32 start)
{ {
@ -310,12 +314,12 @@ DSError TRKTargetAccessDefault(u32 firstRegister, u32 lastRegister,
tempExceptionStatus = gTRKExceptionStatus; tempExceptionStatus = gTRKExceptionStatus;
gTRKExceptionStatus.exceptionDetected = FALSE;
data = gTRKCPUState.Default.GPR + firstRegister; data = gTRKCPUState.Default.GPR + firstRegister;
count = (lastRegister - firstRegister) + 1; count = (lastRegister - firstRegister) + 1;
gTRKExceptionStatus.exceptionDetected = FALSE;
*registersLengthPtr = count * sizeof(u32); *registersLengthPtr = count * sizeof(u32);
if (read) { if (read) {
@ -480,7 +484,7 @@ DSError TRKTargetAccessExtended2(u32 firstRegister, u32 lastRegister,
DSError TRKTargetVersions(DSVersions* versions) DSError TRKTargetVersions(DSVersions* versions)
{ {
versions->kernelMajor = 0; versions->kernelMajor = 0;
versions->kernelMinor = 8; versions->kernelMinor = 10;
versions->protocolMajor = 1; versions->protocolMajor = 1;
versions->protocolMinor = 10; versions->protocolMinor = 10;
return DS_NoError; return DS_NoError;
@ -832,16 +836,26 @@ DSError TRKTargetAddStopInfo(TRKBuffer* buffer)
{ {
DSError error; DSError error;
u32 instruction; u32 instruction;
s32 i;
error = TRKAppendBuffer1_ui32(buffer, gTRKCPUState.Default.PC); error = TRKAppendBuffer1_ui32(buffer, gTRKCPUState.Default.PC);
if (error == 0) { if (error == DS_NoError) {
error = TRKTargetReadInstruction(&instruction, gTRKCPUState.Default.PC); error = TRKTargetReadInstruction(&instruction, gTRKCPUState.Default.PC);
} }
if (error == 0) if (error == DS_NoError)
error = TRKAppendBuffer1_ui32(buffer, instruction); error = TRKAppendBuffer1_ui32(buffer, instruction);
if (error == 0) if (error == DS_NoError)
error error = TRKAppendBuffer1_ui16(buffer, gTRKCPUState.Extended1.exceptionID);
= 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; return error;
} }
@ -938,8 +952,8 @@ DSError TRKTargetSingleStep(u32 count, BOOL stepOver)
if (stepOver) { if (stepOver) {
error = DS_UnsupportedError; error = DS_UnsupportedError;
} else { } else {
gTRKStepStatus.count = count;
gTRKStepStatus.type = DSSTEP_IntoCount; gTRKStepStatus.type = DSSTEP_IntoCount;
gTRKStepStatus.count = count;
error = TRKTargetDoStep(); error = TRKTargetDoStep();
} }
@ -966,36 +980,51 @@ DSError TRKTargetStepOutOfRange(u32 rangeStart, u32 rangeEnd, BOOL stepOver)
u32 TRKTargetGetPC() { return gTRKCPUState.Default.PC; } u32 TRKTargetGetPC() { return gTRKCPUState.Default.PC; }
DSError TRKTargetSupportRequest() DSError TRKTargetSupportRequest(void) {
{
DSError error; DSError error;
u32 spC;
size_t* length; size_t* length;
DSIOResult ioResult;
MessageCommandID commandId; MessageCommandID commandId;
TRKEvent event; TRKEvent event;
u8 ioResult;
commandId = gTRKCPUState.Default.GPR[3]; commandId = (u8) gTRKCPUState.Default.GPR[3];
if (commandId != DSMSG_ReadFile && commandId != DSMSG_WriteFile) { if (commandId != DSMSG_ReadFile && commandId != DSMSG_WriteFile && commandId != DSMSG_OpenFile && commandId != DSMSG_CloseFile && commandId != DSMSG_PositionFile) {
TRKConstructEvent(&event, 4); TRKConstructEvent(&event, NUBEVENT_Exception);
TRKPostEvent(&event); TRKPostEvent(&event);
return DS_NoError; return DS_NoError;
} else { }
length = (size_t*)gTRKCPUState.Default.GPR[5]; if (commandId == DSMSG_OpenFile) {
error = TRKSuppAccessFile((u8)gTRKCPUState.Default.GPR[4], error = HandleOpenFileSupportRequest((char*) gTRKCPUState.Default.GPR[4], gTRKCPUState.Default.GPR[5], (u32*) gTRKCPUState.Default.GPR[6], &ioResult);
(u8*)gTRKCPUState.Default.GPR[6], length, if (ioResult == DS_IONoError && error != DS_NoError) {
&ioResult, TRUE, commandId == DSMSG_ReadFile); 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) { if (ioResult == DS_IONoError && error != DS_NoError) {
ioResult = DS_IOError; ioResult = DS_IOError;
} }
gTRKCPUState.Default.GPR[3] = ioResult; gTRKCPUState.Default.GPR[3] = ioResult;
if (commandId == DSMSG_ReadFile) { if (commandId == DSMSG_ReadFile) {
TRK_flush_cache((void*) gTRKCPUState.Default.GPR[6], *length); TRK_flush_cache((void*) gTRKCPUState.Default.GPR[6], *length);
} }
} }
gTRKCPUState.Default.PC += 4; gTRKCPUState.Default.PC += 4;
return error; return error;
} }
@ -1027,8 +1056,10 @@ DSError TRKPPCAccessSPR(void* value, u32 spr_register_num, BOOL read)
{ {
/* Initialize instruction array with nop */ /* Initialize instruction array with nop */
u32 access_func[5] u32 access_func[10] = {
= { INSTR_NOP, INSTR_NOP, INSTR_NOP, INSTR_NOP, INSTR_NOP }; 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 ** Construct a small assembly function to perform the
** requested access and call it. The read/write function ** requested access and call it. The read/write function
@ -1060,8 +1091,10 @@ DSError TRKPPCAccessSPR(void* value, u32 spr_register_num, BOOL read)
DSError TRKPPCAccessPairedSingleRegister(void* srcDestPtr, u32 psr, BOOL read) DSError TRKPPCAccessPairedSingleRegister(void* srcDestPtr, u32 psr, BOOL read)
{ {
// all nop by default // all nop by default
u32 instructionData[] u32 instructionData[] = {
= { INSTR_NOP, INSTR_NOP, INSTR_NOP, INSTR_NOP, INSTR_NOP }; INSTR_NOP, INSTR_NOP, INSTR_NOP, INSTR_NOP, INSTR_NOP,
INSTR_NOP, INSTR_NOP, INSTR_NOP, INSTR_NOP, INSTR_NOP
};
if (read) { if (read) {
instructionData[0] instructionData[0]
@ -1074,12 +1107,15 @@ DSError TRKPPCAccessPairedSingleRegister(void* srcDestPtr, u32 psr, BOOL read)
return TRKPPCAccessSpecialReg(srcDestPtr, instructionData, read); return TRKPPCAccessSpecialReg(srcDestPtr, instructionData, read);
} }
#pragma dont_inline on
DSError TRKPPCAccessFPRegister(void* srcDestPtr, u32 fpr, BOOL read) DSError TRKPPCAccessFPRegister(void* srcDestPtr, u32 fpr, BOOL read)
{ {
DSError error = DS_NoError; DSError error = DS_NoError;
// all nop by default // all nop by default
u32 instructionData1[] u32 instructionData1[] = {
= { INSTR_NOP, INSTR_NOP, INSTR_NOP, INSTR_NOP, INSTR_NOP }; INSTR_NOP, INSTR_NOP, INSTR_NOP, INSTR_NOP, INSTR_NOP,
INSTR_NOP, INSTR_NOP, INSTR_NOP, INSTR_NOP, INSTR_NOP
};
if (fpr < 0x20) { if (fpr < 0x20) {
if (read) { if (read) {
@ -1090,25 +1126,12 @@ DSError TRKPPCAccessFPRegister(void* srcDestPtr, u32 fpr, BOOL read)
error = TRKPPCAccessSpecialReg(srcDestPtr, instructionData1, read); error = TRKPPCAccessSpecialReg(srcDestPtr, instructionData1, read);
} else if (fpr == 0x20) { } 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; *(u64*)srcDestPtr &= 0xFFFFFFFF;
} else if (fpr == 0x21) { } else if (fpr == 0x21) {
if (!read) { if (!read) {
*(u32*)srcDestPtr = *((u32*)(srcDestPtr) + 1); *(u32*)srcDestPtr = *((u32*)(srcDestPtr) + 1);
} }
error = TRKPPCAccessSPR(srcDestPtr, 1022, read);
error = TRKPPCAccessSPR(srcDestPtr, SPR_FPECR, read);
if (read) { if (read) {
DSFetch_u64(srcDestPtr) = DSFetch_u32(srcDestPtr) & 0xffffffffLL; DSFetch_u64(srcDestPtr) = DSFetch_u32(srcDestPtr) & 0xffffffffLL;
} }
@ -1116,6 +1139,7 @@ DSError TRKPPCAccessFPRegister(void* srcDestPtr, u32 fpr, BOOL read)
return error; return error;
} }
#pragma dont_inline reset
#define DEBUG_VECTORREG_ACCESS 0 #define DEBUG_VECTORREG_ACCESS 0