Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
MorsGames
GitHub Repository: MorsGames/sm64plus
Path: blob/master/lib/src/contramread.c
7857 views
1
#include "libultra_internal.h"
2
#include "PR/rcp.h"
3
#include "controller.h"
4
5
extern s32 func_8030A5C0(OSMesgQueue *, s32);
6
void __osPackRamReadData(int channel, u16 address);
7
8
s32 __osContRamRead(OSMesgQueue *mq, int channel, u16 address, u8 *buffer) {
9
s32 ret;
10
int i;
11
u8 *ptr;
12
__OSContRamReadFormat ramreadformat;
13
int retry;
14
ret = 0;
15
ptr = (u8 *)&__osPfsPifRam;
16
retry = 2;
17
__osSiGetAccess();
18
_osLastSentSiCmd = CONT_CMD_READ_MEMPACK;
19
__osPackRamReadData(channel, address);
20
ret = __osSiRawStartDma(OS_WRITE, &__osPfsPifRam);
21
osRecvMesg(mq, NULL, OS_MESG_BLOCK);
22
do {
23
ret = __osSiRawStartDma(OS_READ, &__osPfsPifRam);
24
osRecvMesg(mq, NULL, OS_MESG_BLOCK);
25
ptr = (u8 *)&__osPfsPifRam;
26
if (channel != 0) {
27
for (i = 0; i < channel; i++) {
28
ptr++;
29
}
30
}
31
ramreadformat = *(__OSContRamReadFormat *)ptr;
32
ret = CHNL_ERR(ramreadformat);
33
if (ret == 0) {
34
u8 c;
35
c = __osContDataCrc((u8*)&ramreadformat.data);
36
if (c != ramreadformat.datacrc) {
37
ret = func_8030A5C0(mq, channel);
38
if (ret != 0) {
39
__osSiRelAccess();
40
return ret;
41
}
42
ret = PFS_ERR_CONTRFAIL;
43
} else {
44
for (i = 0; i < ARRLEN(ramreadformat.data); i++) {
45
*buffer++ = ramreadformat.data[i];
46
}
47
}
48
} else {
49
ret = PFS_ERR_NOPACK;
50
}
51
if (ret != PFS_ERR_CONTRFAIL) {
52
break;
53
}
54
} while (retry-- >= 0);
55
__osSiRelAccess();
56
return ret;
57
}
58
59
void __osPackRamReadData(int channel, u16 address) {
60
u8 *ptr;
61
__OSContRamReadFormat ramreadformat;
62
int i;
63
64
ptr = (u8 *)__osPfsPifRam.ramarray;
65
66
for (i = 0; i < ARRLEN(__osPfsPifRam.ramarray) + 1; i++) { // also clear pifstatus
67
__osPfsPifRam.ramarray[i] = 0;
68
}
69
70
__osPfsPifRam.pifstatus = CONT_CMD_EXE;
71
ramreadformat.dummy = CONT_CMD_NOP;
72
ramreadformat.txsize = CONT_CMD_READ_MEMPACK_TX;
73
ramreadformat.rxsize = CONT_CMD_READ_MEMPACK_RX;
74
ramreadformat.cmd = CONT_CMD_READ_MEMPACK;
75
ramreadformat.address = (address << 0x5) | __osContAddressCrc(address);
76
ramreadformat.datacrc = CONT_CMD_NOP;
77
for (i = 0; i < ARRLEN(ramreadformat.data); i++) {
78
ramreadformat.data[i] = CONT_CMD_NOP;
79
}
80
if (channel != 0) {
81
for (i = 0; i < channel; i++) {
82
*ptr++ = 0;
83
}
84
}
85
*(__OSContRamReadFormat *)ptr = ramreadformat;
86
ptr += sizeof(__OSContRamReadFormat);
87
ptr[0] = CONT_CMD_END;
88
}
89
90