Match OSRtc, more frank issues >.<

This commit is contained in:
Phillip Stephens 2022-10-10 22:33:20 -07:00
parent 32a5ad5b71
commit 76ac2bfd74
5 changed files with 332 additions and 7 deletions

View File

@ -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

View File

@ -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)

View File

@ -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

View File

@ -12,7 +12,6 @@ typedef struct OSSram {
s8 displayOffsetH;
u8 ntd;
u8 language;
u8 flags;
} OSSram;

326
src/Dolphin/os/OSRtc.c Normal file
View File

@ -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);
}