mirror of https://github.com/PrimeDecomp/prime.git
Match OSRtc, more frank issues >.<
This commit is contained in:
parent
32a5ad5b71
commit
76ac2bfd74
|
@ -1044,7 +1044,7 @@ lbl_80380FE0:
|
|||
/* 80380FE0 0037DF40 38 7C 00 00 */ addi r3, r28, 0
|
||||
/* 80380FE4 0037DF44 38 9F 00 00 */ addi r4, r31, 0
|
||||
/* 80380FE8 0037DF48 38 BE 00 00 */ addi r5, r30, 0
|
||||
/* 80380FEC 0037DF4C 48 00 2F 01 */ bl sub_80383eec
|
||||
/* 80380FEC 0037DF4C 48 00 2F 01 */ bl __OSReadROM
|
||||
/* 80380FF0 0037DF50 2C 03 00 00 */ cmpwi r3, 0
|
||||
/* 80380FF4 0037DF54 41 82 FF EC */ beq lbl_80380FE0
|
||||
/* 80380FF8 0037DF58 7F DE FA 14 */ add r30, r30, r31
|
||||
|
|
|
@ -488,8 +488,8 @@ __OSSyncSram:
|
|||
/* 80383EE4 00380E44 80 63 00 4C */ lwz r3, 0x4c(r3)
|
||||
/* 80383EE8 00380E48 4E 80 00 20 */ blr
|
||||
|
||||
.global sub_80383eec
|
||||
sub_80383eec:
|
||||
.global __OSReadROM
|
||||
__OSReadROM:
|
||||
/* 80383EEC 00380E4C 7C 08 02 A6 */ mflr r0
|
||||
/* 80383EF0 00380E50 90 01 00 04 */ stw r0, 4(r1)
|
||||
/* 80383EF4 00380E54 94 21 FF D8 */ stwu r1, -0x28(r1)
|
||||
|
@ -687,8 +687,8 @@ lbl_80384178:
|
|||
/* 8038419C 003810FC 7C 08 03 A6 */ mtlr r0
|
||||
/* 803841A0 00381100 4E 80 00 20 */ blr
|
||||
|
||||
.global sub_803841a4
|
||||
sub_803841a4:
|
||||
.global OSSetProgressiveMode
|
||||
OSSetProgressiveMode:
|
||||
/* 803841A4 00381104 7C 08 02 A6 */ mflr r0
|
||||
/* 803841A8 00381108 3C 80 80 54 */ lis r4, Scb@ha
|
||||
/* 803841AC 0038110C 90 01 00 04 */ stw r0, 4(r1)
|
||||
|
|
|
@ -572,7 +572,7 @@ SetProgressiveMode__9CGraphicsFb:
|
|||
/* 8030962C 0030658C 7C 04 00 D0 */ neg r0, r4
|
||||
/* 80309630 00306590 7C 00 23 78 */ or r0, r0, r4
|
||||
/* 80309634 00306594 54 03 0F FE */ srwi r3, r0, 0x1f
|
||||
/* 80309638 00306598 48 07 AB 6D */ bl sub_803841a4
|
||||
/* 80309638 00306598 48 07 AB 6D */ bl OSSetProgressiveMode
|
||||
/* 8030963C 0030659C 57 C3 06 3E */ clrlwi r3, r30, 0x18
|
||||
/* 80309640 003065A0 57 E0 06 3E */ clrlwi r0, r31, 0x18
|
||||
/* 80309644 003065A4 7C 03 00 40 */ cmplw r3, r0
|
||||
|
|
|
@ -12,7 +12,6 @@ typedef struct OSSram {
|
|||
s8 displayOffsetH;
|
||||
u8 ntd;
|
||||
u8 language;
|
||||
|
||||
u8 flags;
|
||||
} OSSram;
|
||||
|
||||
|
|
|
@ -0,0 +1,326 @@
|
|||
#include "dolphin/OSRtcPriv.h"
|
||||
#include "dolphin/os.h"
|
||||
|
||||
#define RTC_CMD_READ 0x20000000
|
||||
#define RTC_CMD_WRITE 0xa0000000
|
||||
|
||||
#define RTC_SRAM_ADDR 0x00000100
|
||||
#define RTC_SRAM_SIZE 64
|
||||
|
||||
#define RTC_CHAN 0
|
||||
#define RTC_DEV 1
|
||||
#define RTC_FREQ 3 // EXI_FREQ_8M
|
||||
|
||||
typedef struct SramControlBlock {
|
||||
u8 sram[RTC_SRAM_SIZE];
|
||||
u32 offset;
|
||||
BOOL enabled;
|
||||
BOOL locked;
|
||||
BOOL sync;
|
||||
void (*callback)(void);
|
||||
} SramControlBlock;
|
||||
|
||||
static SramControlBlock Scb ATTRIBUTE_ALIGN(32);
|
||||
|
||||
static BOOL GetRTC(u32* rtc) {
|
||||
BOOL err;
|
||||
u32 cmd;
|
||||
|
||||
if (!EXILock(RTC_CHAN, RTC_DEV, 0)) {
|
||||
return FALSE;
|
||||
}
|
||||
if (!EXISelect(RTC_CHAN, RTC_DEV, RTC_FREQ)) {
|
||||
EXIUnlock(RTC_CHAN);
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
cmd = RTC_CMD_READ;
|
||||
err = FALSE;
|
||||
err |= !EXIImm(RTC_CHAN, &cmd, 4, 0x12345, NULL);
|
||||
err |= !EXISync(RTC_CHAN);
|
||||
err |= !EXIImm(RTC_CHAN, &cmd, 4, 0x17231, NULL);
|
||||
err |= !EXISync(RTC_CHAN);
|
||||
err |= !EXIDeselect(RTC_CHAN);
|
||||
EXIUnlock(RTC_CHAN);
|
||||
|
||||
*rtc = cmd;
|
||||
|
||||
return !err;
|
||||
}
|
||||
|
||||
BOOL __OSGetRTC(u32* rtc) {
|
||||
BOOL err;
|
||||
u32 t0;
|
||||
u32 t1;
|
||||
int i;
|
||||
|
||||
for (i = 0; i < 16; i++) {
|
||||
err = FALSE;
|
||||
err |= !GetRTC(&t0);
|
||||
err |= !GetRTC(&t1);
|
||||
if (err) {
|
||||
break;
|
||||
}
|
||||
if (t0 == t1) {
|
||||
*rtc = t0;
|
||||
return TRUE;
|
||||
}
|
||||
}
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
BOOL __OSSetRTC(u32 rtc) {
|
||||
BOOL err;
|
||||
u32 cmd;
|
||||
|
||||
if (!EXILock(RTC_CHAN, RTC_DEV, 0)) {
|
||||
return FALSE;
|
||||
}
|
||||
if (!EXISelect(RTC_CHAN, RTC_DEV, RTC_FREQ)) {
|
||||
EXIUnlock(RTC_CHAN);
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
cmd = RTC_CMD_WRITE;
|
||||
err = FALSE;
|
||||
err |= !EXIImm(RTC_CHAN, &cmd, 4, 0x54321, NULL);
|
||||
err |= !EXISync(RTC_CHAN);
|
||||
err |= !EXIImm(RTC_CHAN, &rtc, 4, 0x12345, NULL);
|
||||
err |= !EXISync(RTC_CHAN);
|
||||
err |= !EXIDeselect(RTC_CHAN);
|
||||
EXIUnlock(RTC_CHAN);
|
||||
|
||||
return !err;
|
||||
}
|
||||
|
||||
static BOOL ReadSram(void* buffer) {
|
||||
BOOL err;
|
||||
u32 cmd;
|
||||
|
||||
DCInvalidateRange(buffer, RTC_SRAM_SIZE);
|
||||
|
||||
if (!EXILock(RTC_CHAN, RTC_DEV, 0)) {
|
||||
return FALSE;
|
||||
}
|
||||
if (!EXISelect(RTC_CHAN, RTC_DEV, RTC_FREQ)) {
|
||||
EXIUnlock(RTC_CHAN);
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
cmd = RTC_CMD_READ | RTC_SRAM_ADDR;
|
||||
err = FALSE;
|
||||
err |= !EXIImm(RTC_CHAN, &cmd, 4, 1, NULL);
|
||||
err |= !EXISync(RTC_CHAN);
|
||||
err |= !EXIDma(RTC_CHAN, buffer, RTC_SRAM_SIZE, 0, NULL);
|
||||
err |= !EXISync(RTC_CHAN);
|
||||
err |= !EXIDeselect(RTC_CHAN);
|
||||
EXIUnlock(RTC_CHAN);
|
||||
|
||||
return !err;
|
||||
}
|
||||
|
||||
BOOL WriteSram(void* buffer, u32 offset, u32 size);
|
||||
static void WriteSramCallback(s32 chan, OSContext* context) {
|
||||
Scb.sync = WriteSram(Scb.sram + Scb.offset, Scb.offset, RTC_SRAM_SIZE - Scb.offset);
|
||||
if (Scb.sync) {
|
||||
Scb.offset = RTC_SRAM_SIZE;
|
||||
}
|
||||
}
|
||||
|
||||
BOOL WriteSram(void* buffer, u32 offset, u32 size) {
|
||||
BOOL err;
|
||||
u32 cmd;
|
||||
|
||||
if (!EXILock(RTC_CHAN, RTC_DEV, WriteSramCallback)) {
|
||||
return FALSE;
|
||||
}
|
||||
if (!EXISelect(RTC_CHAN, RTC_DEV, RTC_FREQ)) {
|
||||
EXIUnlock(RTC_CHAN);
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
offset <<= 6;
|
||||
cmd = RTC_CMD_WRITE | RTC_SRAM_ADDR + offset;
|
||||
err = FALSE;
|
||||
err |= !EXIImm(RTC_CHAN, &cmd, 4, 1, NULL);
|
||||
err |= !EXISync(RTC_CHAN);
|
||||
err |= !EXIImmEx(RTC_CHAN, buffer, (s32)size, 1);
|
||||
err |= !EXIDeselect(RTC_CHAN);
|
||||
EXIUnlock(RTC_CHAN);
|
||||
|
||||
return !err;
|
||||
}
|
||||
|
||||
void __OSInitSram() {
|
||||
Scb.locked = Scb.enabled = FALSE;
|
||||
Scb.sync = ReadSram(Scb.sram);
|
||||
Scb.offset = RTC_SRAM_SIZE;
|
||||
}
|
||||
|
||||
static void* LockSram(u32 offset) {
|
||||
BOOL enabled;
|
||||
enabled = OSDisableInterrupts();
|
||||
|
||||
if (Scb.locked != FALSE) {
|
||||
OSRestoreInterrupts(enabled);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
Scb.enabled = enabled;
|
||||
Scb.locked = TRUE;
|
||||
|
||||
return Scb.sram + offset;
|
||||
}
|
||||
|
||||
OSSram* __OSLockSram() { return LockSram(0); }
|
||||
|
||||
OSSramEx* __OSLockSramEx() { return LockSram(sizeof(OSSram)); }
|
||||
|
||||
static BOOL UnlockSram(BOOL commit, u32 offset) {
|
||||
u16* p;
|
||||
|
||||
if (commit) {
|
||||
if (offset == 0) {
|
||||
OSSram* sram = (OSSram*)Scb.sram;
|
||||
|
||||
if (2u < (sram->flags & 3)) {
|
||||
sram->flags &= ~3;
|
||||
}
|
||||
|
||||
sram->checkSum = sram->checkSumInv = 0;
|
||||
for (p = (u16*)&sram->counterBias; p < (u16*)(Scb.sram + sizeof(OSSram)); p++) {
|
||||
sram->checkSum += *p;
|
||||
sram->checkSumInv += ~*p;
|
||||
}
|
||||
}
|
||||
|
||||
if (offset < Scb.offset) {
|
||||
Scb.offset = offset;
|
||||
}
|
||||
|
||||
Scb.sync = WriteSram(Scb.sram + Scb.offset, Scb.offset, RTC_SRAM_SIZE - Scb.offset);
|
||||
if (Scb.sync) {
|
||||
Scb.offset = RTC_SRAM_SIZE;
|
||||
}
|
||||
}
|
||||
Scb.locked = FALSE;
|
||||
OSRestoreInterrupts(Scb.enabled);
|
||||
return Scb.sync;
|
||||
}
|
||||
|
||||
BOOL __OSUnlockSram(BOOL commit) { return UnlockSram(commit, 0); }
|
||||
|
||||
BOOL __OSUnlockSramEx(BOOL commit) { return UnlockSram(commit, sizeof(OSSram)); }
|
||||
|
||||
BOOL __OSSyncSram() { return Scb.sync; }
|
||||
|
||||
BOOL __OSReadROM(void* buffer, s32 length, s32 offset) {
|
||||
BOOL err;
|
||||
u32 cmd;
|
||||
|
||||
DCInvalidateRange(buffer, (u32)length);
|
||||
|
||||
if (!EXILock(RTC_CHAN, RTC_DEV, 0)) {
|
||||
return FALSE;
|
||||
}
|
||||
if (!EXISelect(RTC_CHAN, RTC_DEV, RTC_FREQ)) {
|
||||
EXIUnlock(RTC_CHAN);
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
cmd = (u32)(offset << 6);
|
||||
err = FALSE;
|
||||
err |= !EXIImm(RTC_CHAN, &cmd, 4, 1, NULL);
|
||||
err |= !EXISync(RTC_CHAN);
|
||||
err |= !EXIDma(RTC_CHAN, buffer, length, 0, NULL);
|
||||
err |= !EXISync(RTC_CHAN);
|
||||
err |= !EXIDeselect(RTC_CHAN);
|
||||
EXIUnlock(RTC_CHAN);
|
||||
|
||||
return !err;
|
||||
}
|
||||
|
||||
u32 OSGetSoundMode() {
|
||||
OSSram* sram;
|
||||
u32 mode;
|
||||
|
||||
sram = __OSLockSram();
|
||||
mode = (sram->flags & 0x4) ? OS_SOUND_MODE_STEREO : OS_SOUND_MODE_MONO;
|
||||
__OSUnlockSram(FALSE);
|
||||
return mode;
|
||||
}
|
||||
|
||||
void OSSetSoundMode(u32 mode) {
|
||||
OSSram* sram;
|
||||
mode <<= 2;
|
||||
mode &= 4;
|
||||
|
||||
sram = __OSLockSram();
|
||||
if (mode == (sram->flags & 4)) {
|
||||
__OSUnlockSram(FALSE);
|
||||
return;
|
||||
}
|
||||
|
||||
sram->flags &= ~4;
|
||||
sram->flags |= mode;
|
||||
__OSUnlockSram(TRUE);
|
||||
}
|
||||
|
||||
u32 OSGetProgressiveMode() {
|
||||
OSSram* sram;
|
||||
u32 mode;
|
||||
|
||||
sram = __OSLockSram();
|
||||
mode = (sram->flags & 0x80) >> 7;
|
||||
__OSUnlockSram(FALSE);
|
||||
return mode;
|
||||
}
|
||||
|
||||
void OSSetProgressiveMode(u32 mode) {
|
||||
OSSram* sram;
|
||||
mode <<= 7;
|
||||
mode &= 0x80;
|
||||
|
||||
sram = __OSLockSram();
|
||||
if (mode == (sram->flags & 0x80)) {
|
||||
__OSUnlockSram(FALSE);
|
||||
return;
|
||||
}
|
||||
|
||||
sram->flags &= ~0x80;
|
||||
sram->flags |= mode;
|
||||
__OSUnlockSram(TRUE);
|
||||
}
|
||||
|
||||
u8 OSGetLanguage() {
|
||||
OSSram* sram;
|
||||
u8 language;
|
||||
|
||||
sram = __OSLockSram();
|
||||
language = sram->language;
|
||||
__OSUnlockSram(FALSE);
|
||||
return language;
|
||||
}
|
||||
|
||||
u32 OSGetWirelessID(u32 channel) {
|
||||
OSSramEx* sram;
|
||||
u16 id;
|
||||
|
||||
sram = __OSLockSramEx();
|
||||
id = sram->wirelessPadID[channel];
|
||||
__OSUnlockSramEx(FALSE);
|
||||
return id;
|
||||
}
|
||||
|
||||
void OSSetWirelessID(u32 channel, u16 id) {
|
||||
OSSramEx* sram;
|
||||
|
||||
sram = __OSLockSramEx();
|
||||
if (sram->wirelessPadID[channel] != id) {
|
||||
sram->wirelessPadID[channel] = id;
|
||||
__OSUnlockSramEx(TRUE);
|
||||
return;
|
||||
}
|
||||
|
||||
__OSUnlockSramEx(FALSE);
|
||||
}
|
Loading…
Reference in New Issue