313 lines
8.7 KiB
Diff
313 lines
8.7 KiB
Diff
|
diff --git a/include/PR/console_type.h b/include/PR/console_type.h
|
||
|
new file mode 100644
|
||
|
index 00000000..e60550ab
|
||
|
--- /dev/null
|
||
|
+++ b/include/PR/console_type.h
|
||
|
@@ -0,0 +1,7 @@
|
||
|
+enum ConsoleType {
|
||
|
+ CONSOLE_N64,
|
||
|
+ CONSOLE_IQUE
|
||
|
+};
|
||
|
+
|
||
|
+extern enum ConsoleType gConsoleType;
|
||
|
+extern enum ConsoleType get_console_type(void);
|
||
|
diff --git a/lib/asm/skGetId.s b/lib/asm/skGetId.s
|
||
|
new file mode 100644
|
||
|
index 00000000..8fb4c449
|
||
|
--- /dev/null
|
||
|
+++ b/lib/asm/skGetId.s
|
||
|
@@ -0,0 +1,18 @@
|
||
|
+# Code by stuckpixel
|
||
|
+
|
||
|
+.set noreorder
|
||
|
+.set gp=64
|
||
|
+
|
||
|
+.include "macros.inc"
|
||
|
+
|
||
|
+glabel skGetId
|
||
|
+ li $v0, 0
|
||
|
+ li $t0, 0xA4300014
|
||
|
+ lw $t1, 0x00($t0)
|
||
|
+ nop
|
||
|
+ jr $ra
|
||
|
+ nop
|
||
|
+ nop
|
||
|
+ nop
|
||
|
+ nop
|
||
|
+ nop
|
||
|
diff --git a/lib/src/__osViSwapContext.c b/lib/src/__osViSwapContext.c
|
||
|
index d7741994..9aced7cf 100644
|
||
|
--- a/lib/src/__osViSwapContext.c
|
||
|
+++ b/lib/src/__osViSwapContext.c
|
||
|
@@ -52,7 +52,9 @@ void __osViSwapContext() {
|
||
|
HW_REG(VI_INTR_REG, u32) = s0->fldRegs[field].vIntr;
|
||
|
HW_REG(VI_X_SCALE_REG, u32) = s1->unk20;
|
||
|
HW_REG(VI_Y_SCALE_REG, u32) = s1->unk2c;
|
||
|
- HW_REG(VI_CONTROL_REG, u32) = s1->features;
|
||
|
+ /* Make sure bit 13 is cleared. Otherwise, graphics will be corrupted on
|
||
|
+ * iQue Player. This has no effect on N64. */
|
||
|
+ HW_REG(VI_CONTROL_REG, u32) = s1->features & ~(1 << 13);
|
||
|
D_80334914 = D_80334910;
|
||
|
D_80334910 = s1;
|
||
|
*D_80334914 = *D_80334910;
|
||
|
diff --git a/lib/src/consoleType.c b/lib/src/consoleType.c
|
||
|
new file mode 100644
|
||
|
index 00000000..ef08d1ef
|
||
|
--- /dev/null
|
||
|
+++ b/lib/src/consoleType.c
|
||
|
@@ -0,0 +1,12 @@
|
||
|
+#include "libultra_internal.h"
|
||
|
+#include <PR/console_type.h>
|
||
|
+
|
||
|
+enum ConsoleType gConsoleType;
|
||
|
+
|
||
|
+void skGetId(u32 *out);
|
||
|
+
|
||
|
+enum ConsoleType get_console_type(void) {
|
||
|
+ u32 id = 0;
|
||
|
+ skGetId(&id);
|
||
|
+ return (id == 0) ? CONSOLE_N64 : CONSOLE_IQUE;
|
||
|
+}
|
||
|
diff --git a/lib/src/osEepromProbe.c b/lib/src/osEepromProbe.c
|
||
|
index d550b846..bbaf2bcc 100644
|
||
|
--- a/lib/src/osEepromProbe.c
|
||
|
+++ b/lib/src/osEepromProbe.c
|
||
|
@@ -1,4 +1,5 @@
|
||
|
#include "libultra_internal.h"
|
||
|
+#include <PR/console_type.h>
|
||
|
|
||
|
// TODO: merge with osEepromWrite
|
||
|
typedef struct {
|
||
|
@@ -13,11 +14,23 @@ s32 osEepromProbe(OSMesgQueue *mq) {
|
||
|
unkStruct sp18;
|
||
|
|
||
|
__osSiGetAccess();
|
||
|
- status = __osEepStatus(mq, &sp18);
|
||
|
- if (status == 0 && (sp18.unk00 & 0x8000) != 0) {
|
||
|
- status = 1;
|
||
|
- } else {
|
||
|
- status = 0;
|
||
|
+ if (gConsoleType == CONSOLE_N64) {
|
||
|
+ status = __osEepStatus(mq, &sp18);
|
||
|
+ if (status == 0 && (sp18.unk00 & 0x8000) != 0) {
|
||
|
+ status = 1;
|
||
|
+ } else {
|
||
|
+ status = 0;
|
||
|
+ }
|
||
|
+ } else if (gConsoleType == CONSOLE_IQUE) {
|
||
|
+ s32 __osBbEepromSize = * (s32*) 0x80000360;
|
||
|
+
|
||
|
+ if (__osBbEepromSize == 0x200) {
|
||
|
+ status = 1;
|
||
|
+ }
|
||
|
+
|
||
|
+ if (__osBbEepromSize == 0x800) {
|
||
|
+ status = 2;
|
||
|
+ }
|
||
|
}
|
||
|
__osSiRelAccess();
|
||
|
return status;
|
||
|
diff --git a/lib/src/osEepromRead.c b/lib/src/osEepromRead.c
|
||
|
index 905eff74..23f34dd5 100644
|
||
|
--- a/lib/src/osEepromRead.c
|
||
|
+++ b/lib/src/osEepromRead.c
|
||
|
@@ -1,4 +1,5 @@
|
||
|
#include "libultra_internal.h"
|
||
|
+#include <PR/console_type.h>
|
||
|
|
||
|
extern u32 D_80365E00[15];
|
||
|
extern u32 D_80365E3C;
|
||
|
@@ -44,33 +45,44 @@ s32 osEepromRead(OSMesgQueue *mq, u8 address, u8 *buffer) {
|
||
|
return -1;
|
||
|
}
|
||
|
__osSiGetAccess();
|
||
|
- sp34 = __osEepStatus(mq, &sp28);
|
||
|
- if (sp34 != 0 || sp28.unk00 != 0x8000) {
|
||
|
+ if (gConsoleType == CONSOLE_N64) {
|
||
|
+ sp34 = __osEepStatus(mq, &sp28);
|
||
|
+ if (sp34 != 0 || sp28.unk00 != 0x8000) {
|
||
|
|
||
|
- return 8;
|
||
|
- }
|
||
|
- while (sp28.unk02 & 0x80) {
|
||
|
- __osEepStatus(mq, &sp28);
|
||
|
- }
|
||
|
- __osPackEepReadData(address);
|
||
|
- sp34 = __osSiRawStartDma(OS_WRITE, &D_80365E00);
|
||
|
- osRecvMesg(mq, NULL, OS_MESG_BLOCK);
|
||
|
- for (sp30 = 0; sp30 < 0x10; sp30++) {
|
||
|
- (D_80365E00)[sp30] = 255;
|
||
|
- }
|
||
|
- D_80365E3C = 0;
|
||
|
- sp34 = __osSiRawStartDma(OS_READ, D_80365E00);
|
||
|
- D_80365D20 = 4;
|
||
|
- osRecvMesg(mq, NULL, OS_MESG_BLOCK);
|
||
|
- for (sp30 = 0; sp30 < 4; sp30++) {
|
||
|
- sp2c++;
|
||
|
- }
|
||
|
- sp20 = *(unkStruct2 *) sp2c;
|
||
|
- sp34 = (sp20.unk01 & 0xc0) >> 4;
|
||
|
- if (sp34 == 0) {
|
||
|
- for (sp30 = 0; sp30 < 8; sp30++) {
|
||
|
- *buffer++ = ((u8 *) &sp20.unk04)[sp30];
|
||
|
+ return 8;
|
||
|
+ }
|
||
|
+ while (sp28.unk02 & 0x80) {
|
||
|
+ __osEepStatus(mq, &sp28);
|
||
|
+ }
|
||
|
+ __osPackEepReadData(address);
|
||
|
+ sp34 = __osSiRawStartDma(OS_WRITE, &D_80365E00);
|
||
|
+ osRecvMesg(mq, NULL, OS_MESG_BLOCK);
|
||
|
+ for (sp30 = 0; sp30 < 0x10; sp30++) {
|
||
|
+ (D_80365E00)[sp30] = 255;
|
||
|
}
|
||
|
+ D_80365E3C = 0;
|
||
|
+ sp34 = __osSiRawStartDma(OS_READ, D_80365E00);
|
||
|
+ D_80365D20 = 4;
|
||
|
+ osRecvMesg(mq, NULL, OS_MESG_BLOCK);
|
||
|
+ for (sp30 = 0; sp30 < 4; sp30++) {
|
||
|
+ sp2c++;
|
||
|
+ }
|
||
|
+ sp20 = *(unkStruct2 *) sp2c;
|
||
|
+ sp34 = (sp20.unk01 & 0xc0) >> 4;
|
||
|
+ if (sp34 == 0) {
|
||
|
+ for (sp30 = 0; sp30 < 8; sp30++) {
|
||
|
+ *buffer++ = ((u8 *) &sp20.unk04)[sp30];
|
||
|
+ }
|
||
|
+ }
|
||
|
+ } else if (gConsoleType == CONSOLE_IQUE) {
|
||
|
+ u8 *__osBbEepromAddress = * (u8**) 0x8000035C;
|
||
|
+ s32 i;
|
||
|
+
|
||
|
+ for (i = 0; i < 8; i++) {
|
||
|
+ buffer[i] = __osBbEepromAddress[(address << 3) + i];
|
||
|
+ }
|
||
|
+
|
||
|
+ sp34 = 0;
|
||
|
}
|
||
|
__osSiRelAccess();
|
||
|
return sp34;
|
||
|
diff --git a/lib/src/osEepromWrite.c b/lib/src/osEepromWrite.c
|
||
|
index 71d0b7d6..c855cc20 100644
|
||
|
--- a/lib/src/osEepromWrite.c
|
||
|
+++ b/lib/src/osEepromWrite.c
|
||
|
@@ -1,5 +1,6 @@
|
||
|
#include "libultra_internal.h"
|
||
|
#include "osContInternal.h"
|
||
|
+#include <PR/console_type.h>
|
||
|
|
||
|
u32 D_80365E00[0x3c >> 2];
|
||
|
u32 D_80365E3C;
|
||
|
@@ -46,36 +47,47 @@ s32 osEepromWrite(OSMesgQueue *mq, u8 address, u8 *buffer) {
|
||
|
}
|
||
|
|
||
|
__osSiGetAccess();
|
||
|
- sp34 = __osEepStatus(mq, &sp1c);
|
||
|
+ if (gConsoleType == CONSOLE_N64) {
|
||
|
+ sp34 = __osEepStatus(mq, &sp1c);
|
||
|
|
||
|
- if (sp34 != 0 || sp1c.unk00 != 0x8000) {
|
||
|
- return 8;
|
||
|
- }
|
||
|
+ if (sp34 != 0 || sp1c.unk00 != 0x8000) {
|
||
|
+ return 8;
|
||
|
+ }
|
||
|
|
||
|
- while (sp1c.unk02 & 0x80) {
|
||
|
- __osEepStatus(mq, &sp1c);
|
||
|
- }
|
||
|
+ while (sp1c.unk02 & 0x80) {
|
||
|
+ __osEepStatus(mq, &sp1c);
|
||
|
+ }
|
||
|
|
||
|
- __osPackEepWriteData(address, buffer);
|
||
|
+ __osPackEepWriteData(address, buffer);
|
||
|
|
||
|
- sp34 = __osSiRawStartDma(OS_WRITE, &D_80365E00);
|
||
|
- osRecvMesg(mq, NULL, OS_MESG_BLOCK);
|
||
|
+ sp34 = __osSiRawStartDma(OS_WRITE, &D_80365E00);
|
||
|
+ osRecvMesg(mq, NULL, OS_MESG_BLOCK);
|
||
|
|
||
|
- for (sp30 = 0; sp30 < 0x10; sp30++) {
|
||
|
- (D_80365E00)[sp30] = 255;
|
||
|
- }
|
||
|
+ for (sp30 = 0; sp30 < 0x10; sp30++) {
|
||
|
+ (D_80365E00)[sp30] = 255;
|
||
|
+ }
|
||
|
|
||
|
- D_80365E3C = 0;
|
||
|
- sp34 = __osSiRawStartDma(OS_READ, D_80365E00);
|
||
|
- D_80365D20 = 5;
|
||
|
- osRecvMesg(mq, NULL, OS_MESG_BLOCK);
|
||
|
+ D_80365E3C = 0;
|
||
|
+ sp34 = __osSiRawStartDma(OS_READ, D_80365E00);
|
||
|
+ D_80365D20 = 5;
|
||
|
+ osRecvMesg(mq, NULL, OS_MESG_BLOCK);
|
||
|
|
||
|
- for (sp30 = 0; sp30 < 4; sp30++) {
|
||
|
- sp2c++;
|
||
|
- }
|
||
|
+ for (sp30 = 0; sp30 < 4; sp30++) {
|
||
|
+ sp2c++;
|
||
|
+ }
|
||
|
+
|
||
|
+ sp20 = *(unkStruct2 *) sp2c;
|
||
|
+ sp34 = (sp20.unk01 & 0xc0) >> 4;
|
||
|
+ } else if (gConsoleType == CONSOLE_N64) {
|
||
|
+ u8 *__osBbEepromAddress = * (u8**) 0x8000035C;
|
||
|
+ s32 i;
|
||
|
|
||
|
- sp20 = *(unkStruct2 *) sp2c;
|
||
|
- sp34 = (sp20.unk01 & 0xc0) >> 4;
|
||
|
+ for (i = 0; i < 8; i++) {
|
||
|
+ __osBbEepromAddress[(address << 3) + i] = buffer[i];
|
||
|
+ }
|
||
|
+
|
||
|
+ sp34 = 0;
|
||
|
+ }
|
||
|
__osSiRelAccess();
|
||
|
return sp34;
|
||
|
}
|
||
|
diff --git a/lib/src/osInitialize.c b/lib/src/osInitialize.c
|
||
|
index 0b9f7128..660d1991 100644
|
||
|
--- a/lib/src/osInitialize.c
|
||
|
+++ b/lib/src/osInitialize.c
|
||
|
@@ -1,6 +1,7 @@
|
||
|
#include "libultra_internal.h"
|
||
|
#include "hardware.h"
|
||
|
#include <macros.h>
|
||
|
+#include <PR/console_type.h>
|
||
|
|
||
|
#define PIF_ADDR_START (void *) 0x1FC007FC
|
||
|
|
||
|
@@ -46,6 +47,7 @@ void osInitialize(void) {
|
||
|
UNUSED u32 eu_sp30;
|
||
|
#endif
|
||
|
UNUSED u32 sp2c;
|
||
|
+ gConsoleType = get_console_type();
|
||
|
D_80365CD0 = TRUE;
|
||
|
__osSetSR(__osGetSR() | 0x20000000);
|
||
|
__osSetFpcCsr(0x01000800);
|
||
|
diff --git a/sm64.ld b/sm64.ld
|
||
|
index 59a5a2a6..c8976649 100755
|
||
|
--- a/sm64.ld
|
||
|
+++ b/sm64.ld
|
||
|
@@ -256,6 +256,8 @@ SECTIONS
|
||
|
BUILD_DIR/libultra.a:func_802F7140.o(.text)
|
||
|
BUILD_DIR/libultra.a:func_802F71A0.o(.text)
|
||
|
BUILD_DIR/libultra.a:func_802F71F0.o(.text)
|
||
|
+ BUILD_DIR/libultra.a:consoleType.o(.text)
|
||
|
+ BUILD_DIR/libultra.a:skGetId.o(.text)
|
||
|
|
||
|
BUILD_DIR/lib/rsp.o(.text);
|
||
|
|
||
|
@@ -369,6 +371,8 @@ SECTIONS
|
||
|
BUILD_DIR/libultra.a:__osGetCause.o(.text);
|
||
|
BUILD_DIR/libultra.a:__osAtomicDec.o(.text);
|
||
|
BUILD_DIR/libultra.a:guLookAtRef.o(.text); /* Fast3DEX2 only */
|
||
|
+ BUILD_DIR/libultra.a:consoleType.o(.text);
|
||
|
+ BUILD_DIR/libultra.a:skGetId.o(.text);
|
||
|
BUILD_DIR/lib/rsp.o(.text);
|
||
|
#endif
|
||
|
|