Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
MorsGames
GitHub Repository: MorsGames/sm64plus
Path: blob/master/lib/src/contramwrite.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 __osPackRamWriteData(int channel, u16 address, u8 *buffer);
7
8
s32 __osContRamWrite(OSMesgQueue *mq, int channel, u16 address, u8 *buffer, int force) {
9
s32 ret;
10
int i;
11
u8 *ptr;
12
__OSContRamReadFormat ramreadformat;
13
int retry;
14
15
ret = 0;
16
ptr = (u8 *)&__osPfsPifRam;
17
retry = 2;
18
if (force != 1 && address < 7 && address != 0) {
19
return 0;
20
}
21
__osSiGetAccess();
22
_osLastSentSiCmd = CONT_CMD_WRITE_MEMPACK;
23
__osPackRamWriteData(channel, address, buffer);
24
ret = __osSiRawStartDma(OS_WRITE, &__osPfsPifRam);
25
osRecvMesg(mq, NULL, OS_MESG_BLOCK);
26
do {
27
ret = __osSiRawStartDma(OS_READ, &__osPfsPifRam);
28
osRecvMesg(mq, NULL, OS_MESG_BLOCK);
29
ptr = (u8 *)&__osPfsPifRam;
30
if (channel != 0) {
31
for (i = 0; i < channel; i++) {
32
ptr++;
33
}
34
}
35
36
ramreadformat = *(__OSContRamReadFormat *)ptr;
37
38
ret = CHNL_ERR(ramreadformat);
39
if (ret == 0) {
40
if (__osContDataCrc(buffer) != ramreadformat.datacrc) {
41
ret = func_8030A5C0(mq, channel);
42
if (ret != 0) {
43
__osSiRelAccess();
44
return ret;
45
}
46
ret = PFS_ERR_CONTRFAIL;
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 __osPackRamWriteData(int channel, u16 address, u8 *buffer) {
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_WRITE_MEMPACK_TX;
73
ramreadformat.rxsize = CONT_CMD_WRITE_MEMPACK_RX;
74
ramreadformat.cmd = CONT_CMD_WRITE_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] = *buffer++;
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