Merge branch 'main' of https://github.com/abnormalhare/marioparty4
This commit is contained in:
commit
0606d9677b
197 changed files with 31800 additions and 2022 deletions
327
src/OdemuExi2/DebuggerDriver.c
Normal file
327
src/OdemuExi2/DebuggerDriver.c
Normal file
|
|
@ -0,0 +1,327 @@
|
|||
#include <dolphin/exi.h>
|
||||
#include <dolphin/hw_regs.h>
|
||||
#include <dolphin/os.h>
|
||||
|
||||
|
||||
typedef void (*MTRCallbackType)(int);
|
||||
|
||||
static MTRCallbackType MTRCallback;
|
||||
|
||||
static void (*DBGCallback)(u32, OSContext *);
|
||||
|
||||
static u32 SendMailData;
|
||||
|
||||
static s32 RecvDataLeng;
|
||||
|
||||
static u8 *pEXIInputFlag;
|
||||
|
||||
static u8 EXIInputFlag;
|
||||
|
||||
static u8 SendCount = 0x80;
|
||||
|
||||
#define IS_TRUE(x) ((x) != FALSE)
|
||||
#define IS_FALSE(x) !IS_TRUE(x)
|
||||
#define ROUND_UP(x, align) (((x) + (align)-1) & (-(align)))
|
||||
|
||||
// TODO
|
||||
|
||||
void DBGEXIInit()
|
||||
{
|
||||
__OSMaskInterrupts(0x18000);
|
||||
__EXIRegs[10] = 0;
|
||||
}
|
||||
|
||||
static u32 DBGEXISelect(u32 v)
|
||||
{
|
||||
u32 regs = __EXIRegs[10];
|
||||
regs &= 0x405;
|
||||
regs |= 0x80 | (v << 4);
|
||||
__EXIRegs[10] = regs;
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
BOOL DBGEXIDeselect(void)
|
||||
{
|
||||
__EXIRegs[10] &= 0x405;
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
static BOOL DBGEXISync()
|
||||
{
|
||||
while (__EXIRegs[13] & 1)
|
||||
;
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
static BOOL DBGEXIImm(void *buffer, s32 bytecounter, u32 write)
|
||||
{
|
||||
u8 *tempPointer;
|
||||
u32 writeOutValue;
|
||||
int i;
|
||||
|
||||
if (write) {
|
||||
tempPointer = buffer;
|
||||
writeOutValue = 0;
|
||||
for (i = 0; i < bytecounter; i++) {
|
||||
u8 *temp = ((u8 *)buffer) + i;
|
||||
writeOutValue |= *temp << ((3 - i) << 3);
|
||||
}
|
||||
__EXIRegs[14] = writeOutValue;
|
||||
}
|
||||
|
||||
__EXIRegs[13] = 1 | write << 2 | (bytecounter - 1) << 4;
|
||||
DBGEXISync();
|
||||
|
||||
if (!write) {
|
||||
writeOutValue = __EXIRegs[14];
|
||||
tempPointer = buffer;
|
||||
for (i = 0; i < bytecounter; i++) {
|
||||
*tempPointer++ = writeOutValue >> ((3 - i) << 3);
|
||||
}
|
||||
}
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
static BOOL DBGWriteMailbox(u32 p1)
|
||||
{
|
||||
u32 cmd = 0xc0000000;
|
||||
u32 v;
|
||||
u32 base = p1;
|
||||
BOOL total = FALSE;
|
||||
|
||||
DBGEXISelect(4);
|
||||
v = (base & 0x1fffffff) | (cmd);
|
||||
total |= IS_FALSE(DBGEXIImm(&v, sizeof(v), 1));
|
||||
total |= IS_FALSE(DBGEXISync());
|
||||
total |= IS_FALSE(DBGEXIDeselect());
|
||||
|
||||
return IS_FALSE(total);
|
||||
}
|
||||
|
||||
#pragma dont_inline on
|
||||
|
||||
static BOOL DBGReadMailbox(u32 *p1)
|
||||
{
|
||||
BOOL total = FALSE;
|
||||
u32 v;
|
||||
|
||||
DBGEXISelect(4);
|
||||
|
||||
v = 0x60000000;
|
||||
total |= IS_FALSE(DBGEXIImm(&v, 2, 1));
|
||||
total |= IS_FALSE(DBGEXISync());
|
||||
|
||||
total |= IS_FALSE(DBGEXIImm(p1, 4, 0));
|
||||
total |= IS_FALSE(DBGEXISync());
|
||||
|
||||
total |= IS_FALSE(DBGEXIDeselect());
|
||||
|
||||
return IS_FALSE(total);
|
||||
}
|
||||
#pragma dont_inline off
|
||||
|
||||
static BOOL DBGRead(u32 count, u32 *buffer, s32 param3)
|
||||
{
|
||||
BOOL total = FALSE;
|
||||
u32 *buf_p = (u32 *)buffer;
|
||||
u32 v1;
|
||||
u32 v;
|
||||
|
||||
DBGEXISelect(4);
|
||||
|
||||
v1 = (count & 0x1fffc) << 8 | 0x20000000;
|
||||
total |= IS_FALSE(DBGEXIImm(&v1, sizeof(v1), 1));
|
||||
total |= IS_FALSE(DBGEXISync());
|
||||
|
||||
while (param3) {
|
||||
total |= IS_FALSE(DBGEXIImm(&v, sizeof(v), 0));
|
||||
total |= IS_FALSE(DBGEXISync());
|
||||
|
||||
*buf_p++ = v;
|
||||
|
||||
param3 -= 4;
|
||||
if (param3 < 0) {
|
||||
param3 = 0;
|
||||
}
|
||||
}
|
||||
|
||||
total |= IS_FALSE(DBGEXIDeselect());
|
||||
return IS_FALSE(total);
|
||||
}
|
||||
|
||||
static BOOL DBGWrite(u32 count, void *buffer, s32 param3)
|
||||
{
|
||||
BOOL total = FALSE;
|
||||
u32 *buf_p = (u32 *)buffer;
|
||||
u32 v1;
|
||||
u32 v;
|
||||
|
||||
DBGEXISelect(4);
|
||||
|
||||
v1 = (count & 0x1fffc) << 8 | 0xa0000000;
|
||||
total |= IS_FALSE(DBGEXIImm(&v1, sizeof(v1), 1));
|
||||
total |= IS_FALSE(DBGEXISync());
|
||||
|
||||
while (param3 != 0) {
|
||||
v = *buf_p++;
|
||||
|
||||
total |= IS_FALSE(DBGEXIImm(&v, sizeof(v), 1));
|
||||
total |= IS_FALSE(DBGEXISync());
|
||||
|
||||
param3 -= 4;
|
||||
if (param3 < 0) {
|
||||
param3 = 0;
|
||||
}
|
||||
}
|
||||
|
||||
total |= IS_FALSE(DBGEXIDeselect());
|
||||
return IS_FALSE(total);
|
||||
}
|
||||
|
||||
static BOOL _DBGReadStatus(u32 *p1)
|
||||
{
|
||||
BOOL total = FALSE;
|
||||
u32 v;
|
||||
|
||||
DBGEXISelect(4);
|
||||
|
||||
v = 1 << 30;
|
||||
total |= IS_FALSE(DBGEXIImm(&v, 2, 1));
|
||||
total |= IS_FALSE(DBGEXISync());
|
||||
|
||||
total |= IS_FALSE(DBGEXIImm(p1, 4, 0));
|
||||
total |= IS_FALSE(DBGEXISync());
|
||||
|
||||
total |= IS_FALSE(DBGEXIDeselect());
|
||||
|
||||
return IS_FALSE(total);
|
||||
}
|
||||
|
||||
static BOOL DBGReadStatus(u32 *p1)
|
||||
{
|
||||
return _DBGReadStatus(p1);
|
||||
}
|
||||
|
||||
static void MWCallback(u32 a, OSContext *b)
|
||||
{
|
||||
EXIInputFlag = TRUE;
|
||||
if (MTRCallback) {
|
||||
MTRCallback(0);
|
||||
}
|
||||
}
|
||||
|
||||
static void DBGHandler(s16 a, OSContext *b)
|
||||
{
|
||||
*__PIRegs = 0x1000;
|
||||
if (DBGCallback) {
|
||||
DBGCallback(a, b);
|
||||
}
|
||||
}
|
||||
|
||||
void DBInitComm(u8 **a, MTRCallbackType b)
|
||||
{
|
||||
BOOL interrupts = OSDisableInterrupts();
|
||||
{
|
||||
pEXIInputFlag = (u8 *)EXIInputFlag;
|
||||
pEXIInputFlag = &EXIInputFlag;
|
||||
|
||||
*a = pEXIInputFlag;
|
||||
|
||||
MTRCallback = b;
|
||||
|
||||
DBGEXIInit();
|
||||
}
|
||||
OSRestoreInterrupts(interrupts);
|
||||
}
|
||||
|
||||
void DBInitInterrupts(void)
|
||||
{
|
||||
__OSMaskInterrupts(0x18000);
|
||||
__OSMaskInterrupts(0x40);
|
||||
DBGCallback = &MWCallback;
|
||||
__OSSetInterruptHandler(0x19, DBGHandler);
|
||||
__OSUnmaskInterrupts(0x40);
|
||||
}
|
||||
|
||||
static void CheckMailBox(void)
|
||||
{
|
||||
u32 v;
|
||||
DBGReadStatus(&v);
|
||||
if (v & 1) {
|
||||
DBGReadMailbox(&v);
|
||||
v &= 0x1fffffff;
|
||||
|
||||
if ((v & 0x1f000000) == 0x1f000000) {
|
||||
SendMailData = v;
|
||||
RecvDataLeng = v & 0x7fff;
|
||||
EXIInputFlag = 1;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
u32 DBQueryData(void)
|
||||
{
|
||||
BOOL interrupts;
|
||||
EXIInputFlag = 0;
|
||||
if (!RecvDataLeng) {
|
||||
interrupts = OSDisableInterrupts();
|
||||
CheckMailBox();
|
||||
}
|
||||
OSRestoreInterrupts(interrupts);
|
||||
return RecvDataLeng;
|
||||
}
|
||||
|
||||
BOOL DBRead(u32 *buffer, s32 count)
|
||||
{
|
||||
u32 interrupts = OSDisableInterrupts();
|
||||
u32 v = SendMailData & 0x10000 ? 0x1000 : 0;
|
||||
|
||||
DBGRead(v + 0x1e000, buffer, ROUND_UP(count, 4));
|
||||
|
||||
RecvDataLeng = 0;
|
||||
EXIInputFlag = 0;
|
||||
|
||||
OSRestoreInterrupts(interrupts);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
BOOL DBWrite(void *src, u32 size)
|
||||
{
|
||||
u32 v;
|
||||
u32 busyFlag;
|
||||
BOOL interrupts = OSDisableInterrupts();
|
||||
|
||||
do {
|
||||
_DBGReadStatus(&busyFlag);
|
||||
} while (busyFlag & 2);
|
||||
|
||||
SendCount++;
|
||||
v = ((SendCount & 1) ? 0x1000 : 0);
|
||||
|
||||
while (!DBGWrite(v | 0x1c000, src, ROUND_UP(size, 4)))
|
||||
;
|
||||
|
||||
do {
|
||||
_DBGReadStatus(&busyFlag);
|
||||
} while (busyFlag & 2);
|
||||
|
||||
v = SendCount;
|
||||
while (!DBGWriteMailbox((0x1f000000) | v << 0x10 | size))
|
||||
;
|
||||
|
||||
do {
|
||||
while (!_DBGReadStatus(&busyFlag))
|
||||
;
|
||||
} while (busyFlag & 2);
|
||||
|
||||
OSRestoreInterrupts(interrupts);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
void DBOpen(void) { }
|
||||
|
||||
void DBClose(void) { }
|
||||
|
|
@ -6,7 +6,6 @@
|
|||
#include "game/sprite.h"
|
||||
#include "game/window.h"
|
||||
#include "game/wipe.h"
|
||||
#include "rel_sqrt_consts.h"
|
||||
|
||||
#include "REL/E3SetupDLL.h"
|
||||
|
||||
|
|
@ -143,8 +142,6 @@ static float cursorYOfsTbl[] = { -100.0f, -50.0f, 0.0f, 50.0f, 100.0f };
|
|||
|
||||
static s32 mgPicTbl[] = { 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, 52 };
|
||||
|
||||
static char startText[] = "\013\016\r PRESS START";
|
||||
|
||||
static void StartMGSelect(omObjData *object)
|
||||
{
|
||||
HuAudSeqPlay(0x2B);
|
||||
|
|
@ -491,12 +488,12 @@ static void CreateMGInterface(omObjData *object)
|
|||
index = HuSprCreate(temp_r3_2, 0x271A, 0);
|
||||
HuSprGrpMemberSet(group, 0, index);
|
||||
index2++;
|
||||
HuWinMesMaxSizeGet(1, sp8, &startText);
|
||||
HuWinMesMaxSizeGet(1, sp8, "\013\016\r PRESS START");
|
||||
index = HuWinCreate(340.0f, 362.0f, sp8[0], sp8[1], 0);
|
||||
unkStruct->unk_2C = index;
|
||||
HuWinMesColSet(index, 0);
|
||||
HuWinBGTPLvlSet(index, 0.0f);
|
||||
HuWinMesSpeedSet(index, 0);
|
||||
HuWinMesSet(index, MAKE_MESSID_PTR(startText));
|
||||
HuWinMesSet(index, MAKE_MESSID_PTR("\013\016\r PRESS START"));
|
||||
object->func = UpdateMGInterface;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,6 +1,6 @@
|
|||
#include "REL/executor.h"
|
||||
#include "dolphin/os.h"
|
||||
#include "rel_sqrt_consts.h"
|
||||
#include "math.h"
|
||||
|
||||
void ObjectSetup(void) {
|
||||
OSReport("minigame dll setup\n");
|
||||
|
|
|
|||
|
|
@ -1,5 +1,5 @@
|
|||
#include "REL/board_executor.h"
|
||||
#include "rel_sqrt_consts.h"
|
||||
#include "math.h"
|
||||
|
||||
static void ObjectSetup(void) {
|
||||
BoardObjectSetup(BoardCreate, BoardDestroy);
|
||||
|
|
|
|||
|
|
@ -15,7 +15,6 @@
|
|||
#include "game/wipe.h"
|
||||
#include "math.h"
|
||||
|
||||
#include "rel_sqrt_consts.h"
|
||||
|
||||
#include "data_num/title.h"
|
||||
|
||||
|
|
|
|||
|
|
@ -21,8 +21,6 @@
|
|||
#include "ext_math.h"
|
||||
#include "math.h"
|
||||
|
||||
#include "rel_sqrt_consts.h"
|
||||
|
||||
#include "REL/instDll.h"
|
||||
|
||||
static s16 lbl_1_data_0 = 1;
|
||||
|
|
|
|||
|
|
@ -17,8 +17,6 @@
|
|||
#include "ext_math.h"
|
||||
#include "math.h"
|
||||
|
||||
#include "rel_sqrt_consts.h"
|
||||
|
||||
float lbl_2_data_0 = -7.1875f;
|
||||
|
||||
s16 lbl_2_data_4[] = { 0, 1, 2, 3, 4, 5, 6, 7 };
|
||||
|
|
|
|||
|
|
@ -22,7 +22,6 @@
|
|||
|
||||
#include "dolphin.h"
|
||||
#include "ext_math.h"
|
||||
#include "rel_sqrt_consts.h"
|
||||
|
||||
#undef ABS
|
||||
#define ABS(x) ((0 > (x)) ? -(x) : (x))
|
||||
|
|
|
|||
|
|
@ -17,7 +17,6 @@
|
|||
#include "game/wipe.h"
|
||||
|
||||
#include "ext_math.h"
|
||||
#include "rel_sqrt_consts.h"
|
||||
|
||||
typedef struct {
|
||||
/* 0x000 */ u8 unk00;
|
||||
|
|
|
|||
|
|
@ -10,7 +10,7 @@
|
|||
#include "game/pad.h"
|
||||
#include "game/sprite.h"
|
||||
#include "game/wipe.h"
|
||||
#include "rel_sqrt_consts.h"
|
||||
|
||||
#include "string.h"
|
||||
|
||||
typedef struct UnkM404Struct {
|
||||
|
|
|
|||
|
|
@ -22,7 +22,6 @@
|
|||
|
||||
#include "dolphin.h"
|
||||
#include "ext_math.h"
|
||||
#include "rel_sqrt_consts.h"
|
||||
|
||||
#undef ABS
|
||||
#define ABS(x) ((0 > (x)) ? -(x) : (x))
|
||||
|
|
|
|||
|
|
@ -5,7 +5,6 @@
|
|||
#include "game/hsfdraw.h"
|
||||
#include "game/minigame_seq.h"
|
||||
#include "game/wipe.h"
|
||||
#include "rel_sqrt_consts.h"
|
||||
|
||||
#include "REL/m406Dll.h"
|
||||
|
||||
|
|
|
|||
|
|
@ -8,8 +8,6 @@
|
|||
#include "game/process.h"
|
||||
#include "math.h"
|
||||
|
||||
#include "rel_sqrt_consts.h"
|
||||
|
||||
#define ARRAY_COUNT(arr) (s32)(sizeof(arr) / sizeof(arr[0]))
|
||||
typedef void (*ObjFuncs)(omObjData *);
|
||||
|
||||
|
|
|
|||
|
|
@ -19,8 +19,6 @@
|
|||
#include "ext_math.h"
|
||||
#include "math.h"
|
||||
|
||||
#include "rel_sqrt_consts.h"
|
||||
|
||||
s32 lbl_1_data_0[] = {
|
||||
DATA_MAKE_NUM(DATADIR_MGCONST, 0x00),
|
||||
DATA_MAKE_NUM(DATADIR_MGCONST, 0x01),
|
||||
|
|
|
|||
|
|
@ -11,7 +11,6 @@
|
|||
#include "game/sprite.h"
|
||||
#include "game/wipe.h"
|
||||
#include "math.h"
|
||||
#include "rel_sqrt_consts.h"
|
||||
|
||||
// bss
|
||||
Process *lbl_1_bss_E8;
|
||||
|
|
|
|||
|
|
@ -5,7 +5,6 @@
|
|||
#include "game/minigame_seq.h"
|
||||
#include "game/object.h"
|
||||
#include "game/wipe.h"
|
||||
#include "rel_sqrt_consts.h"
|
||||
|
||||
#include "REL/m410Dll.h"
|
||||
|
||||
|
|
@ -158,37 +157,36 @@ void fn_1_63C(omObjData *object)
|
|||
return;
|
||||
}
|
||||
switch (var_r31->unk_00) {
|
||||
case 0:
|
||||
WipeCreate(WIPE_MODE_IN, WIPE_TYPE_NORMAL, 60);
|
||||
Hu3DCameraPerspectiveSet(1, 41.5f, 5.0f, 5000.0f, 1.2f);
|
||||
var_r31->unk_00 = 1;
|
||||
var_r31->unk_10 = 0;
|
||||
object->func = fn_1_19C8(lbl_1_bss_28, object);
|
||||
break;
|
||||
case 1:
|
||||
var_r31->unk_00 = 2;
|
||||
var_r31->unk_18 = 0;
|
||||
object->func = fn_1_FF0;
|
||||
break;
|
||||
case 2:
|
||||
var_r31->unk_00 = 3;
|
||||
var_r31->unk_28 = 0;
|
||||
object->func = fn_1_216C(lbl_1_bss_28, object);
|
||||
break;
|
||||
case 3:
|
||||
case 4:
|
||||
var_r31->unk_08 = 1;
|
||||
var_r31->unk_00 = 5;
|
||||
object->func = fn_1_ABC;
|
||||
break;
|
||||
case 5:
|
||||
default:
|
||||
var_r31->unk_00 = 5;
|
||||
object->func = fn_1_DEC;
|
||||
break;
|
||||
case 0:
|
||||
WipeCreate(WIPE_MODE_IN, WIPE_TYPE_NORMAL, 60);
|
||||
Hu3DCameraPerspectiveSet(1, 41.5f, 5.0f, 5000.0f, 1.2f);
|
||||
var_r31->unk_00 = 1;
|
||||
var_r31->unk_10 = 0;
|
||||
object->func = fn_1_19C8(lbl_1_bss_28, object);
|
||||
break;
|
||||
case 1:
|
||||
var_r31->unk_00 = 2;
|
||||
var_r31->unk_18 = 0;
|
||||
object->func = fn_1_FF0;
|
||||
break;
|
||||
case 2:
|
||||
var_r31->unk_00 = 3;
|
||||
var_r31->unk_28 = 0;
|
||||
object->func = fn_1_216C(lbl_1_bss_28, object);
|
||||
break;
|
||||
case 3:
|
||||
case 4:
|
||||
var_r31->unk_08 = 1;
|
||||
var_r31->unk_00 = 5;
|
||||
object->func = fn_1_ABC;
|
||||
break;
|
||||
case 5:
|
||||
default:
|
||||
var_r31->unk_00 = 5;
|
||||
object->func = fn_1_DEC;
|
||||
break;
|
||||
}
|
||||
var_r31->unk_04 = 0;
|
||||
|
||||
}
|
||||
|
||||
void fn_1_7A8(omObjData *object)
|
||||
|
|
@ -233,38 +231,36 @@ void fn_1_FF0(omObjData *object)
|
|||
|
||||
fn_1_5A8(object);
|
||||
switch (var_r29->unk_14) {
|
||||
case 0:
|
||||
var_r29->unk_1C = 30;
|
||||
var_r29->unk_20 = 60;
|
||||
lbl_1_bss_14 = MGSeqCreate(3, 0);
|
||||
MGSeqPosSet(lbl_1_bss_14, 320.0f, 240.0f);
|
||||
CRot.x = -11.2f;
|
||||
CRot.y = CRot.z = 0.0f;
|
||||
Center.x = 0.0f;
|
||||
Center.y = 367.0f;
|
||||
Center.z = 252.0f;
|
||||
CZoom = 592.0f;
|
||||
var_r29->unk_14 = 1;
|
||||
var_r29->unk_18 = 0;
|
||||
break;
|
||||
|
||||
case 1:
|
||||
if (lbl_1_bss_4 < 0 && MGSeqStatGet(lbl_1_bss_14) & 16) {
|
||||
lbl_1_bss_4 = HuAudSeqPlay(71);
|
||||
}
|
||||
if (!MGSeqStatGet(lbl_1_bss_14) && !var_r29->unk_08) {
|
||||
lbl_1_bss_1C = MGSeqCreate(1, var_r29->unk_1C, -1, -1);
|
||||
var_r29->unk_14 = 2;
|
||||
var_r29->unk_18 = 0;
|
||||
object->func = fn_1_139C;
|
||||
}
|
||||
break;
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
case 0:
|
||||
var_r29->unk_1C = 30;
|
||||
var_r29->unk_20 = 60;
|
||||
lbl_1_bss_14 = MGSeqCreate(3, 0);
|
||||
MGSeqPosSet(lbl_1_bss_14, 320.0f, 240.0f);
|
||||
CRot.x = -11.2f;
|
||||
CRot.y = CRot.z = 0.0f;
|
||||
Center.x = 0.0f;
|
||||
Center.y = 367.0f;
|
||||
Center.z = 252.0f;
|
||||
CZoom = 592.0f;
|
||||
var_r29->unk_14 = 1;
|
||||
var_r29->unk_18 = 0;
|
||||
break;
|
||||
|
||||
|
||||
case 1:
|
||||
if (lbl_1_bss_4 < 0 && MGSeqStatGet(lbl_1_bss_14) & 16) {
|
||||
lbl_1_bss_4 = HuAudSeqPlay(71);
|
||||
}
|
||||
if (!MGSeqStatGet(lbl_1_bss_14) && !var_r29->unk_08) {
|
||||
lbl_1_bss_1C = MGSeqCreate(1, var_r29->unk_1C, -1, -1);
|
||||
var_r29->unk_14 = 2;
|
||||
var_r29->unk_18 = 0;
|
||||
object->func = fn_1_139C;
|
||||
}
|
||||
break;
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
void fn_1_139C(omObjData *object)
|
||||
|
|
|
|||
|
|
@ -18,7 +18,6 @@
|
|||
|
||||
#include "dolphin.h"
|
||||
#include "ext_math.h"
|
||||
#include "rel_sqrt_consts.h"
|
||||
|
||||
typedef struct {
|
||||
/* 0x00 */ s16 unk00;
|
||||
|
|
|
|||
|
|
@ -12,7 +12,6 @@
|
|||
#include "game/sprite.h"
|
||||
#include "game/wipe.h"
|
||||
#include "math.h"
|
||||
#include "rel_sqrt_consts.h"
|
||||
|
||||
// bss
|
||||
s16 lbl_1_bss_7A0;
|
||||
|
|
|
|||
|
|
@ -14,8 +14,6 @@
|
|||
|
||||
#include "ext_math.h"
|
||||
|
||||
#include "rel_sqrt_consts.h"
|
||||
|
||||
typedef struct struct_bss_2A6C StructBss2A6C;
|
||||
|
||||
typedef struct struct_sp_14C8 StructSp14C8;
|
||||
|
|
|
|||
|
|
@ -9,7 +9,6 @@
|
|||
#include "game/pad.h"
|
||||
#include "game/sprite.h"
|
||||
#include "game/wipe.h"
|
||||
#include "rel_sqrt_consts.h"
|
||||
|
||||
typedef struct UnkM414Struct {
|
||||
s32 unk00;
|
||||
|
|
|
|||
|
|
@ -15,7 +15,6 @@
|
|||
#include "game/sprite.h"
|
||||
#include "game/wipe.h"
|
||||
#include "math.h"
|
||||
#include "rel_sqrt_consts.h"
|
||||
|
||||
// bss
|
||||
unkStruct5 lbl_1_bss_36C;
|
||||
|
|
|
|||
|
|
@ -17,8 +17,6 @@
|
|||
|
||||
#include "REL/m416Dll.h"
|
||||
|
||||
#include "rel_sqrt_consts.h"
|
||||
|
||||
typedef struct camera_view_params {
|
||||
float zoom;
|
||||
Vec pos;
|
||||
|
|
|
|||
|
|
@ -3,7 +3,6 @@
|
|||
#include "game/hsfdraw.h"
|
||||
#include "game/minigame_seq.h"
|
||||
#include "game/wipe.h"
|
||||
#include "rel_sqrt_consts.h"
|
||||
|
||||
#include "REL/m417Dll.h"
|
||||
|
||||
|
|
|
|||
|
|
@ -7,7 +7,6 @@
|
|||
#include "game/pad.h"
|
||||
#include "game/printfunc.h"
|
||||
#include "game/wipe.h"
|
||||
#include "rel_sqrt_consts.h"
|
||||
|
||||
#include "REL/m420dll.h"
|
||||
|
||||
|
|
|
|||
|
|
@ -10,7 +10,7 @@
|
|||
#include "game/pad.h"
|
||||
#include "game/sprite.h"
|
||||
#include "game/wipe.h"
|
||||
#include "rel_sqrt_consts.h"
|
||||
#include "string.h"
|
||||
|
||||
typedef struct UnkM426Struct {
|
||||
/* 0x00 */ s32 unk_00;
|
||||
|
|
@ -677,7 +677,7 @@ void fn_1_117C(omObjData *object)
|
|||
fn_1_16F8(var_r31->unk_04[0]);
|
||||
}
|
||||
|
||||
void fn_1_11EC(omObjData *object) // TODO this probably gets inlined
|
||||
void fn_1_11EC(omObjData *object)
|
||||
{
|
||||
s32 var_r30;
|
||||
UnkM426Struct *var_r29;
|
||||
|
|
@ -779,6 +779,7 @@ void fn_1_125C(omObjData *object)
|
|||
object->func = NULL;
|
||||
}
|
||||
|
||||
// TODO https://decomp.me/scratch/1aZdv
|
||||
void fn_1_16F8(omObjData *object)
|
||||
{
|
||||
s32 spA8[3];
|
||||
|
|
@ -825,7 +826,7 @@ void fn_1_16F8(omObjData *object)
|
|||
}
|
||||
if (var_r31->unk_14) {
|
||||
sp20 = sp1C = 0.0f;
|
||||
sp10 = var_r21 = 0;
|
||||
sp10 = 0;
|
||||
fn_1_2F5C(object, &sp20, &sp1C, &sp10);
|
||||
}
|
||||
else {
|
||||
|
|
@ -849,7 +850,7 @@ void fn_1_16F8(omObjData *object)
|
|||
if (!lbl_1_bss_40) {
|
||||
sp20 = sp1C = 0.0f;
|
||||
|
||||
sp10 = var_r21 = 0;
|
||||
sp10 = 0;
|
||||
}
|
||||
if (fabs(sp20) > 8.0) {
|
||||
var_f30 = 0.25f * sp20;
|
||||
|
|
@ -958,7 +959,6 @@ void fn_1_16F8(omObjData *object)
|
|||
else {
|
||||
if (fabs(sp20) > 8.0 || fabs(sp1C) > 8.0) {
|
||||
var_f26 = atan2d(sp20, -sp1C);
|
||||
var_f26 = var_f26;
|
||||
}
|
||||
else {
|
||||
var_f26 = object->rot.y;
|
||||
|
|
@ -1124,7 +1124,7 @@ void fn_1_16F8(omObjData *object)
|
|||
var_r31->unk_34 = var_r31->unk_34 ^ 1;
|
||||
}
|
||||
}
|
||||
if (((var_r21 = var_r31->unk_24) == 0 || var_r31->unk_24 == 1 || var_r31->unk_24 == 2) && var_r31->unk_30) {
|
||||
if ((var_r31->unk_24 == 0 || var_r31->unk_24 == 1 || var_r31->unk_24 == 2) && var_r31->unk_30) {
|
||||
if (var_r31->unk_30) {
|
||||
var_r31->unk_30 = var_r31->unk_30 - 1;
|
||||
}
|
||||
|
|
@ -1137,6 +1137,7 @@ void fn_1_16F8(omObjData *object)
|
|||
}
|
||||
Hu3DModelTPLvlSet(var_r24, 1.0f);
|
||||
}
|
||||
(void)var_r21;
|
||||
}
|
||||
|
||||
Vec lbl_1_data_200[2] = {
|
||||
|
|
@ -1203,22 +1204,10 @@ void fn_1_2AC8(omObjData *object)
|
|||
|
||||
void fn_1_2ADC(void)
|
||||
{
|
||||
omObjData *var_r31;
|
||||
s32 var_r30;
|
||||
s32 var_r29;
|
||||
UnkM426Struct *var_r27;
|
||||
omObjData *var_r28;
|
||||
|
||||
for (var_r30 = 0; var_r30 < 2; var_r30++) {
|
||||
var_r31 = lbl_1_bss_8C[var_r30];
|
||||
var_r27 = var_r31->data;
|
||||
for (var_r29 = 0; var_r29 < 2; var_r29++) {
|
||||
var_r28 = var_r27->unk_04[var_r29];
|
||||
var_r28->data = 0;
|
||||
var_r28->func = 0;
|
||||
}
|
||||
var_r31->data = NULL;
|
||||
var_r31->func = NULL;
|
||||
fn_1_11EC(lbl_1_bss_8C[var_r30]);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -1742,8 +1731,7 @@ void fn_1_3EFC(omObjData *object)
|
|||
void fn_1_45FC(omObjData *object)
|
||||
{
|
||||
fn_1_8E10(lbl_1_bss_24);
|
||||
object->data = NULL;
|
||||
object->func = NULL;
|
||||
fn_1_2AC8(object);
|
||||
}
|
||||
|
||||
void fn_1_4644(void)
|
||||
|
|
@ -2134,20 +2122,17 @@ void fn_1_5134(omObjData *object)
|
|||
|
||||
void fn_1_5B34(omObjData *object)
|
||||
{
|
||||
object->data = NULL;
|
||||
object->func = NULL;
|
||||
fn_1_2AC8(object);
|
||||
}
|
||||
|
||||
void fn_1_5B48(void)
|
||||
{
|
||||
omObjData *var_r31;
|
||||
|
||||
var_r31 = lbl_1_bss_74;
|
||||
fn_1_5B34(var_r31);
|
||||
fn_1_5B34(lbl_1_bss_74);
|
||||
lbl_1_bss_74 = NULL;
|
||||
}
|
||||
|
||||
void fn_1_5B88(s32 arg0) // probably gets inlined
|
||||
// unused
|
||||
void fn_1_5B88(s32 arg0)
|
||||
{
|
||||
UnkM426Struct4 *var_r31;
|
||||
s32 var_r28;
|
||||
|
|
|
|||
|
|
@ -21,7 +21,6 @@
|
|||
#include "game/sprite.h"
|
||||
|
||||
#include "ext_math.h"
|
||||
#include "rel_sqrt_consts.h"
|
||||
|
||||
#undef ABS
|
||||
#define ABS(x) ((0 > (x)) ? -(x) : (x))
|
||||
|
|
|
|||
|
|
@ -16,8 +16,6 @@
|
|||
|
||||
#include "REL/m431Dll.h"
|
||||
|
||||
#include "rel_sqrt_consts.h"
|
||||
|
||||
typedef struct bss_5C_struct {
|
||||
s16 unk0[6];
|
||||
s16 unkC[2];
|
||||
|
|
|
|||
File diff suppressed because it is too large
Load diff
|
|
@ -6,15 +6,12 @@
|
|||
#include "game/sprite.h"
|
||||
#include "game/wipe.h"
|
||||
|
||||
|
||||
#include "REL/m434Dll.h"
|
||||
#include "ext_math.h"
|
||||
#include "game/gamework_data.h"
|
||||
#include "game/minigame_seq.h"
|
||||
#include "math.h"
|
||||
|
||||
#include "rel_sqrt_consts.h"
|
||||
|
||||
typedef struct camera_view {
|
||||
float zoom;
|
||||
Vec pos;
|
||||
|
|
|
|||
File diff suppressed because it is too large
Load diff
|
|
@ -16,7 +16,7 @@
|
|||
#include "game/wipe.h"
|
||||
|
||||
#include "dolphin.h"
|
||||
#include "rel_sqrt_consts.h"
|
||||
#include "math.h"
|
||||
#include "string.h"
|
||||
|
||||
typedef struct {
|
||||
|
|
@ -1716,7 +1716,6 @@ void fn_1_6580(s32 arg0, s32 arg1, s32 arg2)
|
|||
|
||||
float lbl_1_data_188 = -1.0f;
|
||||
|
||||
// TODO: https://decomp.me/scratch/dek39
|
||||
void fn_1_65E0(omObjData *arg0)
|
||||
{
|
||||
Mtx sp60;
|
||||
|
|
@ -1835,7 +1834,8 @@ void fn_1_65E0(omObjData *arg0)
|
|||
break;
|
||||
}
|
||||
if ((temp_r31->unk0C == 4 || temp_r31->unk0C == 7) && temp_r31->unk10 == 0) {
|
||||
Hu3DModelObjMtxGet(lbl_1_bss_8FC.unk00->model[0], "m437a01-chara-point", sp60);
|
||||
StructBss8FC *temp = &lbl_1_bss_8FC;
|
||||
Hu3DModelObjMtxGet(temp->unk00->model[0], "m437a01-chara-point", sp60);
|
||||
arg0->trans.y = sp60[1][3];
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -9,7 +9,6 @@
|
|||
#include "game/pad.h"
|
||||
#include "game/sprite.h"
|
||||
#include "game/wipe.h"
|
||||
#include "rel_sqrt_consts.h"
|
||||
|
||||
#include "REL/m438Dll.h"
|
||||
|
||||
|
|
|
|||
|
|
@ -20,8 +20,6 @@
|
|||
|
||||
#include "ext_math.h"
|
||||
|
||||
#include "rel_sqrt_consts.h"
|
||||
|
||||
#include "REL/m439data.h"
|
||||
|
||||
typedef struct camera_params {
|
||||
|
|
|
|||
|
|
@ -12,7 +12,7 @@
|
|||
#include "game/sprite.h"
|
||||
#include "game/wipe.h"
|
||||
#include "math.h"
|
||||
#include "rel_sqrt_consts.h"
|
||||
|
||||
#include "string.h"
|
||||
|
||||
// bss
|
||||
|
|
|
|||
|
|
@ -21,7 +21,6 @@
|
|||
#include "game/sprite.h"
|
||||
|
||||
#include "ext_math.h"
|
||||
#include "rel_sqrt_consts.h"
|
||||
|
||||
#undef ABS
|
||||
#define ABS(x) ((0 > (x)) ? -(x) : (x))
|
||||
|
|
|
|||
|
|
@ -12,7 +12,6 @@
|
|||
#include "game/pad.h"
|
||||
#include "game/sprite.h"
|
||||
#include "game/wipe.h"
|
||||
#include "rel_sqrt_consts.h"
|
||||
|
||||
#include "REL/m442Dll.h"
|
||||
|
||||
|
|
|
|||
|
|
@ -11,7 +11,7 @@
|
|||
#include "game/sprite.h"
|
||||
#include "game/wipe.h"
|
||||
#include "math.h"
|
||||
#include "rel_sqrt_consts.h"
|
||||
|
||||
#include "string.h"
|
||||
|
||||
#ifndef __MWERKS__
|
||||
|
|
@ -806,7 +806,6 @@ void fn_1_3770(omObjData *arg0)
|
|||
s32 var_r30;
|
||||
s32 var_r29;
|
||||
M443DllCameraStruct *var_r28;
|
||||
omObjData *var_r27;
|
||||
s32 var_r26;
|
||||
u32 var_r25;
|
||||
s32 var_r24;
|
||||
|
|
|
|||
|
|
@ -19,8 +19,6 @@
|
|||
#include "ext_math.h"
|
||||
#include "math.h"
|
||||
|
||||
#include "rel_sqrt_consts.h"
|
||||
|
||||
typedef struct camera_view_params {
|
||||
Vec rot;
|
||||
Vec pos;
|
||||
|
|
|
|||
|
|
@ -18,7 +18,6 @@
|
|||
|
||||
#include "dolphin.h"
|
||||
#include "ext_math.h"
|
||||
#include "rel_sqrt_consts.h"
|
||||
|
||||
typedef struct {
|
||||
/* 0x00 */ s16 unk00;
|
||||
|
|
|
|||
|
|
@ -1,5 +1,5 @@
|
|||
#include "REL/m446Dll.h"
|
||||
#include "rel_sqrt_consts.h"
|
||||
#include "math.h"
|
||||
|
||||
#include "game/audio.h"
|
||||
#include "game/frand.h"
|
||||
|
|
|
|||
|
|
@ -11,7 +11,7 @@
|
|||
#include "game/window.h"
|
||||
#include "game/wipe.h"
|
||||
|
||||
#include "rel_sqrt_consts.h"
|
||||
#include "math.h"
|
||||
|
||||
typedef struct {
|
||||
/* 0x00 */ s16 unk00;
|
||||
|
|
|
|||
|
|
@ -20,7 +20,6 @@
|
|||
|
||||
#include "dolphin.h"
|
||||
#include "ext_math.h"
|
||||
#include "rel_sqrt_consts.h"
|
||||
|
||||
typedef struct {
|
||||
/* 0x00 */ s32 unk00;
|
||||
|
|
|
|||
|
|
@ -31,7 +31,6 @@
|
|||
#include "game/sprite.h"
|
||||
|
||||
#include "ext_math.h"
|
||||
#include "rel_sqrt_consts.h"
|
||||
|
||||
#include "game/window.h"
|
||||
#include "string.h"
|
||||
|
|
@ -930,7 +929,7 @@ void fn_1_2C1C(WorkPlayerOld *player, omObjData *obj, s32 arg2, s32 arg3, s32 *a
|
|||
player->unk_10 = NULL;
|
||||
player->unk_50 = NULL;
|
||||
player->unk_64 = 0;
|
||||
player->unk_68 = 0;
|
||||
player->unk_68 = NULL;
|
||||
player->unk_38 = 0;
|
||||
player->unk_3C = 0;
|
||||
player->unk_44 = arg5;
|
||||
|
|
@ -978,7 +977,7 @@ void fn_1_2DC8(WorkPlayerOld *player, s32 count, Vec *data)
|
|||
void fn_1_2DD4(WorkPlayerOld *player)
|
||||
{
|
||||
omSetTra(player->unk_00, player->unk_6C.x, player->unk_6C.y, player->unk_6C.z);
|
||||
omSetRot(player->unk_00, 0, player->unk_9C, 0);
|
||||
omSetRot(player->unk_00, 0.0f, player->unk_9C, 0.0f);
|
||||
}
|
||||
|
||||
void fn_1_2E34(WorkPlayerOld *player)
|
||||
|
|
@ -1123,12 +1122,7 @@ void fn_1_3CE0(WorkPlayerOld *player, s32 *state, u32 *motAttr)
|
|||
}
|
||||
|
||||
if (player->unk_14[3] >= 0 && (player->unk_28 & 0x100)) {
|
||||
player->unk_38 = 1;
|
||||
player->unk_84.y = 26.766666f;
|
||||
player->unk_A4 = 1;
|
||||
if (player->unk_3C & 0x2) {
|
||||
player->unk_3C &= ~0x2;
|
||||
}
|
||||
fn_1_2BD0(player, 26.766666f, 1.0f);
|
||||
*motAttr = HU3D_MOTATTR_NONE;
|
||||
*state = 3;
|
||||
}
|
||||
|
|
@ -1181,12 +1175,7 @@ void fn_1_3ECC(WorkPlayerOld *player, s32 *state, u32 *motAttr)
|
|||
void fn_1_3F84(WorkPlayerOld *player, s32 *state, u32 *motAttr)
|
||||
{
|
||||
if (Hu3DMotionShiftIDGet(player->unk_00->model[0]) < 0 && Hu3DMotionEndCheck(player->unk_00->model[0])) {
|
||||
player->unk_38 = 1;
|
||||
player->unk_84.y = 0;
|
||||
player->unk_A4 = 0;
|
||||
if (player->unk_3C & 0x2) {
|
||||
player->unk_3C &= ~0x2;
|
||||
}
|
||||
fn_1_2BD0(player, 0.0f, 0.0f);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -1352,12 +1341,8 @@ void fn_1_40C0(WorkPlayerOld *player)
|
|||
player->unk_3C |= 0x800;
|
||||
}
|
||||
else {
|
||||
player->unk_38 = 1;
|
||||
player->unk_84.y = 0.0f;
|
||||
player->unk_A4 = 0.0f;
|
||||
if ((player->unk_3C & 2) != 0) {
|
||||
player->unk_3C &= ~2;
|
||||
}
|
||||
fn_1_2BD0(player, 0.0f, 0.0f);
|
||||
|
||||
motAttr = HU3D_MOTATTR_NONE;
|
||||
state = 3;
|
||||
}
|
||||
|
|
@ -6582,12 +6567,7 @@ s32 fn_1_1C898(UnkM450Struct5 *var_r31, omObjData *var_r30)
|
|||
HuAudCharVoicePlay(var_r31->unk_11C, 0x123);
|
||||
var_r31->unk_FC |= 0x10;
|
||||
var_r31->unk_00.unk_3C |= 0x210;
|
||||
var_r31->unk_00.unk_38 = 1;
|
||||
var_r31->unk_00.unk_84.y = 48.179996f;
|
||||
var_r31->unk_00.unk_A4 = 0.0f;
|
||||
if (var_r31->unk_00.unk_3C & 2) {
|
||||
var_r31->unk_00.unk_3C &= ~0x2;
|
||||
}
|
||||
fn_1_2BD0(&var_r31->unk_00, 48.179996f, 0.0f);
|
||||
Hu3DMotionShiftSet(var_r30->model[0], var_r30->motion[8], 0.0f, 8.0f, 0);
|
||||
if (fn_1_125C0(0, 1) <= 0) {
|
||||
var_r31->unk_FC |= 0x80000;
|
||||
|
|
@ -6599,12 +6579,7 @@ s32 fn_1_1C898(UnkM450Struct5 *var_r31, omObjData *var_r30)
|
|||
HuAudCharVoicePlay(var_r31->unk_11C, 0x123);
|
||||
var_r31->unk_FC |= 0x100;
|
||||
var_r31->unk_00.unk_3C |= 0x210;
|
||||
var_r31->unk_00.unk_38 = 1;
|
||||
var_r31->unk_00.unk_84.y = 0.0f;
|
||||
var_r31->unk_00.unk_A4 = 0.0f;
|
||||
if (var_r31->unk_00.unk_3C & 2) {
|
||||
var_r31->unk_00.unk_3C &= ~0x2;
|
||||
}
|
||||
fn_1_2BD0(&var_r31->unk_00, 0.0f, 0.0f);
|
||||
if (fn_1_125C0(0, 1) <= 0) {
|
||||
var_r31->unk_FC |= 0x80000;
|
||||
}
|
||||
|
|
@ -6715,12 +6690,7 @@ void fn_1_1E150(omObjData *var_r29)
|
|||
HuAudCharVoicePlay(var_r31->unk_11C, 0x123);
|
||||
var_r31->unk_FC |= 0x800000;
|
||||
var_r31->unk_118 = 0x7EB;
|
||||
var_r31->unk_00.unk_38 = 1;
|
||||
var_r31->unk_00.unk_84.y = 53.533333f;
|
||||
var_r31->unk_00.unk_A4 = 0.0f;
|
||||
if (var_r31->unk_00.unk_3C & 2) {
|
||||
var_r31->unk_00.unk_3C &= ~0x2;
|
||||
}
|
||||
fn_1_2BD0(&var_r31->unk_00, 53.533333f, 0.0f);
|
||||
Hu3DMotionSet(var_r29->model[0], var_r29->motion[8]);
|
||||
Hu3DModelAttrReset(var_r29->model[0], HU3D_ATTR_DISPOFF);
|
||||
fn_1_125C0(0, 0);
|
||||
|
|
@ -7129,12 +7099,7 @@ void fn_1_20170(omObjData *var_r30)
|
|||
var_r29->unk_00.unk_A8 = MapPos(
|
||||
var_r29->unk_00.unk_6C.x, var_r29->unk_00.unk_6C.y, var_r29->unk_00.unk_6C.z, var_r29->unk_00.unk_C0, &var_r29->unk_00.unk_AC);
|
||||
if (var_r29->unk_00.unk_A8 > var_r29->unk_00.unk_6C.y) {
|
||||
var_r31->unk_00.unk_38 = 1;
|
||||
var_r31->unk_00.unk_84.y = 53.533333f;
|
||||
var_r31->unk_00.unk_A4 = 0.0f;
|
||||
if (var_r31->unk_00.unk_3C & 2) {
|
||||
var_r31->unk_00.unk_3C &= ~2;
|
||||
}
|
||||
fn_1_2BD0(&var_r31->unk_00, 53.533333f, 0.0f);
|
||||
}
|
||||
var_f31 = var_r29->unk_00.unk_6C.x;
|
||||
var_f30 = var_r29->unk_00.unk_6C.z;
|
||||
|
|
|
|||
|
|
@ -17,8 +17,6 @@
|
|||
|
||||
#include "game/gamework_data.h"
|
||||
|
||||
#include "rel_sqrt_consts.h"
|
||||
|
||||
typedef struct bss_348_data {
|
||||
s16 unk0[5];
|
||||
s16 unkA;
|
||||
|
|
|
|||
|
|
@ -12,7 +12,7 @@
|
|||
#include "game/pad.h"
|
||||
#include "game/sprite.h"
|
||||
#include "game/wipe.h"
|
||||
#include "rel_sqrt_consts.h"
|
||||
|
||||
#include "string.h"
|
||||
|
||||
#include "REL/m453Dll.h"
|
||||
|
|
|
|||
|
|
@ -1,25 +1,24 @@
|
|||
#include "game/hsfdraw.h"
|
||||
#include "game/hsfman.h"
|
||||
#include "game/object.h"
|
||||
#include "game/objsub.h"
|
||||
#include "game/hsfman.h"
|
||||
#include "game/hsfdraw.h"
|
||||
|
||||
|
||||
#include "game/hsfmotion.h"
|
||||
#include "game/pad.h"
|
||||
|
||||
#include "game/wipe.h"
|
||||
#include "game/frand.h"
|
||||
#include "game/audio.h"
|
||||
#include "game/minigame_seq.h"
|
||||
#include "game/gamework_data.h"
|
||||
#include "game/chrman.h"
|
||||
#include "REL/m455Dll.h"
|
||||
#include "game/audio.h"
|
||||
#include "game/chrman.h"
|
||||
#include "game/frand.h"
|
||||
#include "game/gamework_data.h"
|
||||
#include "game/minigame_seq.h"
|
||||
#include "game/wipe.h"
|
||||
|
||||
|
||||
#include "ext_math.h"
|
||||
#include "math.h"
|
||||
|
||||
#include "rel_sqrt_consts.h"
|
||||
|
||||
|
||||
typedef struct camera_view_params {
|
||||
float zoom;
|
||||
Vec pos;
|
||||
|
|
@ -51,7 +50,6 @@ Vec lbl_1_bss_8;
|
|||
s16 lbl_1_bss_4;
|
||||
s32 lbl_1_bss_0;
|
||||
|
||||
|
||||
void fn_1_330(omObjData *object);
|
||||
void fn_1_B94(Process *objman);
|
||||
void fn_1_2A90(Process *objman);
|
||||
|
|
@ -68,9 +66,9 @@ void ObjectSetup(void)
|
|||
Hu3DCameraPerspectiveSet(HU3D_CAM0, -1, 20, 25000, 1.2f);
|
||||
Hu3DCameraViewportSet(HU3D_CAM0, 0, 0, 640, 480, 0, 1);
|
||||
lbl_1_bss_3C = omAddObjEx(objman, 32730, 0, 0, -1, omOutView);
|
||||
lbl_1_bss_8.x = lbl_1_data_44.x-lbl_1_data_38.x;
|
||||
lbl_1_bss_8.y = lbl_1_data_44.y-lbl_1_data_38.y;
|
||||
lbl_1_bss_8.z = lbl_1_data_44.z-lbl_1_data_38.z;
|
||||
lbl_1_bss_8.x = lbl_1_data_44.x - lbl_1_data_38.x;
|
||||
lbl_1_bss_8.y = lbl_1_data_44.y - lbl_1_data_38.y;
|
||||
lbl_1_bss_8.z = lbl_1_data_44.z - lbl_1_data_38.z;
|
||||
PSVECNormalize(&lbl_1_bss_8, &lbl_1_bss_8);
|
||||
light = Hu3DGLightCreateV(&lbl_1_data_38, &lbl_1_bss_8, &lbl_1_data_50);
|
||||
Hu3DGLightInfinitytSet(light);
|
||||
|
|
@ -107,7 +105,7 @@ void fn_1_330(omObjData *object)
|
|||
lbl_1_bss_24 = 60;
|
||||
lbl_1_bss_22 = -1;
|
||||
lbl_1_bss_20 = 0;
|
||||
lbl_1_bss_16 = ((frand16()*270.0f)/65536.0f)+30.0f;
|
||||
lbl_1_bss_16 = ((frand16() * 270.0f) / 65536.0f) + 30.0f;
|
||||
WipeCreate(WIPE_MODE_IN, WIPE_TYPE_NORMAL, 60);
|
||||
camera->fov = 30.0f;
|
||||
object->func = fn_1_478;
|
||||
|
|
@ -152,115 +150,114 @@ s16 lbl_1_data_90 = -1;
|
|||
s32 lbl_1_data_94 = -1;
|
||||
s32 lbl_1_data_98 = -1;
|
||||
|
||||
|
||||
|
||||
void fn_1_478(omObjData *object)
|
||||
{
|
||||
s32 i;
|
||||
omObjData **playerList;
|
||||
M455Player *player;
|
||||
|
||||
switch(fn_1_320()) {
|
||||
|
||||
switch (fn_1_320()) {
|
||||
case 0:
|
||||
if(lbl_1_data_98 < 0) {
|
||||
if (lbl_1_data_98 < 0) {
|
||||
lbl_1_data_98 = HuAudFXPlay(1985);
|
||||
}
|
||||
if(--lbl_1_bss_2C == 0) {
|
||||
if (--lbl_1_bss_2C == 0) {
|
||||
fn_1_310(1);
|
||||
lbl_1_bss_2C = 120;
|
||||
}
|
||||
break;
|
||||
|
||||
|
||||
case 1:
|
||||
if(--lbl_1_bss_2C == 0) {
|
||||
if (--lbl_1_bss_2C == 0) {
|
||||
fn_1_310(2);
|
||||
lbl_1_bss_4 = MGSeqStartCreate();
|
||||
}
|
||||
break;
|
||||
|
||||
|
||||
case 2:
|
||||
if(!MGSeqStatGet(lbl_1_bss_4)) {
|
||||
if (!MGSeqStatGet(lbl_1_bss_4)) {
|
||||
fn_1_310(3);
|
||||
}
|
||||
if(lbl_1_data_94 < 0 && (MGSeqStatGet(lbl_1_bss_4) & 0x10)) {
|
||||
if (lbl_1_data_94 < 0 && (MGSeqStatGet(lbl_1_bss_4) & 0x10)) {
|
||||
lbl_1_data_94 = HuAudSeqPlay(60);
|
||||
}
|
||||
break;
|
||||
|
||||
|
||||
case 3:
|
||||
if(--lbl_1_bss_24 == 0) {
|
||||
if (--lbl_1_bss_24 == 0) {
|
||||
lbl_1_bss_26--;
|
||||
if(lbl_1_data_90 >= 0) {
|
||||
if (lbl_1_data_90 >= 0) {
|
||||
MGSeqParamSet(lbl_1_data_90, 1, lbl_1_bss_26);
|
||||
}
|
||||
lbl_1_bss_24 = 60;
|
||||
if(lbl_1_bss_26 == 10) {
|
||||
if (lbl_1_bss_26 == 10) {
|
||||
lbl_1_data_90 = MGSeqTimerCreate(10);
|
||||
}
|
||||
}
|
||||
if(lbl_1_bss_16 >= 0) {
|
||||
if (lbl_1_bss_16 >= 0) {
|
||||
lbl_1_bss_16--;
|
||||
}
|
||||
if(lbl_1_bss_26 == 0 || fn_1_C90()) {
|
||||
if (lbl_1_bss_26 == 0 || fn_1_C90()) {
|
||||
fn_1_310(4);
|
||||
lbl_1_bss_4 = MGSeqFinishCreate();
|
||||
HuAudSeqFadeOut(lbl_1_data_94, 100);
|
||||
}
|
||||
break;
|
||||
|
||||
|
||||
case 4:
|
||||
if(lbl_1_data_90 >= 0) {
|
||||
if (lbl_1_data_90 >= 0) {
|
||||
MGSeqParamSet(lbl_1_data_90, 2, -1);
|
||||
lbl_1_data_90 = -1;
|
||||
}
|
||||
if(!MGSeqStatGet(lbl_1_bss_4)) {
|
||||
if (!MGSeqStatGet(lbl_1_bss_4)) {
|
||||
fn_1_310(7);
|
||||
lbl_1_bss_2C = 120;
|
||||
}
|
||||
break;
|
||||
|
||||
|
||||
case 7:
|
||||
if(--lbl_1_bss_2C == 0) {
|
||||
if (--lbl_1_bss_2C == 0) {
|
||||
fn_1_310(9);
|
||||
if(lbl_1_bss_30 >= 0) {
|
||||
if (lbl_1_bss_30 >= 0) {
|
||||
HuAudSStreamPlay(1);
|
||||
playerList = omGetGroupMemberListEx(HuPrcCurrentGet(), 0);
|
||||
for(i=0; i<4; i++) {
|
||||
for (i = 0; i < 4; i++) {
|
||||
player = playerList[i]->data;
|
||||
if(player->unk28 < 0) {
|
||||
GWPlayerCoinWinSet(i, lbl_1_bss_22+1);
|
||||
if (player->unk28 < 0) {
|
||||
GWPlayerCoinWinSet(i, lbl_1_bss_22 + 1);
|
||||
}
|
||||
}
|
||||
} else {
|
||||
}
|
||||
else {
|
||||
HuAudSStreamPlay(4);
|
||||
for(i=0; i<4; i++) {
|
||||
for (i = 0; i < 4; i++) {
|
||||
GWPlayerCoinWinSet(i, 3);
|
||||
}
|
||||
}
|
||||
lbl_1_bss_2C = 210;
|
||||
}
|
||||
break;
|
||||
|
||||
|
||||
case 9:
|
||||
if(--lbl_1_bss_2C == 0) {
|
||||
if (--lbl_1_bss_2C == 0) {
|
||||
WipeCreate(WIPE_MODE_OUT, WIPE_TYPE_NORMAL, 60);
|
||||
HuAudFXStop(lbl_1_data_98);
|
||||
object->func = fn_1_B38;
|
||||
}
|
||||
break;
|
||||
}
|
||||
if(lbl_1_bss_20) {
|
||||
if(lbl_1_bss_20 >= 2) {
|
||||
for(i=0; i<100; i++){
|
||||
s32 srcIdx = (frand8()*lbl_1_bss_20) >> 8;
|
||||
s32 dstIdx = (frand8()*lbl_1_bss_20) >> 8;
|
||||
if (lbl_1_bss_20) {
|
||||
if (lbl_1_bss_20 >= 2) {
|
||||
for (i = 0; i < 100; i++) {
|
||||
s32 srcIdx = (frand8() * lbl_1_bss_20) >> 8;
|
||||
s32 dstIdx = (frand8() * lbl_1_bss_20) >> 8;
|
||||
s32 temp = lbl_1_bss_18[srcIdx];
|
||||
lbl_1_bss_18[srcIdx] = lbl_1_bss_18[dstIdx];
|
||||
lbl_1_bss_18[dstIdx] = temp;
|
||||
}
|
||||
}
|
||||
playerList = omGetGroupMemberListEx(HuPrcCurrentGet(), 0);
|
||||
for(i=0; i<lbl_1_bss_20; i++) {
|
||||
for (i = 0; i < lbl_1_bss_20; i++) {
|
||||
lbl_1_bss_22++;
|
||||
GWPlayerCoinWinSet(lbl_1_bss_18[i], lbl_1_bss_22);
|
||||
player = playerList[lbl_1_bss_18[i]]->data;
|
||||
|
|
@ -268,7 +265,7 @@ void fn_1_478(omObjData *object)
|
|||
}
|
||||
lbl_1_bss_20 = 0;
|
||||
}
|
||||
if(omSysExitReq && !WipeStatGet()) {
|
||||
if (omSysExitReq && !WipeStatGet()) {
|
||||
WipeCreate(WIPE_MODE_OUT, WIPE_TYPE_NORMAL, 60);
|
||||
object->func = fn_1_B38;
|
||||
}
|
||||
|
|
@ -276,7 +273,7 @@ void fn_1_478(omObjData *object)
|
|||
|
||||
void fn_1_B38(omObjData *object)
|
||||
{
|
||||
if(WipeStatGet()) {
|
||||
if (WipeStatGet()) {
|
||||
return;
|
||||
}
|
||||
fn_1_C28();
|
||||
|
|
@ -295,9 +292,8 @@ void fn_1_B94(Process *objman)
|
|||
lbl_1_bss_28 = 0;
|
||||
lbl_1_bss_14 = 3;
|
||||
omMakeGroupEx(objman, 0, 4);
|
||||
for(i=0; i<4; i++) {
|
||||
for (i = 0; i < 4; i++) {
|
||||
omAddObjEx(objman, 5, 10, 50, 0, fn_1_D14);
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -308,10 +304,10 @@ void fn_1_C28(void)
|
|||
s32 i;
|
||||
omObjData **playerList;
|
||||
playerList = omGetGroupMemberListEx(HuPrcCurrentGet(), 0);
|
||||
if(playerList == NULL) {
|
||||
if (playerList == NULL) {
|
||||
return;
|
||||
}
|
||||
for(i=0; i<4; i++) {
|
||||
for (i = 0; i < 4; i++) {
|
||||
fn_1_2010(playerList[i]);
|
||||
}
|
||||
}
|
||||
|
|
@ -321,9 +317,9 @@ s32 fn_1_C90(void)
|
|||
s32 i;
|
||||
omObjData **playerList;
|
||||
playerList = omGetGroupMemberListEx(HuPrcCurrentGet(), 0);
|
||||
for(i=0; i<4; i++) {
|
||||
for (i = 0; i < 4; i++) {
|
||||
M455Player *player = playerList[i]->data;
|
||||
if(!player->field1) {
|
||||
if (!player->field1) {
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
|
@ -333,11 +329,16 @@ s32 fn_1_C90(void)
|
|||
s32 fn_1_3214(void);
|
||||
|
||||
u32 lbl_1_data_E0[5][2] = {
|
||||
0x5F0000, 0,
|
||||
0x540024, 1,
|
||||
0x54001C, 1,
|
||||
0x5F0017, 0,
|
||||
0x5F0018, 0,
|
||||
0x5F0000,
|
||||
0,
|
||||
0x540024,
|
||||
1,
|
||||
0x54001C,
|
||||
1,
|
||||
0x5F0017,
|
||||
0,
|
||||
0x5F0018,
|
||||
0,
|
||||
};
|
||||
|
||||
Vec lbl_1_data_108[4] = {
|
||||
|
|
@ -372,13 +373,14 @@ void fn_1_D14(omObjData *object)
|
|||
Hu3DModelCameraSet(object->model[0], HU3D_CAM0);
|
||||
object->model[1] = Hu3DModelCreateFile(0x540002);
|
||||
Hu3DModelHookSet(object->model[0], "test11_tex_we-itemhook-r", object->model[1]);
|
||||
Hu3DModelAttrSet(object->model[1], HU3D_MOTATTR_SHAPE_PAUSE|HU3D_MOTATTR_PAUSE);
|
||||
Hu3DModelAttrSet(object->model[1], HU3D_MOTATTR_SHAPE_PAUSE | HU3D_MOTATTR_PAUSE);
|
||||
player->unk1C = 1;
|
||||
for(i=0; i<5; i++) {
|
||||
if(lbl_1_data_E0[i][1] == 0) {
|
||||
for (i = 0; i < 5; i++) {
|
||||
if (lbl_1_data_E0[i][1] == 0) {
|
||||
object->motion[i] = CharModelMotionCreate(player->unk10, lbl_1_data_E0[i][0]);
|
||||
} else {
|
||||
object->motion[i] = CharModelMotionCreate(player->unk10, player->unk10+lbl_1_data_E0[i][0]);
|
||||
}
|
||||
else {
|
||||
object->motion[i] = CharModelMotionCreate(player->unk10, player->unk10 + lbl_1_data_E0[i][0]);
|
||||
}
|
||||
}
|
||||
Hu3DMotionSet(object->model[0], object->motion[player->unk1C]);
|
||||
|
|
@ -400,7 +402,7 @@ void fn_1_D14(omObjData *object)
|
|||
Hu3DMotionSet(object->model[4], i);
|
||||
Hu3DModelAttrSet(object->model[4], HU3D_MOTATTR_LOOP);
|
||||
Hu3DModelAttrSet(object->model[4], HU3D_MOTATTR_PAUSE);
|
||||
player->unk4C.x = object->trans.x+(50.0f*((((s32)frand() & 0x1FF)-256.0f)/256.0f));
|
||||
player->unk4C.x = object->trans.x + (50.0f * ((((s32)frand() & 0x1FF) - 256.0f) / 256.0f));
|
||||
player->unk4C.y = -200;
|
||||
player->unk4C.z = -1500;
|
||||
Hu3DModelPosSetV(object->model[4], &player->unk4C);
|
||||
|
|
@ -413,13 +415,14 @@ void fn_1_D14(omObjData *object)
|
|||
player->unk34[1].z = -1000;
|
||||
CharModelDataClose(player->unk10);
|
||||
object->rot.y = 180;
|
||||
if(((s32)frand() & 0x1F) < 4-player->unk12) {
|
||||
player->unk58 = lbl_1_bss_16-(60.0f*(0.05f*(4-player->unk12)))-((frand8()/256.0f)*6.0f);
|
||||
if(player->unk58 < 0) {
|
||||
if (((s32)frand() & 0x1F) < 4 - player->unk12) {
|
||||
player->unk58 = lbl_1_bss_16 - (60.0f * (0.05f * (4 - player->unk12))) - ((frand8() / 256.0f) * 6.0f);
|
||||
if (player->unk58 < 0) {
|
||||
player->unk58 = 0;
|
||||
}
|
||||
} else {
|
||||
player->unk58 = lbl_1_bss_16+(60.0f*(0.1f*(4-player->unk12)))+((frand8()/256.0f)*30.0f)+6.0f;
|
||||
}
|
||||
else {
|
||||
player->unk58 = lbl_1_bss_16 + (60.0f * (0.1f * (4 - player->unk12))) + ((frand8() / 256.0f) * 30.0f) + 6.0f;
|
||||
}
|
||||
player->unk28 = -1;
|
||||
object->func = fn_1_1444;
|
||||
|
|
@ -428,25 +431,17 @@ void fn_1_D14(omObjData *object)
|
|||
void fn_1_1400(omObjData *object)
|
||||
{
|
||||
M455Player *player = object->data;
|
||||
if(player->unk58 != 0) {
|
||||
if (player->unk58 != 0) {
|
||||
player->unk58--;
|
||||
} else {
|
||||
}
|
||||
else {
|
||||
player->unkA |= PAD_BUTTON_A;
|
||||
}
|
||||
}
|
||||
|
||||
float lbl_1_data_154[4] = {
|
||||
-350,
|
||||
-170,
|
||||
170,
|
||||
350
|
||||
};
|
||||
float lbl_1_data_154[4] = { -350, -170, 170, 350 };
|
||||
|
||||
float lbl_1_data_164[3] = {
|
||||
1.5f,
|
||||
1.0f,
|
||||
0.5f
|
||||
};
|
||||
float lbl_1_data_164[3] = { 1.5f, 1.0f, 0.5f };
|
||||
|
||||
float fn_1_2390(float arg0, float arg1, float arg2);
|
||||
s32 fn_1_24F0(Vec *arg0, Vec *arg1, float arg2);
|
||||
|
|
@ -461,38 +456,39 @@ void fn_1_1444(omObjData *object)
|
|||
Vec spC;
|
||||
float temp_f31;
|
||||
|
||||
|
||||
temp_r31 = object->data;
|
||||
temp_r29 = temp_r31->unk1C;
|
||||
temp_r28 = temp_r31->unk20;
|
||||
object->trans.y = fn_1_687C();
|
||||
if(fn_1_320() < 3) {
|
||||
if (fn_1_320() < 3) {
|
||||
return;
|
||||
}
|
||||
switch(temp_r31->unk16) {
|
||||
switch (temp_r31->unk16) {
|
||||
case 0:
|
||||
if(fn_1_320() == 4 || lbl_1_bss_14 == 0) {
|
||||
if (fn_1_320() == 4 || lbl_1_bss_14 == 0) {
|
||||
temp_r31->field1 = 1;
|
||||
temp_r31->unk16 = 2;
|
||||
espDispOff(temp_r31->unk2A);
|
||||
return;
|
||||
}
|
||||
if(!GWPlayerCfg[temp_r31->unk2].iscom) {
|
||||
if (!GWPlayerCfg[temp_r31->unk2].iscom) {
|
||||
temp_r31->unk6 = HuPadStkX[temp_r31->unk4];
|
||||
temp_r31->unk7 = HuPadStkY[temp_r31->unk4];
|
||||
temp_r31->unk8 = HuPadBtn[temp_r31->unk4];
|
||||
temp_r31->unkA = HuPadBtnDown[temp_r31->unk4];
|
||||
} else {
|
||||
}
|
||||
else {
|
||||
temp_r31->unk8 = temp_r31->unkA = 0;
|
||||
temp_r31->unk6 = temp_r31->unk7 = 0;
|
||||
fn_1_1400(object);
|
||||
}
|
||||
if(lbl_1_bss_16 == 0) {
|
||||
if(temp_r31->unkC) {
|
||||
if (lbl_1_bss_16 == 0) {
|
||||
if (temp_r31->unkC) {
|
||||
omVibrate(temp_r31->unk2, 12, 12, 0);
|
||||
} else {
|
||||
}
|
||||
else {
|
||||
sp18.x = object->trans.x;
|
||||
sp18.y = object->trans.y+300;
|
||||
sp18.y = object->trans.y + 300;
|
||||
sp18.z = object->trans.z;
|
||||
Hu3D3Dto2D(&sp18, HU3D_CAM0, &sp18);
|
||||
espPosSet(temp_r31->unk2A, sp18.x, sp18.y);
|
||||
|
|
@ -501,31 +497,30 @@ void fn_1_1444(omObjData *object)
|
|||
}
|
||||
temp_r31->unk2C = temp_r31->unk2E = 30;
|
||||
}
|
||||
|
||||
if(temp_r31->unkA & PAD_BUTTON_A) {
|
||||
|
||||
if (temp_r31->unkA & PAD_BUTTON_A) {
|
||||
temp_r31->unk16 = 1;
|
||||
temp_r31->unk24 = temp_r31->unk26 = 90;
|
||||
temp_r31->unk2C = -1;
|
||||
if(lbl_1_bss_16 <= 0) {
|
||||
if (lbl_1_bss_16 <= 0) {
|
||||
lbl_1_bss_18[lbl_1_bss_20++] = temp_r31->unk2;
|
||||
}
|
||||
Hu3DModelAttrReset(object->model[1], HU3D_MOTATTR_SHAPE_PAUSE|HU3D_MOTATTR_PAUSE);
|
||||
Hu3DModelAttrReset(object->model[1], HU3D_MOTATTR_SHAPE_PAUSE | HU3D_MOTATTR_PAUSE);
|
||||
Hu3DMotionSpeedSet(object->model[1], 1.2f);
|
||||
Hu3DMotionShapeSpeedSet(object->model[1], 1.2f);
|
||||
HuAudFXPlay(1986);
|
||||
|
||||
}
|
||||
temp_r29 = 1;
|
||||
temp_r28 = HU3D_MOTATTR_LOOP;
|
||||
break;
|
||||
|
||||
|
||||
case 1:
|
||||
temp_r29 = 2;
|
||||
temp_r28 = HU3D_MOTATTR_NONE;
|
||||
if(!temp_r31->field0) {
|
||||
if(temp_r31->unk28 >= 0 && temp_r31->unk28 < 3) {
|
||||
if (!temp_r31->field0) {
|
||||
if (temp_r31->unk28 >= 0 && temp_r31->unk28 < 3) {
|
||||
temp_r31->field0 = 1;
|
||||
if(temp_r31->unk28 == 0) {
|
||||
if (temp_r31->unk28 == 0) {
|
||||
lbl_1_bss_30 = temp_r31->unk2;
|
||||
}
|
||||
temp_f31 = lbl_1_data_164[temp_r31->unk28];
|
||||
|
|
@ -533,13 +528,13 @@ void fn_1_1444(omObjData *object)
|
|||
Hu3DModelAttrReset(object->model[4], HU3D_ATTR_DISPOFF);
|
||||
}
|
||||
}
|
||||
temp_f31 = 1.0f-((float)temp_r31->unk24/temp_r31->unk26);
|
||||
temp_f31 = 1.0f - ((float)temp_r31->unk24 / temp_r31->unk26);
|
||||
sp24[0].x = temp_r31->unk4C.x;
|
||||
sp24[0].y = temp_r31->unk4C.y;
|
||||
sp24[0].z = temp_r31->unk4C.z;
|
||||
sp24[1].x = object->trans.x;
|
||||
sp24[1].y = object->trans.y+1500;
|
||||
sp24[1].z = object->trans.z-200;
|
||||
sp24[1].y = object->trans.y + 1500;
|
||||
sp24[1].z = object->trans.z - 200;
|
||||
sp24[2].x = lbl_1_data_154[temp_r31->unk2];
|
||||
sp24[2].y = 0;
|
||||
sp24[2].z = 150;
|
||||
|
|
@ -547,32 +542,32 @@ void fn_1_1444(omObjData *object)
|
|||
VECSubtract(&sp18, &Hu3DData[object->model[4]].pos, &spC);
|
||||
Hu3DModelRotSet(object->model[4], atan2d(-spC.y, VECMagXZ(&spC)), atan2d(spC.x, spC.z), 0);
|
||||
Hu3DModelPosSetV(object->model[4], &sp18);
|
||||
if(sp18.y > 0.0f) {
|
||||
if(!temp_r31->field2 && temp_r31->field0) {
|
||||
if (sp18.y > 0.0f) {
|
||||
if (!temp_r31->field2 && temp_r31->field0) {
|
||||
fn_1_6CB0(&sp18, -1);
|
||||
fn_1_6698(&sp18, -1, -1, -1);
|
||||
temp_r31->field2 = 1;
|
||||
}
|
||||
}
|
||||
temp_r31->unk34[0].x = temp_f31*(2.0f*lbl_1_data_154[temp_r31->unk2]);
|
||||
temp_r31->unk34[0].y = -200.0f+(-400.0f*temp_f31);
|
||||
temp_r31->unk34[0].z = -500.0f+(-1500.0f*temp_f31);
|
||||
temp_r31->unk34[1].x = temp_f31*lbl_1_data_154[temp_r31->unk2];
|
||||
temp_r31->unk34[1].y = -200.0f+(400.0f*temp_f31);
|
||||
temp_r31->unk34[1].z = -1000.0f+(750.0f*temp_f31);
|
||||
if(--temp_r31->unk24 == 0) {
|
||||
temp_r31->unk34[0].x = temp_f31 * (2.0f * lbl_1_data_154[temp_r31->unk2]);
|
||||
temp_r31->unk34[0].y = -200.0f + (-400.0f * temp_f31);
|
||||
temp_r31->unk34[0].z = -500.0f + (-1500.0f * temp_f31);
|
||||
temp_r31->unk34[1].x = temp_f31 * lbl_1_data_154[temp_r31->unk2];
|
||||
temp_r31->unk34[1].y = -200.0f + (400.0f * temp_f31);
|
||||
temp_r31->unk34[1].z = -1000.0f + (750.0f * temp_f31);
|
||||
if (--temp_r31->unk24 == 0) {
|
||||
temp_r31->unk16 = 2;
|
||||
temp_r31->field1 = 1;
|
||||
if(temp_r31->field0) {
|
||||
if (temp_r31->field0) {
|
||||
Hu3DModelAttrReset(object->model[4], HU3D_MOTATTR_PAUSE);
|
||||
Hu3DModelRotSet(object->model[4], 0, 0, 0);
|
||||
lbl_1_bss_14--;
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
||||
|
||||
case 2:
|
||||
if(fn_1_320() == 7) {
|
||||
if (fn_1_320() == 7) {
|
||||
temp_r31->unk16 = 3;
|
||||
Hu3DModelObjPosGet(object->model[0], "test11_tex_we-itemhook-r", &sp18);
|
||||
CharModelEffectCreate(1, &sp18);
|
||||
|
|
@ -580,46 +575,50 @@ void fn_1_1444(omObjData *object)
|
|||
Hu3DModelAttrSet(object->model[3], HU3D_ATTR_DISPOFF);
|
||||
}
|
||||
break;
|
||||
|
||||
|
||||
case 3:
|
||||
if(fn_1_320() < 9) {
|
||||
if (fn_1_320() < 9) {
|
||||
temp_r29 = 0;
|
||||
temp_r28 = HU3D_MOTATTR_LOOP;
|
||||
} else {
|
||||
}
|
||||
else {
|
||||
object->rot.y = fn_1_2390(object->rot.y, 0, 0.2f);
|
||||
if(temp_r31->unk2 == lbl_1_bss_30) {
|
||||
if (temp_r31->unk2 == lbl_1_bss_30) {
|
||||
temp_r29 = 3;
|
||||
temp_r28 = HU3D_MOTATTR_NONE;
|
||||
} else {
|
||||
}
|
||||
else {
|
||||
temp_r29 = 4;
|
||||
temp_r28 = HU3D_MOTATTR_NONE;
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
if(temp_r31->unk2C) {
|
||||
if(temp_r31->unk2C >= 0) {
|
||||
temp_f31 = (0.5*sind((90.0f*(float)temp_r31->unk2C)/(float)temp_r31->unk2E))+0.5;
|
||||
if (temp_r31->unk2C) {
|
||||
if (temp_r31->unk2C >= 0) {
|
||||
temp_f31 = (0.5 * sind((90.0f * (float)temp_r31->unk2C) / (float)temp_r31->unk2E)) + 0.5;
|
||||
espScaleSet(temp_r31->unk2A, temp_f31, temp_f31);
|
||||
if(--temp_r31->unk2C == 0) {
|
||||
if (--temp_r31->unk2C == 0) {
|
||||
temp_r31->unk2C = temp_r31->unk2E;
|
||||
}
|
||||
temp_r31->unk30++;
|
||||
} else {
|
||||
if(temp_r31->unk30 > 30.0f) {
|
||||
}
|
||||
else {
|
||||
if (temp_r31->unk30 > 30.0f) {
|
||||
espDispOff(temp_r31->unk2A);
|
||||
temp_r31->unk2C = 0;
|
||||
} else {
|
||||
}
|
||||
else {
|
||||
temp_r31->unk30++;
|
||||
}
|
||||
}
|
||||
}
|
||||
if(temp_r31->unk16 >= 2 && temp_r31->unk16 <= 3 && temp_r31->field0) {
|
||||
if (temp_r31->unk16 >= 2 && temp_r31->unk16 <= 3 && temp_r31->field0) {
|
||||
Hu3DData[object->model[4]].rot.y += 2.0f;
|
||||
if(0.0f == Hu3DData[object->model[4]].unk_64) {
|
||||
if (0.0f == Hu3DData[object->model[4]].unk_64) {
|
||||
HuAudFXPlay(1987);
|
||||
}
|
||||
}
|
||||
|
|
@ -633,7 +632,7 @@ void fn_1_1444(omObjData *object)
|
|||
void fn_1_2010(omObjData *object)
|
||||
{
|
||||
M455Player *player = object->data;
|
||||
if(object->data != NULL) {
|
||||
if (object->data != NULL) {
|
||||
HuMemDirectFree(object->data);
|
||||
object->data = NULL;
|
||||
}
|
||||
|
|
@ -647,7 +646,7 @@ void fn_1_2060(ModelData *arg0, Mtx arg1)
|
|||
{
|
||||
Vec vtxPos[4];
|
||||
Mtx mtxHook;
|
||||
|
||||
|
||||
Vec pos;
|
||||
Vec itemHookPos;
|
||||
s32 i;
|
||||
|
|
@ -666,16 +665,16 @@ void fn_1_2060(ModelData *arg0, Mtx arg1)
|
|||
GXSetTevOp(GX_TEVSTAGE0, GX_PASSCLR);
|
||||
GXClearVtxDesc();
|
||||
GXSetVtxDesc(GX_VA_POS, GX_DIRECT);
|
||||
GXSetVtxAttrFmt(GX_VTXFMT0, GX_VA_POS, GX_POS_XYZ, GX_F32, 0);
|
||||
GXSetVtxAttrFmt(GX_VTXFMT0, GX_VA_POS, GX_POS_XYZ, GX_F32, 0);
|
||||
Hu3DModelObjMtxGet(object->model[0], "test11_tex_we-itemhook-r", mtxHook);
|
||||
Hu3DModelObjPosGet(object->model[1], "hook", &pos);
|
||||
MTXMultVec(mtxHook, &pos, &vtxPos[0]);
|
||||
for(i=0; i<2; i++) {
|
||||
vtxPos[i+1].x = player->unk34[i].x;
|
||||
vtxPos[i+1].y = player->unk34[i].y;
|
||||
vtxPos[i+1].z = player->unk34[i].z;
|
||||
for (i = 0; i < 2; i++) {
|
||||
vtxPos[i + 1].x = player->unk34[i].x;
|
||||
vtxPos[i + 1].y = player->unk34[i].y;
|
||||
vtxPos[i + 1].z = player->unk34[i].z;
|
||||
}
|
||||
if(player->field0) {
|
||||
if (player->field0) {
|
||||
Mtx hookMtx;
|
||||
Vec hookPos;
|
||||
Hu3DModelObjMtxGet(object->model[4], "itemhook_C", hookMtx);
|
||||
|
|
@ -683,14 +682,15 @@ void fn_1_2060(ModelData *arg0, Mtx arg1)
|
|||
hookPos.y = -60.000004f;
|
||||
hookPos.z = 35.0f;
|
||||
MTXMultVec(hookMtx, &hookPos, &vtxPos[3]);
|
||||
} else {
|
||||
}
|
||||
else {
|
||||
vtxPos[3].x = modelPuku->pos.x;
|
||||
vtxPos[3].y = modelPuku->pos.y;
|
||||
vtxPos[3].z = modelPuku->pos.z;
|
||||
}
|
||||
GXBegin(GX_LINESTRIP, GX_VTXFMT0, 20);
|
||||
for(i=0; i<20; i++) {
|
||||
fn_1_27A0(vtxPos, &pos, i/19.0f);
|
||||
for (i = 0; i < 20; i++) {
|
||||
fn_1_27A0(vtxPos, &pos, i / 19.0f);
|
||||
GXPosition3f32(pos.x, pos.y, pos.z);
|
||||
}
|
||||
GXEnd();
|
||||
|
|
@ -698,16 +698,16 @@ void fn_1_2060(ModelData *arg0, Mtx arg1)
|
|||
|
||||
float fn_1_2390(float arg0, float arg1, float arg2)
|
||||
{
|
||||
float temp_f31 = fmod(arg1-arg0, 360);
|
||||
float temp_f31 = fmod(arg1 - arg0, 360);
|
||||
float temp_f30;
|
||||
if(temp_f31 < 0) {
|
||||
if (temp_f31 < 0) {
|
||||
temp_f31 += 360.0f;
|
||||
}
|
||||
if(temp_f31 > 180) {
|
||||
if (temp_f31 > 180) {
|
||||
temp_f31 -= 360.0f;
|
||||
}
|
||||
temp_f30 = fmod(arg0+(arg2*temp_f31), 360);
|
||||
if(temp_f30 < 0) {
|
||||
temp_f30 = fmod(arg0 + (arg2 * temp_f31), 360);
|
||||
if (temp_f30 < 0) {
|
||||
temp_f30 += 360.0f;
|
||||
}
|
||||
return temp_f30;
|
||||
|
|
@ -715,8 +715,8 @@ float fn_1_2390(float arg0, float arg1, float arg2)
|
|||
|
||||
float fn_1_2494(float arg0, float arg1, float arg2, float arg3)
|
||||
{
|
||||
float temp_f31 = 1.0f-arg3;
|
||||
return (arg0*(temp_f31*temp_f31))+((2.0f*temp_f31)*arg3*arg1)+(arg2*(arg3*arg3));
|
||||
float temp_f31 = 1.0f - arg3;
|
||||
return (arg0 * (temp_f31 * temp_f31)) + ((2.0f * temp_f31) * arg3 * arg1) + (arg2 * (arg3 * arg3));
|
||||
}
|
||||
|
||||
s32 fn_1_24F0(Vec *arg0, Vec *arg1, float arg2)
|
||||
|
|
@ -728,9 +728,9 @@ s32 fn_1_24F0(Vec *arg0, Vec *arg1, float arg2)
|
|||
|
||||
float fn_1_26F8(float arg0, float arg1, float arg2, float arg3, float arg4)
|
||||
{
|
||||
float temp_f31 = 1.0f-arg0;
|
||||
float temp_f30 = temp_f31*temp_f31;
|
||||
float temp_f29 = temp_f31*temp_f31*temp_f31;
|
||||
float temp_f31 = 1.0f - arg0;
|
||||
float temp_f30 = temp_f31 * temp_f31;
|
||||
float temp_f29 = temp_f31 * temp_f31 * temp_f31;
|
||||
return (arg4 * (arg0 * (arg0 * arg0))) + ((arg3 * (arg0 * (3.0f * temp_f31 * arg0))) + ((temp_f29 * arg1) + (arg2 * (3.0f * temp_f30 * arg0))));
|
||||
}
|
||||
|
||||
|
|
@ -755,33 +755,33 @@ void fn_1_2A90(Process *objman)
|
|||
|
||||
void fn_1_2AF4(s32 arg0, s32 arg1, float arg2)
|
||||
{
|
||||
CZoom = lbl_1_data_0[arg0].zoom+(arg2*(lbl_1_data_0[arg1].zoom-lbl_1_data_0[arg0].zoom));
|
||||
Center.x = lbl_1_data_0[arg0].pos.x+(arg2*(lbl_1_data_0[arg1].pos.x-lbl_1_data_0[arg0].pos.x));
|
||||
Center.y = lbl_1_data_0[arg0].pos.y+(arg2*(lbl_1_data_0[arg1].pos.y-lbl_1_data_0[arg0].pos.y));
|
||||
Center.z = lbl_1_data_0[arg0].pos.z+(arg2*(lbl_1_data_0[arg1].pos.z-lbl_1_data_0[arg0].pos.z));
|
||||
CRot.x = lbl_1_data_0[arg0].rot.x+(arg2*(lbl_1_data_0[arg1].rot.x-lbl_1_data_0[arg0].rot.x));
|
||||
CRot.y = lbl_1_data_0[arg0].rot.y+(arg2*(lbl_1_data_0[arg1].rot.y-lbl_1_data_0[arg0].rot.y));
|
||||
CRot.z = lbl_1_data_0[arg0].rot.z+(arg2*(lbl_1_data_0[arg1].rot.z-lbl_1_data_0[arg0].rot.z));
|
||||
CZoom = lbl_1_data_0[arg0].zoom + (arg2 * (lbl_1_data_0[arg1].zoom - lbl_1_data_0[arg0].zoom));
|
||||
Center.x = lbl_1_data_0[arg0].pos.x + (arg2 * (lbl_1_data_0[arg1].pos.x - lbl_1_data_0[arg0].pos.x));
|
||||
Center.y = lbl_1_data_0[arg0].pos.y + (arg2 * (lbl_1_data_0[arg1].pos.y - lbl_1_data_0[arg0].pos.y));
|
||||
Center.z = lbl_1_data_0[arg0].pos.z + (arg2 * (lbl_1_data_0[arg1].pos.z - lbl_1_data_0[arg0].pos.z));
|
||||
CRot.x = lbl_1_data_0[arg0].rot.x + (arg2 * (lbl_1_data_0[arg1].rot.x - lbl_1_data_0[arg0].rot.x));
|
||||
CRot.y = lbl_1_data_0[arg0].rot.y + (arg2 * (lbl_1_data_0[arg1].rot.y - lbl_1_data_0[arg0].rot.y));
|
||||
CRot.z = lbl_1_data_0[arg0].rot.z + (arg2 * (lbl_1_data_0[arg1].rot.z - lbl_1_data_0[arg0].rot.z));
|
||||
}
|
||||
|
||||
void fn_1_2D44(omObjData *object)
|
||||
{
|
||||
CameraData *camera = &Hu3DCamera[0];
|
||||
switch(fn_1_320()) {
|
||||
switch (fn_1_320()) {
|
||||
case 1:
|
||||
fn_1_2AF4(0, 1, sind(lbl_1_data_184[0]*90.0f));
|
||||
if(lbl_1_data_184[0] < 1.0f) {
|
||||
lbl_1_data_184[0] += 1.0f/60.0f;
|
||||
if(lbl_1_data_184[0] > 1.0f) {
|
||||
fn_1_2AF4(0, 1, sind(lbl_1_data_184[0] * 90.0f));
|
||||
if (lbl_1_data_184[0] < 1.0f) {
|
||||
lbl_1_data_184[0] += 1.0f / 60.0f;
|
||||
if (lbl_1_data_184[0] > 1.0f) {
|
||||
lbl_1_data_184[0] = 1.0f;
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
||||
|
||||
case 6:
|
||||
fn_1_2AF4(1, 1, 0);
|
||||
break;
|
||||
|
||||
|
||||
case 4:
|
||||
case 5:
|
||||
case 7:
|
||||
|
|
@ -794,9 +794,9 @@ s32 fn_1_3214(void)
|
|||
{
|
||||
s32 rumble = HuPadRumbleGet();
|
||||
s32 i;
|
||||
for(i=0; i<4; i++) {
|
||||
if(!GWPlayerCfg[i].iscom) {
|
||||
if((rumble & lbl_1_data_18C[GWPlayerCfg[i].pad_idx]) == 0) {
|
||||
for (i = 0; i < 4; i++) {
|
||||
if (!GWPlayerCfg[i].iscom) {
|
||||
if ((rumble & lbl_1_data_18C[GWPlayerCfg[i].pad_idx]) == 0) {
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
|
@ -804,4 +804,4 @@ s32 fn_1_3214(void)
|
|||
return GWGameStat.rumble;
|
||||
}
|
||||
|
||||
float lbl_1_data_19C[] = { 0,355,0,0,0,275,128,950,6,0,0,0,190,0,550 };
|
||||
float lbl_1_data_19C[] = { 0, 355, 0, 0, 0, 275, 128, 950, 6, 0, 0, 0, 190, 0, 550 };
|
||||
|
|
|
|||
|
|
@ -22,7 +22,6 @@
|
|||
#include "game/sprite.h"
|
||||
|
||||
#include "ext_math.h"
|
||||
#include "rel_sqrt_consts.h"
|
||||
|
||||
#undef ABS
|
||||
#define ABS(x) ((0 > (x)) ? -(x) : (x))
|
||||
|
|
@ -702,7 +701,7 @@ void fn_1_2DC8(WorkPlayerOld *player, s32 count, Vec *data)
|
|||
void fn_1_2DD4(WorkPlayerOld *player)
|
||||
{
|
||||
omSetTra(player->unk0, player->unk6C.x, player->unk6C.y, player->unk6C.z);
|
||||
omSetRot(player->unk0, 0, player->unk9C, 0);
|
||||
omSetRot(player->unk0, 0.0f, player->unk9C, 0.0f);
|
||||
}
|
||||
|
||||
void fn_1_2E34(WorkPlayerOld *player)
|
||||
|
|
@ -840,12 +839,7 @@ void fn_1_3C74(WorkPlayerOld *player, s32 *state, u32 *motAttr)
|
|||
}
|
||||
|
||||
if(player->unk14[3] >= 0 && (player->unk28 & 0x100)) {
|
||||
player->unk38 = 1;
|
||||
player->unk84.y = 26.766666f;
|
||||
player->unkA4 = 1;
|
||||
if(player->unk3C & 0x2) {
|
||||
player->unk3C &= ~0x2;
|
||||
}
|
||||
fn_1_2BD0(player, 26.766666f, 1.0f);
|
||||
*motAttr = HU3D_MOTATTR_NONE;
|
||||
*state = 3;
|
||||
}
|
||||
|
|
@ -868,7 +862,7 @@ void fn_1_3D4C(WorkPlayerOld *player, s32 *state, u32 *motAttr)
|
|||
player->unk84.y += -2.4333334f;
|
||||
if(player->unk14[5] >= 0 && (player->unk28 & 0x140)) {
|
||||
player->unk38 = 3;
|
||||
player->unk84.y = 0;
|
||||
player->unk84.y = 0.0f;
|
||||
player->unk3C &= ~0x3;
|
||||
player->unk3C |= 0x4;
|
||||
*motAttr = HU3D_MOTATTR_NONE;
|
||||
|
|
@ -895,12 +889,7 @@ void fn_1_3E60(WorkPlayerOld *player, s32 *state, u32 *motAttr)
|
|||
void fn_1_3F18(WorkPlayerOld *player, s32 *state, u32 *motAttr)
|
||||
{
|
||||
if(Hu3DMotionShiftIDGet(player->unk0->model[0]) < 0 && Hu3DMotionEndCheck(player->unk0->model[0])) {
|
||||
player->unk38 = 1;
|
||||
player->unk84.y = 0;
|
||||
player->unkA4 = 0;
|
||||
if(player->unk3C & 0x2) {
|
||||
player->unk3C &= ~0x2;
|
||||
}
|
||||
fn_1_2BD0(player, 0.0f, 0.0f);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -2329,4 +2318,4 @@ void fn_1_D70C(omObjData *obj)
|
|||
CharModelKill(lbl_1_data_0[GWPlayerCfg[i].character]);
|
||||
}
|
||||
omOvlReturnEx(1, 1);
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -13,9 +13,6 @@
|
|||
#include "game/wipe.h"
|
||||
#include "math.h"
|
||||
|
||||
|
||||
#include "rel_sqrt_consts.h"
|
||||
|
||||
Process *lbl_1_bss_0;
|
||||
// TODO: unknown type
|
||||
extern s32 lbl_1_bss_A8[];
|
||||
|
|
|
|||
|
|
@ -9,9 +9,8 @@
|
|||
|
||||
#include "dolphin.h"
|
||||
#include "ext_math.h"
|
||||
#include "rel_sqrt_consts.h"
|
||||
|
||||
extern s32 sprintf(char*, const char*, s32);
|
||||
extern s32 sprintf(char *, const char *, s32);
|
||||
|
||||
static void fn_1_2BC(omObjData *arg0);
|
||||
static void fn_1_300(omObjData *arg0);
|
||||
|
|
@ -27,7 +26,8 @@ static u8 lbl_1_bss_4_pad[4];
|
|||
static s16 lbl_1_bss_2;
|
||||
static s16 lbl_1_bss_0;
|
||||
|
||||
void ObjectSetup(void) {
|
||||
void ObjectSetup(void)
|
||||
{
|
||||
OSReport("******* SAFObjectSetup *********\n");
|
||||
lbl_1_bss_34 = omInitObjMan(0x32, 0x2000);
|
||||
CRot.x = -20.0f;
|
||||
|
|
@ -46,12 +46,14 @@ void ObjectSetup(void) {
|
|||
lbl_1_bss_8 = HuPrcChildCreate(fn_1_E88, 100, 0x3000, 0, lbl_1_bss_34);
|
||||
}
|
||||
|
||||
static void fn_1_2BC(omObjData *arg0) {
|
||||
static void fn_1_2BC(omObjData *arg0)
|
||||
{
|
||||
WipeCreate(WIPE_MODE_IN, WIPE_TYPE_NORMAL, 10);
|
||||
arg0->func = fn_1_300;
|
||||
}
|
||||
|
||||
static void fn_1_300(omObjData *arg0) {
|
||||
static void fn_1_300(omObjData *arg0)
|
||||
{
|
||||
Vec sp2C;
|
||||
Vec sp20;
|
||||
Vec sp14;
|
||||
|
|
@ -79,14 +81,14 @@ static void fn_1_300(omObjData *arg0) {
|
|||
sp14.z = cosd(CRot.y) * sind(CRot.x);
|
||||
temp_f31 = CRot.z;
|
||||
sp8.x = sp14.x * (sp20.x * sp20.x + (1.0f - sp20.x * sp20.x) * cosd(temp_f31))
|
||||
+ sp14.y * (sp20.x * sp20.y * (1.0 - cosd(temp_f31)) - sp20.z * sind(temp_f31))
|
||||
+ sp14.z * (sp20.x * sp20.z * (1.0 - cosd(temp_f31)) + sp20.y * sind(temp_f31));
|
||||
+ sp14.y * (sp20.x * sp20.y * (1.0 - cosd(temp_f31)) - sp20.z * sind(temp_f31))
|
||||
+ sp14.z * (sp20.x * sp20.z * (1.0 - cosd(temp_f31)) + sp20.y * sind(temp_f31));
|
||||
sp8.y = sp14.x * (sp20.x * sp20.y * (1.0 - cosd(temp_f31)) + sp20.z * sind(temp_f31))
|
||||
+ sp14.y * (sp20.y * sp20.y + (1.0f - sp20.y * sp20.y) * cosd(temp_f31))
|
||||
+ sp14.z * (sp20.y * sp20.z * (1.0 - cosd(temp_f31)) - sp20.x * sind(temp_f31));
|
||||
+ sp14.y * (sp20.y * sp20.y + (1.0f - sp20.y * sp20.y) * cosd(temp_f31))
|
||||
+ sp14.z * (sp20.y * sp20.z * (1.0 - cosd(temp_f31)) - sp20.x * sind(temp_f31));
|
||||
sp8.z = sp14.x * (sp20.x * sp20.z * (1.0 - cosd(temp_f31)) - sp20.y * sind(temp_f31))
|
||||
+ sp14.y * (sp20.y * sp20.z * (1.0 - cosd(temp_f31)) + sp20.x * sind(temp_f31))
|
||||
+ sp14.z * (sp20.z * sp20.z + (1.0f - sp20.z * sp20.z) * cosd(temp_f31));
|
||||
+ sp14.y * (sp20.y * sp20.z * (1.0 - cosd(temp_f31)) + sp20.x * sind(temp_f31))
|
||||
+ sp14.z * (sp20.z * sp20.z + (1.0f - sp20.z * sp20.z) * cosd(temp_f31));
|
||||
VECCrossProduct(&sp14, &sp20, &sp20);
|
||||
VECNormalize(&sp20, &sp20);
|
||||
temp_r31 = HuPadSubStkX[0] & 0xF8;
|
||||
|
|
@ -104,69 +106,19 @@ static void fn_1_300(omObjData *arg0) {
|
|||
}
|
||||
}
|
||||
|
||||
static char *lbl_1_data_32C[] = {
|
||||
"001_Character_Name_ss",
|
||||
"002_Hidden_Block",
|
||||
"003_Battle_M",
|
||||
"004_Bowser_M",
|
||||
"005_Warp_M",
|
||||
"006_Mushroom_M",
|
||||
"007_Lot_house",
|
||||
"008_Boo_house",
|
||||
"009_ItemName",
|
||||
"010_Bord",
|
||||
"011_RoundItem",
|
||||
"012_Spaceamida",
|
||||
"013_Star_M",
|
||||
"014_RollerCoaster",
|
||||
"015_Last5",
|
||||
"016_ItemShop",
|
||||
"017_System",
|
||||
"018_ModeSelect",
|
||||
"019_Item",
|
||||
"020_Map2_event",
|
||||
"021_Lucky_Minigame",
|
||||
"022_Bord_Start",
|
||||
"023_Map3_event",
|
||||
"024_Minigame_Name",
|
||||
"025_mg_446",
|
||||
"026_debugmes",
|
||||
"027_Party_Mode",
|
||||
"028_SETUP",
|
||||
"029_Miracle",
|
||||
"030_mg_kuppa",
|
||||
"031_Story_Mode",
|
||||
"032_Bowser_Story",
|
||||
"033_Map4_event",
|
||||
"034_mg_inst",
|
||||
"035_E3_only",
|
||||
"036_saf",
|
||||
"037_Mg_inst_sys_",
|
||||
"038_Bord_Results",
|
||||
"039_Bord_Results2",
|
||||
"040_Map5_event",
|
||||
"041_Mg_Mode",
|
||||
"042_mg_445",
|
||||
"043_mg_447",
|
||||
"044_mg_448",
|
||||
"045_mg_449",
|
||||
"046_mg_450",
|
||||
"047_tutorial",
|
||||
"048_Option_Rooml",
|
||||
"049_Map6_event",
|
||||
"050_charley",
|
||||
"051_Present_Room",
|
||||
"052_Extra_Room",
|
||||
"053_Staff_Post",
|
||||
"054_Staff_Name",
|
||||
"055_Opening_Demo",
|
||||
"056_mgex_inst",
|
||||
NULL
|
||||
};
|
||||
static char *lbl_1_data_32C[]
|
||||
= { "001_Character_Name_ss", "002_Hidden_Block", "003_Battle_M", "004_Bowser_M", "005_Warp_M", "006_Mushroom_M", "007_Lot_house", "008_Boo_house",
|
||||
"009_ItemName", "010_Bord", "011_RoundItem", "012_Spaceamida", "013_Star_M", "014_RollerCoaster", "015_Last5", "016_ItemShop", "017_System",
|
||||
"018_ModeSelect", "019_Item", "020_Map2_event", "021_Lucky_Minigame", "022_Bord_Start", "023_Map3_event", "024_Minigame_Name", "025_mg_446",
|
||||
"026_debugmes", "027_Party_Mode", "028_SETUP", "029_Miracle", "030_mg_kuppa", "031_Story_Mode", "032_Bowser_Story", "033_Map4_event",
|
||||
"034_mg_inst", "035_E3_only", "036_saf", "037_Mg_inst_sys_", "038_Bord_Results", "039_Bord_Results2", "040_Map5_event", "041_Mg_Mode",
|
||||
"042_mg_445", "043_mg_447", "044_mg_448", "045_mg_449", "046_mg_450", "047_tutorial", "048_Option_Rooml", "049_Map6_event", "050_charley",
|
||||
"051_Present_Room", "052_Extra_Room", "053_Staff_Post", "054_Staff_Name", "055_Opening_Demo", "056_mgex_inst", NULL };
|
||||
|
||||
static s16 lbl_1_data_410 = -1;
|
||||
|
||||
static void fn_1_E88(void) {
|
||||
static void fn_1_E88(void)
|
||||
{
|
||||
s16 sp10[256]; // unknown size
|
||||
char spC[4];
|
||||
char sp8[4];
|
||||
|
|
@ -192,7 +144,7 @@ static void fn_1_E88(void) {
|
|||
var_r30 = (var_r28 << 16);
|
||||
var_r25 = 0;
|
||||
while (1) {
|
||||
if ((s32) MessData_MesPtrGet(messDataPtr, var_r30 + var_r25) == 0) {
|
||||
if ((s32)MessData_MesPtrGet(messDataPtr, var_r30 + var_r25) == 0) {
|
||||
break;
|
||||
}
|
||||
sp10[var_r28]++;
|
||||
|
|
@ -226,13 +178,15 @@ static void fn_1_E88(void) {
|
|||
var_r31 = 0;
|
||||
}
|
||||
var_r30 = 0;
|
||||
} else if (temp_r3_2 & 0x40) {
|
||||
}
|
||||
else if (temp_r3_2 & 0x40) {
|
||||
var_r31--;
|
||||
if (var_r31 < 0) {
|
||||
var_r31 = var_r27 - 1;
|
||||
}
|
||||
var_r30 = 0;
|
||||
} else if (temp_r3_2 & 0x200) {
|
||||
}
|
||||
else if (temp_r3_2 & 0x200) {
|
||||
var_r30--;
|
||||
if (var_r30 < 0) {
|
||||
var_r31--;
|
||||
|
|
@ -241,7 +195,8 @@ static void fn_1_E88(void) {
|
|||
}
|
||||
var_r30 = sp10[var_r31] - 1;
|
||||
}
|
||||
} else {
|
||||
}
|
||||
else {
|
||||
var_r30++;
|
||||
if (var_r30 >= sp10[var_r31]) {
|
||||
var_r31++;
|
||||
|
|
@ -255,18 +210,10 @@ static void fn_1_E88(void) {
|
|||
}
|
||||
}
|
||||
|
||||
static char *lbl_1_data_440[] = {
|
||||
"]1^",
|
||||
"]2^",
|
||||
"]3^",
|
||||
"]4^",
|
||||
"]5^",
|
||||
"]6^",
|
||||
"]7^",
|
||||
"]8^"
|
||||
};
|
||||
static char *lbl_1_data_440[] = { "]1^", "]2^", "]3^", "]4^", "]5^", "]6^", "]7^", "]8^" };
|
||||
|
||||
static s32 fn_1_11B0(s16 arg0, s16 arg1) {
|
||||
static s32 fn_1_11B0(s16 arg0, s16 arg1)
|
||||
{
|
||||
WindowData *temp_r30;
|
||||
float spC[2];
|
||||
s32 temp_r28;
|
||||
|
|
@ -285,7 +232,7 @@ static s32 fn_1_11B0(s16 arg0, s16 arg1) {
|
|||
}
|
||||
temp_r28 = MAKE_MESSID(arg0, arg1);
|
||||
for (i = 0; i < 8; i++) {
|
||||
HuWinInsertMesSizeGet(MAKE_MESSID_PTR(lbl_1_data_440[i]), (s16) i);
|
||||
HuWinInsertMesSizeGet(MAKE_MESSID_PTR(lbl_1_data_440[i]), (s16)i);
|
||||
}
|
||||
HuWinMesMaxSizeGet(1, &spC[0], temp_r28);
|
||||
if (spC[0] <= 16.0f) {
|
||||
|
|
@ -293,7 +240,7 @@ static s32 fn_1_11B0(s16 arg0, s16 arg1) {
|
|||
}
|
||||
lbl_1_data_410 = HuWinCreate(-10000.0f, -10000.0f, spC[0], spC[1], 0);
|
||||
for (i = 0; i < 8; i++) {
|
||||
HuWinInsertMesSet(lbl_1_data_410, MAKE_MESSID_PTR(lbl_1_data_440[i]), (s16) i);
|
||||
HuWinInsertMesSet(lbl_1_data_410, MAKE_MESSID_PTR(lbl_1_data_440[i]), (s16)i);
|
||||
}
|
||||
temp_r30 = &winData[lbl_1_data_410];
|
||||
temp_r30->push_key |= 0x360;
|
||||
|
|
|
|||
|
|
@ -6,7 +6,6 @@
|
|||
#include "game/wipe.h"
|
||||
|
||||
#include "ext_math.h"
|
||||
#include "rel_sqrt_consts.h"
|
||||
|
||||
typedef struct camera_view_params {
|
||||
Vec rot;
|
||||
|
|
|
|||
|
|
@ -14,6 +14,7 @@
|
|||
#include "math.h"
|
||||
|
||||
#include "REL/modeltestDll.h"
|
||||
#include "math.h"
|
||||
|
||||
// -------------------------------------------------------------------------- //
|
||||
|
||||
|
|
@ -28,8 +29,6 @@ s32 lbl_1_data_0[8] = {
|
|||
DATA_MAKE_NUM(DATADIR_MARIOMOT, 0x04),
|
||||
};
|
||||
|
||||
const f64 unk_rodata_0 = 0.5;
|
||||
const f64 unk_rodata_8 = 3.0;
|
||||
omObjData *lbl_1_bss_9A4;
|
||||
omObjData *lbl_1_bss_9A0;
|
||||
|
||||
|
|
|
|||
|
|
@ -1,26 +1,22 @@
|
|||
#include "game/object.h"
|
||||
#include "REL/modeseldll.h"
|
||||
#include "game/audio.h"
|
||||
#include "game/gamework_data.h"
|
||||
#include "game/hsfman.h"
|
||||
#include "game/object.h"
|
||||
#include "game/objsub.h"
|
||||
#include "game/pad.h"
|
||||
#include "game/process.h"
|
||||
#include "game/window.h"
|
||||
#include "game/objsub.h"
|
||||
#include "game/audio.h"
|
||||
#include "game/wipe.h"
|
||||
#include "game/pad.h"
|
||||
#include "math.h"
|
||||
#include "game/gamework_data.h"
|
||||
#include "REL/modeseldll.h"
|
||||
#include "rel_sqrt_consts.h"
|
||||
|
||||
typedef struct camera_view_params {
|
||||
Vec rot;
|
||||
Vec pos;
|
||||
float zoom;
|
||||
Vec rot;
|
||||
Vec pos;
|
||||
float zoom;
|
||||
} CameraViewParams;
|
||||
|
||||
CameraViewParams lbl_1_data_0[] = {
|
||||
{ { 0, 0, 0 }, { 0, 0, 0 }, 1500 },
|
||||
{ { 0, 0, 0 }, { 0, 0, 0 }, 524 }
|
||||
};
|
||||
CameraViewParams lbl_1_data_0[] = { { { 0, 0, 0 }, { 0, 0, 0 }, 1500 }, { { 0, 0, 0 }, { 0, 0, 0 }, 524 } };
|
||||
|
||||
omObjData *lbl_1_bss_7C;
|
||||
Process *lbl_1_bss_78;
|
||||
|
|
@ -42,325 +38,332 @@ void fn_1_1B6C(void);
|
|||
|
||||
void ObjectSetup(void)
|
||||
{
|
||||
s32 light;
|
||||
OSReport("******* MS ObjectSetup *********\n");
|
||||
lbl_1_bss_78 = omInitObjMan(50, 8192);
|
||||
omGameSysInit(lbl_1_bss_78);
|
||||
lbl_1_bss_24[0].x = -70;
|
||||
lbl_1_bss_24[0].y = 0;
|
||||
lbl_1_bss_24[0].z = 0;
|
||||
lbl_1_bss_C[0].x = 0;
|
||||
lbl_1_bss_C[0].y = 130;
|
||||
lbl_1_bss_C[0].z = -186;
|
||||
lbl_1_bss_4[0] = 1360;
|
||||
lbl_1_bss_64 = lbl_1_bss_24[0];
|
||||
lbl_1_bss_58 = lbl_1_bss_C[0];
|
||||
lbl_1_bss_54 = lbl_1_bss_4[0];
|
||||
lbl_1_bss_70[0] = 0;
|
||||
Hu3DCameraCreate(1);
|
||||
Hu3DCameraPerspectiveSet(1, 30, 20, 8000, 1.2f);
|
||||
Hu3DCameraViewportSet(1, 0, 0, 640, 480, 0, 1);
|
||||
Hu3DCameraScissorSet(1, 0, 16, 640, 448);
|
||||
light = Hu3DGLightCreate(0, 100, 1000, 0, -0.5, -1, 255, 255, 255);
|
||||
Hu3DGLightInfinitytSet(light);
|
||||
HuPrcChildCreate(fn_1_414, 100, 16384, 0, lbl_1_bss_78);
|
||||
HuPrcChildCreate(fn_1_AF0, 200, 4096, 0, lbl_1_bss_78);
|
||||
lbl_1_bss_7C = omAddObjEx(lbl_1_bss_78, 32730, 0, 0, -1, fn_1_B8C);
|
||||
omAddObjEx(lbl_1_bss_78, 0, 32, 32, -1, fn_1_F40);
|
||||
Hu3DBGColorSet(0, 0, 0);
|
||||
mgBoardHostEnableF = 0;
|
||||
HuWinInit(1);
|
||||
mgPracticeEnableF = 0;
|
||||
mgQuitExtraF = 0;
|
||||
s32 light;
|
||||
OSReport("******* MS ObjectSetup *********\n");
|
||||
lbl_1_bss_78 = omInitObjMan(50, 8192);
|
||||
omGameSysInit(lbl_1_bss_78);
|
||||
lbl_1_bss_24[0].x = -70;
|
||||
lbl_1_bss_24[0].y = 0;
|
||||
lbl_1_bss_24[0].z = 0;
|
||||
lbl_1_bss_C[0].x = 0;
|
||||
lbl_1_bss_C[0].y = 130;
|
||||
lbl_1_bss_C[0].z = -186;
|
||||
lbl_1_bss_4[0] = 1360;
|
||||
lbl_1_bss_64 = lbl_1_bss_24[0];
|
||||
lbl_1_bss_58 = lbl_1_bss_C[0];
|
||||
lbl_1_bss_54 = lbl_1_bss_4[0];
|
||||
lbl_1_bss_70[0] = 0;
|
||||
Hu3DCameraCreate(1);
|
||||
Hu3DCameraPerspectiveSet(1, 30, 20, 8000, 1.2f);
|
||||
Hu3DCameraViewportSet(1, 0, 0, 640, 480, 0, 1);
|
||||
Hu3DCameraScissorSet(1, 0, 16, 640, 448);
|
||||
light = Hu3DGLightCreate(0, 100, 1000, 0, -0.5, -1, 255, 255, 255);
|
||||
Hu3DGLightInfinitytSet(light);
|
||||
HuPrcChildCreate(fn_1_414, 100, 16384, 0, lbl_1_bss_78);
|
||||
HuPrcChildCreate(fn_1_AF0, 200, 4096, 0, lbl_1_bss_78);
|
||||
lbl_1_bss_7C = omAddObjEx(lbl_1_bss_78, 32730, 0, 0, -1, fn_1_B8C);
|
||||
omAddObjEx(lbl_1_bss_78, 0, 32, 32, -1, fn_1_F40);
|
||||
Hu3DBGColorSet(0, 0, 0);
|
||||
mgBoardHostEnableF = 0;
|
||||
HuWinInit(1);
|
||||
mgPracticeEnableF = 0;
|
||||
mgQuitExtraF = 0;
|
||||
}
|
||||
|
||||
void fn_1_414(void)
|
||||
{
|
||||
fn_1_9F4();
|
||||
if(omovlevtno) {
|
||||
HuAudSeqPlay(43);
|
||||
} else {
|
||||
if(!fn_1_37DC()) {
|
||||
WipeColorSet(0, 0, 0);
|
||||
WipeCreate(WIPE_MODE_OUT, WIPE_TYPE_NORMAL, 20);
|
||||
HuAudSeqAllFadeOut(1000);
|
||||
while(WipeStatGet()) {
|
||||
HuPrcVSleep();
|
||||
}
|
||||
omOvlReturnEx(1, 1);
|
||||
while(1) {
|
||||
HuPrcVSleep();
|
||||
}
|
||||
} else {
|
||||
s16 group = HuSprGrpCreate(1);
|
||||
s16 sprite = HuTHPSprCreateVol("movie/opmov_s00.thp", 0, 3000, 70.0);
|
||||
HuSprGrpMemberSet(group, 0, sprite);
|
||||
HuSprPosSet(group, 0, 288, 240);
|
||||
HuSprDrawNoSet(group, 0, 127);
|
||||
HuPrcSleep(2);
|
||||
espAttrSet(lbl_1_bss_152[0], HUSPR_ATTR_DISPOFF);
|
||||
HuAudFXStop(lbl_1_data_100);
|
||||
while(!HuTHPEndCheck()) {
|
||||
HuPrcVSleep();
|
||||
}
|
||||
HuTHPClose();
|
||||
HuSprGrpKill(group);
|
||||
}
|
||||
}
|
||||
espAttrReset(lbl_1_bss_152[9], HUSPR_ATTR_DISPOFF);
|
||||
espDrawNoSet(lbl_1_bss_152[9], 127);
|
||||
{
|
||||
s16 result = fn_1_2490();
|
||||
if(result == -1) {
|
||||
HuAudSeqAllFadeOut(1000);
|
||||
WipeColorSet(0, 0, 0);
|
||||
WipeCreate(WIPE_MODE_OUT, WIPE_TYPE_NORMAL, 20);
|
||||
|
||||
while(WipeStatGet()) {
|
||||
HuPrcVSleep();
|
||||
}
|
||||
omOvlGotoEx(OVL_MODESEL, 1, 0, 0);
|
||||
while(1) {
|
||||
HuPrcVSleep();
|
||||
}
|
||||
} else {
|
||||
s16 i;
|
||||
omOvlHisData *his;
|
||||
for(i=0; i<4; i++) {
|
||||
GWPlayerCfg[i].pad_idx = i;
|
||||
if(!HuPadStatGet(i)) {
|
||||
GWPlayerCfg[i].iscom = 0;
|
||||
} else {
|
||||
GWPlayerCfg[i].iscom = 1;
|
||||
}
|
||||
}
|
||||
his = omOvlHisGet(0);
|
||||
omOvlHisChg(0, his->overlay, 1, his->stat);
|
||||
_ClearFlag(FLAG_ID_MAKE(1, 0));
|
||||
_ClearFlag(FLAG_ID_MAKE(1, 8));
|
||||
_ClearFlag(FLAG_ID_MAKE(1, 12));
|
||||
_ClearFlag(FLAG_ID_MAKE(1, 11));
|
||||
GWGameStat.sound_mode = msmSysGetOutputMode();
|
||||
switch(result) {
|
||||
case 0:
|
||||
GWMGExplainSet(GWGameStat.party_pause.explain_mg);
|
||||
GWMGShowComSet(GWGameStat.party_pause.show_com_mg);
|
||||
GWMGListSet(GWGameStat.party_pause.mg_list);
|
||||
GWMessSpeedSet(GWGameStat.party_pause.mess_speed);
|
||||
GWSaveModeSet(GWGameStat.party_pause.save_mode);
|
||||
omOvlCallEx(OVL_MENT, 1, 0, 0);
|
||||
break;
|
||||
|
||||
case 1:
|
||||
GWMGExplainSet(GWGameStat.story_pause.explain_mg);
|
||||
GWMGShowComSet(GWGameStat.story_pause.show_com_mg);
|
||||
GWMGListSet(GWGameStat.story_pause.mg_list);
|
||||
GWMessSpeedSet(GWGameStat.story_pause.mess_speed);
|
||||
GWSaveModeSet(GWGameStat.story_pause.save_mode);
|
||||
omOvlCallEx(OVL_MENT, 1, 1, 0);
|
||||
break;
|
||||
|
||||
case 2:
|
||||
omOvlCallEx(OVL_MGMODE, 1, 0, 0);
|
||||
break;
|
||||
|
||||
case 3:
|
||||
omOvlCallEx(OVL_MENT, 1, 3, 0);
|
||||
break;
|
||||
|
||||
case 4:
|
||||
omOvlCallEx(OVL_MENT, 1, 4, 0);
|
||||
break;
|
||||
|
||||
case 5:
|
||||
omOvlCallEx(OVL_MPEX, 1, 0, 0);
|
||||
break;
|
||||
}
|
||||
while(1) {
|
||||
HuPrcVSleep();
|
||||
}
|
||||
}
|
||||
}
|
||||
fn_1_9F4();
|
||||
if (omovlevtno) {
|
||||
HuAudSeqPlay(43);
|
||||
}
|
||||
else {
|
||||
if (!fn_1_37DC()) {
|
||||
WipeColorSet(0, 0, 0);
|
||||
WipeCreate(WIPE_MODE_OUT, WIPE_TYPE_NORMAL, 20);
|
||||
HuAudSeqAllFadeOut(1000);
|
||||
while (WipeStatGet()) {
|
||||
HuPrcVSleep();
|
||||
}
|
||||
omOvlReturnEx(1, 1);
|
||||
while (1) {
|
||||
HuPrcVSleep();
|
||||
}
|
||||
}
|
||||
else {
|
||||
s16 group = HuSprGrpCreate(1);
|
||||
s16 sprite = HuTHPSprCreateVol("movie/opmov_s00.thp", 0, 3000, 70.0);
|
||||
HuSprGrpMemberSet(group, 0, sprite);
|
||||
HuSprPosSet(group, 0, 288, 240);
|
||||
HuSprDrawNoSet(group, 0, 127);
|
||||
HuPrcSleep(2);
|
||||
espAttrSet(lbl_1_bss_152[0], HUSPR_ATTR_DISPOFF);
|
||||
HuAudFXStop(lbl_1_data_100);
|
||||
while (!HuTHPEndCheck()) {
|
||||
HuPrcVSleep();
|
||||
}
|
||||
HuTHPClose();
|
||||
HuSprGrpKill(group);
|
||||
}
|
||||
}
|
||||
espAttrReset(lbl_1_bss_152[9], HUSPR_ATTR_DISPOFF);
|
||||
espDrawNoSet(lbl_1_bss_152[9], 127);
|
||||
{
|
||||
s16 result = fn_1_2490();
|
||||
if (result == -1) {
|
||||
HuAudSeqAllFadeOut(1000);
|
||||
WipeColorSet(0, 0, 0);
|
||||
WipeCreate(WIPE_MODE_OUT, WIPE_TYPE_NORMAL, 20);
|
||||
|
||||
while (WipeStatGet()) {
|
||||
HuPrcVSleep();
|
||||
}
|
||||
omOvlGotoEx(OVL_MODESEL, 1, 0, 0);
|
||||
while (1) {
|
||||
HuPrcVSleep();
|
||||
}
|
||||
}
|
||||
else {
|
||||
s16 i;
|
||||
omOvlHisData *his;
|
||||
for (i = 0; i < 4; i++) {
|
||||
GWPlayerCfg[i].pad_idx = i;
|
||||
if (!HuPadStatGet(i)) {
|
||||
GWPlayerCfg[i].iscom = 0;
|
||||
}
|
||||
else {
|
||||
GWPlayerCfg[i].iscom = 1;
|
||||
}
|
||||
}
|
||||
his = omOvlHisGet(0);
|
||||
omOvlHisChg(0, his->overlay, 1, his->stat);
|
||||
_ClearFlag(FLAG_ID_MAKE(1, 0));
|
||||
_ClearFlag(FLAG_ID_MAKE(1, 8));
|
||||
_ClearFlag(FLAG_ID_MAKE(1, 12));
|
||||
_ClearFlag(FLAG_ID_MAKE(1, 11));
|
||||
GWGameStat.sound_mode = msmSysGetOutputMode();
|
||||
switch (result) {
|
||||
case 0:
|
||||
GWMGExplainSet(GWGameStat.party_pause.explain_mg);
|
||||
GWMGShowComSet(GWGameStat.party_pause.show_com_mg);
|
||||
GWMGListSet(GWGameStat.party_pause.mg_list);
|
||||
GWMessSpeedSet(GWGameStat.party_pause.mess_speed);
|
||||
GWSaveModeSet(GWGameStat.party_pause.save_mode);
|
||||
omOvlCallEx(OVL_MENT, 1, 0, 0);
|
||||
break;
|
||||
|
||||
case 1:
|
||||
GWMGExplainSet(GWGameStat.story_pause.explain_mg);
|
||||
GWMGShowComSet(GWGameStat.story_pause.show_com_mg);
|
||||
GWMGListSet(GWGameStat.story_pause.mg_list);
|
||||
GWMessSpeedSet(GWGameStat.story_pause.mess_speed);
|
||||
GWSaveModeSet(GWGameStat.story_pause.save_mode);
|
||||
omOvlCallEx(OVL_MENT, 1, 1, 0);
|
||||
break;
|
||||
|
||||
case 2:
|
||||
omOvlCallEx(OVL_MGMODE, 1, 0, 0);
|
||||
break;
|
||||
|
||||
case 3:
|
||||
omOvlCallEx(OVL_MENT, 1, 3, 0);
|
||||
break;
|
||||
|
||||
case 4:
|
||||
omOvlCallEx(OVL_MENT, 1, 4, 0);
|
||||
break;
|
||||
|
||||
case 5:
|
||||
omOvlCallEx(OVL_MPEX, 1, 0, 0);
|
||||
break;
|
||||
}
|
||||
while (1) {
|
||||
HuPrcVSleep();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void fn_1_9F4(void)
|
||||
{
|
||||
Vec pos;
|
||||
Vec target;
|
||||
Vec up;
|
||||
Hu3DShadowCreate(20, 100, 5000);
|
||||
Hu3DShadowTPLvlSet(0.3f);
|
||||
Hu3DShadowSizeSet(192);
|
||||
target.x = target.y = target.z = 0;
|
||||
pos.x = 500;
|
||||
pos.z = 1000;
|
||||
pos.y = 2000;
|
||||
up.x = 0;
|
||||
up.y = 1;
|
||||
up.z = 0;
|
||||
Hu3DShadowPosSet(&pos, &up, &target);
|
||||
fn_1_BED8(lbl_1_data_428);
|
||||
fn_1_C168(lbl_1_data_93C);
|
||||
Vec pos;
|
||||
Vec target;
|
||||
Vec up;
|
||||
Hu3DShadowCreate(20, 100, 5000);
|
||||
Hu3DShadowTPLvlSet(0.3f);
|
||||
Hu3DShadowSizeSet(192);
|
||||
target.x = target.y = target.z = 0;
|
||||
pos.x = 500;
|
||||
pos.z = 1000;
|
||||
pos.y = 2000;
|
||||
up.x = 0;
|
||||
up.y = 1;
|
||||
up.z = 0;
|
||||
Hu3DShadowPosSet(&pos, &up, &target);
|
||||
fn_1_BED8(lbl_1_data_428);
|
||||
fn_1_C168(lbl_1_data_93C);
|
||||
}
|
||||
|
||||
void fn_1_AF0(void)
|
||||
{
|
||||
s16 i;
|
||||
while(1) {
|
||||
if(lbl_1_bss_70[0] || omSysExitReq) {
|
||||
break;
|
||||
}
|
||||
HuPrcVSleep();
|
||||
}
|
||||
for(i=0; i<4; i++) {
|
||||
GWPlayerCfg[i].character = -1;
|
||||
}
|
||||
BoardStatusKill();
|
||||
omOvlReturnEx(1, 1);
|
||||
HuPrcEnd();
|
||||
s16 i;
|
||||
while (1) {
|
||||
if (lbl_1_bss_70[0] || omSysExitReq) {
|
||||
break;
|
||||
}
|
||||
HuPrcVSleep();
|
||||
}
|
||||
for (i = 0; i < 4; i++) {
|
||||
GWPlayerCfg[i].character = -1;
|
||||
}
|
||||
BoardStatusKill();
|
||||
omOvlReturnEx(1, 1);
|
||||
HuPrcEnd();
|
||||
}
|
||||
|
||||
u16 lbl_1_data_6E[] = { 1, 2 };
|
||||
|
||||
void fn_1_B8C(omObjData *object)
|
||||
{
|
||||
s16 i;
|
||||
for(i=0; i<1; i++) {
|
||||
Vec pos, target, up;
|
||||
float x, y, z;
|
||||
|
||||
x = lbl_1_bss_24[i].x;
|
||||
y = lbl_1_bss_24[i].y;
|
||||
z = lbl_1_bss_24[i].z;
|
||||
|
||||
pos.x = (((sin((M_PI*y)/180.0)*cos((M_PI*x)/180.0))*lbl_1_bss_4[i])+lbl_1_bss_C[i].x);
|
||||
pos.y = (-sin((M_PI*x)/180.0)*lbl_1_bss_4[i])+lbl_1_bss_C[i].y;
|
||||
pos.z = ((cos((M_PI*y)/180.0)*cos((M_PI*x)/180.0))*lbl_1_bss_4[i])+lbl_1_bss_C[i].z;
|
||||
target.x = lbl_1_bss_C[i].x;
|
||||
target.y = lbl_1_bss_C[i].y;
|
||||
target.z = lbl_1_bss_C[i].z;
|
||||
up.x = sin((M_PI*y)/180.0)*sin((M_PI*x)/180.0);
|
||||
up.y = cos((M_PI*x)/180.0);
|
||||
up.z = cos((M_PI*y)/180.0)*sin((M_PI*x)/180.0);
|
||||
Hu3DCameraPosSet(lbl_1_data_6E[i], pos.x, pos.y, pos.z, up.x, up.y, up.z, target.x, target.y, target.z);
|
||||
}
|
||||
s16 i;
|
||||
for (i = 0; i < 1; i++) {
|
||||
Vec pos, target, up;
|
||||
float x, y, z;
|
||||
|
||||
x = lbl_1_bss_24[i].x;
|
||||
y = lbl_1_bss_24[i].y;
|
||||
z = lbl_1_bss_24[i].z;
|
||||
|
||||
pos.x = (((sin((M_PI * y) / 180.0) * cos((M_PI * x) / 180.0)) * lbl_1_bss_4[i]) + lbl_1_bss_C[i].x);
|
||||
pos.y = (-sin((M_PI * x) / 180.0) * lbl_1_bss_4[i]) + lbl_1_bss_C[i].y;
|
||||
pos.z = ((cos((M_PI * y) / 180.0) * cos((M_PI * x) / 180.0)) * lbl_1_bss_4[i]) + lbl_1_bss_C[i].z;
|
||||
target.x = lbl_1_bss_C[i].x;
|
||||
target.y = lbl_1_bss_C[i].y;
|
||||
target.z = lbl_1_bss_C[i].z;
|
||||
up.x = sin((M_PI * y) / 180.0) * sin((M_PI * x) / 180.0);
|
||||
up.y = cos((M_PI * x) / 180.0);
|
||||
up.z = cos((M_PI * y) / 180.0) * sin((M_PI * x) / 180.0);
|
||||
Hu3DCameraPosSet(lbl_1_data_6E[i], pos.x, pos.y, pos.z, up.x, up.y, up.z, target.x, target.y, target.z);
|
||||
}
|
||||
}
|
||||
|
||||
void fn_1_F40(omObjData *object)
|
||||
{
|
||||
Vec pos;
|
||||
Vec pos;
|
||||
Vec offset;
|
||||
Vec dir;
|
||||
Vec y_offset;
|
||||
|
||||
|
||||
f32 z_rot;
|
||||
s8 stick_pos;
|
||||
|
||||
if (!lbl_1_bss_0) {
|
||||
fn_1_1B6C();
|
||||
fn_1_1B6C();
|
||||
return;
|
||||
}
|
||||
lbl_1_bss_24[0].y += 0.1f * HuPadStkX[0];
|
||||
lbl_1_bss_24[0].x += 0.1f * HuPadStkY[0];
|
||||
lbl_1_bss_4[0] += HuPadTrigL[0] / 2;
|
||||
lbl_1_bss_4[0] -= HuPadTrigR[0] / 2;
|
||||
if(HuPadBtnDown[0] & PAD_BUTTON_B) {
|
||||
OSReport("%f,%f,%f\n", lbl_1_bss_24[0].x, lbl_1_bss_24[0].y, lbl_1_bss_24[0].z);
|
||||
OSReport("%f,%f,%f\n", lbl_1_bss_C[0].x, lbl_1_bss_C[0].y, lbl_1_bss_C[0].z);
|
||||
OSReport("%f\n", lbl_1_bss_4[0]);
|
||||
}
|
||||
if (lbl_1_bss_4[0] < 100.0f) {
|
||||
lbl_1_bss_4[0] = 100.0f;
|
||||
}
|
||||
pos.x = lbl_1_bss_C[0].x + (lbl_1_bss_4[0] * (sin((M_PI * lbl_1_bss_24[0].y) / 180.0) * cos((M_PI * lbl_1_bss_24[0].x) / 180.0)));
|
||||
pos.y = (lbl_1_bss_C[0].y + (lbl_1_bss_4[0] * -sin((M_PI * lbl_1_bss_24[0].x) / 180.0)));
|
||||
pos.z = (lbl_1_bss_C[0].z + (lbl_1_bss_4[0] * (cos((M_PI * lbl_1_bss_24[0].y) / 180.0) * cos((M_PI * lbl_1_bss_24[0].x) / 180.0))));
|
||||
offset.x = lbl_1_bss_C[0].x - pos.x;
|
||||
offset.y = lbl_1_bss_C[0].y - pos.y;
|
||||
offset.z = lbl_1_bss_C[0].z - pos.z;
|
||||
dir.x = (sin((M_PI * lbl_1_bss_24[0].y) / 180.0) * sin((M_PI * lbl_1_bss_24[0].x) / 180.0));
|
||||
dir.y = cos((M_PI * lbl_1_bss_24[0].x) / 180.0);
|
||||
dir.z = (cos((M_PI * lbl_1_bss_24[0].y) / 180.0) * sin((M_PI * lbl_1_bss_24[0].x) / 180.0));
|
||||
z_rot = lbl_1_bss_24[0].z;
|
||||
y_offset.x = dir.x * (offset.x * offset.x + (1.0f - offset.x * offset.x) * cos((M_PI * z_rot) / 180.0))
|
||||
+ dir.y * (offset.x * offset.y * (1.0f - cos((M_PI * z_rot) / 180.0)) - offset.z * sin((M_PI * z_rot) / 180.0))
|
||||
+ dir.z * (offset.x * offset.z * (1.0f - cos((M_PI * z_rot) / 180.0)) + offset.y * sin((M_PI * z_rot) / 180.0));
|
||||
lbl_1_bss_24[0].y += 0.1f * HuPadStkX[0];
|
||||
lbl_1_bss_24[0].x += 0.1f * HuPadStkY[0];
|
||||
lbl_1_bss_4[0] += HuPadTrigL[0] / 2;
|
||||
lbl_1_bss_4[0] -= HuPadTrigR[0] / 2;
|
||||
if (HuPadBtnDown[0] & PAD_BUTTON_B) {
|
||||
OSReport("%f,%f,%f\n", lbl_1_bss_24[0].x, lbl_1_bss_24[0].y, lbl_1_bss_24[0].z);
|
||||
OSReport("%f,%f,%f\n", lbl_1_bss_C[0].x, lbl_1_bss_C[0].y, lbl_1_bss_C[0].z);
|
||||
OSReport("%f\n", lbl_1_bss_4[0]);
|
||||
}
|
||||
if (lbl_1_bss_4[0] < 100.0f) {
|
||||
lbl_1_bss_4[0] = 100.0f;
|
||||
}
|
||||
pos.x = lbl_1_bss_C[0].x + (lbl_1_bss_4[0] * (sin((M_PI * lbl_1_bss_24[0].y) / 180.0) * cos((M_PI * lbl_1_bss_24[0].x) / 180.0)));
|
||||
pos.y = (lbl_1_bss_C[0].y + (lbl_1_bss_4[0] * -sin((M_PI * lbl_1_bss_24[0].x) / 180.0)));
|
||||
pos.z = (lbl_1_bss_C[0].z + (lbl_1_bss_4[0] * (cos((M_PI * lbl_1_bss_24[0].y) / 180.0) * cos((M_PI * lbl_1_bss_24[0].x) / 180.0))));
|
||||
offset.x = lbl_1_bss_C[0].x - pos.x;
|
||||
offset.y = lbl_1_bss_C[0].y - pos.y;
|
||||
offset.z = lbl_1_bss_C[0].z - pos.z;
|
||||
dir.x = (sin((M_PI * lbl_1_bss_24[0].y) / 180.0) * sin((M_PI * lbl_1_bss_24[0].x) / 180.0));
|
||||
dir.y = cos((M_PI * lbl_1_bss_24[0].x) / 180.0);
|
||||
dir.z = (cos((M_PI * lbl_1_bss_24[0].y) / 180.0) * sin((M_PI * lbl_1_bss_24[0].x) / 180.0));
|
||||
z_rot = lbl_1_bss_24[0].z;
|
||||
y_offset.x = dir.x * (offset.x * offset.x + (1.0f - offset.x * offset.x) * cos((M_PI * z_rot) / 180.0))
|
||||
+ dir.y * (offset.x * offset.y * (1.0f - cos((M_PI * z_rot) / 180.0)) - offset.z * sin((M_PI * z_rot) / 180.0))
|
||||
+ dir.z * (offset.x * offset.z * (1.0f - cos((M_PI * z_rot) / 180.0)) + offset.y * sin((M_PI * z_rot) / 180.0));
|
||||
|
||||
y_offset.y = dir.y * (offset.y * offset.y + (1.0f - offset.y * offset.y) * cos((M_PI * z_rot) / 180.0))
|
||||
+ dir.x * (offset.x * offset.y * (1.0f - cos((M_PI * z_rot) / 180.0)) + offset.z * sin((M_PI * z_rot) / 180.0))
|
||||
+ dir.z * (offset.y * offset.z * (1.0f - cos((M_PI * z_rot) / 180.0)) - offset.x * sin((M_PI * z_rot) / 180.0));
|
||||
|
||||
y_offset.z = dir.z * (offset.z * offset.z + (1.0f - offset.z * offset.z) * cos((M_PI * z_rot) / 180.0))
|
||||
+ (dir.x * (offset.x * offset.z * (1.0 - cos((M_PI * z_rot) / 180.0)) - offset.y * sin((M_PI * z_rot) / 180.0))
|
||||
+ dir.y * (offset.y * offset.z * (1.0 - cos((M_PI * z_rot) / 180.0)) + offset.x * sin((M_PI * z_rot) / 180.0)));
|
||||
y_offset.y = dir.y * (offset.y * offset.y + (1.0f - offset.y * offset.y) * cos((M_PI * z_rot) / 180.0))
|
||||
+ dir.x * (offset.x * offset.y * (1.0f - cos((M_PI * z_rot) / 180.0)) + offset.z * sin((M_PI * z_rot) / 180.0))
|
||||
+ dir.z * (offset.y * offset.z * (1.0f - cos((M_PI * z_rot) / 180.0)) - offset.x * sin((M_PI * z_rot) / 180.0));
|
||||
|
||||
VECCrossProduct(&dir, &offset, &offset);
|
||||
VECNormalize(&offset, &offset);
|
||||
stick_pos = (HuPadSubStkX[0] & 0xF8);
|
||||
if (stick_pos != 0) {
|
||||
lbl_1_bss_C[0].x += 0.05f * (offset.x * stick_pos);
|
||||
lbl_1_bss_C[0].y += 0.05f * (offset.y * stick_pos);
|
||||
lbl_1_bss_C[0].z += 0.05f * (offset.z * stick_pos);
|
||||
}
|
||||
VECNormalize(&y_offset, &offset);
|
||||
stick_pos = -(HuPadSubStkY[0] & 0xF8);
|
||||
if (stick_pos != 0) {
|
||||
lbl_1_bss_C[0].x += 0.05f * (offset.x * stick_pos);
|
||||
lbl_1_bss_C[0].y += 0.05f * (offset.y * stick_pos);
|
||||
lbl_1_bss_C[0].z += 0.05f * (offset.z * stick_pos);
|
||||
}
|
||||
y_offset.z = dir.z * (offset.z * offset.z + (1.0f - offset.z * offset.z) * cos((M_PI * z_rot) / 180.0))
|
||||
+ (dir.x * (offset.x * offset.z * (1.0 - cos((M_PI * z_rot) / 180.0)) - offset.y * sin((M_PI * z_rot) / 180.0))
|
||||
+ dir.y * (offset.y * offset.z * (1.0 - cos((M_PI * z_rot) / 180.0)) + offset.x * sin((M_PI * z_rot) / 180.0)));
|
||||
|
||||
VECCrossProduct(&dir, &offset, &offset);
|
||||
VECNormalize(&offset, &offset);
|
||||
stick_pos = (HuPadSubStkX[0] & 0xF8);
|
||||
if (stick_pos != 0) {
|
||||
lbl_1_bss_C[0].x += 0.05f * (offset.x * stick_pos);
|
||||
lbl_1_bss_C[0].y += 0.05f * (offset.y * stick_pos);
|
||||
lbl_1_bss_C[0].z += 0.05f * (offset.z * stick_pos);
|
||||
}
|
||||
VECNormalize(&y_offset, &offset);
|
||||
stick_pos = -(HuPadSubStkY[0] & 0xF8);
|
||||
if (stick_pos != 0) {
|
||||
lbl_1_bss_C[0].x += 0.05f * (offset.x * stick_pos);
|
||||
lbl_1_bss_C[0].y += 0.05f * (offset.y * stick_pos);
|
||||
lbl_1_bss_C[0].z += 0.05f * (offset.z * stick_pos);
|
||||
}
|
||||
}
|
||||
|
||||
void fn_1_1B6C(void)
|
||||
{
|
||||
Vec delta_vec;
|
||||
float delta_zoom;
|
||||
if(lbl_1_bss_70[0]) {
|
||||
return;
|
||||
}
|
||||
VECSubtract(&lbl_1_bss_64, &lbl_1_bss_24[0], &delta_vec);
|
||||
if(VECMag(&delta_vec) > 0.2) {
|
||||
VECScale(&delta_vec, &delta_vec, 0.05f);
|
||||
VECAdd(&lbl_1_bss_24[0], &delta_vec, &lbl_1_bss_24[0]);
|
||||
} else {
|
||||
lbl_1_bss_24[0] = lbl_1_bss_64;
|
||||
}
|
||||
VECSubtract(&lbl_1_bss_58, &lbl_1_bss_C[0], &delta_vec);
|
||||
if(VECMag(&delta_vec) > 0.2) {
|
||||
VECScale(&delta_vec, &delta_vec, 0.05f);
|
||||
VECAdd(&lbl_1_bss_C[0], &delta_vec, &lbl_1_bss_C[0]);
|
||||
} else {
|
||||
lbl_1_bss_C[0] = lbl_1_bss_58;
|
||||
}
|
||||
delta_zoom = lbl_1_bss_54-lbl_1_bss_4[0];
|
||||
if(sqrtf(delta_zoom*delta_zoom) > 0.2) {
|
||||
delta_zoom *= 0.05f;
|
||||
lbl_1_bss_4[0] += delta_zoom;
|
||||
} else {
|
||||
lbl_1_bss_4[0] = lbl_1_bss_54;
|
||||
}
|
||||
Vec delta_vec;
|
||||
float delta_zoom;
|
||||
if (lbl_1_bss_70[0]) {
|
||||
return;
|
||||
}
|
||||
VECSubtract(&lbl_1_bss_64, &lbl_1_bss_24[0], &delta_vec);
|
||||
if (VECMag(&delta_vec) > 0.2) {
|
||||
VECScale(&delta_vec, &delta_vec, 0.05f);
|
||||
VECAdd(&lbl_1_bss_24[0], &delta_vec, &lbl_1_bss_24[0]);
|
||||
}
|
||||
else {
|
||||
lbl_1_bss_24[0] = lbl_1_bss_64;
|
||||
}
|
||||
VECSubtract(&lbl_1_bss_58, &lbl_1_bss_C[0], &delta_vec);
|
||||
if (VECMag(&delta_vec) > 0.2) {
|
||||
VECScale(&delta_vec, &delta_vec, 0.05f);
|
||||
VECAdd(&lbl_1_bss_C[0], &delta_vec, &lbl_1_bss_C[0]);
|
||||
}
|
||||
else {
|
||||
lbl_1_bss_C[0] = lbl_1_bss_58;
|
||||
}
|
||||
delta_zoom = lbl_1_bss_54 - lbl_1_bss_4[0];
|
||||
if (sqrtf(delta_zoom * delta_zoom) > 0.2) {
|
||||
delta_zoom *= 0.05f;
|
||||
lbl_1_bss_4[0] += delta_zoom;
|
||||
}
|
||||
else {
|
||||
lbl_1_bss_4[0] = lbl_1_bss_54;
|
||||
}
|
||||
}
|
||||
|
||||
void fn_1_1E30(s16 view)
|
||||
{
|
||||
lbl_1_bss_64 = lbl_1_data_0[view].rot;
|
||||
lbl_1_bss_58 = lbl_1_data_0[view].pos;
|
||||
lbl_1_bss_54 = lbl_1_data_0[view].zoom;
|
||||
lbl_1_bss_64 = lbl_1_data_0[view].rot;
|
||||
lbl_1_bss_58 = lbl_1_data_0[view].pos;
|
||||
lbl_1_bss_54 = lbl_1_data_0[view].zoom;
|
||||
}
|
||||
|
||||
void fn_1_1EC0(s16 view)
|
||||
{
|
||||
s16 i;
|
||||
lbl_1_bss_24[0] = lbl_1_data_0[view].rot;
|
||||
lbl_1_bss_64 = lbl_1_bss_24[0];
|
||||
lbl_1_bss_C[0] = lbl_1_data_0[view].pos;
|
||||
lbl_1_bss_58 = lbl_1_bss_C[0];
|
||||
lbl_1_bss_54 = lbl_1_bss_4[0] = lbl_1_data_0[view].zoom;
|
||||
fn_1_B8C(NULL);
|
||||
s16 i;
|
||||
lbl_1_bss_24[0] = lbl_1_data_0[view].rot;
|
||||
lbl_1_bss_64 = lbl_1_bss_24[0];
|
||||
lbl_1_bss_C[0] = lbl_1_data_0[view].pos;
|
||||
lbl_1_bss_58 = lbl_1_bss_C[0];
|
||||
lbl_1_bss_54 = lbl_1_bss_4[0] = lbl_1_data_0[view].zoom;
|
||||
fn_1_B8C(NULL);
|
||||
}
|
||||
|
||||
float fn_1_2368(void)
|
||||
{
|
||||
float delta_zoom = lbl_1_bss_54-lbl_1_bss_4[0];
|
||||
return sqrtf(delta_zoom*delta_zoom);
|
||||
float delta_zoom = lbl_1_bss_54 - lbl_1_bss_4[0];
|
||||
return sqrtf(delta_zoom * delta_zoom);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -8,7 +8,6 @@
|
|||
#include "game/pad.h"
|
||||
#include "game/printfunc.h"
|
||||
#include "game/wipe.h"
|
||||
#include "rel_sqrt_consts.h"
|
||||
|
||||
#include "REL/mpexDll.h"
|
||||
|
||||
|
|
|
|||
|
|
@ -8,7 +8,7 @@
|
|||
#include "game/gamework_data.h"
|
||||
#include "game/flag.h"
|
||||
#include "game/chrman.h"
|
||||
#include "rel_sqrt_consts.h"
|
||||
#include "math.h"
|
||||
#include "REL/executor.h"
|
||||
#include "game/board/main.h"
|
||||
|
||||
|
|
|
|||
|
|
@ -12,7 +12,7 @@
|
|||
#include "game/sprite.h"
|
||||
#include "game/wipe.h"
|
||||
|
||||
#include "rel_sqrt_consts.h"
|
||||
#include "math.h"
|
||||
|
||||
typedef struct {
|
||||
/* 0x00 */ s16 id;
|
||||
|
|
|
|||
|
|
@ -5,7 +5,7 @@
|
|||
#include "game/pad.h"
|
||||
#include "game/process.h"
|
||||
#include "game/wipe.h"
|
||||
#include "rel_sqrt_consts.h"
|
||||
#include "math.h"
|
||||
|
||||
#include "REL/present.h"
|
||||
|
||||
|
|
|
|||
|
|
@ -13,7 +13,6 @@
|
|||
#include "game/saveload.h"
|
||||
#include "game/window.h"
|
||||
#include "game/wipe.h"
|
||||
#include "rel_sqrt_consts.h"
|
||||
|
||||
#include "math.h"
|
||||
|
||||
|
|
|
|||
|
|
@ -3,7 +3,7 @@
|
|||
#include "game/gamework_data.h"
|
||||
#include "game/printfunc.h"
|
||||
#include "game/pad.h"
|
||||
#include "rel_sqrt_consts.h"
|
||||
#include "math.h"
|
||||
|
||||
s32 lbl_1_data_0 = 100;
|
||||
s32 lbl_1_bss_0[192];
|
||||
|
|
|
|||
|
|
@ -14,8 +14,8 @@
|
|||
#include "game/pad.h"
|
||||
#include "game/printfunc.h"
|
||||
#include "game/wipe.h"
|
||||
#include "math.h"
|
||||
|
||||
#include "rel_sqrt_consts.h"
|
||||
|
||||
// MSM Definitions
|
||||
static s8 *msmSeGetIndexPtr(s16 datano);
|
||||
|
|
|
|||
|
|
@ -9,7 +9,7 @@
|
|||
#include "game/window.h"
|
||||
#include "game/wipe.h"
|
||||
|
||||
#include "rel_sqrt_consts.h"
|
||||
#include "math.h"
|
||||
|
||||
typedef struct StaffData {
|
||||
/* 0x00 */ u32 unk_00;
|
||||
|
|
|
|||
|
|
@ -5,7 +5,7 @@
|
|||
#include "game/pad.h"
|
||||
#include "game/wipe.h"
|
||||
|
||||
#include "rel_sqrt_consts.h"
|
||||
#include "math.h"
|
||||
|
||||
static void SubchrMain(void);
|
||||
|
||||
|
|
|
|||
|
|
@ -10,7 +10,6 @@
|
|||
#include "game/sprite.h"
|
||||
#include "game/window.h"
|
||||
#include "game/wipe.h"
|
||||
#include "rel_sqrt_consts.h"
|
||||
|
||||
#include "REL/ztardll.h"
|
||||
|
||||
|
|
|
|||
40
src/amcstubs/AmcExi2Stubs.c
Normal file
40
src/amcstubs/AmcExi2Stubs.c
Normal file
|
|
@ -0,0 +1,40 @@
|
|||
#include <dolphin.h>
|
||||
|
||||
// EXI error codes
|
||||
typedef enum { AMC_EXI_NO_ERROR = 0, AMC_EXI_UNSELECTED } AmcExiError;
|
||||
|
||||
int AMC_IsStub();
|
||||
void EXI2_Unreserve();
|
||||
void EXI2_Reserve();
|
||||
AmcExiError EXI2_WriteN();
|
||||
AmcExiError EXI2_ReadN();
|
||||
int EXI2_Poll();
|
||||
void EXI2_EnableInterrupts();
|
||||
void EXI2_Init();
|
||||
|
||||
int AMC_IsStub()
|
||||
{
|
||||
return 1;
|
||||
}
|
||||
|
||||
void EXI2_Unreserve() { }
|
||||
|
||||
void EXI2_Reserve() { }
|
||||
|
||||
AmcExiError EXI2_WriteN()
|
||||
{
|
||||
return AMC_EXI_NO_ERROR;
|
||||
}
|
||||
|
||||
AmcExiError EXI2_ReadN()
|
||||
{
|
||||
return AMC_EXI_NO_ERROR;
|
||||
}
|
||||
|
||||
int EXI2_Poll()
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
void EXI2_EnableInterrupts() { }
|
||||
void EXI2_Init() { }
|
||||
565
src/dolphin/PPCArch.c
Normal file
565
src/dolphin/PPCArch.c
Normal file
|
|
@ -0,0 +1,565 @@
|
|||
#include "types.h"
|
||||
#include "asm_types.h"
|
||||
|
||||
/* clang-format off */
|
||||
|
||||
union FpscrUnion
|
||||
{
|
||||
f64 f;
|
||||
struct
|
||||
{
|
||||
u32 fpscr_pad;
|
||||
u32 fpscr;
|
||||
} u;
|
||||
};
|
||||
|
||||
#define HID0_SPD 0x00000200 // Speculative cache access enable (0 enable)
|
||||
|
||||
void PPCMthid0 ( u32 newHID0 );
|
||||
|
||||
/*
|
||||
* --INFO--
|
||||
* Address: 8036F7D4
|
||||
* Size: 000008
|
||||
*/
|
||||
asm u32 PPCMfmsr (void)
|
||||
{
|
||||
nofralloc
|
||||
mfmsr r3
|
||||
blr
|
||||
}
|
||||
|
||||
/*
|
||||
* --INFO--
|
||||
* Address: 8036F7DC
|
||||
* Size: 000008
|
||||
*/
|
||||
asm void PPCMtmsr (register u32 newMSR)
|
||||
{
|
||||
nofralloc
|
||||
mtmsr newMSR
|
||||
blr
|
||||
}
|
||||
|
||||
/*
|
||||
* --INFO--
|
||||
* Address: ........
|
||||
* Size: 00000C
|
||||
*/
|
||||
void PPCOrMsr(void)
|
||||
{
|
||||
// UNUSED FUNCTION
|
||||
}
|
||||
|
||||
/*
|
||||
* --INFO--
|
||||
* Address: ........
|
||||
* Size: 00000C
|
||||
*/
|
||||
void PPCAndMsr(void)
|
||||
{
|
||||
// UNUSED FUNCTION
|
||||
}
|
||||
|
||||
/*
|
||||
* --INFO--
|
||||
* Address: ........
|
||||
* Size: 00000C
|
||||
*/
|
||||
void PPCAndCMsr(void)
|
||||
{
|
||||
// UNUSED FUNCTION
|
||||
}
|
||||
|
||||
/*
|
||||
* --INFO--
|
||||
* Address: 8036F7E4
|
||||
* Size: 000008
|
||||
*/
|
||||
asm u32 PPCMfhid0 (void)
|
||||
{
|
||||
nofralloc
|
||||
mfspr r3, HID0
|
||||
blr
|
||||
}
|
||||
|
||||
/*
|
||||
* --INFO--
|
||||
* Address: 8036F7EC
|
||||
* Size: 000008
|
||||
*/
|
||||
asm void PPCMthid0 (register u32 newHID0)
|
||||
{
|
||||
nofralloc
|
||||
mtspr HID0, newHID0
|
||||
blr
|
||||
}
|
||||
|
||||
/*
|
||||
* --INFO--
|
||||
* Address: ........
|
||||
* Size: 000008
|
||||
*/
|
||||
void PPCMfhid1(void)
|
||||
{
|
||||
// UNUSED FUNCTION
|
||||
}
|
||||
|
||||
/*
|
||||
* --INFO--
|
||||
* Address: 8036F7F4
|
||||
* Size: 000008
|
||||
*/
|
||||
asm u32 PPCMfl2cr (void)
|
||||
{
|
||||
nofralloc
|
||||
mfspr r3, L2CR
|
||||
blr
|
||||
}
|
||||
|
||||
/*
|
||||
* --INFO--
|
||||
* Address: 8036F7FC
|
||||
* Size: 000008
|
||||
*/
|
||||
asm void PPCMtl2cr (register u32 newL2cr)
|
||||
{
|
||||
nofralloc
|
||||
mtspr L2CR, newL2cr
|
||||
blr
|
||||
}
|
||||
|
||||
/*
|
||||
* --INFO--
|
||||
* Address: 8036F804
|
||||
* Size: 000008
|
||||
*/
|
||||
__declspec ( weak ) asm void PPCMtdec ( register u32 newDec )
|
||||
{
|
||||
nofralloc
|
||||
mtdec newDec
|
||||
blr
|
||||
}
|
||||
|
||||
/*
|
||||
* --INFO--
|
||||
* Address: ........
|
||||
* Size: 000008
|
||||
*/
|
||||
void PPCMfdec(void)
|
||||
{
|
||||
// UNUSED FUNCTION
|
||||
}
|
||||
|
||||
/*
|
||||
* --INFO--
|
||||
* Address: 8036F80C
|
||||
* Size: 000008
|
||||
*/
|
||||
asm void PPCSync (void)
|
||||
{
|
||||
nofralloc
|
||||
sc
|
||||
blr
|
||||
}
|
||||
|
||||
/*
|
||||
* --INFO--
|
||||
* Address: ........
|
||||
* Size: 000034
|
||||
*/
|
||||
asm void PPCEieio(void) {
|
||||
nofralloc
|
||||
mfmsr r5
|
||||
rlwinm r6, r5, 0, 0x11, 0xf
|
||||
mtmsr r6
|
||||
mfspr r3, hid0
|
||||
ori r4, r3, 8
|
||||
mtspr hid0, r4
|
||||
isync
|
||||
eieio
|
||||
isync
|
||||
|
||||
mtspr hid0, r3
|
||||
mtmsr r5
|
||||
isync
|
||||
|
||||
blr
|
||||
}
|
||||
|
||||
/*
|
||||
* --INFO--
|
||||
* Address: 8036F814
|
||||
* Size: 000014
|
||||
*/
|
||||
__declspec ( weak ) asm void PPCHalt (void) //spins infinitely
|
||||
{
|
||||
nofralloc
|
||||
|
||||
sync
|
||||
|
||||
_spin:
|
||||
nop
|
||||
li r3, 0
|
||||
nop
|
||||
b _spin
|
||||
|
||||
// NEVER REACHED
|
||||
}
|
||||
|
||||
/*
|
||||
* --INFO--
|
||||
* Address: ........
|
||||
* Size: 000008
|
||||
*/
|
||||
asm void PPCMfmmcr0(void)
|
||||
{
|
||||
nofralloc
|
||||
mfspr r3, MMCR0
|
||||
blr
|
||||
}
|
||||
|
||||
/*
|
||||
* --INFO--
|
||||
* Address: ........
|
||||
* Size: 000008
|
||||
* UNUSED
|
||||
*/
|
||||
asm void PPCMtmmcr0 (register u32 newMmcr0)
|
||||
{
|
||||
nofralloc
|
||||
mtspr MMCR0, newMmcr0
|
||||
blr
|
||||
}
|
||||
|
||||
/*
|
||||
* --INFO--
|
||||
* Address: ........
|
||||
* Size: 000008
|
||||
*/
|
||||
asm void PPCMfmmcr1(void)
|
||||
{
|
||||
nofralloc
|
||||
mfspr r3, MMCR1
|
||||
blr}
|
||||
|
||||
/*
|
||||
* --INFO--
|
||||
* Address: ........
|
||||
* Size: 000008
|
||||
* UNUSED
|
||||
*/
|
||||
asm void PPCMtmmcr1 (register u32 newMmcr1)
|
||||
{
|
||||
nofralloc
|
||||
mtspr MMCR1, newMmcr1
|
||||
blr
|
||||
}
|
||||
|
||||
/*
|
||||
* --INFO--
|
||||
* Address: ........
|
||||
* Size: 000008
|
||||
*/
|
||||
asm void PPCMfpmc1(void)
|
||||
{
|
||||
nofralloc
|
||||
mfspr r3, PMC1
|
||||
blr
|
||||
}
|
||||
|
||||
/*
|
||||
* --INFO--
|
||||
* Address: ........
|
||||
* Size: 000008
|
||||
* UNUSED
|
||||
*/
|
||||
asm void PPCMtpmc1 (register u32 newPmc1)
|
||||
{
|
||||
nofralloc
|
||||
mtspr PMC1, newPmc1
|
||||
blr
|
||||
}
|
||||
|
||||
/*
|
||||
* --INFO--
|
||||
* Address: ........
|
||||
* Size: 000008
|
||||
*/
|
||||
asm void PPCMfpmc2(void)
|
||||
{
|
||||
nofralloc
|
||||
mfspr r3, PMC2
|
||||
blr
|
||||
}
|
||||
|
||||
/*
|
||||
* --INFO--
|
||||
* Address: ........
|
||||
* Size: 000008
|
||||
* UNUSED
|
||||
*/
|
||||
asm void PPCMtpmc2 (register u32 newPmc2)
|
||||
{
|
||||
nofralloc
|
||||
mtspr PMC2, newPmc2
|
||||
blr
|
||||
}
|
||||
|
||||
/*
|
||||
* --INFO--
|
||||
* Address: ........
|
||||
* Size: 000008
|
||||
*/
|
||||
asm void PPCMfpmc3(void)
|
||||
{
|
||||
nofralloc
|
||||
mfspr r3, PMC2
|
||||
blr}
|
||||
|
||||
/*
|
||||
* --INFO--
|
||||
* Address: ........
|
||||
* Size: 000008
|
||||
* UNUSED
|
||||
*/
|
||||
asm void PPCMtpmc3 (register u32 newPmc3)
|
||||
{
|
||||
nofralloc
|
||||
mtspr PMC3, newPmc3
|
||||
blr
|
||||
}
|
||||
|
||||
/*
|
||||
* --INFO--
|
||||
* Address: ........
|
||||
* Size: 000008
|
||||
*/
|
||||
asm void PPCMfpmc4(void)
|
||||
{
|
||||
nofralloc
|
||||
mfspr r3, PMC4
|
||||
blr
|
||||
}
|
||||
|
||||
/*
|
||||
* --INFO--
|
||||
* Address: ........
|
||||
* Size: 000008
|
||||
* UNUSED
|
||||
*/
|
||||
asm void PPCMtpmc4 (register u32 newPmc4)
|
||||
{
|
||||
nofralloc
|
||||
mtspr PMC4, newPmc4
|
||||
blr
|
||||
}
|
||||
|
||||
/*
|
||||
* --INFO--
|
||||
* Address: ........
|
||||
* Size: 000008
|
||||
*/
|
||||
asm void PPCMfsia(void)
|
||||
{
|
||||
nofralloc
|
||||
mfspr r3, SIA
|
||||
blr}
|
||||
|
||||
/*
|
||||
* --INFO--
|
||||
* Address: ........
|
||||
* Size: 000008
|
||||
*/
|
||||
asm void PPCMtsia(register u32 newSia)
|
||||
{
|
||||
nofralloc
|
||||
mtspr SIA, newSia
|
||||
blr
|
||||
}
|
||||
|
||||
/*
|
||||
* --INFO--
|
||||
* Address: 8036F828
|
||||
* Size: 000020
|
||||
*/
|
||||
u32 PPCMffpscr(void)
|
||||
{
|
||||
union FpscrUnion m;
|
||||
|
||||
|
||||
asm
|
||||
{
|
||||
mffs fp31
|
||||
stfd fp31, m.f;
|
||||
}
|
||||
|
||||
return m.u.fpscr;
|
||||
}
|
||||
|
||||
/*
|
||||
* --INFO--
|
||||
* Address: 8036F848
|
||||
* Size: 000028
|
||||
*/
|
||||
void PPCMtfpscr(register u32 newFPSCR)
|
||||
{
|
||||
union FpscrUnion m;
|
||||
|
||||
asm
|
||||
{
|
||||
li r4, 0
|
||||
stw r4, m.u.fpscr_pad;
|
||||
stw newFPSCR, m.u.fpscr
|
||||
lfd fp31, m.f
|
||||
mtfsf 0xff, fp31
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* --INFO--
|
||||
* Address: 8036F870
|
||||
* Size: 000008
|
||||
*/
|
||||
asm u32 PPCMfhid2 ( void )
|
||||
{
|
||||
nofralloc
|
||||
mfspr r3, HID2
|
||||
blr
|
||||
}
|
||||
|
||||
/*
|
||||
* --INFO--
|
||||
* Address: 8036F878
|
||||
* Size: 000008
|
||||
*/
|
||||
asm void PPCMthid2 ( register u32 newhid2 )
|
||||
{
|
||||
nofralloc
|
||||
mtspr HID2, newhid2
|
||||
blr
|
||||
}
|
||||
|
||||
/*
|
||||
* --INFO--
|
||||
* Address: 8036F880
|
||||
* Size: 00000C
|
||||
*/
|
||||
asm u32 PPCMfwpar(void)
|
||||
{
|
||||
nofralloc
|
||||
sync
|
||||
mfspr r3, WPAR
|
||||
blr
|
||||
}
|
||||
|
||||
/*
|
||||
* --INFO--
|
||||
* Address: 8036F88C
|
||||
* Size: 000008
|
||||
*/
|
||||
asm void PPCMtwpar ( register u32 newwpar )
|
||||
{
|
||||
nofralloc
|
||||
mtspr WPAR, newwpar
|
||||
blr
|
||||
}
|
||||
|
||||
/*
|
||||
* --INFO--
|
||||
* Address: ........
|
||||
* Size: 000008
|
||||
*/
|
||||
asm void PPCMfdmaU(void)
|
||||
{
|
||||
nofralloc
|
||||
mfspr r3, DMA_U
|
||||
blr
|
||||
}
|
||||
|
||||
/*
|
||||
* --INFO--
|
||||
* Address: ........
|
||||
* Size: 000008
|
||||
*/
|
||||
asm void PPCMfdmaL(void)
|
||||
{
|
||||
nofralloc
|
||||
mfspr r3, DMA_L
|
||||
blr
|
||||
}
|
||||
|
||||
/*
|
||||
* --INFO--
|
||||
* Address: ........
|
||||
* Size: 000008
|
||||
*/
|
||||
void PPCMtdmaU(void)
|
||||
{
|
||||
// UNUSED FUNCTION
|
||||
}
|
||||
|
||||
/*
|
||||
* --INFO--
|
||||
* Address: ........
|
||||
* Size: 000008
|
||||
*/
|
||||
void PPCMtdmaL(void)
|
||||
{
|
||||
// UNUSED FUNCTION
|
||||
}
|
||||
|
||||
/*
|
||||
* --INFO--
|
||||
* Address: ........
|
||||
* Size: 000008
|
||||
*/
|
||||
void PPCMfpvr(void)
|
||||
{
|
||||
// UNUSED FUNCTION
|
||||
}
|
||||
|
||||
/*
|
||||
* --INFO--
|
||||
* Address: ........
|
||||
* Size: 000028
|
||||
*/
|
||||
void PPCEnableSpeculation(void)
|
||||
{
|
||||
// UNUSED FUNCTION
|
||||
}
|
||||
|
||||
/*
|
||||
* --INFO--
|
||||
* Address: 8036F894
|
||||
* Size: 000028
|
||||
*/
|
||||
void PPCDisableSpeculation (void)
|
||||
{
|
||||
PPCMthid0(PPCMfhid0() | HID0_SPD);
|
||||
}
|
||||
|
||||
/*
|
||||
* --INFO--
|
||||
* Address: 8036F8BC
|
||||
* Size: 000008
|
||||
*/
|
||||
asm void PPCSetFpIEEEMode(void)
|
||||
{
|
||||
nofralloc
|
||||
mtfsb0 4*7+1
|
||||
blr
|
||||
}
|
||||
/*
|
||||
* --INFO--
|
||||
* Address: 8036F8C4
|
||||
* Size: 000008
|
||||
*/
|
||||
asm void PPCSetFpNonIEEEMode (void)
|
||||
{
|
||||
nofralloc
|
||||
mtfsb1 4*7+1
|
||||
blr
|
||||
}
|
||||
|
||||
/* clang-format on */
|
||||
362
src/dolphin/ai.c
Normal file
362
src/dolphin/ai.c
Normal file
|
|
@ -0,0 +1,362 @@
|
|||
#include "dolphin/ai.h"
|
||||
#include "dolphin/hw_regs.h"
|
||||
#include "dolphin/os.h"
|
||||
|
||||
const char *__AIVersion = "<< Dolphin SDK - AI\trelease build: Sep 5 2002 05:34:25 (0x2301) >>";
|
||||
|
||||
static AISCallback __AIS_Callback = NULL;
|
||||
static AIDCallback __AID_Callback = NULL;
|
||||
static u8 *__CallbackStack;
|
||||
static u8 *__OldStack;
|
||||
static volatile s32 __AI_init_flag = FALSE;
|
||||
static volatile s32 __AID_Active = FALSE;
|
||||
|
||||
static OSTime bound_32KHz;
|
||||
static OSTime bound_48KHz;
|
||||
static OSTime min_wait;
|
||||
static OSTime max_wait;
|
||||
static OSTime buffer;
|
||||
|
||||
void __AISHandler(s16 interrupt, OSContext *context);
|
||||
void __AIDHandler(s16 interrupt, OSContext *context);
|
||||
void __AICallbackStackSwitch(register AIDCallback cb);
|
||||
void __AI_SRC_INIT(void);
|
||||
|
||||
AIDCallback AIRegisterDMACallback(AIDCallback callback)
|
||||
{
|
||||
s32 oldInts;
|
||||
AIDCallback ret;
|
||||
|
||||
ret = __AID_Callback;
|
||||
oldInts = OSDisableInterrupts();
|
||||
__AID_Callback = callback;
|
||||
OSRestoreInterrupts(oldInts);
|
||||
return ret;
|
||||
}
|
||||
|
||||
void AIInitDMA(u32 addr, u32 length)
|
||||
{
|
||||
s32 oldInts;
|
||||
oldInts = OSDisableInterrupts();
|
||||
__DSPRegs[24] = (u16)((__DSPRegs[24] & ~0x3FF) | (addr >> 16));
|
||||
__DSPRegs[25] = (u16)((__DSPRegs[25] & ~0xFFE0) | (0xffff & addr));
|
||||
__DSPRegs[27] = (u16)((__DSPRegs[27] & ~0x7FFF) | (u16)((length >> 5) & 0xFFFF));
|
||||
OSRestoreInterrupts(oldInts);
|
||||
}
|
||||
|
||||
void AIStartDMA()
|
||||
{
|
||||
__DSPRegs[27] |= 0x8000;
|
||||
}
|
||||
|
||||
void AIStopDMA(void)
|
||||
{
|
||||
__DSPRegs[27] &= ~0x8000;
|
||||
}
|
||||
|
||||
u32 AIGetDMAStartAddr(void)
|
||||
{
|
||||
return (u32)((__DSPRegs[24] & 0x03ff) << 16) | (__DSPRegs[25] & 0xffe0);
|
||||
}
|
||||
|
||||
AISCallback AIRegisterStreamCallback(AISCallback callback)
|
||||
{
|
||||
AISCallback ret;
|
||||
s32 oldInts;
|
||||
|
||||
ret = __AIS_Callback;
|
||||
oldInts = OSDisableInterrupts();
|
||||
__AIS_Callback = callback;
|
||||
OSRestoreInterrupts(oldInts);
|
||||
return ret;
|
||||
}
|
||||
|
||||
void AIResetStreamSampleCount(void)
|
||||
{
|
||||
__AIRegs[0] = (__AIRegs[0] & ~0x20) | 0x20;
|
||||
}
|
||||
|
||||
void AISetStreamTrigger(u32 trigger)
|
||||
{
|
||||
__AIRegs[3] = trigger;
|
||||
}
|
||||
|
||||
void AISetStreamPlayState(u32 state)
|
||||
{
|
||||
s32 oldInts;
|
||||
u8 volRight;
|
||||
u8 volLeft;
|
||||
|
||||
if (state == AIGetStreamPlayState()) {
|
||||
return;
|
||||
}
|
||||
if ((AIGetStreamSampleRate() == 0U) && (state == 1)) {
|
||||
volRight = AIGetStreamVolRight();
|
||||
volLeft = AIGetStreamVolLeft();
|
||||
AISetStreamVolRight(0);
|
||||
AISetStreamVolLeft(0);
|
||||
oldInts = OSDisableInterrupts();
|
||||
__AI_SRC_INIT();
|
||||
__AIRegs[0] = (__AIRegs[0] & ~0x20) | 0x20;
|
||||
__AIRegs[0] = (__AIRegs[0] & ~1) | 1;
|
||||
OSRestoreInterrupts(oldInts);
|
||||
AISetStreamVolLeft(volRight);
|
||||
AISetStreamVolRight(volLeft);
|
||||
}
|
||||
else {
|
||||
__AIRegs[0] = (__AIRegs[0] & ~1) | state;
|
||||
}
|
||||
}
|
||||
|
||||
u32 AIGetStreamPlayState()
|
||||
{
|
||||
return __AIRegs[0] & 1;
|
||||
}
|
||||
|
||||
void AISetDSPSampleRate(u32 rate)
|
||||
{
|
||||
u32 state;
|
||||
s32 oldInts;
|
||||
u8 left;
|
||||
u8 right;
|
||||
u32 sampleRate;
|
||||
|
||||
if (rate == AIGetDSPSampleRate()) {
|
||||
return;
|
||||
}
|
||||
|
||||
__AIRegs[0] &= ~0x40;
|
||||
if (rate == 0) {
|
||||
left = AIGetStreamVolLeft();
|
||||
right = AIGetStreamVolRight();
|
||||
state = AIGetStreamPlayState();
|
||||
sampleRate = AIGetStreamSampleRate();
|
||||
AISetStreamVolLeft(0);
|
||||
AISetStreamVolRight(0);
|
||||
oldInts = OSDisableInterrupts();
|
||||
__AI_SRC_INIT();
|
||||
__AIRegs[0] = (__AIRegs[0] & ~0x20) | 0x20;
|
||||
__AIRegs[0] = (__AIRegs[0] & ~2) | (sampleRate * 2);
|
||||
__AIRegs[0] = (__AIRegs[0] & ~1) | state;
|
||||
__AIRegs[0] |= 0x40;
|
||||
OSRestoreInterrupts(oldInts);
|
||||
AISetStreamVolLeft(left);
|
||||
AISetStreamVolRight(right);
|
||||
}
|
||||
}
|
||||
|
||||
u32 AIGetDSPSampleRate()
|
||||
{
|
||||
return ((__AIRegs[0] >> 6) & 1) ^ 1;
|
||||
}
|
||||
|
||||
void __AI_set_stream_sample_rate(u32 rate)
|
||||
{
|
||||
s32 oldInts;
|
||||
s32 state;
|
||||
u8 left;
|
||||
u8 right;
|
||||
s32 temp_r26;
|
||||
|
||||
if (rate == AIGetStreamSampleRate()) {
|
||||
return;
|
||||
}
|
||||
state = AIGetStreamPlayState();
|
||||
left = AIGetStreamVolLeft();
|
||||
right = AIGetStreamVolRight();
|
||||
AISetStreamVolRight(0);
|
||||
AISetStreamVolLeft(0);
|
||||
temp_r26 = __AIRegs[0] & 0x40;
|
||||
__AIRegs[0] &= ~0x40;
|
||||
oldInts = OSDisableInterrupts();
|
||||
__AI_SRC_INIT();
|
||||
__AIRegs[0] |= temp_r26;
|
||||
__AIRegs[0] = (__AIRegs[0] & ~0x20) | 0x20;
|
||||
__AIRegs[0] = (__AIRegs[0] & ~2) | (rate * 2);
|
||||
OSRestoreInterrupts(oldInts);
|
||||
AISetStreamPlayState(state);
|
||||
AISetStreamVolLeft(left);
|
||||
AISetStreamVolRight(right);
|
||||
}
|
||||
|
||||
u32 AIGetStreamSampleRate()
|
||||
{
|
||||
return (__AIRegs[0] >> 1) & 1;
|
||||
}
|
||||
|
||||
void AISetStreamVolLeft(u8 volume)
|
||||
{
|
||||
__AIRegs[1] = (__AIRegs[1] & ~0xFF) | (volume & 0xFF);
|
||||
}
|
||||
|
||||
u8 AIGetStreamVolLeft()
|
||||
{
|
||||
return __AIRegs[1];
|
||||
}
|
||||
|
||||
void AISetStreamVolRight(u8 volume)
|
||||
{
|
||||
__AIRegs[1] = (__AIRegs[1] & ~0xFF00) | ((volume & 0xFF) << 8);
|
||||
}
|
||||
|
||||
u8 AIGetStreamVolRight()
|
||||
{
|
||||
return __AIRegs[1] >> 8;
|
||||
}
|
||||
|
||||
void AIInit(u8 *stack)
|
||||
{
|
||||
if (__AI_init_flag == TRUE) {
|
||||
return;
|
||||
}
|
||||
|
||||
bound_32KHz = OSNanosecondsToTicks(31524);
|
||||
bound_48KHz = OSNanosecondsToTicks(42024);
|
||||
min_wait = OSNanosecondsToTicks(42000);
|
||||
max_wait = OSNanosecondsToTicks(63000);
|
||||
buffer = OSNanosecondsToTicks(3000);
|
||||
|
||||
AISetStreamVolRight(0);
|
||||
AISetStreamVolLeft(0);
|
||||
AISetStreamTrigger(0);
|
||||
AIResetStreamSampleCount();
|
||||
__AI_set_stream_sample_rate(1);
|
||||
AISetDSPSampleRate(0);
|
||||
__AIS_Callback = 0;
|
||||
__AID_Callback = 0;
|
||||
__CallbackStack = stack;
|
||||
__OSSetInterruptHandler(5, __AIDHandler);
|
||||
__OSUnmaskInterrupts(0x04000000);
|
||||
__OSSetInterruptHandler(8, __AISHandler);
|
||||
__OSUnmaskInterrupts(0x800000);
|
||||
__AI_init_flag = TRUE;
|
||||
}
|
||||
|
||||
void __AISHandler(s16 interrupt, OSContext *context)
|
||||
{
|
||||
OSContext tmpContext;
|
||||
__AIRegs[0] |= 8;
|
||||
OSClearContext(&tmpContext);
|
||||
OSSetCurrentContext(&tmpContext);
|
||||
if (__AIS_Callback != NULL) {
|
||||
__AIS_Callback(__AIRegs[2]);
|
||||
}
|
||||
OSClearContext(&tmpContext);
|
||||
OSSetCurrentContext(context);
|
||||
}
|
||||
|
||||
void __AIDHandler(s16 interrupt, OSContext *context)
|
||||
{
|
||||
OSContext tempContext;
|
||||
u16 temp = __DSPRegs[5];
|
||||
__DSPRegs[5] = (temp & ~0xA0) | 8;
|
||||
OSClearContext(&tempContext);
|
||||
OSSetCurrentContext(&tempContext);
|
||||
if (__AID_Callback) {
|
||||
if (__CallbackStack) {
|
||||
__AICallbackStackSwitch(__AID_Callback);
|
||||
}
|
||||
else {
|
||||
__AID_Callback();
|
||||
}
|
||||
}
|
||||
|
||||
OSClearContext(&tempContext);
|
||||
OSSetCurrentContext(context);
|
||||
}
|
||||
|
||||
// clang-format off
|
||||
asm void __AICallbackStackSwitch(register AIDCallback cb) {
|
||||
// Allocate stack frame
|
||||
fralloc
|
||||
|
||||
// Store current stack
|
||||
lis r5, __OldStack@ha
|
||||
addi r5, r5, __OldStack@l
|
||||
stw r1, 0(r5)
|
||||
|
||||
// Load stack for callback
|
||||
lis r5, __CallbackStack@ha
|
||||
addi r5, r5, __CallbackStack@l
|
||||
lwz r1,0(r5)
|
||||
|
||||
// Move stack down 8 bytes
|
||||
subi r1, r1, 8
|
||||
// Call callback
|
||||
mtlr cb
|
||||
blrl
|
||||
|
||||
// Restore old stack
|
||||
lis r5, __OldStack @ha
|
||||
addi r5, r5, __OldStack@l
|
||||
lwz r1,0(r5)
|
||||
|
||||
// Free stack frame
|
||||
frfree
|
||||
|
||||
blr
|
||||
}
|
||||
// clang-format on
|
||||
|
||||
void __AI_SRC_INIT(void)
|
||||
{
|
||||
OSTime rise32 = 0;
|
||||
OSTime rise48 = 0;
|
||||
OSTime diff = 0;
|
||||
OSTime unused1 = 0;
|
||||
OSTime temp = 0;
|
||||
u32 temp0 = 0;
|
||||
u32 temp1 = 0;
|
||||
u32 done = 0;
|
||||
u32 walking = 0;
|
||||
u32 unused2 = 0;
|
||||
u32 initCnt = 0;
|
||||
|
||||
walking = 0;
|
||||
initCnt = 0;
|
||||
temp = 0;
|
||||
|
||||
while (!done) {
|
||||
__AIRegs[0] = (__AIRegs[0] & ~0x20) | 0x20;
|
||||
__AIRegs[0] &= ~2;
|
||||
__AIRegs[0] = (__AIRegs[0] & ~1) | 1;
|
||||
|
||||
temp0 = __AIRegs[2];
|
||||
|
||||
while (temp0 == __AIRegs[2])
|
||||
;
|
||||
rise32 = OSGetTime();
|
||||
|
||||
__AIRegs[0] = (__AIRegs[0] & ~2) | 2;
|
||||
__AIRegs[0] = (__AIRegs[0] & ~1) | 1;
|
||||
|
||||
temp1 = __AIRegs[2];
|
||||
while (temp1 == __AIRegs[2])
|
||||
;
|
||||
|
||||
rise48 = OSGetTime();
|
||||
|
||||
diff = rise48 - rise32;
|
||||
__AIRegs[0] &= ~2;
|
||||
__AIRegs[0] &= ~1;
|
||||
|
||||
if (diff < (bound_32KHz - buffer)) {
|
||||
temp = min_wait;
|
||||
done = 1;
|
||||
++initCnt;
|
||||
}
|
||||
else if (diff >= (bound_32KHz + buffer) && diff < (bound_48KHz - buffer)) {
|
||||
temp = max_wait;
|
||||
done = 1;
|
||||
++initCnt;
|
||||
}
|
||||
else {
|
||||
done = 0;
|
||||
walking = 1;
|
||||
++initCnt;
|
||||
}
|
||||
}
|
||||
|
||||
while ((rise48 + temp) > OSGetTime())
|
||||
;
|
||||
}
|
||||
251
src/dolphin/ar/ar.c
Normal file
251
src/dolphin/ar/ar.c
Normal file
|
|
@ -0,0 +1,251 @@
|
|||
#include "dolphin/ar.h"
|
||||
|
||||
#include "dolphin/hw_regs.h"
|
||||
#include "dolphin/os.h"
|
||||
|
||||
static ARCallback __AR_Callback;
|
||||
static u32 __AR_Size;
|
||||
static u32 __AR_InternalSize;
|
||||
static u32 __AR_ExpansionSize;
|
||||
|
||||
static u32 __AR_StackPointer;
|
||||
static u32 __AR_FreeBlocks;
|
||||
static u32* __AR_BlockLength;
|
||||
|
||||
static volatile BOOL __AR_init_flag = FALSE;
|
||||
|
||||
static void __ARHandler(__OSInterrupt interrupt, OSContext* context);
|
||||
static void __ARChecksize(void);
|
||||
static void __ARClearArea(u32 start_addr, u32 length);
|
||||
|
||||
ARCallback ARRegisterDMACallback(ARCallback callback) {
|
||||
ARCallback oldCb;
|
||||
BOOL enabled;
|
||||
oldCb = __AR_Callback;
|
||||
enabled = OSDisableInterrupts();
|
||||
__AR_Callback = callback;
|
||||
OSRestoreInterrupts(enabled);
|
||||
return oldCb;
|
||||
}
|
||||
|
||||
u32 ARGetDMAStatus() {
|
||||
BOOL enabled;
|
||||
u32 val;
|
||||
enabled = OSDisableInterrupts();
|
||||
val = __DSPRegs[5] & 0x0200;
|
||||
OSRestoreInterrupts(enabled);
|
||||
return val;
|
||||
}
|
||||
|
||||
void ARStartDMA(u32 type, u32 mainmem_addr, u32 aram_addr, u32 length) {
|
||||
BOOL enabled;
|
||||
|
||||
enabled = OSDisableInterrupts();
|
||||
|
||||
__DSPRegs[16] = (u16)(__DSPRegs[16] & ~0x3ff) | (u16)(mainmem_addr >> 16);
|
||||
__DSPRegs[17] = (u16)(__DSPRegs[17] & ~0xffe0) | (u16)(mainmem_addr & 0xffff);
|
||||
__DSPRegs[18] = (u16)(__DSPRegs[18] & ~0x3ff) | (u16)(aram_addr >> 16);
|
||||
__DSPRegs[19] = (u16)(__DSPRegs[19] & ~0xffe0) | (u16)(aram_addr & 0xffff);
|
||||
__DSPRegs[20] = (u16)((__DSPRegs[20] & ~0x8000) | (type << 15));
|
||||
__DSPRegs[20] = (u16)(__DSPRegs[20] & ~0x3ff) | (u16)(length >> 16);
|
||||
__DSPRegs[21] = (u16)(__DSPRegs[21] & ~0xffe0) | (u16)(length & 0xffff);
|
||||
OSRestoreInterrupts(enabled);
|
||||
}
|
||||
|
||||
u32 ARAlloc(u32 length) {
|
||||
u32 tmp;
|
||||
BOOL enabled;
|
||||
|
||||
enabled = OSDisableInterrupts();
|
||||
tmp = __AR_StackPointer;
|
||||
__AR_StackPointer += length;
|
||||
*__AR_BlockLength = length;
|
||||
__AR_BlockLength++;
|
||||
__AR_FreeBlocks--;
|
||||
OSRestoreInterrupts(enabled);
|
||||
|
||||
return tmp;
|
||||
}
|
||||
|
||||
#if NONMATCHING
|
||||
u32 ARFree(u32* length) {
|
||||
BOOL old;
|
||||
|
||||
old = OSDisableInterrupts();
|
||||
|
||||
__AR_BlockLength--;
|
||||
|
||||
if (length) {
|
||||
*length = *__AR_BlockLength;
|
||||
}
|
||||
|
||||
__AR_StackPointer -= *__AR_BlockLength;
|
||||
|
||||
__AR_FreeBlocks++;
|
||||
|
||||
OSRestoreInterrupts(old);
|
||||
|
||||
return __AR_StackPointer;
|
||||
}
|
||||
#else
|
||||
/* clang-format off */
|
||||
#pragma push
|
||||
#pragma optimization_level 0
|
||||
#pragma optimizewithasm off
|
||||
asm u32 ARFree(u32* length) {
|
||||
nofralloc
|
||||
mflr r0
|
||||
stw r0, 4(r1)
|
||||
stwu r1, -0x18(r1)
|
||||
stw r31, 0x14(r1)
|
||||
mr r31, r3
|
||||
bl OSDisableInterrupts
|
||||
lwz r4, __AR_BlockLength
|
||||
cmplwi r31, 0
|
||||
addi r0, r4, -4
|
||||
stw r0, __AR_BlockLength
|
||||
beq lbl_8036DAB4
|
||||
lwz r4, __AR_BlockLength
|
||||
lwz r0, 0(r4)
|
||||
stw r0, 0(r31)
|
||||
lbl_8036DAB4:
|
||||
lwz r5, __AR_BlockLength
|
||||
lwz r4, __AR_FreeBlocks
|
||||
lwz r6, 0(r5)
|
||||
addi r0, r4, 1
|
||||
lwz r5, __AR_StackPointer
|
||||
stw r0, __AR_FreeBlocks
|
||||
subf r0, r6, r5
|
||||
stw r0, __AR_StackPointer
|
||||
bl OSRestoreInterrupts
|
||||
lwz r3, __AR_StackPointer
|
||||
lwz r0, 0x1c(r1)
|
||||
lwz r31, 0x14(r1)
|
||||
addi r1, r1, 0x18
|
||||
mtlr r0
|
||||
blr
|
||||
}
|
||||
#pragma pop
|
||||
/* clang-format on */
|
||||
#endif
|
||||
|
||||
BOOL ARCheckInit() { return __AR_init_flag; }
|
||||
|
||||
u32 ARInit(u32* stack_index_addr, u32 num_entries) {
|
||||
|
||||
BOOL old;
|
||||
u16 refresh;
|
||||
|
||||
if (__AR_init_flag == TRUE) {
|
||||
return 0x4000;
|
||||
}
|
||||
|
||||
old = OSDisableInterrupts();
|
||||
|
||||
__AR_Callback = NULL;
|
||||
|
||||
__OSSetInterruptHandler(__OS_INTERRUPT_DSP_ARAM, __ARHandler);
|
||||
__OSUnmaskInterrupts(OS_INTERRUPTMASK_DSP_ARAM);
|
||||
|
||||
__AR_StackPointer = 0x4000;
|
||||
__AR_FreeBlocks = num_entries;
|
||||
__AR_BlockLength = stack_index_addr;
|
||||
|
||||
refresh = (u16)(__DSPRegs[13] & 0x000000ff);
|
||||
|
||||
__DSPRegs[13] = (u16)((__DSPRegs[13] & ~0x000000ff) | (refresh & 0x000000ff));
|
||||
|
||||
__ARChecksize();
|
||||
|
||||
__AR_init_flag = TRUE;
|
||||
|
||||
OSRestoreInterrupts(old);
|
||||
|
||||
return __AR_StackPointer;
|
||||
}
|
||||
|
||||
u32 ARGetBaseAddress(void) { return 0x4000; }
|
||||
|
||||
void ARSetSize(void)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
u32 ARGetSize() { return __AR_Size; }
|
||||
|
||||
static void __ARHandler(__OSInterrupt interrupt, OSContext* context) {
|
||||
|
||||
OSContext exceptionContext;
|
||||
u16 tmp;
|
||||
|
||||
tmp = __DSPRegs[5];
|
||||
tmp = (u16)((tmp & ~0x00000088) | 0x20);
|
||||
__DSPRegs[5] = tmp;
|
||||
|
||||
OSClearContext(&exceptionContext);
|
||||
OSSetCurrentContext(&exceptionContext);
|
||||
|
||||
if (__AR_Callback) {
|
||||
(*__AR_Callback)();
|
||||
}
|
||||
|
||||
OSClearContext(&exceptionContext);
|
||||
OSSetCurrentContext(context);
|
||||
}
|
||||
|
||||
#define RoundUP32(x) (((u32)(x) + 32 - 1) & ~(32 - 1))
|
||||
|
||||
void __ARClearInterrupt(void) {
|
||||
|
||||
u16 tmp;
|
||||
tmp = __DSPRegs[5];
|
||||
tmp = (u16)((tmp & ~(0x00000080 | 0x00000008)) | 0x00000020);
|
||||
__DSPRegs[5] = tmp;
|
||||
}
|
||||
u16 __ARGetInterruptStatus(void) { return ((u16)(__DSPRegs[5] & 0x0200)); }
|
||||
|
||||
static void __ARWaitForDMA(void) {
|
||||
|
||||
while (__DSPRegs[5] & 0x0200) {
|
||||
}
|
||||
}
|
||||
|
||||
static void __ARWriteDMA(u32 mmem_addr, u32 aram_addr, u32 length) {
|
||||
|
||||
__DSPRegs[16] = (u16)((__DSPRegs[16] & ~0x03ff) | (u16)(mmem_addr >> 16));
|
||||
__DSPRegs[16 + 1] = (u16)((__DSPRegs[16 + 1] & ~0xffe0) | (u16)(mmem_addr & 0xffff));
|
||||
|
||||
__DSPRegs[18] = (u16)((__DSPRegs[18] & ~0x03ff) | (u16)(aram_addr >> 16));
|
||||
__DSPRegs[18 + 1] = (u16)((__DSPRegs[18 + 1] & ~0xffe0) | (u16)(aram_addr & 0xffff));
|
||||
|
||||
__DSPRegs[20] = (u16)(__DSPRegs[20] & ~0x8000);
|
||||
|
||||
__DSPRegs[20] = (u16)((__DSPRegs[20] & ~0x03ff) | (u16)(length >> 16));
|
||||
__DSPRegs[20 + 1] = (u16)((__DSPRegs[20 + 1] & ~0xffe0) | (u16)(length & 0xffff));
|
||||
|
||||
__ARWaitForDMA();
|
||||
|
||||
__ARClearInterrupt();
|
||||
}
|
||||
|
||||
static void __ARReadDMA(u32 mmem_addr, u32 aram_addr, u32 length) {
|
||||
|
||||
__DSPRegs[16] = (u16)((__DSPRegs[16] & ~0x03ff) | (u16)(mmem_addr >> 16));
|
||||
__DSPRegs[16 + 1] = (u16)((__DSPRegs[16 + 1] & ~0xffe0) | (u16)(mmem_addr & 0xffff));
|
||||
|
||||
__DSPRegs[18] = (u16)((__DSPRegs[18] & ~0x03ff) | (u16)(aram_addr >> 16));
|
||||
__DSPRegs[18 + 1] = (u16)((__DSPRegs[18 + 1] & ~0xffe0) | (u16)(aram_addr & 0xffff));
|
||||
|
||||
__DSPRegs[20] = (u16)(__DSPRegs[20] | 0x8000);
|
||||
|
||||
__DSPRegs[20] = (u16)((__DSPRegs[20] & ~0x03ff) | (u16)(length >> 16));
|
||||
__DSPRegs[20 + 1] = (u16)((__DSPRegs[20 + 1] & ~0xffe0) | (u16)(length & 0xffff));
|
||||
|
||||
__ARWaitForDMA();
|
||||
|
||||
__ARClearInterrupt();
|
||||
}
|
||||
|
||||
static void __ARChecksize(void) {
|
||||
//TODO: Implement for this SDK version
|
||||
}
|
||||
168
src/dolphin/ar/arq.c
Normal file
168
src/dolphin/ar/arq.c
Normal file
|
|
@ -0,0 +1,168 @@
|
|||
#include "dolphin/arq.h"
|
||||
#include "dolphin/os.h"
|
||||
|
||||
static ARQRequest* __ARQRequestQueueHi;
|
||||
static ARQRequest* __ARQRequestTailHi;
|
||||
static ARQRequest* __ARQRequestQueueLo;
|
||||
static ARQRequest* __ARQRequestTailLo;
|
||||
static ARQRequest* __ARQRequestPendingHi;
|
||||
static ARQRequest* __ARQRequestPendingLo;
|
||||
static ARQCallback __ARQCallbackHi;
|
||||
static ARQCallback __ARQCallbackLo;
|
||||
static u32 __ARQChunkSize;
|
||||
|
||||
static volatile BOOL __ARQ_init_flag = FALSE;
|
||||
|
||||
void __ARQPopTaskQueueHi(void);
|
||||
void __ARQServiceQueueLo(void);
|
||||
void __ARQCallbackHack(void);
|
||||
void __ARQInterruptServiceRoutine(void);
|
||||
void __ARQInitTempQueue(void);
|
||||
void __ARQPushTempQueue(ARQRequest* task);
|
||||
|
||||
void __ARQPopTaskQueueHi(void) {
|
||||
|
||||
if (__ARQRequestQueueHi) {
|
||||
if (__ARQRequestQueueHi->type == ARQ_TYPE_MRAM_TO_ARAM) {
|
||||
ARStartDMA(__ARQRequestQueueHi->type, __ARQRequestQueueHi->source, __ARQRequestQueueHi->dest,
|
||||
__ARQRequestQueueHi->length);
|
||||
} else {
|
||||
ARStartDMA(__ARQRequestQueueHi->type, __ARQRequestQueueHi->dest, __ARQRequestQueueHi->source,
|
||||
__ARQRequestQueueHi->length);
|
||||
}
|
||||
|
||||
__ARQCallbackHi = __ARQRequestQueueHi->callback;
|
||||
|
||||
__ARQRequestPendingHi = __ARQRequestQueueHi;
|
||||
|
||||
__ARQRequestQueueHi = __ARQRequestQueueHi->next;
|
||||
}
|
||||
}
|
||||
|
||||
void __ARQServiceQueueLo(void) {
|
||||
|
||||
if ((__ARQRequestPendingLo == NULL) && (__ARQRequestQueueLo)) {
|
||||
__ARQRequestPendingLo = __ARQRequestQueueLo;
|
||||
|
||||
__ARQRequestQueueLo = __ARQRequestQueueLo->next;
|
||||
}
|
||||
|
||||
if (__ARQRequestPendingLo) {
|
||||
if (__ARQRequestPendingLo->length <= __ARQChunkSize) {
|
||||
if (__ARQRequestPendingLo->type == ARQ_TYPE_MRAM_TO_ARAM)
|
||||
ARStartDMA(__ARQRequestPendingLo->type, __ARQRequestPendingLo->source,
|
||||
__ARQRequestPendingLo->dest, __ARQRequestPendingLo->length);
|
||||
else
|
||||
ARStartDMA(__ARQRequestPendingLo->type, __ARQRequestPendingLo->dest,
|
||||
__ARQRequestPendingLo->source, __ARQRequestPendingLo->length);
|
||||
|
||||
__ARQCallbackLo = __ARQRequestPendingLo->callback;
|
||||
} else {
|
||||
if (__ARQRequestPendingLo->type == ARQ_TYPE_MRAM_TO_ARAM)
|
||||
ARStartDMA(__ARQRequestPendingLo->type, __ARQRequestPendingLo->source,
|
||||
__ARQRequestPendingLo->dest, __ARQChunkSize);
|
||||
else
|
||||
ARStartDMA(__ARQRequestPendingLo->type, __ARQRequestPendingLo->dest,
|
||||
__ARQRequestPendingLo->source, __ARQChunkSize);
|
||||
}
|
||||
|
||||
__ARQRequestPendingLo->length -= __ARQChunkSize;
|
||||
__ARQRequestPendingLo->source += __ARQChunkSize;
|
||||
__ARQRequestPendingLo->dest += __ARQChunkSize;
|
||||
}
|
||||
}
|
||||
void __ARQCallbackHack(void) { return; }
|
||||
|
||||
void __ARQInterruptServiceRoutine(void) {
|
||||
|
||||
if (__ARQCallbackHi) {
|
||||
(*__ARQCallbackHi)((u32)__ARQRequestPendingHi);
|
||||
__ARQRequestPendingHi = NULL;
|
||||
__ARQCallbackHi = NULL;
|
||||
}
|
||||
|
||||
else if (__ARQCallbackLo) {
|
||||
(*__ARQCallbackLo)((u32)__ARQRequestPendingLo);
|
||||
__ARQRequestPendingLo = NULL;
|
||||
__ARQCallbackLo = NULL;
|
||||
}
|
||||
|
||||
__ARQPopTaskQueueHi();
|
||||
|
||||
if (__ARQRequestPendingHi == NULL)
|
||||
__ARQServiceQueueLo();
|
||||
}
|
||||
|
||||
void ARQInit(void) {
|
||||
|
||||
if (TRUE == __ARQ_init_flag) {
|
||||
return;
|
||||
}
|
||||
|
||||
__ARQRequestQueueHi = __ARQRequestQueueLo = NULL;
|
||||
__ARQChunkSize = ARQ_CHUNK_SIZE_DEFAULT;
|
||||
ARRegisterDMACallback(&__ARQInterruptServiceRoutine);
|
||||
__ARQRequestPendingHi = NULL;
|
||||
__ARQRequestPendingLo = NULL;
|
||||
__ARQCallbackHi = NULL;
|
||||
__ARQCallbackLo = NULL;
|
||||
__ARQ_init_flag = TRUE;
|
||||
}
|
||||
|
||||
void ARQPostRequest(ARQRequest* request, u32 owner, u32 type, u32 priority, u32 source, u32 dest,
|
||||
u32 length, ARQCallback callback) {
|
||||
|
||||
BOOL enabled;
|
||||
|
||||
request->next = NULL;
|
||||
request->owner = owner;
|
||||
request->type = type;
|
||||
request->source = source;
|
||||
request->dest = dest;
|
||||
request->length = length;
|
||||
|
||||
if (callback) {
|
||||
request->callback = callback;
|
||||
} else {
|
||||
request->callback = (ARQCallback)&__ARQCallbackHack;
|
||||
}
|
||||
|
||||
enabled = OSDisableInterrupts();
|
||||
|
||||
switch (priority) {
|
||||
case ARQ_PRIORITY_LOW:
|
||||
|
||||
if (__ARQRequestQueueLo) {
|
||||
__ARQRequestTailLo->next = request;
|
||||
} else {
|
||||
__ARQRequestQueueLo = request;
|
||||
}
|
||||
__ARQRequestTailLo = request;
|
||||
|
||||
break;
|
||||
|
||||
case ARQ_PRIORITY_HIGH:
|
||||
|
||||
if (__ARQRequestQueueHi) {
|
||||
__ARQRequestTailHi->next = request;
|
||||
} else {
|
||||
__ARQRequestQueueHi = request;
|
||||
}
|
||||
|
||||
__ARQRequestTailHi = request;
|
||||
|
||||
break;
|
||||
}
|
||||
|
||||
if ((__ARQRequestPendingHi == NULL) && (__ARQRequestPendingLo == NULL)) {
|
||||
__ARQPopTaskQueueHi();
|
||||
|
||||
if (__ARQRequestPendingHi == NULL) {
|
||||
__ARQServiceQueueLo();
|
||||
}
|
||||
}
|
||||
|
||||
OSRestoreInterrupts(enabled);
|
||||
}
|
||||
|
||||
u32 ARQGetChunkSize(void) { return __ARQChunkSize; }
|
||||
615
src/dolphin/card/CARDBios.c
Normal file
615
src/dolphin/card/CARDBios.c
Normal file
|
|
@ -0,0 +1,615 @@
|
|||
#include <dolphin/card.h>
|
||||
#include <dolphin/dsp.h>
|
||||
#include <dolphin/dvd.h>
|
||||
#include <dolphin/exi.h>
|
||||
#include <dolphin/os.h>
|
||||
|
||||
#include <dolphin/CARDPriv.h>
|
||||
|
||||
CARDControl __CARDBlock[2];
|
||||
DVDDiskID __CARDDiskNone;
|
||||
|
||||
static u16 __CARDEncode;
|
||||
|
||||
s32 __CARDReadStatus(s32 chan, u8 *status);
|
||||
s32 __CARDClearStatus(s32 chan);
|
||||
void __CARDSetDiskID(const DVDDiskID *id);
|
||||
static s32 Retry(s32 chan);
|
||||
|
||||
static BOOL OnReset(BOOL f);
|
||||
static OSResetFunctionInfo ResetFunctionInfo = { OnReset, 127 };
|
||||
|
||||
void __CARDDefaultApiCallback(s32 chan, s32 result) { }
|
||||
|
||||
void __CARDSyncCallback(s32 chan, s32 result)
|
||||
{
|
||||
OSWakeupThread(&__CARDBlock[chan].threadQueue);
|
||||
}
|
||||
|
||||
void __CARDExtHandler(s32 chan, OSContext *context)
|
||||
{
|
||||
CARDControl *card;
|
||||
CARDCallback callback;
|
||||
|
||||
card = &__CARDBlock[chan];
|
||||
if (card->attached) {
|
||||
card->attached = FALSE;
|
||||
EXISetExiCallback(chan, 0);
|
||||
OSCancelAlarm(&card->alarm);
|
||||
callback = card->exiCallback;
|
||||
|
||||
if (callback) {
|
||||
card->exiCallback = 0;
|
||||
callback(chan, CARD_RESULT_NOCARD);
|
||||
}
|
||||
|
||||
if (card->result != CARD_RESULT_BUSY) {
|
||||
card->result = CARD_RESULT_NOCARD;
|
||||
}
|
||||
|
||||
callback = card->extCallback;
|
||||
if (callback && CARD_MAX_MOUNT_STEP <= card->mountStep) {
|
||||
card->extCallback = 0;
|
||||
callback(chan, CARD_RESULT_NOCARD);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void __CARDExiHandler(s32 chan, OSContext *context)
|
||||
{
|
||||
CARDControl *card;
|
||||
CARDCallback callback;
|
||||
u8 status;
|
||||
s32 result;
|
||||
|
||||
card = &__CARDBlock[chan];
|
||||
|
||||
OSCancelAlarm(&card->alarm);
|
||||
|
||||
if (!card->attached) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (!EXILock(chan, 0, 0)) {
|
||||
result = CARD_RESULT_FATAL_ERROR;
|
||||
goto fatal;
|
||||
}
|
||||
|
||||
if ((result = __CARDReadStatus(chan, &status)) < 0 || (result = __CARDClearStatus(chan)) < 0) {
|
||||
goto error;
|
||||
}
|
||||
|
||||
if ((result = (status & 0x18) ? CARD_RESULT_IOERROR : CARD_RESULT_READY) == CARD_RESULT_IOERROR && --card->retry > 0) {
|
||||
result = Retry(chan);
|
||||
if (result >= 0) {
|
||||
return;
|
||||
}
|
||||
goto fatal;
|
||||
}
|
||||
|
||||
error:
|
||||
EXIUnlock(chan);
|
||||
|
||||
fatal:
|
||||
callback = card->exiCallback;
|
||||
if (callback) {
|
||||
card->exiCallback = 0;
|
||||
callback(chan, result);
|
||||
}
|
||||
}
|
||||
|
||||
void __CARDTxHandler(s32 chan, OSContext *context)
|
||||
{
|
||||
CARDControl *card;
|
||||
CARDCallback callback;
|
||||
BOOL err;
|
||||
|
||||
card = &__CARDBlock[chan];
|
||||
err = !EXIDeselect(chan);
|
||||
EXIUnlock(chan);
|
||||
callback = card->txCallback;
|
||||
if (callback) {
|
||||
card->txCallback = 0;
|
||||
callback(chan, (!err && EXIProbe(chan)) ? CARD_RESULT_READY : CARD_RESULT_NOCARD);
|
||||
}
|
||||
}
|
||||
|
||||
void __CARDUnlockedHandler(s32 chan, OSContext *context)
|
||||
{
|
||||
CARDControl *card;
|
||||
CARDCallback callback;
|
||||
|
||||
card = &__CARDBlock[chan];
|
||||
callback = card->unlockCallback;
|
||||
if (callback) {
|
||||
card->unlockCallback = 0;
|
||||
callback(chan, EXIProbe(chan) ? CARD_RESULT_UNLOCKED : CARD_RESULT_NOCARD);
|
||||
}
|
||||
}
|
||||
|
||||
s32 __CARDEnableInterrupt(s32 chan, BOOL enable)
|
||||
{
|
||||
BOOL err;
|
||||
u32 cmd;
|
||||
|
||||
if (!EXISelect(chan, 0, 4)) {
|
||||
return CARD_RESULT_NOCARD;
|
||||
}
|
||||
|
||||
cmd = enable ? 0x81010000 : 0x81000000;
|
||||
err = FALSE;
|
||||
err |= !EXIImm(chan, &cmd, 2, 1, NULL);
|
||||
err |= !EXISync(chan);
|
||||
err |= !EXIDeselect(chan);
|
||||
return err ? CARD_RESULT_NOCARD : CARD_RESULT_READY;
|
||||
}
|
||||
|
||||
s32 __CARDReadStatus(s32 chan, u8 *status)
|
||||
{
|
||||
BOOL err;
|
||||
u32 cmd;
|
||||
|
||||
if (!EXISelect(chan, 0, 4)) {
|
||||
return CARD_RESULT_NOCARD;
|
||||
}
|
||||
|
||||
cmd = 0x83000000;
|
||||
err = FALSE;
|
||||
err |= !EXIImm(chan, &cmd, 2, 1, NULL);
|
||||
err |= !EXISync(chan);
|
||||
err |= !EXIImm(chan, status, 1, 0, NULL);
|
||||
err |= !EXISync(chan);
|
||||
err |= !EXIDeselect(chan);
|
||||
return err ? CARD_RESULT_NOCARD : CARD_RESULT_READY;
|
||||
}
|
||||
|
||||
s32 __CARDClearStatus(s32 chan)
|
||||
{
|
||||
BOOL err;
|
||||
u32 cmd;
|
||||
|
||||
if (!EXISelect(chan, 0, 4)) {
|
||||
return CARD_RESULT_NOCARD;
|
||||
}
|
||||
|
||||
cmd = 0x89000000;
|
||||
err = FALSE;
|
||||
err |= !EXIImm(chan, &cmd, 1, 1, 0);
|
||||
err |= !EXISync(chan);
|
||||
err |= !EXIDeselect(chan);
|
||||
|
||||
return err ? CARD_RESULT_NOCARD : CARD_RESULT_READY;
|
||||
}
|
||||
|
||||
static void TimeoutHandler(OSAlarm *alarm, OSContext *context)
|
||||
{
|
||||
s32 chan;
|
||||
CARDControl *card;
|
||||
CARDCallback callback;
|
||||
for (chan = 0; chan < 2; ++chan) {
|
||||
card = &__CARDBlock[chan];
|
||||
if (alarm == &card->alarm) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (!card->attached) {
|
||||
return;
|
||||
}
|
||||
|
||||
EXISetExiCallback(chan, NULL);
|
||||
callback = card->exiCallback;
|
||||
if (callback) {
|
||||
card->exiCallback = 0;
|
||||
callback(chan, CARD_RESULT_IOERROR);
|
||||
}
|
||||
}
|
||||
|
||||
static void SetupTimeoutAlarm(CARDControl *card)
|
||||
{
|
||||
OSCancelAlarm(&card->alarm);
|
||||
switch (card->cmd[0]) {
|
||||
case 0xF2:
|
||||
OSSetAlarm(&card->alarm, OSMillisecondsToTicks(100), TimeoutHandler);
|
||||
break;
|
||||
case 0xF3:
|
||||
break;
|
||||
case 0xF4:
|
||||
case 0xF1:
|
||||
OSSetAlarm(&card->alarm, OSSecondsToTicks((OSTime)2) * (card->sectorSize / 0x2000), TimeoutHandler);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
static s32 Retry(s32 chan)
|
||||
{
|
||||
CARDControl *card;
|
||||
card = &__CARDBlock[chan];
|
||||
|
||||
if (!EXISelect(chan, 0, 4)) {
|
||||
EXIUnlock(chan);
|
||||
return CARD_RESULT_NOCARD;
|
||||
}
|
||||
|
||||
SetupTimeoutAlarm(card);
|
||||
|
||||
if (!EXIImmEx(chan, card->cmd, card->cmdlen, 1)) {
|
||||
EXIDeselect(chan);
|
||||
EXIUnlock(chan);
|
||||
return CARD_RESULT_NOCARD;
|
||||
}
|
||||
|
||||
if (card->cmd[0] == 0x52 && !EXIImmEx(chan, (u8 *)card->workArea + sizeof(CARDID), card->latency, 1)) {
|
||||
EXIDeselect(chan);
|
||||
EXIUnlock(chan);
|
||||
return CARD_RESULT_NOCARD;
|
||||
}
|
||||
|
||||
if (card->mode == 0xffffffff) {
|
||||
EXIDeselect(chan);
|
||||
EXIUnlock(chan);
|
||||
return CARD_RESULT_READY;
|
||||
}
|
||||
|
||||
if (!EXIDma(chan, card->buffer, (s32)((card->cmd[0] == 0x52) ? 512 : 128), card->mode, __CARDTxHandler)) {
|
||||
EXIDeselect(chan);
|
||||
EXIUnlock(chan);
|
||||
return CARD_RESULT_NOCARD;
|
||||
}
|
||||
|
||||
return CARD_RESULT_READY;
|
||||
}
|
||||
|
||||
static void UnlockedCallback(s32 chan, s32 result)
|
||||
{
|
||||
CARDCallback callback;
|
||||
CARDControl *card;
|
||||
|
||||
card = &__CARDBlock[chan];
|
||||
if (result >= 0) {
|
||||
card->unlockCallback = UnlockedCallback;
|
||||
if (!EXILock(chan, 0, __CARDUnlockedHandler)) {
|
||||
result = CARD_RESULT_READY;
|
||||
}
|
||||
else {
|
||||
card->unlockCallback = 0;
|
||||
result = Retry(chan);
|
||||
}
|
||||
}
|
||||
|
||||
if (result < 0) {
|
||||
switch (card->cmd[0]) {
|
||||
case 0x52:
|
||||
callback = card->txCallback;
|
||||
if (callback) {
|
||||
card->txCallback = 0;
|
||||
callback(chan, result);
|
||||
}
|
||||
|
||||
break;
|
||||
case 0xF2:
|
||||
case 0xF4:
|
||||
case 0xF1:
|
||||
callback = card->exiCallback;
|
||||
if (callback) {
|
||||
card->exiCallback = 0;
|
||||
callback(chan, result);
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static s32 __CARDStart(s32 chan, CARDCallback txCallback, CARDCallback exiCallback)
|
||||
{
|
||||
BOOL enabled;
|
||||
CARDControl *card;
|
||||
s32 result;
|
||||
|
||||
enabled = OSDisableInterrupts();
|
||||
|
||||
card = &__CARDBlock[chan];
|
||||
if (!card->attached) {
|
||||
result = CARD_RESULT_NOCARD;
|
||||
}
|
||||
else {
|
||||
|
||||
if (txCallback) {
|
||||
card->txCallback = txCallback;
|
||||
}
|
||||
if (exiCallback) {
|
||||
card->exiCallback = exiCallback;
|
||||
}
|
||||
card->unlockCallback = UnlockedCallback;
|
||||
if (!EXILock(chan, 0, __CARDUnlockedHandler)) {
|
||||
result = CARD_RESULT_BUSY;
|
||||
}
|
||||
else {
|
||||
card->unlockCallback = 0;
|
||||
|
||||
if (!EXISelect(chan, 0, 4)) {
|
||||
EXIUnlock(chan);
|
||||
result = CARD_RESULT_NOCARD;
|
||||
}
|
||||
else {
|
||||
SetupTimeoutAlarm(card);
|
||||
result = CARD_RESULT_READY;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
OSRestoreInterrupts(enabled);
|
||||
return result;
|
||||
}
|
||||
|
||||
#define AD1(x) ((u8)(((x) >> 17) & 0x7f))
|
||||
#define AD1EX(x) ((u8)(AD1(x) | 0x80));
|
||||
#define AD2(x) ((u8)(((x) >> 9) & 0xff))
|
||||
#define AD3(x) ((u8)(((x) >> 7) & 0x03))
|
||||
#define BA(x) ((u8)((x)&0x7f))
|
||||
|
||||
s32 __CARDReadSegment(s32 chan, CARDCallback callback)
|
||||
{
|
||||
CARDControl *card;
|
||||
s32 result;
|
||||
|
||||
card = &__CARDBlock[chan];
|
||||
card->cmd[0] = 0x52;
|
||||
card->cmd[1] = AD1(card->addr);
|
||||
card->cmd[2] = AD2(card->addr);
|
||||
card->cmd[3] = AD3(card->addr);
|
||||
card->cmd[4] = BA(card->addr);
|
||||
card->cmdlen = 5;
|
||||
card->mode = 0;
|
||||
card->retry = 0;
|
||||
|
||||
result = __CARDStart(chan, callback, 0);
|
||||
if (result == CARD_RESULT_BUSY) {
|
||||
result = CARD_RESULT_READY;
|
||||
}
|
||||
else if (result >= 0) {
|
||||
if (!EXIImmEx(chan, card->cmd, card->cmdlen, 1)
|
||||
|| !EXIImmEx(chan, (u8 *)card->workArea + sizeof(CARDID), card->latency,
|
||||
1)
|
||||
|| // XXX use DMA if possible
|
||||
!EXIDma(chan, card->buffer, 512, card->mode, __CARDTxHandler)) {
|
||||
card->txCallback = 0;
|
||||
EXIDeselect(chan);
|
||||
EXIUnlock(chan);
|
||||
result = CARD_RESULT_NOCARD;
|
||||
}
|
||||
else {
|
||||
result = CARD_RESULT_READY;
|
||||
}
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
s32 __CARDWritePage(s32 chan, CARDCallback callback)
|
||||
{
|
||||
CARDControl *card;
|
||||
s32 result;
|
||||
|
||||
card = &__CARDBlock[chan];
|
||||
card->cmd[0] = 0xF2;
|
||||
card->cmd[1] = AD1(card->addr);
|
||||
card->cmd[2] = AD2(card->addr);
|
||||
card->cmd[3] = AD3(card->addr);
|
||||
card->cmd[4] = BA(card->addr);
|
||||
card->cmdlen = 5;
|
||||
card->mode = 1;
|
||||
card->retry = 3;
|
||||
|
||||
result = __CARDStart(chan, 0, callback);
|
||||
if (result == CARD_RESULT_BUSY) {
|
||||
result = CARD_RESULT_READY;
|
||||
}
|
||||
else if (result >= 0) {
|
||||
if (!EXIImmEx(chan, card->cmd, card->cmdlen, 1) || !EXIDma(chan, card->buffer, 128, card->mode, __CARDTxHandler)) {
|
||||
card->exiCallback = 0;
|
||||
EXIDeselect(chan);
|
||||
EXIUnlock(chan);
|
||||
result = CARD_RESULT_NOCARD;
|
||||
}
|
||||
else {
|
||||
result = CARD_RESULT_READY;
|
||||
}
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
s32 __CARDEraseSector(s32 chan, u32 addr, CARDCallback callback)
|
||||
{
|
||||
CARDControl *card;
|
||||
s32 result;
|
||||
|
||||
card = &__CARDBlock[chan];
|
||||
card->cmd[0] = 0xF1;
|
||||
card->cmd[1] = AD1(addr);
|
||||
card->cmd[2] = AD2(addr);
|
||||
card->cmdlen = 3;
|
||||
card->mode = -1;
|
||||
card->retry = 3;
|
||||
|
||||
result = __CARDStart(chan, 0, callback);
|
||||
|
||||
if (result == CARD_RESULT_BUSY) {
|
||||
result = CARD_RESULT_READY;
|
||||
}
|
||||
else if (result >= 0) {
|
||||
if (!EXIImmEx(chan, card->cmd, card->cmdlen, 1)) {
|
||||
card->exiCallback = NULL;
|
||||
result = CARD_RESULT_NOCARD;
|
||||
}
|
||||
else {
|
||||
result = CARD_RESULT_READY;
|
||||
}
|
||||
|
||||
EXIDeselect(chan);
|
||||
EXIUnlock(chan);
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
void CARDInit(void)
|
||||
{
|
||||
int chan;
|
||||
|
||||
if (__CARDBlock[0].diskID && __CARDBlock[1].diskID) {
|
||||
return;
|
||||
}
|
||||
|
||||
DSPInit();
|
||||
OSInitAlarm();
|
||||
|
||||
for (chan = 0; chan < 2; ++chan) {
|
||||
CARDControl *card = &__CARDBlock[chan];
|
||||
|
||||
card->result = CARD_RESULT_NOCARD;
|
||||
OSInitThreadQueue(&card->threadQueue);
|
||||
OSCreateAlarm(&card->alarm);
|
||||
}
|
||||
__CARDSetDiskID((DVDDiskID *)OSPhysicalToCached(0x0));
|
||||
|
||||
OSRegisterResetFunction(&ResetFunctionInfo);
|
||||
}
|
||||
|
||||
u16 __CARDGetFontEncode()
|
||||
{
|
||||
return __CARDEncode;
|
||||
}
|
||||
|
||||
void __CARDSetDiskID(const DVDDiskID *id)
|
||||
{
|
||||
__CARDBlock[0].diskID = id ? id : &__CARDDiskNone;
|
||||
__CARDBlock[1].diskID = id ? id : &__CARDDiskNone;
|
||||
}
|
||||
|
||||
s32 __CARDGetControlBlock(s32 chan, CARDControl **pcard)
|
||||
{
|
||||
BOOL enabled;
|
||||
s32 result;
|
||||
CARDControl *card;
|
||||
|
||||
card = &__CARDBlock[chan];
|
||||
if (chan < 0 || chan >= 2 || card->diskID == NULL) {
|
||||
return CARD_RESULT_FATAL_ERROR;
|
||||
}
|
||||
|
||||
enabled = OSDisableInterrupts();
|
||||
if (!card->attached) {
|
||||
result = CARD_RESULT_NOCARD;
|
||||
}
|
||||
else if (card->result == CARD_RESULT_BUSY) {
|
||||
result = CARD_RESULT_BUSY;
|
||||
}
|
||||
else {
|
||||
card->result = CARD_RESULT_BUSY;
|
||||
result = CARD_RESULT_READY;
|
||||
card->apiCallback = 0;
|
||||
*pcard = card;
|
||||
}
|
||||
OSRestoreInterrupts(enabled);
|
||||
return result;
|
||||
}
|
||||
|
||||
s32 __CARDPutControlBlock(CARDControl *card, s32 result)
|
||||
{
|
||||
BOOL enabled;
|
||||
|
||||
enabled = OSDisableInterrupts();
|
||||
if (card->attached) {
|
||||
card->result = result;
|
||||
}
|
||||
else if (card->result == CARD_RESULT_BUSY) {
|
||||
card->result = result;
|
||||
}
|
||||
OSRestoreInterrupts(enabled);
|
||||
return result;
|
||||
}
|
||||
|
||||
s32 CARDGetResultCode(s32 chan)
|
||||
{
|
||||
CARDControl *card;
|
||||
if (chan < 0 || chan >= 2) {
|
||||
return CARD_RESULT_FATAL_ERROR;
|
||||
}
|
||||
card = &__CARDBlock[chan];
|
||||
return card->result;
|
||||
}
|
||||
|
||||
s32 CARDFreeBlocks(s32 chan, s32 *byteNotUsed, s32 *filesNotUsed)
|
||||
{
|
||||
CARDControl *card;
|
||||
s32 result;
|
||||
u16 *fat;
|
||||
CARDDir *dir;
|
||||
CARDDir *ent;
|
||||
u16 fileNo;
|
||||
|
||||
result = __CARDGetControlBlock(chan, &card);
|
||||
if (result < 0) {
|
||||
return result;
|
||||
}
|
||||
|
||||
fat = __CARDGetFatBlock(card);
|
||||
dir = __CARDGetDirBlock(card);
|
||||
if (fat == 0 || dir == 0) {
|
||||
return __CARDPutControlBlock(card, CARD_RESULT_BROKEN);
|
||||
}
|
||||
|
||||
if (byteNotUsed) {
|
||||
*byteNotUsed = (s32)(card->sectorSize * fat[CARD_FAT_FREEBLOCKS]);
|
||||
}
|
||||
|
||||
if (filesNotUsed) {
|
||||
*filesNotUsed = 0;
|
||||
for (fileNo = 0; fileNo < CARD_MAX_FILE; fileNo++) {
|
||||
ent = &dir[fileNo];
|
||||
if (ent->fileName[0] == 0xff) {
|
||||
++*filesNotUsed;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return __CARDPutControlBlock(card, CARD_RESULT_READY);
|
||||
}
|
||||
|
||||
s32 CARDGetSectorSize(s32 chan, u32 *size)
|
||||
{
|
||||
struct CARDControl *card;
|
||||
long result;
|
||||
|
||||
result = __CARDGetControlBlock(chan, &card);
|
||||
if (result < 0) {
|
||||
return result;
|
||||
}
|
||||
*size = card->sectorSize;
|
||||
return __CARDPutControlBlock(card, 0);
|
||||
}
|
||||
|
||||
s32 __CARDSync(s32 chan)
|
||||
{
|
||||
CARDControl *block;
|
||||
s32 result;
|
||||
s32 enabled;
|
||||
|
||||
block = &__CARDBlock[chan];
|
||||
enabled = OSDisableInterrupts();
|
||||
while ((result = CARDGetResultCode(chan)) == -1) {
|
||||
OSSleepThread(&block->threadQueue);
|
||||
}
|
||||
OSRestoreInterrupts(enabled);
|
||||
return result;
|
||||
}
|
||||
|
||||
static BOOL OnReset(BOOL f)
|
||||
{
|
||||
if (!f) {
|
||||
if (CARDUnmount(0) == CARD_RESULT_BUSY || CARDUnmount(1) == CARD_RESULT_BUSY) {
|
||||
return FALSE;
|
||||
}
|
||||
}
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
170
src/dolphin/card/CARDBlock.c
Normal file
170
src/dolphin/card/CARDBlock.c
Normal file
|
|
@ -0,0 +1,170 @@
|
|||
#include <dolphin/card.h>
|
||||
#include <dolphin/dsp.h>
|
||||
#include <dolphin/dvd.h>
|
||||
#include <dolphin/os.h>
|
||||
|
||||
#include "string.h"
|
||||
|
||||
#include <dolphin/CARDPriv.h>
|
||||
|
||||
u16 *__CARDGetFatBlock(CARDControl *card)
|
||||
{
|
||||
return card->currentFat;
|
||||
}
|
||||
|
||||
static void WriteCallback(s32 chan, s32 result)
|
||||
{
|
||||
CARDControl *card;
|
||||
CARDCallback callback;
|
||||
u16 *fat;
|
||||
u16 *fatBack;
|
||||
|
||||
card = &__CARDBlock[chan];
|
||||
|
||||
if (result >= 0) {
|
||||
fat = (u16 *)((u8 *)card->workArea + 0x6000);
|
||||
fatBack = (u16 *)((u8 *)card->workArea + 0x8000);
|
||||
|
||||
if (card->currentFat == fat) {
|
||||
card->currentFat = fatBack;
|
||||
memcpy(fatBack, fat, 0x2000);
|
||||
}
|
||||
else {
|
||||
card->currentFat = fat;
|
||||
memcpy(fat, fatBack, 0x2000);
|
||||
}
|
||||
}
|
||||
|
||||
if (card->apiCallback == NULL) {
|
||||
__CARDPutControlBlock(card, result);
|
||||
}
|
||||
|
||||
callback = card->eraseCallback;
|
||||
if (callback) {
|
||||
card->eraseCallback = NULL;
|
||||
callback(chan, result);
|
||||
}
|
||||
}
|
||||
|
||||
static void EraseCallback(s32 chan, s32 result)
|
||||
{
|
||||
CARDControl *card;
|
||||
CARDCallback callback;
|
||||
u32 temp[2]; /* this compiler sucks */
|
||||
u16 *fat;
|
||||
u32 addr;
|
||||
|
||||
card = &__CARDBlock[chan];
|
||||
if (result < 0) {
|
||||
goto error;
|
||||
}
|
||||
|
||||
fat = __CARDGetFatBlock(card);
|
||||
addr = ((u32)fat - (u32)card->workArea) / CARD_SYSTEM_BLOCK_SIZE * card->sectorSize;
|
||||
result = __CARDWrite(chan, addr, CARD_SYSTEM_BLOCK_SIZE, fat, WriteCallback);
|
||||
if (result < 0) {
|
||||
goto error;
|
||||
}
|
||||
|
||||
return;
|
||||
|
||||
error:
|
||||
if (card->apiCallback == NULL) {
|
||||
__CARDPutControlBlock(card, result);
|
||||
}
|
||||
callback = card->eraseCallback;
|
||||
if (callback) {
|
||||
card->eraseCallback = NULL;
|
||||
callback(chan, result);
|
||||
}
|
||||
}
|
||||
|
||||
s32 __CARDAllocBlock(s32 chan, u32 cBlock, CARDCallback callback)
|
||||
{
|
||||
CARDControl *card;
|
||||
u16 *fat;
|
||||
u16 iBlock;
|
||||
u16 startBlock;
|
||||
u16 prevBlock;
|
||||
u16 count;
|
||||
|
||||
card = &__CARDBlock[chan];
|
||||
if (!card->attached) {
|
||||
return CARD_RESULT_NOCARD;
|
||||
}
|
||||
|
||||
fat = __CARDGetFatBlock(card);
|
||||
if (fat[3] < cBlock) {
|
||||
return CARD_RESULT_INSSPACE;
|
||||
}
|
||||
|
||||
fat[3] -= cBlock;
|
||||
startBlock = 0xFFFF;
|
||||
iBlock = fat[4];
|
||||
count = 0;
|
||||
while (0 < cBlock) {
|
||||
if (card->cBlock - 5 < ++count) {
|
||||
return CARD_RESULT_BROKEN;
|
||||
}
|
||||
|
||||
iBlock++;
|
||||
if (!CARDIsValidBlockNo(card, iBlock)) {
|
||||
iBlock = 5;
|
||||
}
|
||||
|
||||
if (fat[iBlock] == 0x0000u) {
|
||||
if (startBlock == 0xFFFF) {
|
||||
startBlock = iBlock;
|
||||
}
|
||||
else {
|
||||
fat[prevBlock] = iBlock;
|
||||
}
|
||||
prevBlock = iBlock;
|
||||
fat[iBlock] = 0xFFFF;
|
||||
--cBlock;
|
||||
}
|
||||
}
|
||||
fat[4] = iBlock;
|
||||
card->startBlock = startBlock;
|
||||
|
||||
return __CARDUpdateFatBlock(chan, fat, callback);
|
||||
}
|
||||
|
||||
s32 __CARDFreeBlock(s32 chan, u16 nBlock, CARDCallback callback)
|
||||
{
|
||||
CARDControl *card;
|
||||
u16 *fat;
|
||||
u16 nextBlock;
|
||||
|
||||
card = card = &__CARDBlock[chan];
|
||||
if (!card->attached) {
|
||||
return CARD_RESULT_NOCARD;
|
||||
}
|
||||
|
||||
fat = __CARDGetFatBlock(card);
|
||||
while (nBlock != 0xFFFF) {
|
||||
if (!CARDIsValidBlockNo(card, nBlock)) {
|
||||
return CARD_RESULT_BROKEN;
|
||||
}
|
||||
|
||||
nextBlock = fat[nBlock];
|
||||
fat[nBlock] = 0;
|
||||
nBlock = nextBlock;
|
||||
++fat[3];
|
||||
}
|
||||
|
||||
return __CARDUpdateFatBlock(chan, fat, callback);
|
||||
}
|
||||
|
||||
s32 __CARDUpdateFatBlock(s32 chan, u16 *fat, CARDCallback callback)
|
||||
{
|
||||
CARDControl *card;
|
||||
|
||||
card = &__CARDBlock[chan];
|
||||
++fat[2];
|
||||
__CARDCheckSum(fat + 2, 0x1FFC, fat, fat + 1);
|
||||
DCStoreRange(fat, 0x2000);
|
||||
card->eraseCallback = callback;
|
||||
|
||||
return __CARDEraseSector(chan, (((u32)fat - (u32)card->workArea) / 8192u) * card->sectorSize, EraseCallback);
|
||||
}
|
||||
343
src/dolphin/card/CARDCheck.c
Normal file
343
src/dolphin/card/CARDCheck.c
Normal file
|
|
@ -0,0 +1,343 @@
|
|||
#include <dolphin/card.h>
|
||||
#include <dolphin/dsp.h>
|
||||
#include <dolphin/dvd.h>
|
||||
#include <dolphin/os.h>
|
||||
|
||||
#include <dolphin/CARDPriv.h>
|
||||
#include <dolphin/OSRtcPriv.h>
|
||||
|
||||
#include "string.h"
|
||||
|
||||
void __CARDCheckSum(void *ptr, int length, u16 *checksum, u16 *checksumInv)
|
||||
{
|
||||
u16 *p;
|
||||
int i;
|
||||
|
||||
length /= sizeof(u16);
|
||||
*checksum = *checksumInv = 0;
|
||||
for (i = 0, p = ptr; i < length; i++, p++) {
|
||||
*checksum += *p;
|
||||
*checksumInv += ~*p;
|
||||
}
|
||||
if (*checksum == 0xffff) {
|
||||
*checksum = 0;
|
||||
}
|
||||
if (*checksumInv == 0xffff) {
|
||||
*checksumInv = 0;
|
||||
}
|
||||
}
|
||||
|
||||
static s32 VerifyID(CARDControl *card)
|
||||
{
|
||||
CARDID *id;
|
||||
u16 checksum;
|
||||
u16 checksumInv;
|
||||
OSSramEx *sramEx;
|
||||
OSTime rand;
|
||||
int i;
|
||||
|
||||
id = card->workArea;
|
||||
|
||||
if (id->deviceID != 0 || id->size != card->size)
|
||||
return CARD_RESULT_BROKEN;
|
||||
|
||||
__CARDCheckSum(id, sizeof(CARDID) - sizeof(u32), &checksum, &checksumInv);
|
||||
if (id->checkSum != checksum || id->checkSumInv != checksumInv)
|
||||
return CARD_RESULT_BROKEN;
|
||||
|
||||
if (id->encode != OSGetFontEncode())
|
||||
return CARD_RESULT_ENCODING;
|
||||
|
||||
rand = *(OSTime *)&id->serial[12];
|
||||
sramEx = __OSLockSramEx();
|
||||
for (i = 0; i < 12; i++) {
|
||||
rand = (rand * 1103515245 + 12345) >> 16;
|
||||
if (id->serial[i] != (u8)(sramEx->flashID[card - __CARDBlock][i] + rand)) {
|
||||
__OSUnlockSramEx(FALSE);
|
||||
return CARD_RESULT_BROKEN;
|
||||
}
|
||||
rand = ((rand * 1103515245 + 12345) >> 16) & 0x7FFF;
|
||||
}
|
||||
|
||||
__OSUnlockSramEx(FALSE);
|
||||
|
||||
return CARD_RESULT_READY;
|
||||
}
|
||||
|
||||
static s32 VerifyDir(CARDControl *card, int *outCurrent)
|
||||
{
|
||||
CARDDir *dir[2];
|
||||
CARDDirCheck *check[2];
|
||||
u16 checkSum;
|
||||
u16 checkSumInv;
|
||||
int i;
|
||||
int errors;
|
||||
int current;
|
||||
|
||||
current = errors = 0;
|
||||
for (i = 0; i < 2; i++) {
|
||||
dir[i] = (CARDDir *)((u8 *)card->workArea + (1 + i) * CARD_SYSTEM_BLOCK_SIZE);
|
||||
check[i] = __CARDGetDirCheck(dir[i]);
|
||||
__CARDCheckSum(dir[i], CARD_SYSTEM_BLOCK_SIZE - sizeof(u32), &checkSum, &checkSumInv);
|
||||
if (check[i]->checkSum != checkSum || check[i]->checkSumInv != checkSumInv) {
|
||||
++errors;
|
||||
current = i;
|
||||
card->currentDir = 0;
|
||||
}
|
||||
}
|
||||
|
||||
if (0 == errors) {
|
||||
if (card->currentDir == 0) {
|
||||
if ((check[0]->checkCode - check[1]->checkCode) < 0) {
|
||||
current = 0;
|
||||
}
|
||||
else {
|
||||
current = 1;
|
||||
}
|
||||
card->currentDir = dir[current];
|
||||
memcpy(dir[current], dir[current ^ 1], CARD_SYSTEM_BLOCK_SIZE);
|
||||
}
|
||||
else {
|
||||
current = (card->currentDir == dir[0]) ? 0 : 1;
|
||||
}
|
||||
}
|
||||
if (outCurrent) {
|
||||
*outCurrent = current;
|
||||
}
|
||||
return errors;
|
||||
}
|
||||
|
||||
static s32 VerifyFAT(CARDControl *card, int *outCurrent)
|
||||
{
|
||||
u16 *fat[2];
|
||||
u16 *fatp;
|
||||
u16 nBlock;
|
||||
u16 cFree;
|
||||
int i;
|
||||
u16 checkSum;
|
||||
u16 checkSumInv;
|
||||
int errors;
|
||||
int current;
|
||||
|
||||
current = errors = 0;
|
||||
for (i = 0; i < 2; i++) {
|
||||
fatp = fat[i] = (u16 *)((u8 *)card->workArea + (3 + i) * CARD_SYSTEM_BLOCK_SIZE);
|
||||
|
||||
__CARDCheckSum(&fatp[CARD_FAT_CHECKCODE], CARD_SYSTEM_BLOCK_SIZE - sizeof(u32), &checkSum, &checkSumInv);
|
||||
if (fatp[CARD_FAT_CHECKSUM] != checkSum || fatp[CARD_FAT_CHECKSUMINV] != checkSumInv) {
|
||||
++errors;
|
||||
current = i;
|
||||
card->currentFat = 0;
|
||||
continue;
|
||||
}
|
||||
|
||||
cFree = 0;
|
||||
for (nBlock = CARD_NUM_SYSTEM_BLOCK; nBlock < card->cBlock; nBlock++) {
|
||||
if (fatp[nBlock] == CARD_FAT_AVAIL) {
|
||||
cFree++;
|
||||
}
|
||||
}
|
||||
if (cFree != fatp[CARD_FAT_FREEBLOCKS]) {
|
||||
++errors;
|
||||
current = i;
|
||||
card->currentFat = 0;
|
||||
continue;
|
||||
}
|
||||
}
|
||||
|
||||
if (0 == errors) {
|
||||
if (card->currentFat == 0) {
|
||||
if (((s16)fat[0][CARD_FAT_CHECKCODE] - (s16)fat[1][CARD_FAT_CHECKCODE]) < 0) {
|
||||
current = 0;
|
||||
}
|
||||
else {
|
||||
current = 1;
|
||||
}
|
||||
card->currentFat = fat[current];
|
||||
memcpy(fat[current], fat[current ^ 1], CARD_SYSTEM_BLOCK_SIZE);
|
||||
}
|
||||
else {
|
||||
current = (card->currentFat == fat[0]) ? 0 : 1;
|
||||
}
|
||||
}
|
||||
if (outCurrent) {
|
||||
*outCurrent = current;
|
||||
}
|
||||
return errors;
|
||||
}
|
||||
|
||||
s32 __CARDVerify(CARDControl *card)
|
||||
{
|
||||
s32 result;
|
||||
int errors;
|
||||
|
||||
result = VerifyID(card);
|
||||
if (result < 0) {
|
||||
return result;
|
||||
}
|
||||
|
||||
errors = VerifyDir(card, NULL);
|
||||
errors += VerifyFAT(card, NULL);
|
||||
switch (errors) {
|
||||
case 0:
|
||||
return CARD_RESULT_READY;
|
||||
case 1:
|
||||
return CARD_RESULT_BROKEN;
|
||||
default:
|
||||
return CARD_RESULT_BROKEN;
|
||||
}
|
||||
}
|
||||
|
||||
s32 CARDCheckExAsync(s32 chan, s32 *xferBytes, CARDCallback callback)
|
||||
{
|
||||
CARDControl *card;
|
||||
CARDDir *dir[2];
|
||||
u16 *fat[2];
|
||||
u16 *map;
|
||||
s32 result;
|
||||
int errors;
|
||||
int currentFat;
|
||||
int currentDir;
|
||||
s32 fileNo;
|
||||
u16 iBlock;
|
||||
u16 cBlock;
|
||||
u16 cFree;
|
||||
BOOL updateFat = FALSE;
|
||||
BOOL updateDir = FALSE;
|
||||
BOOL updateOrphan = FALSE;
|
||||
|
||||
if (xferBytes) {
|
||||
*xferBytes = 0;
|
||||
}
|
||||
|
||||
result = __CARDGetControlBlock(chan, &card);
|
||||
if (result < 0) {
|
||||
return result;
|
||||
}
|
||||
|
||||
result = VerifyID(card);
|
||||
if (result < 0) {
|
||||
return __CARDPutControlBlock(card, result);
|
||||
}
|
||||
|
||||
errors = VerifyDir(card, ¤tDir);
|
||||
errors += VerifyFAT(card, ¤tFat);
|
||||
if (1 < errors) {
|
||||
return __CARDPutControlBlock(card, CARD_RESULT_BROKEN);
|
||||
}
|
||||
|
||||
dir[0] = (CARDDir *)((u8 *)card->workArea + (1 + 0) * CARD_SYSTEM_BLOCK_SIZE);
|
||||
dir[1] = (CARDDir *)((u8 *)card->workArea + (1 + 1) * CARD_SYSTEM_BLOCK_SIZE);
|
||||
fat[0] = (u16 *)((u8 *)card->workArea + (3 + 0) * CARD_SYSTEM_BLOCK_SIZE);
|
||||
fat[1] = (u16 *)((u8 *)card->workArea + (3 + 1) * CARD_SYSTEM_BLOCK_SIZE);
|
||||
|
||||
switch (errors) {
|
||||
case 0:
|
||||
break;
|
||||
case 1:
|
||||
if (!card->currentDir) {
|
||||
card->currentDir = dir[currentDir];
|
||||
memcpy(dir[currentDir], dir[currentDir ^ 1], CARD_SYSTEM_BLOCK_SIZE);
|
||||
updateDir = TRUE;
|
||||
}
|
||||
else {
|
||||
card->currentFat = fat[currentFat];
|
||||
memcpy(fat[currentFat], fat[currentFat ^ 1], CARD_SYSTEM_BLOCK_SIZE);
|
||||
updateFat = TRUE;
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
map = fat[currentFat ^ 1];
|
||||
memset(map, 0, CARD_SYSTEM_BLOCK_SIZE);
|
||||
|
||||
for (fileNo = 0; fileNo < CARD_MAX_FILE; fileNo++) {
|
||||
CARDDir *ent;
|
||||
|
||||
ent = &card->currentDir[fileNo];
|
||||
if (ent->gameName[0] == 0xff) {
|
||||
continue;
|
||||
}
|
||||
|
||||
for (iBlock = ent->startBlock, cBlock = 0; iBlock != 0xFFFF && cBlock < ent->length; iBlock = card->currentFat[iBlock], ++cBlock) {
|
||||
if (!CARDIsValidBlockNo(card, iBlock) || 1 < ++map[iBlock]) {
|
||||
return __CARDPutControlBlock(card, CARD_RESULT_BROKEN);
|
||||
}
|
||||
}
|
||||
if (cBlock != ent->length || iBlock != 0xFFFF) {
|
||||
return __CARDPutControlBlock(card, CARD_RESULT_BROKEN);
|
||||
}
|
||||
}
|
||||
|
||||
cFree = 0;
|
||||
for (iBlock = CARD_NUM_SYSTEM_BLOCK; iBlock < card->cBlock; iBlock++) {
|
||||
u16 nextBlock;
|
||||
|
||||
nextBlock = card->currentFat[iBlock];
|
||||
if (map[iBlock] == 0) {
|
||||
if (nextBlock != CARD_FAT_AVAIL) {
|
||||
card->currentFat[iBlock] = CARD_FAT_AVAIL;
|
||||
updateOrphan = TRUE;
|
||||
}
|
||||
cFree++;
|
||||
}
|
||||
else if (!CARDIsValidBlockNo(card, nextBlock) && nextBlock != 0xFFFF) {
|
||||
return __CARDPutControlBlock(card, CARD_RESULT_BROKEN);
|
||||
}
|
||||
}
|
||||
if (cFree != card->currentFat[CARD_FAT_FREEBLOCKS]) {
|
||||
card->currentFat[CARD_FAT_FREEBLOCKS] = cFree;
|
||||
updateOrphan = TRUE;
|
||||
}
|
||||
if (updateOrphan) {
|
||||
__CARDCheckSum(&card->currentFat[CARD_FAT_CHECKCODE], CARD_SYSTEM_BLOCK_SIZE - sizeof(u32), &card->currentFat[CARD_FAT_CHECKSUM],
|
||||
&card->currentFat[CARD_FAT_CHECKSUMINV]);
|
||||
}
|
||||
|
||||
memcpy(fat[currentFat ^ 1], fat[currentFat], CARD_SYSTEM_BLOCK_SIZE);
|
||||
|
||||
if (updateDir) {
|
||||
if (xferBytes) {
|
||||
*xferBytes = CARD_SYSTEM_BLOCK_SIZE;
|
||||
}
|
||||
return __CARDUpdateDir(chan, callback);
|
||||
}
|
||||
|
||||
if (updateFat | updateOrphan) {
|
||||
if (xferBytes) {
|
||||
*xferBytes = CARD_SYSTEM_BLOCK_SIZE;
|
||||
}
|
||||
return __CARDUpdateFatBlock(chan, card->currentFat, callback);
|
||||
}
|
||||
|
||||
__CARDPutControlBlock(card, CARD_RESULT_READY);
|
||||
if (callback) {
|
||||
BOOL enabled = OSDisableInterrupts();
|
||||
callback(chan, CARD_RESULT_READY);
|
||||
OSRestoreInterrupts(enabled);
|
||||
}
|
||||
return CARD_RESULT_READY;
|
||||
}
|
||||
|
||||
s32 CARDCheckAsync(s32 chan, CARDCallback callback)
|
||||
{
|
||||
s32 xferBytes;
|
||||
|
||||
return CARDCheckExAsync(chan, &xferBytes, callback);
|
||||
}
|
||||
|
||||
s32 CARDCheck(s32 chan)
|
||||
{
|
||||
s32 xferBytes;
|
||||
|
||||
s32 result = CARDCheckExAsync(chan, &xferBytes, __CARDSyncCallback);
|
||||
if (result >= 0) {
|
||||
if (&xferBytes == NULL) {
|
||||
return result;
|
||||
}
|
||||
|
||||
return __CARDSync(chan);
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
126
src/dolphin/card/CARDCreate.c
Normal file
126
src/dolphin/card/CARDCreate.c
Normal file
|
|
@ -0,0 +1,126 @@
|
|||
#include <dolphin/card.h>
|
||||
#include <dolphin/dsp.h>
|
||||
#include <dolphin/dvd.h>
|
||||
#include <dolphin/os.h>
|
||||
|
||||
#include <dolphin/CARDPriv.h>
|
||||
|
||||
static void CreateCallbackFat(s32 chan, s32 result)
|
||||
{
|
||||
CARDControl *card;
|
||||
CARDDir *dir;
|
||||
CARDDir *ent;
|
||||
CARDCallback callback;
|
||||
|
||||
card = &__CARDBlock[chan];
|
||||
callback = card->apiCallback;
|
||||
card->apiCallback = 0;
|
||||
if (result < 0) {
|
||||
goto error;
|
||||
}
|
||||
|
||||
dir = __CARDGetDirBlock(card);
|
||||
ent = &dir[card->freeNo];
|
||||
memcpy(ent->gameName, card->diskID->gameName, sizeof(ent->gameName));
|
||||
memcpy(ent->company, card->diskID->company, sizeof(ent->company));
|
||||
ent->permission = CARD_ATTR_PUBLIC;
|
||||
ent->copyTimes = 0;
|
||||
ent->startBlock = card->startBlock;
|
||||
|
||||
ent->bannerFormat = 0;
|
||||
ent->iconAddr = 0xffffffff;
|
||||
ent->iconFormat = 0;
|
||||
ent->iconSpeed = 0;
|
||||
ent->commentAddr = 0xffffffff;
|
||||
|
||||
CARDSetIconSpeed(ent, 0, CARD_STAT_SPEED_FAST);
|
||||
|
||||
card->fileInfo->offset = 0;
|
||||
card->fileInfo->iBlock = ent->startBlock;
|
||||
|
||||
ent->time = (u32)OSTicksToSeconds(OSGetTime());
|
||||
result = __CARDUpdateDir(chan, callback);
|
||||
if (result < 0) {
|
||||
goto error;
|
||||
}
|
||||
return;
|
||||
|
||||
error:
|
||||
__CARDPutControlBlock(card, result);
|
||||
if (callback) {
|
||||
callback(chan, result);
|
||||
}
|
||||
}
|
||||
|
||||
s32 CARDCreateAsync(s32 chan, const char *fileName, u32 size, CARDFileInfo *fileInfo, CARDCallback callback)
|
||||
{
|
||||
CARDControl *card;
|
||||
CARDDir *dir;
|
||||
CARDDir *ent;
|
||||
s32 result;
|
||||
u16 fileNo;
|
||||
u16 freeNo;
|
||||
u16 *fat;
|
||||
|
||||
if (strlen(fileName) > (u32)CARD_FILENAME_MAX) {
|
||||
return CARD_RESULT_NAMETOOLONG;
|
||||
}
|
||||
|
||||
result = __CARDGetControlBlock(chan, &card);
|
||||
if (result < 0) {
|
||||
return result;
|
||||
}
|
||||
|
||||
if (size <= 0 || (size % card->sectorSize) != 0) {
|
||||
return CARD_RESULT_FATAL_ERROR;
|
||||
}
|
||||
|
||||
freeNo = (u16)-1;
|
||||
dir = __CARDGetDirBlock(card);
|
||||
for (fileNo = 0; fileNo < CARD_MAX_FILE; fileNo++) {
|
||||
ent = &dir[fileNo];
|
||||
if (ent->gameName[0] == 0xff) {
|
||||
if (freeNo == (u16)-1) {
|
||||
freeNo = fileNo;
|
||||
}
|
||||
}
|
||||
else if (memcmp(ent->gameName, card->diskID->gameName, sizeof(ent->gameName)) == 0
|
||||
&& memcmp(ent->company, card->diskID->company, sizeof(ent->company)) == 0 && __CARDCompareFileName(ent, fileName)) {
|
||||
return __CARDPutControlBlock(card, CARD_RESULT_EXIST);
|
||||
}
|
||||
}
|
||||
if (freeNo == (u16)-1) {
|
||||
return __CARDPutControlBlock(card, CARD_RESULT_NOENT);
|
||||
}
|
||||
|
||||
fat = __CARDGetFatBlock(card);
|
||||
if (card->sectorSize * fat[CARD_FAT_FREEBLOCKS] < size) {
|
||||
return __CARDPutControlBlock(card, CARD_RESULT_INSSPACE);
|
||||
}
|
||||
|
||||
card->apiCallback = callback ? callback : __CARDDefaultApiCallback;
|
||||
card->freeNo = freeNo;
|
||||
ent = &dir[freeNo];
|
||||
ent->length = (u16)(size / card->sectorSize);
|
||||
strcat(ent->fileName, fileName, CARD_FILENAME_MAX);
|
||||
|
||||
card->fileInfo = fileInfo;
|
||||
fileInfo->chan = chan;
|
||||
fileInfo->fileNo = freeNo;
|
||||
|
||||
result = __CARDAllocBlock(chan, size / card->sectorSize, CreateCallbackFat);
|
||||
if (result < 0) {
|
||||
return __CARDPutControlBlock(card, result);
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
s32 CARDCreate(s32 chan, const char *fileName, u32 size, CARDFileInfo *fileInfo)
|
||||
{
|
||||
s32 result = CARDCreateAsync(chan, fileName, size, fileInfo, __CARDSyncCallback);
|
||||
if (result < 0) {
|
||||
return result;
|
||||
}
|
||||
|
||||
return __CARDSync(chan);
|
||||
}
|
||||
111
src/dolphin/card/CARDDelete.c
Normal file
111
src/dolphin/card/CARDDelete.c
Normal file
|
|
@ -0,0 +1,111 @@
|
|||
#include <dolphin/card.h>
|
||||
#include <dolphin/dsp.h>
|
||||
#include <dolphin/dvd.h>
|
||||
#include <dolphin/os.h>
|
||||
|
||||
#include "string.h"
|
||||
|
||||
#include <dolphin/CARDPriv.h>
|
||||
|
||||
static void DeleteCallback(s32 chan, s32 result)
|
||||
{
|
||||
CARDControl *card;
|
||||
CARDCallback callback;
|
||||
|
||||
card = &__CARDBlock[chan];
|
||||
callback = card->apiCallback;
|
||||
card->apiCallback = 0;
|
||||
|
||||
if (result < 0) {
|
||||
goto error;
|
||||
}
|
||||
|
||||
result = __CARDFreeBlock(chan, card->startBlock, callback);
|
||||
if (result < 0) {
|
||||
goto error;
|
||||
}
|
||||
return;
|
||||
|
||||
error:
|
||||
__CARDPutControlBlock(card, result);
|
||||
if (callback) {
|
||||
callback(chan, result);
|
||||
}
|
||||
}
|
||||
|
||||
s32 CARDFastDeleteAsync(s32 chan, s32 fileNo, CARDCallback callback)
|
||||
{
|
||||
CARDControl *card;
|
||||
CARDDir *dir;
|
||||
CARDDir *ent;
|
||||
s32 result;
|
||||
|
||||
if (fileNo < 0 || CARD_MAX_FILE <= fileNo) {
|
||||
return CARD_RESULT_FATAL_ERROR;
|
||||
}
|
||||
result = __CARDGetControlBlock(chan, &card);
|
||||
if (result < 0) {
|
||||
return result;
|
||||
}
|
||||
|
||||
dir = __CARDGetDirBlock(card);
|
||||
ent = &dir[fileNo];
|
||||
result = __CARDAccess(card, ent);
|
||||
if (result < 0) {
|
||||
return __CARDPutControlBlock(card, result);
|
||||
}
|
||||
if (__CARDIsOpened(card, fileNo)) {
|
||||
return __CARDPutControlBlock(card, CARD_RESULT_BUSY);
|
||||
}
|
||||
card->startBlock = ent->startBlock;
|
||||
memset(ent, 0xff, sizeof(CARDDir));
|
||||
|
||||
card->apiCallback = callback ? callback : __CARDDefaultApiCallback;
|
||||
result = __CARDUpdateDir(chan, DeleteCallback);
|
||||
if (result < 0) {
|
||||
__CARDPutControlBlock(card, result);
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
s32 CARDDeleteAsync(s32 chan, const char *fileName, CARDCallback callback)
|
||||
{
|
||||
CARDControl *card;
|
||||
s32 fileNo;
|
||||
s32 result;
|
||||
CARDDir *dir;
|
||||
CARDDir *ent;
|
||||
|
||||
result = __CARDGetControlBlock(chan, &card);
|
||||
if (result < 0) {
|
||||
return result;
|
||||
}
|
||||
result = __CARDGetFileNo(card, fileName, &fileNo);
|
||||
if (result < 0) {
|
||||
return __CARDPutControlBlock(card, result);
|
||||
}
|
||||
if (__CARDIsOpened(card, fileNo)) {
|
||||
return __CARDPutControlBlock(card, CARD_RESULT_BUSY);
|
||||
}
|
||||
|
||||
dir = __CARDGetDirBlock(card);
|
||||
ent = &dir[fileNo];
|
||||
card->startBlock = ent->startBlock;
|
||||
memset(ent, 0xff, sizeof(CARDDir));
|
||||
|
||||
card->apiCallback = callback ? callback : __CARDDefaultApiCallback;
|
||||
result = __CARDUpdateDir(chan, DeleteCallback);
|
||||
if (result < 0) {
|
||||
__CARDPutControlBlock(card, result);
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
s32 CARDDelete(s32 chan, const char *fileName)
|
||||
{
|
||||
s32 result = CARDDeleteAsync(chan, fileName, __CARDSyncCallback);
|
||||
|
||||
if (result < 0)
|
||||
return result;
|
||||
return __CARDSync(chan);
|
||||
}
|
||||
101
src/dolphin/card/CARDDir.c
Normal file
101
src/dolphin/card/CARDDir.c
Normal file
|
|
@ -0,0 +1,101 @@
|
|||
#include <dolphin/card.h>
|
||||
#include <dolphin/dsp.h>
|
||||
#include <dolphin/dvd.h>
|
||||
#include <dolphin/os.h>
|
||||
|
||||
#include "string.h"
|
||||
|
||||
#include <dolphin/CARDPriv.h>
|
||||
|
||||
CARDDir *__CARDGetDirBlock(CARDControl *card)
|
||||
{
|
||||
return card->currentDir;
|
||||
}
|
||||
|
||||
static void WriteCallback(s32 chan, s32 result)
|
||||
{
|
||||
CARDControl *card;
|
||||
CARDCallback callback;
|
||||
|
||||
card = &__CARDBlock[chan];
|
||||
if (0 <= result) {
|
||||
CARDDir *dir0 = (CARDDir *)((u8 *)card->workArea + 0x2000);
|
||||
CARDDir *dir1 = (CARDDir *)((u8 *)card->workArea + 0x4000);
|
||||
|
||||
if (card->currentDir == dir0) {
|
||||
card->currentDir = dir1;
|
||||
memcpy(dir1, dir0, 0x2000);
|
||||
}
|
||||
else {
|
||||
card->currentDir = dir0;
|
||||
memcpy(dir0, dir1, 0x2000);
|
||||
}
|
||||
}
|
||||
|
||||
error:
|
||||
if (card->apiCallback == 0) {
|
||||
__CARDPutControlBlock(card, result);
|
||||
}
|
||||
callback = card->eraseCallback;
|
||||
if (callback) {
|
||||
card->eraseCallback = 0;
|
||||
callback(chan, result);
|
||||
}
|
||||
}
|
||||
|
||||
static void EraseCallback(s32 chan, s32 result)
|
||||
{
|
||||
CARDControl *card;
|
||||
CARDCallback callback;
|
||||
CARDDir *dir;
|
||||
u32 tmp[2];
|
||||
u32 addr;
|
||||
|
||||
card = &__CARDBlock[chan];
|
||||
if (result < 0) {
|
||||
goto error;
|
||||
}
|
||||
|
||||
dir = __CARDGetDirBlock(card);
|
||||
addr = ((u32)dir - (u32)card->workArea) / 0x2000 * card->sectorSize;
|
||||
result = __CARDWrite(chan, addr, 0x2000, dir, WriteCallback);
|
||||
if (result < 0) {
|
||||
goto error;
|
||||
}
|
||||
|
||||
return;
|
||||
|
||||
error:
|
||||
if (card->apiCallback == 0) {
|
||||
__CARDPutControlBlock(card, result);
|
||||
}
|
||||
callback = card->eraseCallback;
|
||||
if (callback) {
|
||||
card->eraseCallback = 0;
|
||||
callback(chan, result);
|
||||
}
|
||||
}
|
||||
|
||||
s32 __CARDUpdateDir(s32 chan, CARDCallback callback)
|
||||
{
|
||||
CARDControl *card;
|
||||
CARDDirCheck *check;
|
||||
u32 tmp[2];
|
||||
u32 addr;
|
||||
CARDDir *dir;
|
||||
|
||||
card = &__CARDBlock[chan];
|
||||
if (!card->attached) {
|
||||
return CARD_RESULT_NOCARD;
|
||||
}
|
||||
|
||||
dir = __CARDGetDirBlock(card);
|
||||
check = __CARDGetDirCheck(dir);
|
||||
++check->checkCode;
|
||||
__CARDCheckSum(dir, 0x2000 - sizeof(u32), &check->checkSum, &check->checkSumInv);
|
||||
DCStoreRange(dir, 0x2000);
|
||||
|
||||
card->eraseCallback = callback;
|
||||
addr = ((u32)dir - (u32)card->workArea) / 0x2000 * card->sectorSize;
|
||||
return __CARDEraseSector(chan, addr, EraseCallback);
|
||||
}
|
||||
141
src/dolphin/card/CARDFormat.c
Normal file
141
src/dolphin/card/CARDFormat.c
Normal file
|
|
@ -0,0 +1,141 @@
|
|||
#include <dolphin/card.h>
|
||||
#include <dolphin/dsp.h>
|
||||
#include <dolphin/dvd.h>
|
||||
#include <dolphin/os.h>
|
||||
|
||||
#include <dolphin/CARDPriv.h>
|
||||
#include <dolphin/OSRtcPriv.h>
|
||||
#include <dolphin/hw_regs.h>
|
||||
#include <dolphin/vi.h>
|
||||
|
||||
#include "string.h"
|
||||
|
||||
static void FormatCallback(s32 chan, s32 result)
|
||||
{
|
||||
CARDControl *card;
|
||||
CARDCallback callback;
|
||||
|
||||
card = &__CARDBlock[chan];
|
||||
if (result < 0) {
|
||||
goto error;
|
||||
}
|
||||
|
||||
++card->formatStep;
|
||||
if (card->formatStep < CARD_NUM_SYSTEM_BLOCK) {
|
||||
result = __CARDEraseSector(chan, (u32)card->sectorSize * card->formatStep, FormatCallback);
|
||||
if (0 <= result) {
|
||||
return;
|
||||
}
|
||||
}
|
||||
else if (card->formatStep < 2 * CARD_NUM_SYSTEM_BLOCK) {
|
||||
int step = card->formatStep - CARD_NUM_SYSTEM_BLOCK;
|
||||
result = __CARDWrite(
|
||||
chan, (u32)card->sectorSize * step, CARD_SYSTEM_BLOCK_SIZE, (u8 *)card->workArea + (CARD_SYSTEM_BLOCK_SIZE * step), FormatCallback);
|
||||
if (result >= 0) {
|
||||
return;
|
||||
}
|
||||
}
|
||||
else {
|
||||
card->currentDir = (CARDDir *)((u8 *)card->workArea + (1 + 0) * CARD_SYSTEM_BLOCK_SIZE);
|
||||
memcpy(card->currentDir, (u8 *)card->workArea + (1 + 1) * CARD_SYSTEM_BLOCK_SIZE, CARD_SYSTEM_BLOCK_SIZE);
|
||||
card->currentFat = (u16 *)((u8 *)card->workArea + (3 + 0) * CARD_SYSTEM_BLOCK_SIZE);
|
||||
memcpy(card->currentFat, (u8 *)card->workArea + (3 + 1) * CARD_SYSTEM_BLOCK_SIZE, CARD_SYSTEM_BLOCK_SIZE);
|
||||
}
|
||||
|
||||
error:
|
||||
callback = card->apiCallback;
|
||||
card->apiCallback = 0;
|
||||
__CARDPutControlBlock(card, result);
|
||||
callback(chan, result);
|
||||
}
|
||||
|
||||
s32 __CARDFormatRegionAsync(s32 chan, u16 encode, CARDCallback callback)
|
||||
{
|
||||
CARDControl *card;
|
||||
CARDID *id;
|
||||
CARDDir *dir;
|
||||
u16 *fat;
|
||||
s16 i;
|
||||
s32 result;
|
||||
OSSram *sram;
|
||||
OSSramEx *sramEx;
|
||||
u16 viDTVStatus;
|
||||
OSTime time;
|
||||
OSTime rand;
|
||||
|
||||
result = __CARDGetControlBlock(chan, &card);
|
||||
if (result < 0) {
|
||||
return result;
|
||||
}
|
||||
|
||||
id = (CARDID *)card->workArea;
|
||||
memset(id, 0xff, CARD_SYSTEM_BLOCK_SIZE);
|
||||
viDTVStatus = __VIRegs[55];
|
||||
|
||||
id->encode = encode;
|
||||
|
||||
sram = __OSLockSram();
|
||||
*(u32 *)&id->serial[20] = sram->counterBias;
|
||||
*(u32 *)&id->serial[24] = sram->language;
|
||||
__OSUnlockSram(FALSE);
|
||||
|
||||
rand = time = OSGetTime();
|
||||
|
||||
sramEx = __OSLockSramEx();
|
||||
for (i = 0; i < 12; i++) {
|
||||
rand = (rand * 1103515245 + 12345) >> 16;
|
||||
id->serial[i] = (u8)(sramEx->flashID[chan][i] + rand);
|
||||
rand = ((rand * 1103515245 + 12345) >> 16) & 0x7FFF;
|
||||
}
|
||||
__OSUnlockSramEx(FALSE);
|
||||
|
||||
*(u32 *)&id->serial[28] = viDTVStatus;
|
||||
*(OSTime *)&id->serial[12] = time;
|
||||
|
||||
id->deviceID = 0;
|
||||
id->size = card->size;
|
||||
__CARDCheckSum(id, sizeof(CARDID) - sizeof(u32), &id->checkSum, &id->checkSumInv);
|
||||
|
||||
for (i = 0; i < 2; i++) {
|
||||
CARDDirCheck *check;
|
||||
|
||||
dir = (CARDDir *)((u8 *)card->workArea + (1 + i) * CARD_SYSTEM_BLOCK_SIZE);
|
||||
memset(dir, 0xff, CARD_SYSTEM_BLOCK_SIZE);
|
||||
check = __CARDGetDirCheck(dir);
|
||||
check->checkCode = i;
|
||||
__CARDCheckSum(dir, CARD_SYSTEM_BLOCK_SIZE - sizeof(u32), &check->checkSum, &check->checkSumInv);
|
||||
}
|
||||
for (i = 0; i < 2; i++) {
|
||||
fat = (u16 *)((u8 *)card->workArea + (3 + i) * CARD_SYSTEM_BLOCK_SIZE);
|
||||
memset(fat, 0x00, CARD_SYSTEM_BLOCK_SIZE);
|
||||
fat[CARD_FAT_CHECKCODE] = (u16)i;
|
||||
fat[CARD_FAT_FREEBLOCKS] = (u16)(card->cBlock - CARD_NUM_SYSTEM_BLOCK);
|
||||
fat[CARD_FAT_LASTSLOT] = CARD_NUM_SYSTEM_BLOCK - 1;
|
||||
__CARDCheckSum(&fat[CARD_FAT_CHECKCODE], CARD_SYSTEM_BLOCK_SIZE - sizeof(u32), &fat[CARD_FAT_CHECKSUM], &fat[CARD_FAT_CHECKSUMINV]);
|
||||
}
|
||||
|
||||
card->apiCallback = callback ? callback : __CARDDefaultApiCallback;
|
||||
DCStoreRange(card->workArea, CARD_WORKAREA_SIZE);
|
||||
|
||||
card->formatStep = 0;
|
||||
result = __CARDEraseSector(chan, (u32)card->sectorSize * card->formatStep, FormatCallback);
|
||||
if (result < 0) {
|
||||
__CARDPutControlBlock(card, result);
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
s32 CARDFormatAsync(s32 chan, CARDCallback callback)
|
||||
{
|
||||
return __CARDFormatRegionAsync(chan, __CARDGetFontEncode(), callback);
|
||||
}
|
||||
|
||||
s32 CARDFormat(s32 chan)
|
||||
{
|
||||
s32 result = __CARDFormatRegionAsync(chan, OSGetFontEncode(), __CARDSyncCallback);
|
||||
if (result < 0) {
|
||||
return result;
|
||||
}
|
||||
|
||||
return __CARDSync(chan);
|
||||
}
|
||||
396
src/dolphin/card/CARDMount.c
Normal file
396
src/dolphin/card/CARDMount.c
Normal file
|
|
@ -0,0 +1,396 @@
|
|||
#include <dolphin/card.h>
|
||||
#include <dolphin/dsp.h>
|
||||
#include <dolphin/dvd.h>
|
||||
#include <dolphin/exi.h>
|
||||
#include <dolphin/os.h>
|
||||
|
||||
#include <dolphin/CARDPriv.h>
|
||||
#include <dolphin/OSRtcPriv.h>
|
||||
|
||||
u8 GameChoice : (OS_BASE_CACHED | 0x000030E3);
|
||||
|
||||
static u32 SectorSizeTable[8] = {
|
||||
8 * 1024,
|
||||
16 * 1024,
|
||||
32 * 1024,
|
||||
64 * 1024,
|
||||
128 * 1024,
|
||||
256 * 1024,
|
||||
0,
|
||||
0,
|
||||
};
|
||||
|
||||
static u32 LatencyTable[8] = {
|
||||
4,
|
||||
8,
|
||||
16,
|
||||
32,
|
||||
64,
|
||||
128,
|
||||
256,
|
||||
512,
|
||||
};
|
||||
|
||||
void __CARDMountCallback(s32 chan, s32 result);
|
||||
static void DoUnmount(s32 chan, s32 result);
|
||||
|
||||
static BOOL IsCard(u32 id)
|
||||
{
|
||||
u32 size;
|
||||
s32 sectorSize;
|
||||
if (id & (0xFFFF0000) && (id != 0x80000004 || __CARDVendorID == 0xFFFF)) {
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
if ((id & 3) != 0) {
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
size = id & 0xfc;
|
||||
switch (size) {
|
||||
case 4:
|
||||
case 8:
|
||||
case 16:
|
||||
case 32:
|
||||
case 64:
|
||||
case 128:
|
||||
break;
|
||||
default:
|
||||
return FALSE;
|
||||
break;
|
||||
}
|
||||
|
||||
sectorSize = SectorSizeTable[(id & 0x00003800) >> 11];
|
||||
if (sectorSize == 0) {
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
if ((size * 1024 * 1024 / 8) / sectorSize < 8) {
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
s32 CARDProbeEx(s32 chan, s32 *memSize, s32 *sectorSize)
|
||||
{
|
||||
u32 id;
|
||||
CARDControl *card;
|
||||
BOOL enabled;
|
||||
s32 result;
|
||||
int probe;
|
||||
|
||||
if (chan < 0 || 2 <= chan) {
|
||||
return CARD_RESULT_FATAL_ERROR;
|
||||
}
|
||||
|
||||
if (GameChoice & 0x80) {
|
||||
return CARD_RESULT_NOCARD;
|
||||
}
|
||||
|
||||
card = &__CARDBlock[chan];
|
||||
enabled = OSDisableInterrupts();
|
||||
|
||||
probe = EXIProbeEx(chan);
|
||||
if (probe == -1) {
|
||||
result = CARD_RESULT_NOCARD;
|
||||
}
|
||||
else if (probe == 0) {
|
||||
result = CARD_RESULT_BUSY;
|
||||
}
|
||||
else if (card->attached) {
|
||||
if (card->mountStep < 1) {
|
||||
result = CARD_RESULT_BUSY;
|
||||
}
|
||||
else {
|
||||
if (memSize) {
|
||||
*memSize = card->size;
|
||||
}
|
||||
if (sectorSize) {
|
||||
*sectorSize = card->sectorSize;
|
||||
}
|
||||
result = CARD_RESULT_READY;
|
||||
}
|
||||
}
|
||||
else if ((EXIGetState(chan) & 8)) {
|
||||
result = CARD_RESULT_WRONGDEVICE;
|
||||
}
|
||||
else if (!EXIGetID(chan, 0, &id)) {
|
||||
result = CARD_RESULT_BUSY;
|
||||
}
|
||||
else if (IsCard(id)) {
|
||||
if (memSize) {
|
||||
*memSize = (s32)(id & 0xfc);
|
||||
}
|
||||
if (sectorSize) {
|
||||
*sectorSize = SectorSizeTable[(id & 0x00003800) >> 11];
|
||||
}
|
||||
result = CARD_RESULT_READY;
|
||||
}
|
||||
else {
|
||||
result = CARD_RESULT_WRONGDEVICE;
|
||||
}
|
||||
|
||||
OSRestoreInterrupts(enabled);
|
||||
return result;
|
||||
}
|
||||
|
||||
static s32 DoMount(s32 chan)
|
||||
{
|
||||
CARDControl *card;
|
||||
u32 id;
|
||||
u8 status;
|
||||
s32 result;
|
||||
OSSramEx *sram;
|
||||
int i;
|
||||
u8 checkSum;
|
||||
int step;
|
||||
|
||||
card = &__CARDBlock[chan];
|
||||
|
||||
if (card->mountStep == 0) {
|
||||
if (EXIGetID(chan, 0, &id) == 0) {
|
||||
result = CARD_RESULT_NOCARD;
|
||||
}
|
||||
else if (IsCard(id)) {
|
||||
result = CARD_RESULT_READY;
|
||||
}
|
||||
else {
|
||||
result = CARD_RESULT_WRONGDEVICE;
|
||||
}
|
||||
if (result < 0) {
|
||||
goto error;
|
||||
}
|
||||
|
||||
card->cid = id;
|
||||
|
||||
card->size = (u16)(id & 0xFC);
|
||||
card->sectorSize = SectorSizeTable[(id & 0x00003800) >> 11];
|
||||
card->cBlock = (u16)((card->size * 1024 * 1024 / 8) / card->sectorSize);
|
||||
card->latency = LatencyTable[(id & 0x00000700) >> 8];
|
||||
|
||||
result = __CARDClearStatus(chan);
|
||||
if (result < 0) {
|
||||
goto error;
|
||||
}
|
||||
result = __CARDReadStatus(chan, &status);
|
||||
if (result < 0) {
|
||||
goto error;
|
||||
}
|
||||
|
||||
if (!EXIProbe(chan)) {
|
||||
result = CARD_RESULT_NOCARD;
|
||||
goto error;
|
||||
}
|
||||
|
||||
if (!(status & 0x40)) {
|
||||
result = __CARDUnlock(chan, card->id);
|
||||
if (result < 0) {
|
||||
goto error;
|
||||
}
|
||||
|
||||
checkSum = 0;
|
||||
sram = __OSLockSramEx();
|
||||
for (i = 0; i < 12; i++) {
|
||||
sram->flashID[chan][i] = card->id[i];
|
||||
checkSum += card->id[i];
|
||||
}
|
||||
sram->flashIDCheckSum[chan] = (u8)~checkSum;
|
||||
__OSUnlockSramEx(TRUE);
|
||||
|
||||
return result;
|
||||
}
|
||||
else {
|
||||
card->mountStep = 1;
|
||||
|
||||
checkSum = 0;
|
||||
sram = __OSLockSramEx();
|
||||
for (i = 0; i < 12; i++) {
|
||||
checkSum += sram->flashID[chan][i];
|
||||
}
|
||||
__OSUnlockSramEx(FALSE);
|
||||
if (sram->flashIDCheckSum[chan] != (u8)~checkSum) {
|
||||
result = CARD_RESULT_IOERROR;
|
||||
goto error;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (card->mountStep == 1) {
|
||||
if (card->cid == 0x80000004) {
|
||||
u16 vendorID;
|
||||
|
||||
sram = __OSLockSramEx();
|
||||
vendorID = *(u16 *)sram->flashID[chan];
|
||||
__OSUnlockSramEx(FALSE);
|
||||
|
||||
if (__CARDVendorID == 0xffff || vendorID != __CARDVendorID) {
|
||||
result = CARD_RESULT_WRONGDEVICE;
|
||||
goto error;
|
||||
}
|
||||
}
|
||||
|
||||
card->mountStep = 2;
|
||||
|
||||
result = __CARDEnableInterrupt(chan, TRUE);
|
||||
if (result < 0) {
|
||||
goto error;
|
||||
}
|
||||
|
||||
EXISetExiCallback(chan, __CARDExiHandler);
|
||||
EXIUnlock(chan);
|
||||
DCInvalidateRange(card->workArea, CARD_WORKAREA_SIZE);
|
||||
}
|
||||
|
||||
step = card->mountStep - 2;
|
||||
result = __CARDRead(
|
||||
chan, (u32)card->sectorSize * step, CARD_SYSTEM_BLOCK_SIZE, (u8 *)card->workArea + (CARD_SYSTEM_BLOCK_SIZE * step), __CARDMountCallback);
|
||||
if (result < 0) {
|
||||
__CARDPutControlBlock(card, result);
|
||||
}
|
||||
return result;
|
||||
|
||||
error:
|
||||
EXIUnlock(chan);
|
||||
DoUnmount(chan, result);
|
||||
return result;
|
||||
}
|
||||
|
||||
void __CARDMountCallback(s32 chan, s32 result)
|
||||
{
|
||||
CARDControl *card;
|
||||
CARDCallback callback;
|
||||
|
||||
card = &__CARDBlock[chan];
|
||||
|
||||
switch (result) {
|
||||
case CARD_RESULT_READY:
|
||||
if (++card->mountStep < CARD_MAX_MOUNT_STEP) {
|
||||
result = DoMount(chan);
|
||||
if (0 <= result) {
|
||||
return;
|
||||
}
|
||||
}
|
||||
else {
|
||||
result = __CARDVerify(card);
|
||||
}
|
||||
break;
|
||||
case CARD_RESULT_UNLOCKED:
|
||||
card->unlockCallback = __CARDMountCallback;
|
||||
if (!EXILock(chan, 0, __CARDUnlockedHandler)) {
|
||||
return;
|
||||
}
|
||||
card->unlockCallback = 0;
|
||||
|
||||
result = DoMount(chan);
|
||||
if (0 <= result) {
|
||||
return;
|
||||
}
|
||||
break;
|
||||
case CARD_RESULT_IOERROR:
|
||||
case CARD_RESULT_NOCARD:
|
||||
DoUnmount(chan, result);
|
||||
break;
|
||||
}
|
||||
|
||||
callback = card->apiCallback;
|
||||
card->apiCallback = 0;
|
||||
__CARDPutControlBlock(card, result);
|
||||
callback(chan, result);
|
||||
}
|
||||
|
||||
s32 CARDMountAsync(s32 chan, void *workArea, CARDCallback detachCallback, CARDCallback attachCallback)
|
||||
{
|
||||
CARDControl *card;
|
||||
BOOL enabled;
|
||||
|
||||
if (chan < 0 || 2 <= chan) {
|
||||
return CARD_RESULT_FATAL_ERROR;
|
||||
}
|
||||
if (GameChoice & 0x80) {
|
||||
return CARD_RESULT_NOCARD;
|
||||
}
|
||||
card = &__CARDBlock[chan];
|
||||
|
||||
enabled = OSDisableInterrupts();
|
||||
if (card->result == CARD_RESULT_BUSY) {
|
||||
OSRestoreInterrupts(enabled);
|
||||
return CARD_RESULT_BUSY;
|
||||
}
|
||||
|
||||
if (!card->attached && (EXIGetState(chan) & 0x08)) {
|
||||
OSRestoreInterrupts(enabled);
|
||||
return CARD_RESULT_WRONGDEVICE;
|
||||
}
|
||||
|
||||
card->result = CARD_RESULT_BUSY;
|
||||
card->workArea = workArea;
|
||||
card->extCallback = detachCallback;
|
||||
card->apiCallback = attachCallback ? attachCallback : __CARDDefaultApiCallback;
|
||||
card->exiCallback = 0;
|
||||
|
||||
if (!card->attached && !EXIAttach(chan, __CARDExtHandler)) {
|
||||
card->result = CARD_RESULT_NOCARD;
|
||||
OSRestoreInterrupts(enabled);
|
||||
return CARD_RESULT_NOCARD;
|
||||
}
|
||||
|
||||
card->mountStep = 0;
|
||||
card->attached = TRUE;
|
||||
EXISetExiCallback(chan, 0);
|
||||
OSCancelAlarm(&card->alarm);
|
||||
|
||||
card->currentDir = 0;
|
||||
card->currentFat = 0;
|
||||
|
||||
OSRestoreInterrupts(enabled);
|
||||
|
||||
card->unlockCallback = __CARDMountCallback;
|
||||
if (!EXILock(chan, 0, __CARDUnlockedHandler)) {
|
||||
return CARD_RESULT_READY;
|
||||
}
|
||||
card->unlockCallback = 0;
|
||||
|
||||
return DoMount(chan);
|
||||
}
|
||||
|
||||
s32 CARDMount(s32 chan, void *workArea, CARDCallback attachCb)
|
||||
{
|
||||
s32 result = CARDMountAsync(chan, workArea, attachCb, __CARDSyncCallback);
|
||||
if (result < 0) {
|
||||
return result;
|
||||
}
|
||||
|
||||
return __CARDSync(chan);
|
||||
}
|
||||
|
||||
static void DoUnmount(s32 chan, s32 result)
|
||||
{
|
||||
CARDControl *card;
|
||||
BOOL enabled;
|
||||
|
||||
card = &__CARDBlock[chan];
|
||||
enabled = OSDisableInterrupts();
|
||||
if (card->attached) {
|
||||
EXISetExiCallback(chan, 0);
|
||||
EXIDetach(chan);
|
||||
OSCancelAlarm(&card->alarm);
|
||||
card->attached = FALSE;
|
||||
card->result = result;
|
||||
card->mountStep = 0;
|
||||
}
|
||||
OSRestoreInterrupts(enabled);
|
||||
}
|
||||
|
||||
s32 CARDUnmount(s32 chan)
|
||||
{
|
||||
CARDControl *card;
|
||||
s32 result;
|
||||
|
||||
result = __CARDGetControlBlock(chan, &card);
|
||||
if (result < 0) {
|
||||
return result;
|
||||
}
|
||||
DoUnmount(chan, CARD_RESULT_NOCARD);
|
||||
return CARD_RESULT_READY;
|
||||
}
|
||||
34
src/dolphin/card/CARDNet.c
Normal file
34
src/dolphin/card/CARDNet.c
Normal file
|
|
@ -0,0 +1,34 @@
|
|||
#include <dolphin/card.h>
|
||||
#include <dolphin/dsp.h>
|
||||
#include <dolphin/dvd.h>
|
||||
#include <dolphin/os.h>
|
||||
|
||||
#include <dolphin/CARDPriv.h>
|
||||
|
||||
u16 __CARDVendorID = 0xffff;
|
||||
|
||||
s32 CARDGetSerialNo(s32 chan, u64 *serialNo)
|
||||
{
|
||||
CARDControl *card;
|
||||
CARDID *id;
|
||||
int i;
|
||||
u64 code;
|
||||
s32 result;
|
||||
|
||||
if (!(0 <= chan && chan < 2)) {
|
||||
return CARD_RESULT_FATAL_ERROR;
|
||||
}
|
||||
|
||||
result = __CARDGetControlBlock(chan, &card);
|
||||
if (result < 0) {
|
||||
return result;
|
||||
}
|
||||
|
||||
id = (CARDID *)card->workArea;
|
||||
for (code = 0, i = 0; i < sizeof(id->serial) / sizeof(u64); ++i) {
|
||||
code ^= *(u64 *)&id->serial[sizeof(u64) * i];
|
||||
}
|
||||
*serialNo = code;
|
||||
|
||||
return __CARDPutControlBlock(card, CARD_RESULT_READY);
|
||||
}
|
||||
134
src/dolphin/card/CARDOpen.c
Normal file
134
src/dolphin/card/CARDOpen.c
Normal file
|
|
@ -0,0 +1,134 @@
|
|||
#include <dolphin/card.h>
|
||||
#include <dolphin/dsp.h>
|
||||
#include <dolphin/dvd.h>
|
||||
#include <dolphin/os.h>
|
||||
|
||||
#include <dolphin/CARDPriv.h>
|
||||
|
||||
BOOL __CARDCompareFileName(CARDDir *ent, const char *fileName)
|
||||
{
|
||||
char *entName;
|
||||
char c1;
|
||||
char c2;
|
||||
int n;
|
||||
|
||||
entName = (char *)ent->fileName;
|
||||
n = CARD_FILENAME_MAX;
|
||||
while (0 <= --n) {
|
||||
if ((c1 = *entName++) != (c2 = *fileName++)) {
|
||||
return FALSE;
|
||||
}
|
||||
else if (c2 == '\0') {
|
||||
return TRUE;
|
||||
}
|
||||
}
|
||||
|
||||
if (*fileName == '\0') {
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
s32 __CARDAccess(CARDControl *card, CARDDir *ent)
|
||||
{
|
||||
if (ent->gameName[0] == 0xFF) {
|
||||
return CARD_RESULT_NOFILE;
|
||||
}
|
||||
|
||||
if (card->diskID == &__CARDDiskNone
|
||||
|| (memcmp(ent->gameName, card->diskID->gameName, 4) == 0 && memcmp(ent->company, card->diskID->company, 2) == 0)) {
|
||||
return CARD_RESULT_READY;
|
||||
}
|
||||
|
||||
return CARD_RESULT_NOPERM;
|
||||
}
|
||||
|
||||
BOOL __CARDIsPublic(CARDDir *ent)
|
||||
{
|
||||
if (ent->gameName[0] == 0xFF) {
|
||||
return CARD_RESULT_NOFILE;
|
||||
}
|
||||
|
||||
if ((ent->permission & CARD_ATTR_PUBLIC) != 0) {
|
||||
return CARD_RESULT_READY;
|
||||
}
|
||||
|
||||
return CARD_RESULT_NOPERM;
|
||||
}
|
||||
|
||||
s32 __CARDGetFileNo(CARDControl *card, const char *fileName, s32 *pfileNo)
|
||||
{
|
||||
CARDDir *dir;
|
||||
CARDDir *ent;
|
||||
s32 fileNo;
|
||||
s32 result;
|
||||
|
||||
if (!card->attached) {
|
||||
return CARD_RESULT_NOCARD;
|
||||
}
|
||||
|
||||
dir = __CARDGetDirBlock(card);
|
||||
for (fileNo = 0; fileNo < CARD_MAX_FILE; fileNo++) {
|
||||
ent = &dir[fileNo];
|
||||
result = __CARDAccess(card, ent);
|
||||
if (result < 0) {
|
||||
continue;
|
||||
}
|
||||
if (__CARDCompareFileName(ent, fileName)) {
|
||||
*pfileNo = fileNo;
|
||||
return CARD_RESULT_READY;
|
||||
}
|
||||
}
|
||||
|
||||
return CARD_RESULT_NOFILE;
|
||||
}
|
||||
|
||||
s32 CARDOpen(s32 chan, const char *fileName, CARDFileInfo *fileInfo)
|
||||
{
|
||||
CARDControl *card;
|
||||
CARDDir *dir;
|
||||
CARDDir *ent;
|
||||
s32 result;
|
||||
s32 fileNo;
|
||||
|
||||
fileInfo->chan = -1;
|
||||
result = __CARDGetControlBlock(chan, &card);
|
||||
if (result < 0) {
|
||||
return result;
|
||||
}
|
||||
result = __CARDGetFileNo(card, fileName, &fileNo);
|
||||
if (0 <= result) {
|
||||
dir = __CARDGetDirBlock(card);
|
||||
ent = &dir[fileNo];
|
||||
if (!CARDIsValidBlockNo(card, ent->startBlock)) {
|
||||
result = CARD_RESULT_BROKEN;
|
||||
}
|
||||
else {
|
||||
fileInfo->chan = chan;
|
||||
fileInfo->fileNo = fileNo;
|
||||
fileInfo->offset = 0;
|
||||
fileInfo->iBlock = ent->startBlock;
|
||||
}
|
||||
}
|
||||
return __CARDPutControlBlock(card, result);
|
||||
}
|
||||
|
||||
s32 CARDClose(CARDFileInfo *fileInfo)
|
||||
{
|
||||
CARDControl *card;
|
||||
s32 result;
|
||||
|
||||
result = __CARDGetControlBlock(fileInfo->chan, &card);
|
||||
if (result < 0) {
|
||||
return result;
|
||||
}
|
||||
|
||||
fileInfo->chan = -1;
|
||||
return __CARDPutControlBlock(card, CARD_RESULT_READY);
|
||||
}
|
||||
|
||||
BOOL __CARDIsOpened(CARDControl *card, s32 fileNo)
|
||||
{
|
||||
return FALSE;
|
||||
}
|
||||
108
src/dolphin/card/CARDRdwr.c
Normal file
108
src/dolphin/card/CARDRdwr.c
Normal file
|
|
@ -0,0 +1,108 @@
|
|||
#include <dolphin/card.h>
|
||||
#include <dolphin/dsp.h>
|
||||
#include <dolphin/dvd.h>
|
||||
#include <dolphin/os.h>
|
||||
|
||||
#include <dolphin/CARDPriv.h>
|
||||
|
||||
static void BlockReadCallback(s32 chan, s32 result)
|
||||
{
|
||||
CARDControl *card;
|
||||
CARDCallback callback;
|
||||
|
||||
card = &__CARDBlock[chan];
|
||||
if (result < 0) {
|
||||
goto error;
|
||||
}
|
||||
|
||||
card->xferred += CARD_SEG_SIZE;
|
||||
|
||||
card->addr += CARD_SEG_SIZE;
|
||||
(u8 *)card->buffer += CARD_SEG_SIZE;
|
||||
if (--card->repeat <= 0) {
|
||||
goto error;
|
||||
}
|
||||
|
||||
result = __CARDReadSegment(chan, BlockReadCallback);
|
||||
if (result < 0) {
|
||||
goto error;
|
||||
}
|
||||
return;
|
||||
|
||||
error:
|
||||
if (card->apiCallback == 0) {
|
||||
__CARDPutControlBlock(card, result);
|
||||
}
|
||||
callback = card->xferCallback;
|
||||
if (callback) {
|
||||
card->xferCallback = 0;
|
||||
callback(chan, result);
|
||||
}
|
||||
}
|
||||
|
||||
s32 __CARDRead(s32 chan, u32 addr, s32 length, void *dst, CARDCallback callback)
|
||||
{
|
||||
CARDControl *card;
|
||||
card = &__CARDBlock[chan];
|
||||
if (!card->attached) {
|
||||
return CARD_RESULT_NOCARD;
|
||||
}
|
||||
|
||||
card->xferCallback = callback;
|
||||
card->repeat = (int)(length / CARD_SEG_SIZE);
|
||||
card->addr = addr;
|
||||
card->buffer = dst;
|
||||
|
||||
return __CARDReadSegment(chan, BlockReadCallback);
|
||||
}
|
||||
|
||||
static void BlockWriteCallback(s32 chan, s32 result)
|
||||
{
|
||||
CARDControl *card;
|
||||
CARDCallback callback;
|
||||
|
||||
card = &__CARDBlock[chan];
|
||||
if (result < 0) {
|
||||
goto error;
|
||||
}
|
||||
|
||||
card->xferred += CARD_PAGE_SIZE;
|
||||
|
||||
card->addr += CARD_PAGE_SIZE;
|
||||
(u8 *)card->buffer += CARD_PAGE_SIZE;
|
||||
if (--card->repeat <= 0) {
|
||||
goto error;
|
||||
}
|
||||
|
||||
result = __CARDWritePage(chan, BlockWriteCallback);
|
||||
if (result < 0) {
|
||||
goto error;
|
||||
}
|
||||
return;
|
||||
|
||||
error:
|
||||
if (card->apiCallback == 0) {
|
||||
__CARDPutControlBlock(card, result);
|
||||
}
|
||||
callback = card->xferCallback;
|
||||
if (callback) {
|
||||
card->xferCallback = 0;
|
||||
callback(chan, result);
|
||||
}
|
||||
}
|
||||
|
||||
s32 __CARDWrite(s32 chan, u32 addr, s32 length, void *dst, CARDCallback callback)
|
||||
{
|
||||
CARDControl *card;
|
||||
card = &__CARDBlock[chan];
|
||||
if (!card->attached) {
|
||||
return CARD_RESULT_NOCARD;
|
||||
}
|
||||
|
||||
card->xferCallback = callback;
|
||||
card->repeat = (int)(length / CARD_PAGE_SIZE);
|
||||
card->addr = addr;
|
||||
card->buffer = dst;
|
||||
|
||||
return __CARDWritePage(chan, BlockWriteCallback);
|
||||
}
|
||||
149
src/dolphin/card/CARDRead.c
Normal file
149
src/dolphin/card/CARDRead.c
Normal file
|
|
@ -0,0 +1,149 @@
|
|||
#include <dolphin/card.h>
|
||||
#include <dolphin/dsp.h>
|
||||
#include <dolphin/dvd.h>
|
||||
#include <dolphin/os.h>
|
||||
|
||||
#include <dolphin/CARDPriv.h>
|
||||
|
||||
s32 __CARDSeek(CARDFileInfo *fileInfo, s32 length, s32 offset, CARDControl **pcard)
|
||||
{
|
||||
CARDControl *card;
|
||||
CARDDir *dir;
|
||||
CARDDir *ent;
|
||||
s32 result;
|
||||
u16 *fat;
|
||||
|
||||
result = __CARDGetControlBlock(fileInfo->chan, &card);
|
||||
if (result < 0) {
|
||||
return result;
|
||||
}
|
||||
|
||||
if (!CARDIsValidBlockNo(card, fileInfo->iBlock) || card->cBlock * card->sectorSize <= fileInfo->offset) {
|
||||
return __CARDPutControlBlock(card, CARD_RESULT_FATAL_ERROR);
|
||||
}
|
||||
|
||||
dir = __CARDGetDirBlock(card);
|
||||
ent = &dir[fileInfo->fileNo];
|
||||
if (ent->length * card->sectorSize <= offset || ent->length * card->sectorSize < offset + length) {
|
||||
return __CARDPutControlBlock(card, CARD_RESULT_LIMIT);
|
||||
}
|
||||
|
||||
card->fileInfo = fileInfo;
|
||||
fileInfo->length = length;
|
||||
if (offset < fileInfo->offset) {
|
||||
fileInfo->offset = 0;
|
||||
fileInfo->iBlock = ent->startBlock;
|
||||
if (!CARDIsValidBlockNo(card, fileInfo->iBlock)) {
|
||||
return __CARDPutControlBlock(card, CARD_RESULT_BROKEN);
|
||||
}
|
||||
}
|
||||
fat = __CARDGetFatBlock(card);
|
||||
while (fileInfo->offset < TRUNC(offset, card->sectorSize)) {
|
||||
fileInfo->offset += card->sectorSize;
|
||||
fileInfo->iBlock = fat[fileInfo->iBlock];
|
||||
if (!CARDIsValidBlockNo(card, fileInfo->iBlock)) {
|
||||
return __CARDPutControlBlock(card, CARD_RESULT_BROKEN);
|
||||
}
|
||||
}
|
||||
|
||||
fileInfo->offset = offset;
|
||||
|
||||
*pcard = card;
|
||||
return CARD_RESULT_READY;
|
||||
}
|
||||
|
||||
static void ReadCallback(s32 chan, s32 result)
|
||||
{
|
||||
CARDControl *card;
|
||||
CARDCallback callback;
|
||||
u16 *fat;
|
||||
CARDFileInfo *fileInfo;
|
||||
s32 length;
|
||||
|
||||
card = &__CARDBlock[chan];
|
||||
if (result < 0) {
|
||||
goto error;
|
||||
}
|
||||
|
||||
fileInfo = card->fileInfo;
|
||||
if (fileInfo->length < 0) {
|
||||
result = CARD_RESULT_CANCELED;
|
||||
goto error;
|
||||
}
|
||||
|
||||
length = (s32)TRUNC(fileInfo->offset + card->sectorSize, card->sectorSize) - fileInfo->offset;
|
||||
fileInfo->length -= length;
|
||||
if (fileInfo->length <= 0) {
|
||||
goto error;
|
||||
}
|
||||
|
||||
fat = __CARDGetFatBlock(card);
|
||||
fileInfo->offset += length;
|
||||
fileInfo->iBlock = fat[fileInfo->iBlock];
|
||||
if (!CARDIsValidBlockNo(card, fileInfo->iBlock)) {
|
||||
result = CARD_RESULT_BROKEN;
|
||||
goto error;
|
||||
}
|
||||
|
||||
result = __CARDRead(chan, card->sectorSize * (u32)fileInfo->iBlock, (fileInfo->length < card->sectorSize) ? fileInfo->length : card->sectorSize,
|
||||
card->buffer, ReadCallback);
|
||||
if (result < 0) {
|
||||
goto error;
|
||||
}
|
||||
|
||||
return;
|
||||
|
||||
error:
|
||||
callback = card->apiCallback;
|
||||
card->apiCallback = 0;
|
||||
__CARDPutControlBlock(card, result);
|
||||
callback(chan, result);
|
||||
}
|
||||
|
||||
s32 CARDReadAsync(CARDFileInfo *fileInfo, void *buf, s32 length, s32 offset, CARDCallback callback)
|
||||
{
|
||||
CARDControl *card;
|
||||
s32 result;
|
||||
CARDDir *dir;
|
||||
CARDDir *ent;
|
||||
|
||||
if (OFFSET(offset, CARD_SEG_SIZE) != 0 || OFFSET(length, CARD_SEG_SIZE) != 0) {
|
||||
return CARD_RESULT_FATAL_ERROR;
|
||||
}
|
||||
result = __CARDSeek(fileInfo, length, offset, &card);
|
||||
if (result < 0) {
|
||||
return result;
|
||||
}
|
||||
|
||||
dir = __CARDGetDirBlock(card);
|
||||
ent = &dir[fileInfo->fileNo];
|
||||
result = __CARDAccess(card, ent);
|
||||
if (result == CARD_RESULT_NOPERM) {
|
||||
result = __CARDIsPublic(ent);
|
||||
}
|
||||
|
||||
if (result < 0) {
|
||||
return __CARDPutControlBlock(card, result);
|
||||
}
|
||||
|
||||
DCInvalidateRange(buf, (u32)length);
|
||||
card->apiCallback = callback ? callback : __CARDDefaultApiCallback;
|
||||
|
||||
offset = (s32)OFFSET(fileInfo->offset, card->sectorSize);
|
||||
length = (length < card->sectorSize - offset) ? length : card->sectorSize - offset;
|
||||
result = __CARDRead(fileInfo->chan, card->sectorSize * (u32)fileInfo->iBlock + offset, length, buf, ReadCallback);
|
||||
if (result < 0) {
|
||||
__CARDPutControlBlock(card, result);
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
s32 CARDRead(CARDFileInfo *fileInfo, void *buf, s32 length, s32 offset)
|
||||
{
|
||||
s32 result = CARDReadAsync(fileInfo, buf, length, offset, __CARDSyncCallback);
|
||||
if (result < 0) {
|
||||
return result;
|
||||
}
|
||||
|
||||
return __CARDSync(fileInfo->chan);
|
||||
}
|
||||
70
src/dolphin/card/CARDRename.c
Normal file
70
src/dolphin/card/CARDRename.c
Normal file
|
|
@ -0,0 +1,70 @@
|
|||
#include <dolphin/card.h>
|
||||
#include <dolphin/dsp.h>
|
||||
#include <dolphin/dvd.h>
|
||||
#include <dolphin/os.h>
|
||||
|
||||
#include <dolphin/CARDPriv.h>
|
||||
|
||||
s32 CARDRenameAsync(s32 chan, const char* old, const char* new, CARDCallback callback) {
|
||||
CARDControl* card;
|
||||
CARDDir* dir;
|
||||
CARDDir* ent;
|
||||
s32 result;
|
||||
int fileNo;
|
||||
int newNo;
|
||||
int oldNo;
|
||||
|
||||
if (*old == 0xff || *new == 0xff || *old == 0x00 || *new == 0x00) {
|
||||
return CARD_RESULT_FATAL_ERROR;
|
||||
}
|
||||
if (CARD_FILENAME_MAX < (u32)strlen(old) || CARD_FILENAME_MAX < (u32)strlen(new)) {
|
||||
return CARD_RESULT_NAMETOOLONG;
|
||||
}
|
||||
result = __CARDGetControlBlock(chan, &card);
|
||||
if (result < 0) {
|
||||
return result;
|
||||
}
|
||||
|
||||
newNo = oldNo = -1;
|
||||
dir = __CARDGetDirBlock(card);
|
||||
for (fileNo = 0; fileNo < CARD_MAX_FILE; fileNo++) {
|
||||
ent = &dir[fileNo];
|
||||
if (ent->gameName[0] == 0xff) {
|
||||
continue;
|
||||
}
|
||||
|
||||
if (memcmp(ent->gameName, card->diskID->gameName, sizeof(ent->gameName)) != 0 ||
|
||||
memcmp(ent->company, card->diskID->company, sizeof(ent->company)) != 0) {
|
||||
continue;
|
||||
}
|
||||
|
||||
if (__CARDCompareFileName(ent, old)) {
|
||||
oldNo = fileNo;
|
||||
}
|
||||
if (__CARDCompareFileName(ent, new)) {
|
||||
newNo = fileNo;
|
||||
}
|
||||
}
|
||||
|
||||
if (oldNo == -1) {
|
||||
return __CARDPutControlBlock(card, CARD_RESULT_NOFILE);
|
||||
}
|
||||
if (newNo != -1) {
|
||||
return __CARDPutControlBlock(card, CARD_RESULT_EXIST);
|
||||
}
|
||||
|
||||
ent = &dir[oldNo];
|
||||
result = __CARDAccess(card, ent);
|
||||
if (result < 0) {
|
||||
return __CARDPutControlBlock(card, result);
|
||||
}
|
||||
|
||||
strncpy((char*)ent->fileName, new, CARD_FILENAME_MAX);
|
||||
|
||||
ent->time = (u32)OSTicksToSeconds(OSGetTime());
|
||||
result = __CARDUpdateDir(chan, callback);
|
||||
if (result < 0) {
|
||||
__CARDPutControlBlock(card, result);
|
||||
}
|
||||
return result;
|
||||
}
|
||||
158
src/dolphin/card/CARDStat.c
Normal file
158
src/dolphin/card/CARDStat.c
Normal file
|
|
@ -0,0 +1,158 @@
|
|||
#include <dolphin/card.h>
|
||||
#include <dolphin/dsp.h>
|
||||
#include <dolphin/dvd.h>
|
||||
#include <dolphin/os.h>
|
||||
|
||||
#include "string.h"
|
||||
|
||||
#include <dolphin/CARDPriv.h>
|
||||
|
||||
static void UpdateIconOffsets(CARDDir *ent, CARDStat *stat)
|
||||
{
|
||||
u32 offset;
|
||||
BOOL iconTlut;
|
||||
int i;
|
||||
|
||||
offset = ent->iconAddr;
|
||||
if (offset == 0xffffffff) {
|
||||
stat->bannerFormat = 0;
|
||||
stat->iconFormat = 0;
|
||||
stat->iconSpeed = 0;
|
||||
offset = 0;
|
||||
}
|
||||
|
||||
iconTlut = FALSE;
|
||||
switch (CARDGetBannerFormat(ent)) {
|
||||
case CARD_STAT_BANNER_C8:
|
||||
stat->offsetBanner = offset;
|
||||
offset += CARD_BANNER_WIDTH * CARD_BANNER_HEIGHT;
|
||||
stat->offsetBannerTlut = offset;
|
||||
offset += 2 * 256;
|
||||
break;
|
||||
case CARD_STAT_BANNER_RGB5A3:
|
||||
stat->offsetBanner = offset;
|
||||
offset += 2 * CARD_BANNER_WIDTH * CARD_BANNER_HEIGHT;
|
||||
stat->offsetBannerTlut = 0xffffffff;
|
||||
break;
|
||||
default:
|
||||
stat->offsetBanner = 0xffffffff;
|
||||
stat->offsetBannerTlut = 0xffffffff;
|
||||
break;
|
||||
}
|
||||
for (i = 0; i < CARD_ICON_MAX; ++i) {
|
||||
switch (CARDGetIconFormat(ent, i)) {
|
||||
case CARD_STAT_ICON_C8:
|
||||
stat->offsetIcon[i] = offset;
|
||||
offset += CARD_ICON_WIDTH * CARD_ICON_HEIGHT;
|
||||
iconTlut = TRUE;
|
||||
break;
|
||||
case CARD_STAT_ICON_RGB5A3:
|
||||
stat->offsetIcon[i] = offset;
|
||||
offset += 2 * CARD_ICON_WIDTH * CARD_ICON_HEIGHT;
|
||||
break;
|
||||
default:
|
||||
stat->offsetIcon[i] = 0xffffffff;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (iconTlut) {
|
||||
stat->offsetIconTlut = offset;
|
||||
offset += 2 * 256;
|
||||
}
|
||||
else {
|
||||
stat->offsetIconTlut = 0xffffffff;
|
||||
}
|
||||
stat->offsetData = offset;
|
||||
}
|
||||
|
||||
s32 CARDGetStatus(s32 chan, s32 fileNo, CARDStat *stat)
|
||||
{
|
||||
CARDControl *card;
|
||||
CARDDir *dir;
|
||||
CARDDir *ent;
|
||||
s32 result;
|
||||
|
||||
if (fileNo < 0 || CARD_MAX_FILE <= fileNo) {
|
||||
return CARD_RESULT_FATAL_ERROR;
|
||||
}
|
||||
result = __CARDGetControlBlock(chan, &card);
|
||||
if (result < 0) {
|
||||
return result;
|
||||
}
|
||||
|
||||
dir = __CARDGetDirBlock(card);
|
||||
ent = &dir[fileNo];
|
||||
result = __CARDAccess(card, ent);
|
||||
if (result == CARD_RESULT_NOPERM) {
|
||||
result = __CARDIsPublic(ent);
|
||||
}
|
||||
|
||||
if (result >= 0) {
|
||||
memcpy(stat->gameName, ent->gameName, sizeof(stat->gameName));
|
||||
memcpy(stat->company, ent->company, sizeof(stat->company));
|
||||
stat->length = (u32)ent->length * card->sectorSize;
|
||||
memcpy(stat->fileName, ent->fileName, CARD_FILENAME_MAX);
|
||||
stat->time = ent->time;
|
||||
|
||||
stat->bannerFormat = ent->bannerFormat;
|
||||
stat->iconAddr = ent->iconAddr;
|
||||
stat->iconFormat = ent->iconFormat;
|
||||
stat->iconSpeed = ent->iconSpeed;
|
||||
stat->commentAddr = ent->commentAddr;
|
||||
|
||||
UpdateIconOffsets(ent, stat);
|
||||
}
|
||||
return __CARDPutControlBlock(card, result);
|
||||
}
|
||||
|
||||
s32 CARDSetStatusAsync(s32 chan, s32 fileNo, CARDStat *stat, CARDCallback callback)
|
||||
{
|
||||
CARDControl *card;
|
||||
CARDDir *dir;
|
||||
CARDDir *ent;
|
||||
s32 result;
|
||||
|
||||
if (fileNo < 0 || CARD_MAX_FILE <= fileNo || (stat->iconAddr != 0xffffffff && CARD_READ_SIZE <= stat->iconAddr)
|
||||
|| (stat->commentAddr != 0xffffffff && CARD_SYSTEM_BLOCK_SIZE - CARD_COMMENT_SIZE < stat->commentAddr % CARD_SYSTEM_BLOCK_SIZE)) {
|
||||
return CARD_RESULT_FATAL_ERROR;
|
||||
}
|
||||
result = __CARDGetControlBlock(chan, &card);
|
||||
if (result < 0) {
|
||||
return result;
|
||||
}
|
||||
|
||||
dir = __CARDGetDirBlock(card);
|
||||
ent = &dir[fileNo];
|
||||
result = __CARDAccess(card, ent);
|
||||
if (result < 0) {
|
||||
return __CARDPutControlBlock(card, result);
|
||||
}
|
||||
|
||||
ent->bannerFormat = stat->bannerFormat;
|
||||
ent->iconAddr = stat->iconAddr;
|
||||
ent->iconFormat = stat->iconFormat;
|
||||
ent->iconSpeed = stat->iconSpeed;
|
||||
ent->commentAddr = stat->commentAddr;
|
||||
UpdateIconOffsets(ent, stat);
|
||||
|
||||
if (ent->iconAddr == 0xffffffff) {
|
||||
CARDSetIconSpeed(ent, 0, CARD_STAT_SPEED_FAST);
|
||||
}
|
||||
|
||||
ent->time = (u32)OSTicksToSeconds(OSGetTime());
|
||||
result = __CARDUpdateDir(chan, callback);
|
||||
if (result < 0) {
|
||||
__CARDPutControlBlock(card, result);
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
s32 CARDSetStatus(s32 chan, s32 fileNo, CARDStat *stat)
|
||||
{
|
||||
s32 result = CARDSetStatusAsync(chan, fileNo, stat, __CARDSyncCallback);
|
||||
if (result < 0) {
|
||||
return result;
|
||||
}
|
||||
|
||||
return __CARDSync(chan);
|
||||
}
|
||||
406
src/dolphin/card/CARDUnlock.c
Normal file
406
src/dolphin/card/CARDUnlock.c
Normal file
|
|
@ -0,0 +1,406 @@
|
|||
#include <dolphin/card.h>
|
||||
#include <dolphin/dsp.h>
|
||||
#include <dolphin/dvd.h>
|
||||
#include <dolphin/exi.h>
|
||||
#include <dolphin/os.h>
|
||||
|
||||
#include "string.h"
|
||||
|
||||
#include <dolphin/CARDPriv.h>
|
||||
|
||||
static void InitCallback(void *task);
|
||||
static void DoneCallback(void *task);
|
||||
|
||||
static u8 CardData[] ATTRIBUTE_ALIGN(32) = { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x21, 0x02, 0xFF, 0x00, 0x21, 0x13, 0x06, 0x12, 0x03, 0x12, 0x04, 0x13, 0x05, 0x00,
|
||||
0x92, 0x00, 0xFF, 0x00, 0x88, 0xFF, 0xFF, 0x00, 0x89, 0xFF, 0xFF, 0x00, 0x8A, 0xFF, 0xFF, 0x00, 0x8B, 0xFF, 0xFF, 0x8F, 0x00, 0x02, 0xBF, 0x00,
|
||||
0x88, 0x16, 0xFC, 0xDC, 0xD1, 0x16, 0xFD, 0x00, 0x00, 0x16, 0xFB, 0x00, 0x01, 0x02, 0xBF, 0x00, 0x8E, 0x25, 0xFF, 0x03, 0x80, 0xFF, 0x00, 0x02,
|
||||
0x94, 0x00, 0x27, 0x02, 0xBF, 0x00, 0x8E, 0x1F, 0xDF, 0x24, 0xFF, 0x02, 0x40, 0x0F, 0xFF, 0x00, 0x98, 0x04, 0x00, 0x00, 0x9A, 0x00, 0x10, 0x00,
|
||||
0x99, 0x00, 0x00, 0x8E, 0x00, 0x02, 0xBF, 0x00, 0x94, 0x02, 0xBF, 0x86, 0x44, 0x02, 0xBF, 0x00, 0x88, 0x16, 0xFC, 0xDC, 0xD1, 0x16, 0xFD, 0x00,
|
||||
0x03, 0x16, 0xFB, 0x00, 0x01, 0x8F, 0x00, 0x02, 0xBF, 0x00, 0x8E, 0x03, 0x80, 0xCD, 0xD1, 0x02, 0x94, 0x00, 0x48, 0x27, 0xFF, 0x03, 0x80, 0x00,
|
||||
0x01, 0x02, 0x95, 0x00, 0x5A, 0x03, 0x80, 0x00, 0x02, 0x02, 0x95, 0x80, 0x00, 0x02, 0x9F, 0x00, 0x48, 0x00, 0x21, 0x8E, 0x00, 0x02, 0xBF, 0x00,
|
||||
0x8E, 0x25, 0xFF, 0x02, 0xBF, 0x00, 0x8E, 0x25, 0xFF, 0x02, 0xBF, 0x00, 0x8E, 0x25, 0xFF, 0x02, 0xBF, 0x00, 0x8E, 0x00, 0xC5, 0xFF, 0xFF, 0x03,
|
||||
0x40, 0x0F, 0xFF, 0x1C, 0x9F, 0x02, 0xBF, 0x00, 0x8E, 0x00, 0xC7, 0xFF, 0xFF, 0x02, 0xBF, 0x00, 0x8E, 0x00, 0xC6, 0xFF, 0xFF, 0x02, 0xBF, 0x00,
|
||||
0x8E, 0x00, 0xC0, 0xFF, 0xFF, 0x02, 0xBF, 0x00, 0x8E, 0x20, 0xFF, 0x03, 0x40, 0x0F, 0xFF, 0x1F, 0x5F, 0x02, 0xBF, 0x00, 0x8E, 0x21, 0xFF, 0x02,
|
||||
0xBF, 0x00, 0x8E, 0x23, 0xFF, 0x12, 0x05, 0x12, 0x06, 0x02, 0x9F, 0x80, 0xB5, 0x00, 0x21, 0x27, 0xFC, 0x03, 0xC0, 0x80, 0x00, 0x02, 0x9D, 0x00,
|
||||
0x88, 0x02, 0xDF, 0x27, 0xFE, 0x03, 0xC0, 0x80, 0x00, 0x02, 0x9C, 0x00, 0x8E, 0x02, 0xDF, 0x2E, 0xCE, 0x2C, 0xCF, 0x00, 0xF8, 0xFF, 0xCD, 0x00,
|
||||
0xF9, 0xFF, 0xC9, 0x00, 0xFA, 0xFF, 0xCB, 0x26, 0xC9, 0x02, 0xC0, 0x00, 0x04, 0x02, 0x9D, 0x00, 0x9C, 0x02, 0xDF, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 };
|
||||
|
||||
typedef struct DecodeParameters {
|
||||
u8 *inputAddr;
|
||||
u32 inputLength;
|
||||
u32 aramAddr;
|
||||
u8 *outputAddr;
|
||||
} DecodeParameters;
|
||||
|
||||
static unsigned long int next = 1;
|
||||
|
||||
static int CARDRand(void)
|
||||
{
|
||||
next = next * 1103515245 + 12345;
|
||||
return (int)((unsigned int)(next / 65536) % 32768);
|
||||
}
|
||||
|
||||
static void CARDSrand(unsigned int seed)
|
||||
{
|
||||
next = seed;
|
||||
}
|
||||
|
||||
static u32 GetInitVal(void)
|
||||
{
|
||||
u32 tmp;
|
||||
u32 tick;
|
||||
|
||||
tick = OSGetTick();
|
||||
CARDSrand(tick);
|
||||
tmp = 0x7fec8000;
|
||||
tmp |= CARDRand();
|
||||
tmp &= 0xfffff000;
|
||||
return tmp;
|
||||
}
|
||||
|
||||
static u32 exnor_1st(u32 data, u32 rshift)
|
||||
{
|
||||
u32 wk;
|
||||
u32 w;
|
||||
u32 i;
|
||||
|
||||
w = data;
|
||||
for (i = 0; i < rshift; i++) {
|
||||
wk = ~(w ^ (w >> 7) ^ (w >> 15) ^ (w >> 23));
|
||||
w = (w >> 1) | ((wk << 30) & 0x40000000);
|
||||
}
|
||||
return w;
|
||||
}
|
||||
|
||||
static u32 exnor(u32 data, u32 lshift)
|
||||
{
|
||||
u32 wk;
|
||||
u32 w;
|
||||
u32 i;
|
||||
|
||||
w = data;
|
||||
for (i = 0; i < lshift; i++) {
|
||||
// 1bit Left Shift
|
||||
wk = ~(w ^ (w << 7) ^ (w << 15) ^ (w << 23));
|
||||
w = (w << 1) | ((wk >> 30) & 0x00000002);
|
||||
// printf("i=%d, w=%8x\n", i, w);
|
||||
}
|
||||
return w;
|
||||
}
|
||||
|
||||
static u32 bitrev(u32 data)
|
||||
{
|
||||
u32 wk;
|
||||
u32 i;
|
||||
u32 k = 0;
|
||||
u32 j = 1;
|
||||
|
||||
wk = 0;
|
||||
for (i = 0; i < 32; i++) {
|
||||
if (i > 15) {
|
||||
if (i == 31) {
|
||||
wk |= (((data & (0x01 << 31)) >> 31) & 0x01);
|
||||
}
|
||||
else {
|
||||
wk |= ((data & (0x01 << i)) >> j);
|
||||
j += 2;
|
||||
}
|
||||
}
|
||||
else {
|
||||
wk |= ((data & (0x01 << i)) << (31 - i - k));
|
||||
k++;
|
||||
}
|
||||
}
|
||||
return wk;
|
||||
}
|
||||
|
||||
#define SEC_AD1(x) ((u8)(((x) >> 29) & 0x03))
|
||||
#define SEC_AD2(x) ((u8)(((x) >> 21) & 0xff))
|
||||
#define SEC_AD3(x) ((u8)(((x) >> 19) & 0x03))
|
||||
#define SEC_BA(x) ((u8)(((x) >> 12) & 0x7f))
|
||||
|
||||
static s32 ReadArrayUnlock(s32 chan, u32 data, void *rbuf, s32 rlen, s32 mode)
|
||||
{
|
||||
CARDControl *card;
|
||||
BOOL err;
|
||||
u8 cmd[5];
|
||||
|
||||
card = &__CARDBlock[chan];
|
||||
if (!EXISelect(chan, 0, 4)) {
|
||||
return CARD_RESULT_NOCARD;
|
||||
}
|
||||
|
||||
data &= 0xfffff000;
|
||||
memset(cmd, 0, 5);
|
||||
cmd[0] = 0x52;
|
||||
if (mode == 0) {
|
||||
cmd[1] = SEC_AD1(data);
|
||||
cmd[2] = SEC_AD2(data);
|
||||
cmd[3] = SEC_AD3(data);
|
||||
cmd[4] = SEC_BA(data);
|
||||
}
|
||||
else {
|
||||
cmd[1] = (u8)((data & 0xff000000) >> 24);
|
||||
cmd[2] = (u8)((data & 0x00ff0000) >> 16);
|
||||
}
|
||||
|
||||
err = FALSE;
|
||||
err |= !EXIImmEx(chan, cmd, 5, 1);
|
||||
err |= !EXIImmEx(chan, (u8 *)card->workArea + (u32)sizeof(CARDID), card->latency, 1);
|
||||
err |= !EXIImmEx(chan, rbuf, rlen, 0);
|
||||
err |= !EXIDeselect(chan);
|
||||
|
||||
return err ? CARD_RESULT_NOCARD : CARD_RESULT_READY;
|
||||
}
|
||||
|
||||
// Calculate Dummy Read Length, 4-32Bytes
|
||||
static s32 DummyLen(void)
|
||||
{
|
||||
u32 tick;
|
||||
u32 wk;
|
||||
s32 tmp;
|
||||
u32 max;
|
||||
|
||||
wk = 1;
|
||||
max = 0;
|
||||
tick = OSGetTick();
|
||||
CARDSrand(tick);
|
||||
|
||||
tmp = CARDRand();
|
||||
tmp &= 0x0000001f;
|
||||
tmp += 1;
|
||||
while ((tmp < 4) && (max < 10)) {
|
||||
tick = OSGetTick();
|
||||
tmp = (s32)(tick << wk);
|
||||
wk++;
|
||||
if (wk > 16) {
|
||||
wk = 1;
|
||||
}
|
||||
CARDSrand((u32)tmp);
|
||||
tmp = CARDRand();
|
||||
tmp &= 0x0000001f;
|
||||
tmp += 1;
|
||||
max++;
|
||||
}
|
||||
if (tmp < 4) {
|
||||
tmp = 4;
|
||||
}
|
||||
|
||||
return tmp;
|
||||
}
|
||||
|
||||
s32 __CARDUnlock(s32 chan, u8 flashID[12])
|
||||
{
|
||||
u32 init_val;
|
||||
u32 data;
|
||||
|
||||
s32 dummy;
|
||||
s32 rlen;
|
||||
u32 rshift;
|
||||
|
||||
u8 fsts;
|
||||
u32 wk, wk1;
|
||||
u32 Ans1 = 0;
|
||||
u32 Ans2 = 0;
|
||||
u32 *dp;
|
||||
u8 rbuf[64];
|
||||
u32 para1A = 0;
|
||||
u32 para1B = 0;
|
||||
u32 para2A = 0;
|
||||
u32 para2B = 0;
|
||||
|
||||
CARDControl *card;
|
||||
DSPTaskInfo *task;
|
||||
DecodeParameters *param;
|
||||
u8 *input;
|
||||
u8 *output;
|
||||
|
||||
card = &__CARDBlock[chan];
|
||||
task = &card->task;
|
||||
param = (DecodeParameters *)card->workArea;
|
||||
input = (u8 *)((u8 *)param + sizeof(DecodeParameters));
|
||||
input = (u8 *)OSRoundUp32B(input);
|
||||
output = input + 32;
|
||||
|
||||
fsts = 0;
|
||||
init_val = GetInitVal();
|
||||
|
||||
dummy = DummyLen();
|
||||
rlen = dummy;
|
||||
if (ReadArrayUnlock(chan, init_val, rbuf, rlen, 0) < 0) {
|
||||
return CARD_RESULT_NOCARD;
|
||||
}
|
||||
|
||||
rshift = (u32)(dummy * 8 + 1);
|
||||
wk = exnor_1st(init_val, rshift);
|
||||
wk1 = ~(wk ^ (wk >> 7) ^ (wk >> 15) ^ (wk >> 23));
|
||||
card->scramble = (wk | ((wk1 << 31) & 0x80000000));
|
||||
card->scramble = bitrev(card->scramble);
|
||||
dummy = DummyLen();
|
||||
rlen = 20 + dummy;
|
||||
data = 0;
|
||||
if (ReadArrayUnlock(chan, data, rbuf, rlen, 1) < 0) {
|
||||
return CARD_RESULT_NOCARD;
|
||||
}
|
||||
dp = (u32 *)rbuf;
|
||||
para1A = *dp++;
|
||||
para1B = *dp++;
|
||||
Ans1 = *dp++;
|
||||
para2A = *dp++;
|
||||
para2B = *dp++;
|
||||
para1A = (para1A ^ card->scramble);
|
||||
rshift = 32;
|
||||
wk = exnor(card->scramble, rshift);
|
||||
wk1 = ~(wk ^ (wk << 7) ^ (wk << 15) ^ (wk << 23));
|
||||
card->scramble = (wk | ((wk1 >> 31) & 0x00000001));
|
||||
para1B = (para1B ^ card->scramble);
|
||||
rshift = 32;
|
||||
wk = exnor(card->scramble, rshift);
|
||||
wk1 = ~(wk ^ (wk << 7) ^ (wk << 15) ^ (wk << 23));
|
||||
card->scramble = (wk | ((wk1 >> 31) & 0x00000001));
|
||||
Ans1 ^= card->scramble;
|
||||
rshift = 32;
|
||||
wk = exnor(card->scramble, rshift);
|
||||
wk1 = ~(wk ^ (wk << 7) ^ (wk << 15) ^ (wk << 23));
|
||||
card->scramble = (wk | ((wk1 >> 31) & 0x00000001));
|
||||
para2A = (para2A ^ card->scramble);
|
||||
rshift = 32;
|
||||
wk = exnor(card->scramble, rshift);
|
||||
wk1 = ~(wk ^ (wk << 7) ^ (wk << 15) ^ (wk << 23));
|
||||
card->scramble = (wk | ((wk1 >> 31) & 0x00000001));
|
||||
para2B = (para2B ^ card->scramble);
|
||||
rshift = (u32)(dummy * 8);
|
||||
wk = exnor(card->scramble, rshift);
|
||||
wk1 = ~(wk ^ (wk << 7) ^ (wk << 15) ^ (wk << 23));
|
||||
card->scramble = (wk | ((wk1 >> 31) & 0x00000001));
|
||||
rshift = 32 + 1;
|
||||
wk = exnor(card->scramble, rshift);
|
||||
wk1 = ~(wk ^ (wk << 7) ^ (wk << 15) ^ (wk << 23));
|
||||
card->scramble = (wk | ((wk1 >> 31) & 0x00000001));
|
||||
|
||||
*(u32 *)&input[0] = para2A;
|
||||
*(u32 *)&input[4] = para2B;
|
||||
|
||||
param->inputAddr = input;
|
||||
param->inputLength = 8;
|
||||
param->outputAddr = output;
|
||||
param->aramAddr = 0;
|
||||
|
||||
DCFlushRange(input, 8);
|
||||
DCInvalidateRange(output, 4);
|
||||
DCFlushRange(param, sizeof(DecodeParameters));
|
||||
|
||||
task->priority = 255;
|
||||
task->iram_mmem_addr = (u16 *)OSPhysicalToCached(CardData);
|
||||
task->iram_length = 0x160;
|
||||
task->iram_addr = 0;
|
||||
task->dsp_init_vector = 0x10;
|
||||
task->init_cb = InitCallback;
|
||||
task->res_cb = NULL;
|
||||
task->done_cb = DoneCallback;
|
||||
task->req_cb = NULL;
|
||||
DSPAddTask(task);
|
||||
|
||||
dp = (u32 *)flashID;
|
||||
*dp++ = para1A;
|
||||
*dp++ = para1B;
|
||||
*dp = Ans1;
|
||||
|
||||
return CARD_RESULT_READY;
|
||||
}
|
||||
|
||||
static void InitCallback(void *_task)
|
||||
{
|
||||
s32 chan;
|
||||
CARDControl *card;
|
||||
DSPTaskInfo *task;
|
||||
DecodeParameters *param;
|
||||
|
||||
task = _task;
|
||||
for (chan = 0; chan < 2; ++chan) {
|
||||
card = &__CARDBlock[chan];
|
||||
if ((DSPTaskInfo *)&card->task == task) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
param = (DecodeParameters *)card->workArea;
|
||||
|
||||
DSPSendMailToDSP(0xff000000);
|
||||
while (DSPCheckMailToDSP())
|
||||
;
|
||||
|
||||
DSPSendMailToDSP((u32)param);
|
||||
while (DSPCheckMailToDSP())
|
||||
;
|
||||
}
|
||||
|
||||
static void DoneCallback(void *_task)
|
||||
{
|
||||
u8 rbuf[64];
|
||||
u32 data;
|
||||
s32 dummy;
|
||||
s32 rlen;
|
||||
u32 rshift;
|
||||
|
||||
u8 unk;
|
||||
u32 wk, wk1;
|
||||
u32 Ans2;
|
||||
|
||||
s32 chan;
|
||||
CARDControl *card;
|
||||
s32 result;
|
||||
DSPTaskInfo *task;
|
||||
DecodeParameters *param;
|
||||
|
||||
u8 *input;
|
||||
u8 *output;
|
||||
task = _task;
|
||||
for (chan = 0; chan < 2; ++chan) {
|
||||
card = &__CARDBlock[chan];
|
||||
if ((DSPTaskInfo *)&card->task == task) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
param = (DecodeParameters *)card->workArea;
|
||||
input = (u8 *)((u8 *)param + sizeof(DecodeParameters));
|
||||
input = (u8 *)OSRoundUp32B(input);
|
||||
output = input + 32;
|
||||
|
||||
Ans2 = *(u32 *)output;
|
||||
dummy = DummyLen();
|
||||
rlen = dummy;
|
||||
data = ((Ans2 ^ card->scramble) & 0xffff0000);
|
||||
if (ReadArrayUnlock(chan, data, rbuf, rlen, 1) < 0) {
|
||||
EXIUnlock(chan);
|
||||
__CARDMountCallback(chan, CARD_RESULT_NOCARD);
|
||||
return;
|
||||
}
|
||||
|
||||
rshift = (u32)((dummy + 4 + card->latency) * 8 + 1);
|
||||
wk = exnor(card->scramble, rshift);
|
||||
wk1 = ~(wk ^ (wk << 7) ^ (wk << 15) ^ (wk << 23));
|
||||
card->scramble = (wk | ((wk1 >> 31) & 0x00000001));
|
||||
|
||||
dummy = DummyLen();
|
||||
rlen = dummy;
|
||||
data = (((Ans2 << 16) ^ card->scramble) & 0xffff0000);
|
||||
if (ReadArrayUnlock(chan, data, rbuf, rlen, 1) < 0) {
|
||||
EXIUnlock(chan);
|
||||
__CARDMountCallback(chan, CARD_RESULT_NOCARD);
|
||||
return;
|
||||
}
|
||||
result = __CARDReadStatus(chan, &unk);
|
||||
if (!EXIProbe(chan)) {
|
||||
EXIUnlock(chan);
|
||||
__CARDMountCallback(chan, CARD_RESULT_NOCARD);
|
||||
return;
|
||||
}
|
||||
if (result == CARD_RESULT_READY && !(unk & 0x40)) {
|
||||
EXIUnlock(chan);
|
||||
result = CARD_RESULT_IOERROR;
|
||||
}
|
||||
__CARDMountCallback(chan, result);
|
||||
}
|
||||
128
src/dolphin/card/CARDWrite.c
Normal file
128
src/dolphin/card/CARDWrite.c
Normal file
|
|
@ -0,0 +1,128 @@
|
|||
#include <dolphin/card.h>
|
||||
#include <dolphin/dsp.h>
|
||||
#include <dolphin/dvd.h>
|
||||
#include <dolphin/os.h>
|
||||
|
||||
#include <dolphin/CARDPriv.h>
|
||||
|
||||
static void EraseCallback(s32 chan, s32 result);
|
||||
|
||||
static void WriteCallback(s32 chan, s32 result)
|
||||
{
|
||||
CARDControl *card;
|
||||
CARDCallback callback;
|
||||
u16 *fat;
|
||||
CARDDir *dir;
|
||||
CARDDir *ent;
|
||||
CARDFileInfo *fileInfo;
|
||||
|
||||
card = &__CARDBlock[chan];
|
||||
if (result < 0) {
|
||||
goto error;
|
||||
}
|
||||
|
||||
fileInfo = card->fileInfo;
|
||||
if (fileInfo->length < 0) {
|
||||
result = CARD_RESULT_CANCELED;
|
||||
goto error;
|
||||
}
|
||||
|
||||
fileInfo->length -= card->sectorSize;
|
||||
if (fileInfo->length <= 0) {
|
||||
dir = __CARDGetDirBlock(card);
|
||||
ent = &dir[fileInfo->fileNo];
|
||||
ent->time = (u32)OSTicksToSeconds(OSGetTime());
|
||||
callback = card->apiCallback;
|
||||
card->apiCallback = 0;
|
||||
result = __CARDUpdateDir(chan, callback);
|
||||
}
|
||||
else {
|
||||
fat = __CARDGetFatBlock(card);
|
||||
fileInfo->offset += card->sectorSize;
|
||||
fileInfo->iBlock = fat[fileInfo->iBlock];
|
||||
if (!CARDIsValidBlockNo(card, fileInfo->iBlock)) {
|
||||
result = CARD_RESULT_BROKEN;
|
||||
goto error;
|
||||
}
|
||||
result = __CARDEraseSector(chan, card->sectorSize * (u32)fileInfo->iBlock, EraseCallback);
|
||||
}
|
||||
|
||||
if (result < 0) {
|
||||
goto error;
|
||||
}
|
||||
return;
|
||||
|
||||
error:
|
||||
callback = card->apiCallback;
|
||||
card->apiCallback = 0;
|
||||
__CARDPutControlBlock(card, result);
|
||||
callback(chan, result);
|
||||
}
|
||||
|
||||
static void EraseCallback(s32 chan, s32 result)
|
||||
{
|
||||
CARDControl *card;
|
||||
CARDCallback callback;
|
||||
CARDFileInfo *fileInfo;
|
||||
|
||||
card = &__CARDBlock[chan];
|
||||
if (result < 0) {
|
||||
goto error;
|
||||
}
|
||||
|
||||
fileInfo = card->fileInfo;
|
||||
result = __CARDWrite(chan, card->sectorSize * (u32)fileInfo->iBlock, card->sectorSize, card->buffer, WriteCallback);
|
||||
if (result < 0) {
|
||||
goto error;
|
||||
}
|
||||
return;
|
||||
|
||||
error:
|
||||
callback = card->apiCallback;
|
||||
card->apiCallback = 0;
|
||||
__CARDPutControlBlock(card, result);
|
||||
callback(chan, result);
|
||||
}
|
||||
|
||||
s32 CARDWriteAsync(CARDFileInfo *fileInfo, const void *buf, s32 length, s32 offset, CARDCallback callback)
|
||||
{
|
||||
CARDControl *card;
|
||||
s32 result;
|
||||
CARDDir *dir;
|
||||
CARDDir *ent;
|
||||
|
||||
result = __CARDSeek(fileInfo, length, offset, &card);
|
||||
if (result < 0) {
|
||||
return result;
|
||||
}
|
||||
|
||||
if (OFFSET(offset, card->sectorSize) != 0 || OFFSET(length, card->sectorSize) != 0) {
|
||||
return __CARDPutControlBlock(card, CARD_RESULT_FATAL_ERROR);
|
||||
}
|
||||
|
||||
dir = __CARDGetDirBlock(card);
|
||||
ent = &dir[fileInfo->fileNo];
|
||||
result = __CARDAccess(card, ent);
|
||||
if (result < 0) {
|
||||
return __CARDPutControlBlock(card, result);
|
||||
}
|
||||
|
||||
DCStoreRange((void *)buf, (u32)length);
|
||||
card->apiCallback = callback ? callback : __CARDDefaultApiCallback;
|
||||
card->buffer = (void *)buf;
|
||||
result = __CARDEraseSector(fileInfo->chan, card->sectorSize * (u32)fileInfo->iBlock, EraseCallback);
|
||||
if (result < 0) {
|
||||
__CARDPutControlBlock(card, result);
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
s32 CARDWrite(CARDFileInfo *fileInfo, const void *buf, s32 length, s32 offset)
|
||||
{
|
||||
s32 result = CARDWriteAsync(fileInfo, buf, length, offset, __CARDSyncCallback);
|
||||
if (result < 0) {
|
||||
return result;
|
||||
}
|
||||
|
||||
return __CARDSync(fileInfo->chan);
|
||||
}
|
||||
43
src/dolphin/db.c
Normal file
43
src/dolphin/db.c
Normal file
|
|
@ -0,0 +1,43 @@
|
|||
#include <dolphin/db.h>
|
||||
#include <dolphin/os.h>
|
||||
|
||||
DBInterface* __DBInterface = NULL;
|
||||
int DBVerbose;
|
||||
|
||||
extern void __DBExceptionStart();
|
||||
extern void __DBExceptionEnd();
|
||||
extern void __DBExceptionSetNumber();
|
||||
|
||||
void DBInit(void) {
|
||||
__DBInterface = (DBInterface*)OSPhysicalToCached(OS_DBINTERFACE_ADDR);
|
||||
__DBInterface->ExceptionDestination = (void (*)())OSCachedToPhysical(__DBExceptionDestination);
|
||||
DBVerbose = TRUE;
|
||||
}
|
||||
|
||||
void __DBExceptionDestinationAux(void) {
|
||||
u32* contextAddr = (void*)0x00C0;
|
||||
OSContext* context = (OSContext*)OSPhysicalToCached(*contextAddr);
|
||||
|
||||
OSReport("DBExceptionDestination\n");
|
||||
OSDumpContext(context);
|
||||
PPCHalt();
|
||||
}
|
||||
|
||||
/* clang-format off */
|
||||
asm void __DBExceptionDestination(void) {
|
||||
nofralloc
|
||||
mfmsr r3
|
||||
ori r3, r3, 0x10|0x20
|
||||
mtmsr r3
|
||||
|
||||
b __DBExceptionDestinationAux
|
||||
}
|
||||
/* clang-format on */
|
||||
|
||||
BOOL __DBIsExceptionMarked(__OSException exception) {
|
||||
u32 mask = 1 << exception;
|
||||
|
||||
return (BOOL)(__DBInterface->exceptionMask & mask);
|
||||
}
|
||||
|
||||
void DBPrintf(char* format, ...) {}
|
||||
773
src/dolphin/demo/DEMOFont.c
Normal file
773
src/dolphin/demo/DEMOFont.c
Normal file
|
|
@ -0,0 +1,773 @@
|
|||
#include <dolphin.h>
|
||||
#include <dolphin/demo.h>
|
||||
|
||||
unsigned long DEMOFontBitmap[768] ATTRIBUTE_ALIGN(32) = {
|
||||
0x00000000,
|
||||
0x00000000,
|
||||
0x00000000,
|
||||
0x00000000,
|
||||
0x00000000,
|
||||
0x00000000,
|
||||
0x00000000,
|
||||
0x00000000,
|
||||
0x00000000,
|
||||
0x000FF000,
|
||||
0x000FF000,
|
||||
0x000FF000,
|
||||
0x000FF000,
|
||||
0x000FF000,
|
||||
0x00000000,
|
||||
0x000FF000,
|
||||
0x00000000,
|
||||
0x00F00F00,
|
||||
0x00F00F00,
|
||||
0x00000000,
|
||||
0x00000000,
|
||||
0x00000000,
|
||||
0x00000000,
|
||||
0x00000000,
|
||||
0x00000000,
|
||||
0x00F00F00,
|
||||
0x00F00F00,
|
||||
0x0FFFFFF0,
|
||||
0x00F00F00,
|
||||
0x0FFFFFF0,
|
||||
0x00F00F00,
|
||||
0x00F00F00,
|
||||
0x00000000,
|
||||
0x0000F000,
|
||||
0x00FFFFF0,
|
||||
0x0F00F000,
|
||||
0x00FFFF00,
|
||||
0x0000F0F0,
|
||||
0x0FFFFF00,
|
||||
0x0000F000,
|
||||
0x00000000,
|
||||
0x0FF000F0,
|
||||
0x0FF00F00,
|
||||
0x0000F000,
|
||||
0x000F0000,
|
||||
0x00F00FF0,
|
||||
0x0F000FF0,
|
||||
0x00000000,
|
||||
0x00000000,
|
||||
0x000F0000,
|
||||
0x00F0F000,
|
||||
0x00F0F000,
|
||||
0x00FF0000,
|
||||
0x0F000FF0,
|
||||
0x0F0000F0,
|
||||
0x00FFFF00,
|
||||
0x00000000,
|
||||
0x000FF000,
|
||||
0x000FF000,
|
||||
0x0000F000,
|
||||
0x000F0000,
|
||||
0x00000000,
|
||||
0x00000000,
|
||||
0x00000000,
|
||||
0x00000000,
|
||||
0x0000F000,
|
||||
0x000F0000,
|
||||
0x00F00000,
|
||||
0x00F00000,
|
||||
0x00F00000,
|
||||
0x000F0000,
|
||||
0x0000F000,
|
||||
0x00000000,
|
||||
0x000F0000,
|
||||
0x0000F000,
|
||||
0x00000F00,
|
||||
0x00000F00,
|
||||
0x00000F00,
|
||||
0x0000F000,
|
||||
0x000F0000,
|
||||
0x00000000,
|
||||
0x00000000,
|
||||
0x00F000F0,
|
||||
0x000F0F00,
|
||||
0x00FFFFF0,
|
||||
0x000F0F00,
|
||||
0x00F000F0,
|
||||
0x00000000,
|
||||
0x00000000,
|
||||
0x00000000,
|
||||
0x0000F000,
|
||||
0x0000F000,
|
||||
0x00FFFFF0,
|
||||
0x0000F000,
|
||||
0x0000F000,
|
||||
0x00000000,
|
||||
0x00000000,
|
||||
0x00000000,
|
||||
0x00000000,
|
||||
0x00000000,
|
||||
0x000FF000,
|
||||
0x000FF000,
|
||||
0x0000F000,
|
||||
0x000F0000,
|
||||
0x00000000,
|
||||
0x00000000,
|
||||
0x00000000,
|
||||
0x00000000,
|
||||
0x00FFFFF0,
|
||||
0x00000000,
|
||||
0x00000000,
|
||||
0x00000000,
|
||||
0x00000000,
|
||||
0x00000000,
|
||||
0x00000000,
|
||||
0x00000000,
|
||||
0x00000000,
|
||||
0x00000000,
|
||||
0x000FF000,
|
||||
0x000FF000,
|
||||
0x00000000,
|
||||
0x000000F0,
|
||||
0x00000F00,
|
||||
0x0000F000,
|
||||
0x000F0000,
|
||||
0x00F00000,
|
||||
0x0F000000,
|
||||
0x00000000,
|
||||
0x00000000,
|
||||
0x000FF000,
|
||||
0x00F00F00,
|
||||
0x0F0000F0,
|
||||
0x0F0000F0,
|
||||
0x0F0000F0,
|
||||
0x00F00F00,
|
||||
0x000FF000,
|
||||
0x00000000,
|
||||
0x0000F000,
|
||||
0x000FF000,
|
||||
0x0000F000,
|
||||
0x0000F000,
|
||||
0x0000F000,
|
||||
0x0000F000,
|
||||
0x000FFF00,
|
||||
0x00000000,
|
||||
0x00FFFF00,
|
||||
0x0F0000F0,
|
||||
0x000000F0,
|
||||
0x00000F00,
|
||||
0x0000F000,
|
||||
0x000F0000,
|
||||
0x0FFFFFF0,
|
||||
0x00000000,
|
||||
0x00FFFF00,
|
||||
0x0F0000F0,
|
||||
0x000000F0,
|
||||
0x0000FF00,
|
||||
0x000000F0,
|
||||
0x0F0000F0,
|
||||
0x00FFFF00,
|
||||
0x00000000,
|
||||
0x00000F00,
|
||||
0x0000FF00,
|
||||
0x000F0F00,
|
||||
0x00F00F00,
|
||||
0x0FFFFFF0,
|
||||
0x00000F00,
|
||||
0x00000F00,
|
||||
0x00000000,
|
||||
0x0FFFFFF0,
|
||||
0x0F000000,
|
||||
0x0F000000,
|
||||
0x0FFFFF00,
|
||||
0x000000F0,
|
||||
0x0F0000F0,
|
||||
0x00FFFF00,
|
||||
0x00000000,
|
||||
0x000FFF00,
|
||||
0x00F00000,
|
||||
0x0F000000,
|
||||
0x0FFFFF00,
|
||||
0x0F0000F0,
|
||||
0x0F0000F0,
|
||||
0x00FFFF00,
|
||||
0x00000000,
|
||||
0x0FFFFFF0,
|
||||
0x0F0000F0,
|
||||
0x00000F00,
|
||||
0x0000F000,
|
||||
0x0000F000,
|
||||
0x0000F000,
|
||||
0x0000F000,
|
||||
0x00000000,
|
||||
0x00FFFF00,
|
||||
0x0F0000F0,
|
||||
0x0F0000F0,
|
||||
0x00FFFF00,
|
||||
0x0F0000F0,
|
||||
0x0F0000F0,
|
||||
0x00FFFF00,
|
||||
0x00000000,
|
||||
0x00FFFF00,
|
||||
0x0F0000F0,
|
||||
0x0F0000F0,
|
||||
0x00FFFFF0,
|
||||
0x000000F0,
|
||||
0x000000F0,
|
||||
0x00FFFF00,
|
||||
0x00000000,
|
||||
0x00000000,
|
||||
0x000FF000,
|
||||
0x000FF000,
|
||||
0x00000000,
|
||||
0x000FF000,
|
||||
0x000FF000,
|
||||
0x00000000,
|
||||
0x00000000,
|
||||
0x000FF000,
|
||||
0x000FF000,
|
||||
0x00000000,
|
||||
0x000FF000,
|
||||
0x000FF000,
|
||||
0x0000F000,
|
||||
0x000F0000,
|
||||
0x00000000,
|
||||
0x00000F00,
|
||||
0x0000F000,
|
||||
0x000F0000,
|
||||
0x00F00000,
|
||||
0x000F0000,
|
||||
0x0000F000,
|
||||
0x00000F00,
|
||||
0x00000000,
|
||||
0x00000000,
|
||||
0x00000000,
|
||||
0x0FFFFFF0,
|
||||
0x00000000,
|
||||
0x0FFFFFF0,
|
||||
0x00000000,
|
||||
0x00000000,
|
||||
0x00000000,
|
||||
0x00F00000,
|
||||
0x000F0000,
|
||||
0x0000F000,
|
||||
0x00000F00,
|
||||
0x0000F000,
|
||||
0x000F0000,
|
||||
0x00F00000,
|
||||
0x00000000,
|
||||
0x00FFFF00,
|
||||
0x0F0000F0,
|
||||
0x0F0000F0,
|
||||
0x0000FF00,
|
||||
0x000FF000,
|
||||
0x00000000,
|
||||
0x000FF000,
|
||||
0x00000000,
|
||||
0x00FFFF00,
|
||||
0x0F0000F0,
|
||||
0x0F000FF0,
|
||||
0x0F00F0F0,
|
||||
0x0F00FFF0,
|
||||
0x0F000000,
|
||||
0x00FFFFF0,
|
||||
0x00000000,
|
||||
0x000FF000,
|
||||
0x00F00F00,
|
||||
0x0F0000F0,
|
||||
0x0F0000F0,
|
||||
0x0FFFFFF0,
|
||||
0x0F0000F0,
|
||||
0x0F0000F0,
|
||||
0x00000000,
|
||||
0x0FFFFF00,
|
||||
0x0F0000F0,
|
||||
0x0F0000F0,
|
||||
0x0FFFFF00,
|
||||
0x0F0000F0,
|
||||
0x0F0000F0,
|
||||
0x0FFFFF00,
|
||||
0x00000000,
|
||||
0x000FFF00,
|
||||
0x00F000F0,
|
||||
0x0F000000,
|
||||
0x0F000000,
|
||||
0x0F000000,
|
||||
0x00F000F0,
|
||||
0x000FFF00,
|
||||
0x00000000,
|
||||
0x0FFFF000,
|
||||
0x0F000F00,
|
||||
0x0F0000F0,
|
||||
0x0F0000F0,
|
||||
0x0F0000F0,
|
||||
0x0F000F00,
|
||||
0x0FFFF000,
|
||||
0x00000000,
|
||||
0x0FFFFFF0,
|
||||
0x0F000000,
|
||||
0x0F000000,
|
||||
0x0FFFFF00,
|
||||
0x0F000000,
|
||||
0x0F000000,
|
||||
0x0FFFFFF0,
|
||||
0x00000000,
|
||||
0x0FFFFFF0,
|
||||
0x0F000000,
|
||||
0x0F000000,
|
||||
0x0FFFFF00,
|
||||
0x0F000000,
|
||||
0x0F000000,
|
||||
0x0F000000,
|
||||
0x00000000,
|
||||
0x000FFF00,
|
||||
0x00F00000,
|
||||
0x0F000000,
|
||||
0x0F00FFF0,
|
||||
0x0F0000F0,
|
||||
0x00F000F0,
|
||||
0x000FFF00,
|
||||
0x00000000,
|
||||
0x0F0000F0,
|
||||
0x0F0000F0,
|
||||
0x0F0000F0,
|
||||
0x0FFFFFF0,
|
||||
0x0F0000F0,
|
||||
0x0F0000F0,
|
||||
0x0F0000F0,
|
||||
0x00000000,
|
||||
0x000FFF00,
|
||||
0x0000F000,
|
||||
0x0000F000,
|
||||
0x0000F000,
|
||||
0x0000F000,
|
||||
0x0000F000,
|
||||
0x000FFF00,
|
||||
0x00000000,
|
||||
0x0000FFF0,
|
||||
0x00000F00,
|
||||
0x00000F00,
|
||||
0x00000F00,
|
||||
0x00000F00,
|
||||
0x0F000F00,
|
||||
0x00FFF000,
|
||||
0x00000000,
|
||||
0x0F0000F0,
|
||||
0x0F000F00,
|
||||
0x0F00F000,
|
||||
0x0FFF0000,
|
||||
0x0F00F000,
|
||||
0x0F000F00,
|
||||
0x0F0000F0,
|
||||
0x00000000,
|
||||
0x0F000000,
|
||||
0x0F000000,
|
||||
0x0F000000,
|
||||
0x0F000000,
|
||||
0x0F000000,
|
||||
0x0F000000,
|
||||
0x0FFFFFF0,
|
||||
0x00000000,
|
||||
0x0F00000F,
|
||||
0x0FF000FF,
|
||||
0x0F0F0F0F,
|
||||
0x0F00F00F,
|
||||
0x0F00F00F,
|
||||
0x0F00000F,
|
||||
0x0F00000F,
|
||||
0x00000000,
|
||||
0x0F0000F0,
|
||||
0x0FF000F0,
|
||||
0x0F0F00F0,
|
||||
0x0F00F0F0,
|
||||
0x0F00F0F0,
|
||||
0x0F000FF0,
|
||||
0x0F0000F0,
|
||||
0x00000000,
|
||||
0x00FFFF00,
|
||||
0x0F0000F0,
|
||||
0x0F0000F0,
|
||||
0x0F0000F0,
|
||||
0x0F0000F0,
|
||||
0x0F0000F0,
|
||||
0x00FFFF00,
|
||||
0x00000000,
|
||||
0x0FFFFF00,
|
||||
0x0F0000F0,
|
||||
0x0F0000F0,
|
||||
0x0FFFFF00,
|
||||
0x0F000000,
|
||||
0x0F000000,
|
||||
0x0F000000,
|
||||
0x00000000,
|
||||
0x00FFFF00,
|
||||
0x0F0000F0,
|
||||
0x0F0000F0,
|
||||
0x0F0000F0,
|
||||
0x0F00F0F0,
|
||||
0x0F000F00,
|
||||
0x00FFF0F0,
|
||||
0x00000000,
|
||||
0x0FFFFF00,
|
||||
0x0F0000F0,
|
||||
0x0F0000F0,
|
||||
0x0FFFFF00,
|
||||
0x0F00F000,
|
||||
0x0F000F00,
|
||||
0x0F0000F0,
|
||||
0x00000000,
|
||||
0x00FFFF00,
|
||||
0x0F0000F0,
|
||||
0x0F000000,
|
||||
0x00FFFF00,
|
||||
0x000000F0,
|
||||
0x0F0000F0,
|
||||
0x00FFFF00,
|
||||
0x00000000,
|
||||
0x0FFFFFFF,
|
||||
0x0000F000,
|
||||
0x0000F000,
|
||||
0x0000F000,
|
||||
0x0000F000,
|
||||
0x0000F000,
|
||||
0x0000F000,
|
||||
0x00000000,
|
||||
0x0F0000F0,
|
||||
0x0F0000F0,
|
||||
0x0F0000F0,
|
||||
0x0F0000F0,
|
||||
0x0F0000F0,
|
||||
0x0F0000F0,
|
||||
0x00FFFF00,
|
||||
0x00000000,
|
||||
0x0F0000F0,
|
||||
0x0F0000F0,
|
||||
0x0F0000F0,
|
||||
0x0F0000F0,
|
||||
0x00F00F00,
|
||||
0x00F00F00,
|
||||
0x000FF000,
|
||||
0x00000000,
|
||||
0x0F00000F,
|
||||
0x0F00000F,
|
||||
0x0F00000F,
|
||||
0x0F00F00F,
|
||||
0x0F00F00F,
|
||||
0x0F00F00F,
|
||||
0x00FF0FF0,
|
||||
0x00000000,
|
||||
0x0F0000F0,
|
||||
0x0F0000F0,
|
||||
0x00F00F00,
|
||||
0x000FF000,
|
||||
0x00F00F00,
|
||||
0x0F0000F0,
|
||||
0x0F0000F0,
|
||||
0x00000000,
|
||||
0x0F00000F,
|
||||
0x00F000F0,
|
||||
0x000F0F00,
|
||||
0x0000F000,
|
||||
0x0000F000,
|
||||
0x0000F000,
|
||||
0x0000F000,
|
||||
0x00000000,
|
||||
0x0FFFFFF0,
|
||||
0x000000F0,
|
||||
0x00000F00,
|
||||
0x000FF000,
|
||||
0x00F00000,
|
||||
0x0F000000,
|
||||
0x0FFFFFF0,
|
||||
0x00000000,
|
||||
0x000FFF00,
|
||||
0x000F0000,
|
||||
0x000F0000,
|
||||
0x000F0000,
|
||||
0x000F0000,
|
||||
0x000F0000,
|
||||
0x000FFF00,
|
||||
0x00000000,
|
||||
0x0F000000,
|
||||
0x00F00000,
|
||||
0x000F0000,
|
||||
0x0000F000,
|
||||
0x00000F00,
|
||||
0x000000F0,
|
||||
0x00000000,
|
||||
0x00000000,
|
||||
0x00FFF000,
|
||||
0x0000F000,
|
||||
0x0000F000,
|
||||
0x0000F000,
|
||||
0x0000F000,
|
||||
0x0000F000,
|
||||
0x00FFF000,
|
||||
0x00000000,
|
||||
0x000FF000,
|
||||
0x00F00F00,
|
||||
0x0F0000F0,
|
||||
0x00000000,
|
||||
0x00000000,
|
||||
0x00000000,
|
||||
0x00000000,
|
||||
0x00000000,
|
||||
0x00000000,
|
||||
0x00000000,
|
||||
0x00000000,
|
||||
0x00000000,
|
||||
0x00000000,
|
||||
0x00000000,
|
||||
0x0FFFFFF0,
|
||||
0x00000000,
|
||||
0x000FF000,
|
||||
0x000FF000,
|
||||
0x000F0000,
|
||||
0x0000F000,
|
||||
0x00000000,
|
||||
0x00000000,
|
||||
0x00000000,
|
||||
0x00000000,
|
||||
0x00000000,
|
||||
0x00000000,
|
||||
0x00FFFF00,
|
||||
0x0F000F00,
|
||||
0x0F000F00,
|
||||
0x0F000F00,
|
||||
0x00FFFFF0,
|
||||
0x00000000,
|
||||
0x00F00000,
|
||||
0x00F00000,
|
||||
0x00F00000,
|
||||
0x00FFFF00,
|
||||
0x00F000F0,
|
||||
0x00F000F0,
|
||||
0x00FFFF00,
|
||||
0x00000000,
|
||||
0x00000000,
|
||||
0x00000000,
|
||||
0x00FFFF00,
|
||||
0x0F000000,
|
||||
0x0F000000,
|
||||
0x0F000000,
|
||||
0x00FFFF00,
|
||||
0x00000000,
|
||||
0x000000F0,
|
||||
0x000000F0,
|
||||
0x000000F0,
|
||||
0x000FFFF0,
|
||||
0x00F000F0,
|
||||
0x00F000F0,
|
||||
0x000FFFF0,
|
||||
0x00000000,
|
||||
0x00000000,
|
||||
0x00000000,
|
||||
0x00FFFF00,
|
||||
0x0F0000F0,
|
||||
0x0FFFFFF0,
|
||||
0x0F000000,
|
||||
0x00FFFF00,
|
||||
0x00000000,
|
||||
0x0000FF00,
|
||||
0x000F0000,
|
||||
0x000F0000,
|
||||
0x0FFFFF00,
|
||||
0x000F0000,
|
||||
0x000F0000,
|
||||
0x000F0000,
|
||||
0x00000000,
|
||||
0x00000000,
|
||||
0x000FFFF0,
|
||||
0x00F000F0,
|
||||
0x00F000F0,
|
||||
0x000FFFF0,
|
||||
0x000000F0,
|
||||
0x000FFF00,
|
||||
0x00000000,
|
||||
0x00F00000,
|
||||
0x00F00000,
|
||||
0x00F00000,
|
||||
0x00F0FF00,
|
||||
0x00FF00F0,
|
||||
0x00F000F0,
|
||||
0x00F000F0,
|
||||
0x00000000,
|
||||
0x00000000,
|
||||
0x0000F000,
|
||||
0x00000000,
|
||||
0x0000F000,
|
||||
0x0000F000,
|
||||
0x0000F000,
|
||||
0x0000F000,
|
||||
0x00000000,
|
||||
0x00000F00,
|
||||
0x00000000,
|
||||
0x00000F00,
|
||||
0x00000F00,
|
||||
0x00000F00,
|
||||
0x00F00F00,
|
||||
0x000FF000,
|
||||
0x00000000,
|
||||
0x00000000,
|
||||
0x00F00000,
|
||||
0x00F00000,
|
||||
0x00F00F00,
|
||||
0x00F0F000,
|
||||
0x00FFF000,
|
||||
0x00F00F00,
|
||||
0x00000000,
|
||||
0x0000F000,
|
||||
0x0000F000,
|
||||
0x0000F000,
|
||||
0x0000F000,
|
||||
0x0000F000,
|
||||
0x0000F000,
|
||||
0x00000F00,
|
||||
0x00000000,
|
||||
0x00000000,
|
||||
0x00000000,
|
||||
0x00F0FF00,
|
||||
0x0F0F00F0,
|
||||
0x0F0F00F0,
|
||||
0x0F0F00F0,
|
||||
0x0F0F00F0,
|
||||
0x00000000,
|
||||
0x00000000,
|
||||
0x00000000,
|
||||
0x00F0FF00,
|
||||
0x00FF00F0,
|
||||
0x00F000F0,
|
||||
0x00F000F0,
|
||||
0x00F000F0,
|
||||
0x00000000,
|
||||
0x00000000,
|
||||
0x00000000,
|
||||
0x000FFF00,
|
||||
0x00F000F0,
|
||||
0x00F000F0,
|
||||
0x00F000F0,
|
||||
0x000FFF00,
|
||||
0x00000000,
|
||||
0x00000000,
|
||||
0x00FFF000,
|
||||
0x00F00F00,
|
||||
0x00F00F00,
|
||||
0x00FFF000,
|
||||
0x00F00000,
|
||||
0x00F00000,
|
||||
0x00000000,
|
||||
0x00000000,
|
||||
0x000FFF00,
|
||||
0x00F00F00,
|
||||
0x00F00F00,
|
||||
0x000FFF00,
|
||||
0x00000F00,
|
||||
0x00000FF0,
|
||||
0x00000000,
|
||||
0x00000000,
|
||||
0x00000000,
|
||||
0x00F0FFF0,
|
||||
0x00FF0000,
|
||||
0x00F00000,
|
||||
0x00F00000,
|
||||
0x00F00000,
|
||||
0x00000000,
|
||||
0x00000000,
|
||||
0x00000000,
|
||||
0x000FFFF0,
|
||||
0x00F00000,
|
||||
0x000FFF00,
|
||||
0x000000F0,
|
||||
0x00FFFF00,
|
||||
0x00000000,
|
||||
0x00000000,
|
||||
0x0000F000,
|
||||
0x00FFFFF0,
|
||||
0x0000F000,
|
||||
0x0000F000,
|
||||
0x0000F000,
|
||||
0x00000FF0,
|
||||
0x00000000,
|
||||
0x00000000,
|
||||
0x00000000,
|
||||
0x00F000F0,
|
||||
0x00F000F0,
|
||||
0x00F000F0,
|
||||
0x00F000F0,
|
||||
0x000FFFF0,
|
||||
0x00000000,
|
||||
0x00000000,
|
||||
0x00000000,
|
||||
0x00F000F0,
|
||||
0x00F000F0,
|
||||
0x00F000F0,
|
||||
0x000F0F00,
|
||||
0x0000F000,
|
||||
0x00000000,
|
||||
0x00000000,
|
||||
0x00000000,
|
||||
0x0F0000F0,
|
||||
0x0F00F0F0,
|
||||
0x0F00F0F0,
|
||||
0x0F00F0F0,
|
||||
0x00FF0F00,
|
||||
0x00000000,
|
||||
0x00000000,
|
||||
0x00000000,
|
||||
0x00F000F0,
|
||||
0x000F0F00,
|
||||
0x0000F000,
|
||||
0x000F0F00,
|
||||
0x00F000F0,
|
||||
0x00000000,
|
||||
0x00000000,
|
||||
0x0F000F00,
|
||||
0x0F000F00,
|
||||
0x00F00F00,
|
||||
0x000FFF00,
|
||||
0x00000F00,
|
||||
0x00FFF000,
|
||||
0x00000000,
|
||||
0x00000000,
|
||||
0x00000000,
|
||||
0x00FFFFF0,
|
||||
0x00000F00,
|
||||
0x0000F000,
|
||||
0x000F0000,
|
||||
0x00FFFFF0,
|
||||
0x00000000,
|
||||
0x00000F00,
|
||||
0x0000F000,
|
||||
0x0000F000,
|
||||
0x00FF0000,
|
||||
0x0000F000,
|
||||
0x0000F000,
|
||||
0x00000F00,
|
||||
0x00000000,
|
||||
0x0000F000,
|
||||
0x0000F000,
|
||||
0x0000F000,
|
||||
0x0000F000,
|
||||
0x0000F000,
|
||||
0x0000F000,
|
||||
0x0000F000,
|
||||
0x00000000,
|
||||
0x000F0000,
|
||||
0x0000F000,
|
||||
0x0000F000,
|
||||
0x00000FF0,
|
||||
0x0000F000,
|
||||
0x0000F000,
|
||||
0x000F0000,
|
||||
0x00000000,
|
||||
0x00FF00FF,
|
||||
0x0F00FF00,
|
||||
0x00000000,
|
||||
0x00000000,
|
||||
0x00000000,
|
||||
0x00000000,
|
||||
0x00000000,
|
||||
0x00000000,
|
||||
0x00FF0000,
|
||||
0x0FF00000,
|
||||
0xFFFFFFFF,
|
||||
0xFFFFF000,
|
||||
0xFFFFF000,
|
||||
0xFFF00000,
|
||||
0x00000000
|
||||
};
|
||||
251
src/dolphin/demo/DEMOInit.c
Normal file
251
src/dolphin/demo/DEMOInit.c
Normal file
|
|
@ -0,0 +1,251 @@
|
|||
#include <dolphin.h>
|
||||
#include <dolphin/demo.h>
|
||||
#include <dolphin/gx.h>
|
||||
#include <dolphin/pad.h>
|
||||
#include <dolphin/vi.h>
|
||||
#include "game/init.h"
|
||||
|
||||
#include <dolphin/demoPriv.h>
|
||||
|
||||
extern unsigned char DemoStatEnable; // size: 0x1, address: 0x0
|
||||
|
||||
// .bss
|
||||
static struct _GXRenderModeObj rmodeobj; // size: 0x3C, address: 0x0
|
||||
|
||||
// .sdata
|
||||
static unsigned char DemoFirstFrame = 1; // size: 0x1, address: 0x0
|
||||
|
||||
// .sbss
|
||||
static void *DefaultFifo = NULL; // size: 0x4, address: 0x0
|
||||
static GXFifoObj *DefaultFifoObj = NULL; // size: 0x4, address: 0x4
|
||||
static struct _GXRenderModeObj *rmode; // size: 0x4, address: 0x8
|
||||
static int BypassWorkaround; // size: 0x4, address: 0xC
|
||||
static unsigned long FrameCount; // size: 0x4, address: 0x10
|
||||
static unsigned long FrameMissThreshold; // size: 0x4, address: 0x14
|
||||
|
||||
// functions
|
||||
static void __DEMOInitRenderMode(struct _GXRenderModeObj *mode);
|
||||
static void __DEMOInitMem();
|
||||
static void __DEMOInitGX();
|
||||
static void __DEMOInitVI();
|
||||
static void __DEMOInitForEmu();
|
||||
static void __BypassRetraceCallback();
|
||||
static void LoadMemInfo();
|
||||
|
||||
void DEMOInit(struct _GXRenderModeObj *mode)
|
||||
{
|
||||
OSInit();
|
||||
DVDInit();
|
||||
VIInit();
|
||||
DEMOPadInit();
|
||||
__DEMOInitRenderMode(mode);
|
||||
__DEMOInitMem();
|
||||
VIConfigure(rmode);
|
||||
DefaultFifo = OSAllocFromHeap(__OSCurrHeap, 0x40000);
|
||||
DefaultFifoObj = GXInit(DefaultFifo, 0x40000);
|
||||
__DEMOInitGX();
|
||||
__DEMOInitVI();
|
||||
}
|
||||
|
||||
static void __DEMOInitRenderMode(struct _GXRenderModeObj *mode)
|
||||
{
|
||||
if (mode != NULL) {
|
||||
rmode = mode;
|
||||
return;
|
||||
}
|
||||
switch (VIGetTvFormat()) {
|
||||
case VI_NTSC:
|
||||
rmode = &GXNtsc480IntDf;
|
||||
break;
|
||||
case VI_PAL:
|
||||
rmode = &GXPal528IntDf;
|
||||
break;
|
||||
case VI_MPAL:
|
||||
rmode = &GXMpal480IntDf;
|
||||
break;
|
||||
default:
|
||||
OSPanic(__FILE__, 0x1A6, "DEMOInit: invalid TV format\n");
|
||||
break;
|
||||
}
|
||||
GXAdjustForOverscan(rmode, &rmodeobj, 0, 0x10);
|
||||
rmode = &rmodeobj;
|
||||
}
|
||||
|
||||
static void __DEMOInitMem()
|
||||
{
|
||||
void *arenaLo = OSGetArenaLo();
|
||||
void *arenaHi = OSGetArenaHi();
|
||||
unsigned long fbSize = ((u16)(rmode->fbWidth + 15) & 0xFFF0) * rmode->xfbHeight * 2;
|
||||
|
||||
DemoFrameBuffer1 = (void *)(((u32)arenaLo + 0x1F) & 0xFFFFFFE0);
|
||||
DemoFrameBuffer2 = (void *)(((u32)DemoFrameBuffer1 + fbSize + 0x1F) & 0xFFFFFFE0);
|
||||
DemoCurrentBuffer = DemoFrameBuffer2;
|
||||
arenaLo = (void *)(((u32)DemoFrameBuffer2 + fbSize + 0x1F) & 0xFFFFFFE0);
|
||||
OSSetArenaLo(arenaLo);
|
||||
if (((OSGetConsoleType() + 0xF0000000) == 4U) && ((OSGetPhysicalMemSize() + 0xFFC00000) != 0U)
|
||||
&& (OSGetConsoleSimulatedMemSize() < 0x01800000U)) {
|
||||
LoadMemInfo();
|
||||
return;
|
||||
}
|
||||
arenaLo = OSGetArenaLo();
|
||||
arenaHi = OSGetArenaHi();
|
||||
arenaLo = OSInitAlloc(arenaLo, arenaHi, 1);
|
||||
OSSetArenaLo(arenaLo);
|
||||
arenaLo = (void *)(((u32)arenaLo + 0x1F) & 0xFFFFFFE0);
|
||||
arenaHi = (void *)((u32)arenaHi & 0xFFFFFFE0);
|
||||
OSSetCurrentHeap(OSCreateHeap((void *)(((u32)arenaLo)), arenaHi));
|
||||
OSSetArenaLo((arenaLo = arenaHi));
|
||||
}
|
||||
|
||||
static void __DEMOInitGX()
|
||||
{
|
||||
GXSetViewport(0.0f, 0.0f, rmode->fbWidth, rmode->xfbHeight, 0.0f, 1.0f);
|
||||
GXSetScissor(0, 0, rmode->fbWidth, rmode->efbHeight);
|
||||
GXSetDispCopySrc(0, 0, rmode->fbWidth, rmode->efbHeight);
|
||||
GXSetDispCopyDst(rmode->fbWidth, rmode->xfbHeight);
|
||||
GXSetDispCopyYScale(((f32)rmode->xfbHeight / (f32)rmode->efbHeight));
|
||||
GXSetCopyFilter(rmode->aa, rmode->sample_pattern, 1, rmode->vfilter);
|
||||
if (rmode->aa != 0) {
|
||||
GXSetPixelFmt(2, 0);
|
||||
}
|
||||
else {
|
||||
GXSetPixelFmt(0, 0);
|
||||
}
|
||||
GXCopyDisp(DemoCurrentBuffer, 1);
|
||||
GXSetDispCopyGamma(0);
|
||||
}
|
||||
|
||||
static void __DEMOInitVI()
|
||||
{
|
||||
unsigned long nin;
|
||||
|
||||
VISetNextFrameBuffer(DemoFrameBuffer1);
|
||||
DemoCurrentBuffer = DemoFrameBuffer2;
|
||||
VIFlush();
|
||||
VIWaitForRetrace();
|
||||
nin = rmode->viTVmode & 1;
|
||||
if (nin != 0) {
|
||||
VIWaitForRetrace();
|
||||
}
|
||||
}
|
||||
|
||||
static void __DEMOInitForEmu() { }
|
||||
|
||||
void DEMOBeforeRender()
|
||||
{
|
||||
if (BypassWorkaround != 0) {
|
||||
GXSetDrawSync(0xFEEB);
|
||||
}
|
||||
if (rmode->field_rendering != 0) {
|
||||
GXSetViewportJitter(0.0f, 0.0f, rmode->fbWidth, rmode->xfbHeight, 0.0f, 1.0f, VIGetNextField());
|
||||
}
|
||||
else {
|
||||
GXSetViewport(0.0f, 0.0f, rmode->fbWidth, rmode->xfbHeight, 0.0f, 1.0f);
|
||||
}
|
||||
GXInvalidateVtxCache();
|
||||
GXInvalidateTexAll();
|
||||
}
|
||||
|
||||
void DEMOSwapBuffers()
|
||||
{
|
||||
VISetNextFrameBuffer(DemoCurrentBuffer);
|
||||
if (DemoFirstFrame != 0) {
|
||||
VISetBlack(0);
|
||||
DemoFirstFrame = 0;
|
||||
}
|
||||
VIFlush();
|
||||
VIWaitForRetrace();
|
||||
if ((u32)DemoCurrentBuffer == (u32)DemoFrameBuffer1) {
|
||||
DemoCurrentBuffer = DemoFrameBuffer2;
|
||||
return;
|
||||
}
|
||||
DemoCurrentBuffer = DemoFrameBuffer1;
|
||||
}
|
||||
|
||||
struct _GXRenderModeObj *DEMOGetRenderModeObj()
|
||||
{
|
||||
return rmode;
|
||||
}
|
||||
|
||||
u32 DEMOGetCurrentBuffer(void)
|
||||
{
|
||||
return (u32)DemoCurrentBuffer;
|
||||
}
|
||||
|
||||
void DEMOEnableBypassWorkaround(unsigned long timeoutFrames)
|
||||
{
|
||||
BypassWorkaround = 1;
|
||||
FrameMissThreshold = timeoutFrames;
|
||||
VISetPreRetraceCallback(__BypassRetraceCallback);
|
||||
}
|
||||
|
||||
static void __BypassRetraceCallback()
|
||||
{
|
||||
FrameCount += 1;
|
||||
}
|
||||
|
||||
static void LoadMemInfo()
|
||||
{
|
||||
void *arenaHiOld;
|
||||
void *arenaLo;
|
||||
void *arenaHi;
|
||||
void *simMemEnd;
|
||||
struct DVDFileInfo fileInfo;
|
||||
unsigned long length;
|
||||
unsigned long transferLength;
|
||||
long offset;
|
||||
unsigned long i;
|
||||
unsigned long indexMax;
|
||||
char *buf[63];
|
||||
struct {
|
||||
void *start;
|
||||
void *end;
|
||||
} *memEntry;
|
||||
|
||||
OSReport("\nNow, try to find memory info file...\n\n");
|
||||
if (!DVDOpen("/meminfo.bin", &fileInfo)) {
|
||||
OSReport("\nCan't find memory info file. Use /XXX toolname/ to maximize available\n");
|
||||
OSReport("memory space. For now, we only use the first %dMB.\n", OSGetConsoleSimulatedMemSize() >> 0x14);
|
||||
arenaLo = OSGetArenaLo();
|
||||
arenaHi = OSGetArenaHi();
|
||||
arenaLo = OSInitAlloc(arenaLo, arenaHi, 1);
|
||||
OSSetArenaLo(arenaLo);
|
||||
arenaLo = (void *)(((u32)arenaLo + 0x1F) & 0xFFFFFFE0);
|
||||
arenaHi = (void *)((u32)arenaHi & 0xFFFFFFE0);
|
||||
OSSetCurrentHeap(OSCreateHeap((void *)(((u32)arenaLo)), arenaHi));
|
||||
OSSetArenaLo((arenaLo = arenaHi));
|
||||
return;
|
||||
}
|
||||
memEntry = (void *)((u32)buf + 0x1F & 0xFFFFFFE0);
|
||||
arenaHiOld = OSGetArenaHi();
|
||||
simMemEnd = OSPhysicalToCached(OSGetConsoleSimulatedMemSize());
|
||||
OSSetArenaHi(OSPhysicalToCached(OSGetPhysicalMemSize()));
|
||||
arenaLo = OSGetArenaLo();
|
||||
arenaHi = OSGetArenaHi();
|
||||
arenaLo = OSInitAlloc(arenaLo, arenaHi, 1);
|
||||
OSSetArenaLo(arenaLo);
|
||||
arenaLo = (void *)(((u32)arenaLo + 0x1F) & 0xFFFFFFE0);
|
||||
arenaHi = (void *)((u32)arenaHi & 0xFFFFFFE0);
|
||||
OSSetCurrentHeap(OSCreateHeap((void *)(arenaLo), arenaHi));
|
||||
OSSetArenaLo((arenaLo = arenaHi));
|
||||
OSAllocFixed(&arenaHiOld, &simMemEnd);
|
||||
length = fileInfo.length;
|
||||
offset = 0;
|
||||
while (length) {
|
||||
OSReport("loop\n");
|
||||
transferLength = (length < 0x20) ? length : 0x20;
|
||||
if (DVDReadPrio(&fileInfo, memEntry, (transferLength + 0x1F) & 0xFFFFFFE0, offset, 2) < 0) {
|
||||
OSPanic(__FILE__, 0x49F, "An error occurred when issuing read to /meminfo.bin\n");
|
||||
}
|
||||
indexMax = (transferLength / 8);
|
||||
for (i = 0; i < indexMax; i++) {
|
||||
OSReport("start: 0x%08x, end: 0x%08x\n", memEntry[i].start, memEntry[i].end);
|
||||
OSAllocFixed(&memEntry[i].start, &memEntry[i].end);
|
||||
OSReport("Removed 0x%08x - 0x%08x from the current heap\n", memEntry[i].start, (char *)memEntry[i].end - 1);
|
||||
}
|
||||
length -= transferLength;
|
||||
offset += transferLength;
|
||||
}
|
||||
DVDClose(&fileInfo);
|
||||
OSDumpHeap(__OSCurrHeap);
|
||||
}
|
||||
146
src/dolphin/demo/DEMOPuts.c
Normal file
146
src/dolphin/demo/DEMOPuts.c
Normal file
|
|
@ -0,0 +1,146 @@
|
|||
#include "stdarg.h"
|
||||
#include "stdio.h"
|
||||
#include <dolphin.h>
|
||||
#include <dolphin/demo.h>
|
||||
#include <dolphin/gx.h>
|
||||
#include <dolphin/mtx.h>
|
||||
|
||||
#include <dolphin/demoPriv.h>
|
||||
|
||||
extern unsigned long DEMOFontBitmap[]; // size: 0x0, address: 0x0
|
||||
|
||||
// .bss
|
||||
static struct _GXTexObj fontTexObj; // size: 0x20, address: 0x0
|
||||
|
||||
// .sbss
|
||||
static long fontShift; // size: 0x4, address: 0x0
|
||||
|
||||
// functions
|
||||
static void DrawFontChar(int x, int y, int z, int xChar, int yChar);
|
||||
static void LoadSheet(void *image, enum _GXTexMapID texMapID);
|
||||
|
||||
void DEMOSetFontType(DMFontType attr)
|
||||
{
|
||||
switch (attr) {
|
||||
case DM_FT_RVS:
|
||||
GXSetBlendMode(2, 0, 0, 0xC);
|
||||
break;
|
||||
case DM_FT_XLU:
|
||||
GXSetBlendMode(1, 1, 1, 0);
|
||||
break;
|
||||
case DM_FT_OPQ:
|
||||
default:
|
||||
GXSetBlendMode(1, 1, 0, 0);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
void DEMOLoadFont(enum _GXTexMapID texMap, enum _GXTexMtx texMtx, DMTexFlt texFlt)
|
||||
{
|
||||
float fontTMtx[3][4];
|
||||
unsigned short width;
|
||||
unsigned short height;
|
||||
|
||||
width = 64;
|
||||
height = 0x1800 / width;
|
||||
GXInitTexObj(&fontTexObj, (void *)DEMOFontBitmap, width, (u16)height, 0, 0, 0, 0);
|
||||
if (texFlt == 0) {
|
||||
GXInitTexObjLOD(&fontTexObj, 0, 0, 0, 0, 0, 0.0f, 0.0f, 0.0f);
|
||||
fontShift = 0;
|
||||
}
|
||||
GXLoadTexObj(&fontTexObj, texMap);
|
||||
MTXScale(fontTMtx, 1.0f / width, 1.0f / height, 1.0f);
|
||||
GXLoadTexMtxImm(fontTMtx, texMtx, 1);
|
||||
GXSetNumTexGens(1);
|
||||
GXSetTexCoordGen(0, 1, 4, texMtx);
|
||||
}
|
||||
|
||||
void DEMOSetupScrnSpc(long width, long height, float depth)
|
||||
{
|
||||
float pMtx[4][4];
|
||||
float mMtx[3][4];
|
||||
|
||||
MTXOrtho(pMtx, 0.0f, height, 0.0f, width, 0.0f, -depth);
|
||||
GXSetProjection(pMtx, 1);
|
||||
MTXIdentity(mMtx);
|
||||
GXLoadPosMtxImm(mMtx, 0);
|
||||
GXSetCurrentMtx(0);
|
||||
}
|
||||
|
||||
void DEMOInitCaption(long font_type, long width, long height)
|
||||
{
|
||||
DEMOSetupScrnSpc(width, height, 100.0f);
|
||||
GXSetZMode(1, 7, 1);
|
||||
GXSetNumChans(0);
|
||||
GXSetNumTevStages(1);
|
||||
GXSetTevOp(0, 3);
|
||||
GXSetTevOrder(0, 0, 0, 0xFF);
|
||||
DEMOLoadFont(0, 0x1E, 0);
|
||||
DEMOSetFontType(font_type);
|
||||
}
|
||||
|
||||
void DEMOPuts(s16 x, s16 y, s16 z, char *string)
|
||||
{
|
||||
char *str;
|
||||
long s;
|
||||
long t;
|
||||
long c;
|
||||
long w;
|
||||
long len;
|
||||
long i;
|
||||
|
||||
str = string;
|
||||
GXClearVtxDesc();
|
||||
GXSetVtxDesc(9, 1);
|
||||
GXSetVtxDesc(0xD, 1);
|
||||
GXSetVtxAttrFmt(0, 9, 1, 3, 0);
|
||||
GXSetVtxAttrFmt(0, 0xD, 1, 3, 1);
|
||||
|
||||
// calc len
|
||||
len = 0;
|
||||
while (1) {
|
||||
c = *(str++);
|
||||
if ((c >= 0x20) && (c <= 0x7F)) {
|
||||
len++;
|
||||
continue;
|
||||
}
|
||||
|
||||
if (len > 0) {
|
||||
GXBegin(0x80, 0, len * 4);
|
||||
for (i = 0; i < len; i++) {
|
||||
w = string[i] - 0x20;
|
||||
s = fontShift + ((w % 8) * 0x10);
|
||||
t = fontShift + ((w / 8) * 0x10);
|
||||
GXPosition3s16(x + (i * 8), y, z);
|
||||
GXTexCoord2s16(s, t);
|
||||
GXPosition3s16(x + (i * 8) + 8, y, z);
|
||||
GXTexCoord2s16(s + 0x10, t);
|
||||
GXPosition3s16(x + (i * 8) + 8, y + 8, z);
|
||||
GXTexCoord2s16(s + 0x10, t + 0x10);
|
||||
GXPosition3s16(x + (i * 8), y + 8, z);
|
||||
GXTexCoord2s16(s, t + 0x10);
|
||||
}
|
||||
GXEnd();
|
||||
len = 0;
|
||||
}
|
||||
|
||||
string = str;
|
||||
if (c == 0xA) {
|
||||
y += 0x8;
|
||||
}
|
||||
else {
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void DEMOPrintf(s16 x, s16 y, s16 z, char *fmt, ...)
|
||||
{
|
||||
va_list vlist;
|
||||
char buf[256];
|
||||
|
||||
va_start(vlist, fmt);
|
||||
vsprintf(buf, fmt, vlist);
|
||||
DEMOPuts(x, y, z, buf);
|
||||
va_end(vlist);
|
||||
}
|
||||
424
src/dolphin/demo/DEMOStats.c
Normal file
424
src/dolphin/demo/DEMOStats.c
Normal file
|
|
@ -0,0 +1,424 @@
|
|||
#include "dolphin/gx/GXPerf.h"
|
||||
#include "string.h"
|
||||
#include <dolphin.h>
|
||||
#include <dolphin/demo.h>
|
||||
#include <dolphin/gx.h>
|
||||
|
||||
#include <dolphin/demoPriv.h>
|
||||
|
||||
unsigned char DemoStatEnable = 0;
|
||||
static DemoStatData *DemoStat;
|
||||
static unsigned long DemoStatIndx;
|
||||
static unsigned long DemoStatMaxIndx;
|
||||
static unsigned long DemoStatClocks;
|
||||
static unsigned long DemoStatDisp;
|
||||
static unsigned long DemoStatStrLen;
|
||||
static unsigned long topPixIn;
|
||||
static unsigned long topPixOut;
|
||||
static unsigned long botPixIn;
|
||||
static unsigned long botPixOut;
|
||||
static unsigned long clrPixIn;
|
||||
static unsigned long copyClks;
|
||||
static unsigned long vcCheck;
|
||||
static unsigned long vcMiss;
|
||||
static unsigned long vcStall;
|
||||
static unsigned long cpReq;
|
||||
static unsigned long tcReq;
|
||||
static unsigned long cpuRdReq;
|
||||
static unsigned long cpuWrReq;
|
||||
static unsigned long dspReq;
|
||||
static unsigned long ioReq;
|
||||
static unsigned long viReq;
|
||||
static unsigned long peReq;
|
||||
static unsigned long rfReq;
|
||||
static unsigned long fiReq;
|
||||
|
||||
// functions
|
||||
static void DEMOWriteStats(unsigned char update);
|
||||
static void DEMOWriteStats(unsigned char update);
|
||||
|
||||
void DEMOSetStats(DemoStatData *stat, unsigned long nstats, DEMO_STAT_DISP disp)
|
||||
{
|
||||
if (!stat || nstats == 0) {
|
||||
DemoStatEnable = FALSE;
|
||||
}
|
||||
else {
|
||||
DemoStatEnable = TRUE;
|
||||
DemoStat = stat;
|
||||
DemoStatIndx = 0;
|
||||
DemoStatMaxIndx = nstats;
|
||||
DemoStatDisp = disp;
|
||||
DemoStatStrLen = strlen(DemoStat->text);
|
||||
}
|
||||
}
|
||||
|
||||
static void DEMOWriteStats(unsigned char update)
|
||||
{
|
||||
unsigned long cnt0;
|
||||
unsigned long cnt1;
|
||||
unsigned long cnt2;
|
||||
unsigned long cnt3;
|
||||
unsigned long cnt4;
|
||||
unsigned long cnt5;
|
||||
unsigned long cnt6;
|
||||
unsigned long cnt7;
|
||||
unsigned long cnt8;
|
||||
unsigned long cnt9;
|
||||
|
||||
switch (DemoStat[DemoStatIndx].stat_type) {
|
||||
case DEMO_STAT_GP0:
|
||||
if (update) {
|
||||
cnt0 = GXReadGP0Metric();
|
||||
DemoStat[DemoStatIndx].count = cnt0;
|
||||
GXSetGPMetric(GX_PERF0_NONE, GX_PERF1_NONE);
|
||||
break;
|
||||
}
|
||||
GXSetGPMetric(DemoStat[DemoStatIndx].stat, GX_PERF1_NONE);
|
||||
GXClearGPMetric();
|
||||
break;
|
||||
case DEMO_STAT_GP1:
|
||||
if (update) {
|
||||
cnt0 = GXReadGP1Metric();
|
||||
DemoStat[DemoStatIndx].count = cnt0;
|
||||
GXSetGPMetric(GX_PERF0_NONE, GX_PERF1_NONE);
|
||||
break;
|
||||
}
|
||||
GXSetGPMetric(GX_PERF0_NONE, DemoStat[DemoStatIndx].stat);
|
||||
GXClearGPMetric();
|
||||
break;
|
||||
case DEMO_STAT_MEM:
|
||||
if (update) {
|
||||
GXReadMemMetric(&cnt0, &cnt1, &cnt2, &cnt3, &cnt4, &cnt5, &cnt6, &cnt7, &cnt8, &cnt9);
|
||||
cpReq = cnt0;
|
||||
tcReq = cnt1;
|
||||
cpuRdReq = cnt2;
|
||||
cpuWrReq = cnt3;
|
||||
dspReq = cnt4;
|
||||
ioReq = cnt5;
|
||||
viReq = cnt6;
|
||||
peReq = cnt7;
|
||||
rfReq = cnt8;
|
||||
fiReq = cnt9;
|
||||
break;
|
||||
}
|
||||
GXClearMemMetric();
|
||||
break;
|
||||
case DEMO_STAT_PIX:
|
||||
if (update) {
|
||||
GXReadPixMetric(&cnt0, &cnt1, &cnt2, &cnt3, &cnt4, &cnt5);
|
||||
topPixIn = cnt0;
|
||||
topPixOut = cnt1;
|
||||
botPixIn = cnt2;
|
||||
botPixOut = cnt3;
|
||||
clrPixIn = cnt4;
|
||||
copyClks = cnt5;
|
||||
break;
|
||||
}
|
||||
GXClearPixMetric();
|
||||
break;
|
||||
case DEMO_STAT_VC:
|
||||
if (update) {
|
||||
GXReadVCacheMetric(&cnt0, &cnt1, &cnt2);
|
||||
vcCheck = cnt0;
|
||||
vcMiss = cnt1;
|
||||
vcStall = cnt2;
|
||||
break;
|
||||
}
|
||||
GXSetVCacheMetric(GX_VC_POS);
|
||||
GXClearVCacheMetric();
|
||||
break;
|
||||
case DEMO_STAT_FR:
|
||||
if (update) {
|
||||
GXReadPixMetric(&cnt0, &cnt1, &cnt2, &cnt3, &cnt4, &cnt5);
|
||||
topPixIn = cnt0;
|
||||
topPixOut = cnt1;
|
||||
botPixIn = cnt2;
|
||||
botPixOut = cnt3;
|
||||
clrPixIn = cnt4;
|
||||
copyClks = cnt5;
|
||||
DemoStatClocks = GXReadGP0Metric();
|
||||
GXSetGPMetric(GX_PERF0_NONE, GX_PERF1_NONE);
|
||||
break;
|
||||
}
|
||||
GXClearPixMetric();
|
||||
GXSetGPMetric(GX_PERF0_CLOCKS, GX_PERF1_NONE);
|
||||
GXClearGPMetric();
|
||||
break;
|
||||
case DEMO_STAT_TBW:
|
||||
case DEMO_STAT_TBP:
|
||||
GXClearPixMetric();
|
||||
if (update) {
|
||||
GXReadPixMetric(&cnt0, &cnt1, &cnt2, &cnt3, &cnt4, &cnt5);
|
||||
topPixIn = cnt0;
|
||||
topPixOut = cnt1;
|
||||
botPixIn = cnt2;
|
||||
botPixOut = cnt3;
|
||||
clrPixIn = cnt4;
|
||||
copyClks = cnt5;
|
||||
DemoStatClocks = GXReadGP0Metric(cnt4, cnt3, cnt2, cnt1, cnt0);
|
||||
GXReadMemMetric(&cnt0, &cnt1, &cnt2, &cnt3, &cnt4, &cnt5, &cnt6, &cnt7, &cnt8, &cnt9);
|
||||
tcReq = cnt1;
|
||||
GXSetGPMetric(GX_PERF0_NONE, GX_PERF1_NONE);
|
||||
break;
|
||||
}
|
||||
GXClearMemMetric();
|
||||
GXSetGPMetric(GX_PERF0_CLOCKS, GX_PERF1_NONE);
|
||||
GXClearGPMetric();
|
||||
break;
|
||||
case DEMO_STAT_MYC:
|
||||
case DEMO_STAT_MYR:
|
||||
break;
|
||||
default:
|
||||
OSPanic("DEMOStats.c", 0x127, "DEMOSetStats: Unknown demo stat type\n");
|
||||
}
|
||||
}
|
||||
|
||||
void DEMOUpdateStats(unsigned char inc)
|
||||
{
|
||||
DEMOWriteStats(inc);
|
||||
if (inc) {
|
||||
DemoStatIndx = DemoStatIndx + 1;
|
||||
if (DemoStatIndx == DemoStatMaxIndx) {
|
||||
DemoStatIndx = 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void DEMOPrintStats(void)
|
||||
{
|
||||
GXRenderModeObj *rmode;
|
||||
unsigned long i;
|
||||
signed short text_x;
|
||||
signed short text_y;
|
||||
signed short text_yinc;
|
||||
unsigned short wd;
|
||||
unsigned short ht;
|
||||
float rate;
|
||||
|
||||
if (DemoStatDisp == DEMO_STAT_IO) {
|
||||
for (i = 0; i < DemoStatMaxIndx; i++) {
|
||||
switch (DemoStat[i].stat_type) {
|
||||
case DEMO_STAT_PIX:
|
||||
switch (DemoStat[i].stat) {
|
||||
case 0:
|
||||
OSReport("%s: %8d\n", DemoStat[i].text, topPixIn);
|
||||
break;
|
||||
case 1:
|
||||
OSReport("%s: %8d\n", DemoStat[i].text, topPixOut);
|
||||
break;
|
||||
case 2:
|
||||
OSReport("%s: %8d\n", DemoStat[i].text, botPixIn);
|
||||
break;
|
||||
case 3:
|
||||
OSReport("%s: %8d\n", DemoStat[i].text, botPixOut);
|
||||
break;
|
||||
case 4:
|
||||
OSReport("%s: %8d\n", DemoStat[i].text, clrPixIn);
|
||||
break;
|
||||
case 5:
|
||||
OSReport("%s: %8d\n", DemoStat[i].text, copyClks);
|
||||
break;
|
||||
}
|
||||
break;
|
||||
case DEMO_STAT_FR:
|
||||
rate = 162.0F * (topPixIn + botPixIn) / (float)(DemoStatClocks - copyClks);
|
||||
OSReport("%s: %8.2f\n", DemoStat[i].text, rate);
|
||||
break;
|
||||
case DEMO_STAT_TBW:
|
||||
rate = 162.0F * (tcReq << 5) / (float)(DemoStatClocks - copyClks);
|
||||
OSReport("%s: %8.2f\n", DemoStat[i].text, rate);
|
||||
break;
|
||||
case DEMO_STAT_TBP:
|
||||
rate = (tcReq << 5) / (float)(topPixIn + botPixIn);
|
||||
OSReport("%s: %8.2f\n", DemoStat[i].text, rate);
|
||||
break;
|
||||
case DEMO_STAT_VC:
|
||||
switch (DemoStat[i].stat) {
|
||||
case 0:
|
||||
OSReport("%s: %8d\n", DemoStat[i].text, vcCheck);
|
||||
break;
|
||||
case 1:
|
||||
OSReport("%s: %8d\n", DemoStat[i].text, vcMiss);
|
||||
break;
|
||||
case 2:
|
||||
OSReport("%s: %8d\n", DemoStat[i].text, vcStall);
|
||||
break;
|
||||
}
|
||||
break;
|
||||
case DEMO_STAT_MYR:
|
||||
rate = DemoStat[i].stat / (float)DemoStat[i].count;
|
||||
OSReport("%s: %8.2f\n", DemoStat[i].text, rate);
|
||||
break;
|
||||
case DEMO_STAT_MEM:
|
||||
switch (DemoStat[i].stat) {
|
||||
case 0:
|
||||
OSReport("%s: %8d\n", DemoStat[i].text, cpReq);
|
||||
break;
|
||||
case 1:
|
||||
OSReport("%s: %8d\n", DemoStat[i].text, tcReq);
|
||||
break;
|
||||
case 2:
|
||||
OSReport("%s: %8d\n", DemoStat[i].text, cpuRdReq);
|
||||
break;
|
||||
case 3:
|
||||
OSReport("%s: %8d\n", DemoStat[i].text, cpuWrReq);
|
||||
break;
|
||||
case 4:
|
||||
OSReport("%s: %8d\n", DemoStat[i].text, dspReq);
|
||||
break;
|
||||
case 5:
|
||||
OSReport("%s: %8d\n", DemoStat[i].text, ioReq);
|
||||
break;
|
||||
case 6:
|
||||
OSReport("%s: %8d\n", DemoStat[i].text, viReq);
|
||||
break;
|
||||
case 7:
|
||||
OSReport("%s: %8d\n", DemoStat[i].text, peReq);
|
||||
break;
|
||||
case 8:
|
||||
OSReport("%s: %8d\n", DemoStat[i].text, rfReq);
|
||||
break;
|
||||
case 9:
|
||||
OSReport("%s: %8d\n", DemoStat[i].text, fiReq);
|
||||
break;
|
||||
}
|
||||
break;
|
||||
default:
|
||||
OSReport("%s: %8d\n", DemoStat[i].text, DemoStat[i].count);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
else {
|
||||
rmode = DEMOGetRenderModeObj();
|
||||
switch (DemoStatDisp) {
|
||||
case DEMO_STAT_TL:
|
||||
text_x = 0x10;
|
||||
text_y = 0x10;
|
||||
text_yinc = 0xA;
|
||||
wd = rmode->fbWidth;
|
||||
ht = rmode->xfbHeight;
|
||||
break;
|
||||
case DEMO_STAT_BL:
|
||||
text_x = 0x10;
|
||||
text_y = rmode->xfbHeight - 0x18;
|
||||
text_yinc = -0xA;
|
||||
wd = rmode->fbWidth;
|
||||
ht = rmode->xfbHeight;
|
||||
break;
|
||||
case DEMO_STAT_TLD:
|
||||
text_x = 8;
|
||||
text_y = 8;
|
||||
text_yinc = 9;
|
||||
wd = rmode->fbWidth / 2;
|
||||
ht = rmode->xfbHeight / 2;
|
||||
break;
|
||||
case DEMO_STAT_BLD:
|
||||
text_x = 8;
|
||||
text_y = (rmode->xfbHeight - 0x18) / 2;
|
||||
text_yinc = -9;
|
||||
wd = rmode->fbWidth / 2;
|
||||
ht = rmode->xfbHeight / 2;
|
||||
break;
|
||||
}
|
||||
DEMOInitCaption(0, wd, ht);
|
||||
for (i = 0; i < DemoStatMaxIndx; i++) {
|
||||
switch (DemoStat[i].stat_type) {
|
||||
case DEMO_STAT_PIX:
|
||||
switch (DemoStat[i].stat) {
|
||||
case 0:
|
||||
DEMOPrintf(text_x, text_y, 0, "%s: %8d\n", DemoStat[i].text, topPixIn);
|
||||
break;
|
||||
case 1:
|
||||
DEMOPrintf(text_x, text_y, 0, "%s: %8d\n", DemoStat[i].text, topPixOut);
|
||||
break;
|
||||
case 2:
|
||||
DEMOPrintf(text_x, text_y, 0, "%s: %8d\n", DemoStat[i].text, botPixIn);
|
||||
break;
|
||||
case 3:
|
||||
DEMOPrintf(text_x, text_y, 0, "%s: %8d\n", DemoStat[i].text, botPixOut);
|
||||
break;
|
||||
case 4:
|
||||
DEMOPrintf(text_x, text_y, 0, "%s: %8d\n", DemoStat[i].text, clrPixIn);
|
||||
break;
|
||||
case 5:
|
||||
DEMOPrintf(text_x, text_y, 0, "%s: %8d\n", DemoStat[i].text, copyClks);
|
||||
break;
|
||||
}
|
||||
break;
|
||||
case DEMO_STAT_FR:
|
||||
rate = 162.0F * (topPixIn + botPixIn) / (float)(DemoStatClocks - copyClks);
|
||||
DEMOPrintf(text_x, text_y, 0, "%s: %8.2f\n", DemoStat[i].text, rate);
|
||||
break;
|
||||
case DEMO_STAT_TBW:
|
||||
rate = 162.0F * (tcReq << 5) / (float)(DemoStatClocks - copyClks);
|
||||
DEMOPrintf(text_x, text_y, 0, "%s: %8.2f\n", DemoStat[i].text, rate);
|
||||
break;
|
||||
case DEMO_STAT_TBP:
|
||||
rate = (tcReq << 5) / (float)(topPixIn - botPixIn);
|
||||
DEMOPrintf(text_x, text_y, 0, "%s: %8.3f\n", DemoStat[i].text, rate);
|
||||
break;
|
||||
case DEMO_STAT_VC:
|
||||
switch (DemoStat[i].stat) {
|
||||
case 0:
|
||||
DEMOPrintf(text_x, text_y, 0, "%s: %8d\n", DemoStat[i].text, vcCheck);
|
||||
break;
|
||||
case 1:
|
||||
DEMOPrintf(text_x, text_y, 0, "%s: %8d\n", DemoStat[i].text, vcMiss);
|
||||
break;
|
||||
case 2:
|
||||
DEMOPrintf(text_x, text_y, 0, "%s: %8d\n", DemoStat[i].text, vcStall);
|
||||
break;
|
||||
}
|
||||
break;
|
||||
case DEMO_STAT_MEM:
|
||||
switch (DemoStat[i].stat) {
|
||||
case 0:
|
||||
DEMOPrintf(text_x, text_y, 0, "%s: %8d\n", DemoStat[i].text, cpReq);
|
||||
break;
|
||||
case 1:
|
||||
DEMOPrintf(text_x, text_y, 0, "%s: %8d\n", DemoStat[i].text, tcReq);
|
||||
break;
|
||||
case 2:
|
||||
DEMOPrintf(text_x, text_y, 0, "%s: %8d\n", DemoStat[i].text, cpuRdReq);
|
||||
break;
|
||||
case 3:
|
||||
DEMOPrintf(text_x, text_y, 0, "%s: %8d\n", DemoStat[i].text, cpuWrReq);
|
||||
break;
|
||||
case 4:
|
||||
DEMOPrintf(text_x, text_y, 0, "%s: %8d\n", DemoStat[i].text, dspReq);
|
||||
break;
|
||||
case 5:
|
||||
DEMOPrintf(text_x, text_y, 0, "%s: %8d\n", DemoStat[i].text, ioReq);
|
||||
break;
|
||||
case 6:
|
||||
DEMOPrintf(text_x, text_y, 0, "%s: %8d\n", DemoStat[i].text, viReq);
|
||||
break;
|
||||
case 7:
|
||||
DEMOPrintf(text_x, text_y, 0, "%s: %8d\n", DemoStat[i].text, peReq);
|
||||
break;
|
||||
case 8:
|
||||
DEMOPrintf(text_x, text_y, 0, "%s: %8d\n", DemoStat[i].text, rfReq);
|
||||
break;
|
||||
case 9:
|
||||
DEMOPrintf(text_x, text_y, 0, "%s: %8d\n", DemoStat[i].text, fiReq);
|
||||
break;
|
||||
}
|
||||
break;
|
||||
case DEMO_STAT_GP0:
|
||||
case DEMO_STAT_GP1:
|
||||
case DEMO_STAT_MYC:
|
||||
DEMOPrintf(text_x, text_y, 0, "%s: %8d", DemoStat[i].text, DemoStat[i].count);
|
||||
break;
|
||||
case DEMO_STAT_MYR:
|
||||
rate = DemoStat[i].stat / (float)DemoStat[i].count;
|
||||
DEMOPrintf(text_x, text_y, 0, "%s: %8.3f", DemoStat[i].text, rate);
|
||||
break;
|
||||
default:
|
||||
OSReport("Undefined stat type %d in DEMOPrintStats()\n", DemoStat[i].stat_type);
|
||||
break;
|
||||
}
|
||||
text_y += text_yinc;
|
||||
}
|
||||
}
|
||||
}
|
||||
99
src/dolphin/dsp/dsp.c
Normal file
99
src/dolphin/dsp/dsp.c
Normal file
|
|
@ -0,0 +1,99 @@
|
|||
#include "dolphin/dsp.h"
|
||||
#include "dolphin/os.h"
|
||||
|
||||
#include "dolphin/hw_regs.h"
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
static s32 __DSP_init_flag = 0;
|
||||
extern DSPTaskInfo* __DSP_tmp_task;
|
||||
extern DSPTaskInfo* __DSP_last_task;
|
||||
extern DSPTaskInfo* __DSP_first_task;
|
||||
extern DSPTaskInfo* __DSP_curr_task;
|
||||
|
||||
extern void __DSPHandler(__OSInterrupt, OSContext*);
|
||||
extern void __DSP_debug_printf(const char* fmt, ...);
|
||||
extern void __DSP_boot_task(DSPTaskInfo* task);
|
||||
|
||||
u32 DSPCheckMailToDSP(void) { return (__DSPRegs[0] >> 0xF) & 1; }
|
||||
|
||||
u32 DSPCheckMailFromDSP(void) { return (__DSPRegs[2] >> 0xF) & 1; }
|
||||
|
||||
u32 DSPReadMailFromDSP() {
|
||||
u16 reg1;
|
||||
u16 reg2;
|
||||
reg1 = __DSPRegs[2];
|
||||
reg2 = __DSPRegs[3];
|
||||
return reg1 << 16 | reg2;
|
||||
}
|
||||
|
||||
void DSPSendMailToDSP(u32 mail) {
|
||||
__DSPRegs[0] = mail >> 16;
|
||||
__DSPRegs[1] = mail;
|
||||
}
|
||||
|
||||
void DSPInit(void) {
|
||||
u32 oldInt;
|
||||
u16 reg;
|
||||
__DSP_debug_printf("DSPInit(): Build Date: %s %s\n", "Dec 17 2001", "18:25:00");
|
||||
|
||||
if (__DSP_init_flag == 1) {
|
||||
return;
|
||||
}
|
||||
oldInt = OSDisableInterrupts();
|
||||
__OSSetInterruptHandler(7, __DSPHandler);
|
||||
__OSUnmaskInterrupts(0x1000000);
|
||||
reg = __DSPRegs[5];
|
||||
reg = (reg & ~0xA8) | 0x800;
|
||||
__DSPRegs[5] = reg;
|
||||
reg = __DSPRegs[5];
|
||||
reg = reg & ~0xAC;
|
||||
__DSPRegs[5] = reg;
|
||||
__DSP_tmp_task = 0;
|
||||
__DSP_curr_task = 0;
|
||||
__DSP_last_task = 0;
|
||||
__DSP_first_task = 0;
|
||||
__DSP_init_flag = 1;
|
||||
OSRestoreInterrupts(oldInt);
|
||||
}
|
||||
|
||||
void DSPReset(void) {
|
||||
u16 reg;
|
||||
u32 oldInt;
|
||||
oldInt = OSDisableInterrupts();
|
||||
reg = __DSPRegs[5];
|
||||
__DSPRegs[5] = (reg & ~0xA8) | 0x801;
|
||||
__DSP_init_flag = 0;
|
||||
OSRestoreInterrupts(oldInt);
|
||||
}
|
||||
|
||||
void DSPHalt(void) {
|
||||
u16 reg;
|
||||
u32 oldInt;
|
||||
oldInt = OSDisableInterrupts();
|
||||
reg = __DSPRegs[5];
|
||||
__DSPRegs[5] = (reg & ~0xA8) | 4;
|
||||
OSRestoreInterrupts(oldInt);
|
||||
}
|
||||
|
||||
u32 DSPGetDMAStatus(void) { return __DSPRegs[5] & 0x200; }
|
||||
|
||||
DSPTaskInfo* DSPAddTask(DSPTaskInfo* task) {
|
||||
u32 oldInt;
|
||||
oldInt = OSDisableInterrupts();
|
||||
__DSP_insert_task(task);
|
||||
task->state = 0;
|
||||
task->flags = 1;
|
||||
OSRestoreInterrupts(oldInt);
|
||||
if (task == __DSP_first_task) {
|
||||
__DSP_boot_task(task);
|
||||
}
|
||||
|
||||
return task;
|
||||
}
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
5
src/dolphin/dsp/dsp_debug.c
Normal file
5
src/dolphin/dsp/dsp_debug.c
Normal file
|
|
@ -0,0 +1,5 @@
|
|||
#include "types.h"
|
||||
|
||||
void __DSP_debug_printf(const char* fmt, ...) {
|
||||
// UNUSED(fmt);
|
||||
}
|
||||
389
src/dolphin/dsp/dsp_task.c
Normal file
389
src/dolphin/dsp/dsp_task.c
Normal file
|
|
@ -0,0 +1,389 @@
|
|||
#include "dolphin/dsp.h"
|
||||
#include "dolphin/hw_regs.h"
|
||||
|
||||
DSPTaskInfo *__DSP_curr_task;
|
||||
DSPTaskInfo *__DSP_first_task;
|
||||
DSPTaskInfo *__DSP_last_task;
|
||||
DSPTaskInfo *__DSP_tmp_task;
|
||||
DSPTaskInfo *__DSP_rude_task;
|
||||
|
||||
BOOL __DSP_rude_task_pending;
|
||||
|
||||
void __DSPHandler(__OSInterrupt, OSContext *context)
|
||||
{
|
||||
DSPTaskInfo *tmp_task;
|
||||
OSContext exceptionContext;
|
||||
u16 tmp;
|
||||
u32 mail;
|
||||
|
||||
tmp = __DSPRegs[5];
|
||||
tmp = (u16)(tmp & ~0x28) | 0x80;
|
||||
__DSPRegs[5] = tmp;
|
||||
|
||||
OSClearContext(&exceptionContext);
|
||||
OSSetCurrentContext(&exceptionContext);
|
||||
|
||||
while (!DSPCheckMailFromDSP())
|
||||
;
|
||||
mail = DSPReadMailFromDSP();
|
||||
|
||||
if ((__DSP_curr_task->flags & DSP_TASK_FLAG_CANCEL) && (mail == 0xDCD10002)) {
|
||||
mail = 0xDCD10003;
|
||||
}
|
||||
|
||||
switch (mail) {
|
||||
case 0xDCD10000:
|
||||
__DSP_curr_task->state = DSP_TASK_STATE_RUN;
|
||||
|
||||
if (__DSP_curr_task->init_cb) {
|
||||
(*(__DSP_curr_task->init_cb))((void *)(__DSP_curr_task));
|
||||
}
|
||||
break;
|
||||
case 0xDCD10001:
|
||||
__DSP_curr_task->state = DSP_TASK_STATE_RUN;
|
||||
if (__DSP_curr_task->res_cb) {
|
||||
(*(__DSP_curr_task->res_cb))((void *)(__DSP_curr_task));
|
||||
}
|
||||
break;
|
||||
case 0xDCD10002:
|
||||
if (__DSP_rude_task_pending) {
|
||||
|
||||
if (__DSP_curr_task == __DSP_rude_task) {
|
||||
DSPSendMailToDSP(0xCDD10003);
|
||||
while (DSPCheckMailToDSP()) { }
|
||||
|
||||
__DSP_rude_task = NULL;
|
||||
__DSP_rude_task_pending = FALSE;
|
||||
|
||||
if (__DSP_curr_task->res_cb) {
|
||||
(*(__DSP_curr_task->res_cb))((void *)(__DSP_curr_task));
|
||||
}
|
||||
|
||||
break;
|
||||
}
|
||||
else {
|
||||
DSPSendMailToDSP(0xCDD10001);
|
||||
while (DSPCheckMailToDSP())
|
||||
;
|
||||
__DSP_exec_task(__DSP_curr_task, __DSP_rude_task);
|
||||
|
||||
__DSP_curr_task->state = DSP_TASK_STATE_YIELD;
|
||||
__DSP_curr_task = __DSP_rude_task;
|
||||
|
||||
__DSP_rude_task = NULL;
|
||||
__DSP_rude_task_pending = FALSE;
|
||||
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (__DSP_curr_task->next == NULL) {
|
||||
|
||||
if (__DSP_curr_task == __DSP_first_task) {
|
||||
|
||||
DSPSendMailToDSP(0xCDD10003);
|
||||
while (DSPCheckMailToDSP())
|
||||
;
|
||||
|
||||
if (__DSP_curr_task->res_cb) {
|
||||
(*(__DSP_curr_task->res_cb))((void *)(__DSP_curr_task));
|
||||
}
|
||||
}
|
||||
else {
|
||||
DSPSendMailToDSP(0xCDD10001);
|
||||
while (DSPCheckMailToDSP()) { }
|
||||
|
||||
__DSP_exec_task(__DSP_curr_task, __DSP_first_task);
|
||||
|
||||
__DSP_curr_task->state = DSP_TASK_STATE_YIELD;
|
||||
__DSP_curr_task = __DSP_first_task;
|
||||
}
|
||||
}
|
||||
else {
|
||||
|
||||
DSPSendMailToDSP(0xCDD10001);
|
||||
while (DSPCheckMailToDSP()) { }
|
||||
|
||||
__DSP_exec_task(__DSP_curr_task, __DSP_curr_task->next);
|
||||
|
||||
__DSP_curr_task->state = DSP_TASK_STATE_YIELD;
|
||||
__DSP_curr_task = __DSP_curr_task->next;
|
||||
}
|
||||
break;
|
||||
case 0xDCD10003:
|
||||
if (__DSP_rude_task_pending) {
|
||||
|
||||
if (__DSP_curr_task->done_cb) {
|
||||
(*(__DSP_curr_task->done_cb))((void *)(__DSP_curr_task));
|
||||
}
|
||||
|
||||
DSPSendMailToDSP(0xCDD10001);
|
||||
while (DSPCheckMailToDSP())
|
||||
;
|
||||
|
||||
__DSP_exec_task(NULL, __DSP_rude_task);
|
||||
|
||||
__DSP_remove_task(__DSP_curr_task);
|
||||
__DSP_curr_task = __DSP_rude_task;
|
||||
|
||||
__DSP_rude_task = NULL;
|
||||
__DSP_rude_task_pending = FALSE;
|
||||
|
||||
break;
|
||||
}
|
||||
|
||||
if (__DSP_curr_task->next == NULL) {
|
||||
|
||||
if (__DSP_curr_task == __DSP_first_task) {
|
||||
|
||||
if (__DSP_curr_task->done_cb) {
|
||||
(*(__DSP_curr_task->done_cb))((void *)(__DSP_curr_task));
|
||||
}
|
||||
|
||||
DSPSendMailToDSP(0xCDD10002);
|
||||
while (DSPCheckMailToDSP())
|
||||
;
|
||||
|
||||
__DSP_curr_task->state = DSP_TASK_STATE_DONE;
|
||||
|
||||
__DSP_remove_task(__DSP_curr_task);
|
||||
}
|
||||
else {
|
||||
|
||||
if (__DSP_curr_task->done_cb) {
|
||||
(*(__DSP_curr_task->done_cb))((void *)(__DSP_curr_task));
|
||||
}
|
||||
|
||||
DSPSendMailToDSP(0xCDD10001);
|
||||
while (DSPCheckMailToDSP())
|
||||
;
|
||||
|
||||
__DSP_curr_task->state = DSP_TASK_STATE_DONE;
|
||||
__DSP_exec_task(NULL, __DSP_first_task);
|
||||
|
||||
__DSP_curr_task = __DSP_first_task;
|
||||
__DSP_remove_task(__DSP_last_task);
|
||||
}
|
||||
}
|
||||
else {
|
||||
if (__DSP_curr_task->done_cb) {
|
||||
(*(__DSP_curr_task->done_cb))((void *)(__DSP_curr_task));
|
||||
}
|
||||
DSPSendMailToDSP(0xCDD10001);
|
||||
while (DSPCheckMailToDSP())
|
||||
;
|
||||
|
||||
__DSP_curr_task->state = DSP_TASK_STATE_DONE;
|
||||
__DSP_exec_task(NULL, __DSP_curr_task->next);
|
||||
|
||||
__DSP_curr_task = __DSP_curr_task->next;
|
||||
__DSP_remove_task(__DSP_curr_task->prev);
|
||||
}
|
||||
break;
|
||||
|
||||
case 0xDCD10004:
|
||||
|
||||
if (__DSP_curr_task->req_cb) {
|
||||
(*(__DSP_curr_task->req_cb))((void *)(__DSP_curr_task));
|
||||
}
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
OSClearContext(&exceptionContext);
|
||||
OSSetCurrentContext(context);
|
||||
}
|
||||
|
||||
void __DSP_exec_task(DSPTaskInfo *curr, DSPTaskInfo *next)
|
||||
{
|
||||
if (curr) {
|
||||
DSPSendMailToDSP((u32)(curr->dram_mmem_addr));
|
||||
while (DSPCheckMailToDSP())
|
||||
;
|
||||
DSPSendMailToDSP((u32)(curr->dram_length));
|
||||
while (DSPCheckMailToDSP())
|
||||
;
|
||||
DSPSendMailToDSP((u32)(curr->dram_addr));
|
||||
while (DSPCheckMailToDSP())
|
||||
;
|
||||
}
|
||||
else {
|
||||
|
||||
DSPSendMailToDSP((u32)(0));
|
||||
while (DSPCheckMailToDSP())
|
||||
;
|
||||
DSPSendMailToDSP((u32)(0));
|
||||
while (DSPCheckMailToDSP())
|
||||
;
|
||||
DSPSendMailToDSP((u32)(0));
|
||||
while (DSPCheckMailToDSP())
|
||||
;
|
||||
}
|
||||
|
||||
DSPSendMailToDSP((u32)(next->iram_mmem_addr));
|
||||
while (DSPCheckMailToDSP())
|
||||
;
|
||||
DSPSendMailToDSP((u32)(next->iram_length));
|
||||
while (DSPCheckMailToDSP())
|
||||
;
|
||||
DSPSendMailToDSP((u32)(next->iram_addr));
|
||||
while (DSPCheckMailToDSP())
|
||||
;
|
||||
|
||||
if (DSP_TASK_STATE_INIT == next->state) {
|
||||
DSPSendMailToDSP((u32)(next->dsp_init_vector));
|
||||
while (DSPCheckMailToDSP())
|
||||
;
|
||||
DSPSendMailToDSP((u32)(0));
|
||||
while (DSPCheckMailToDSP())
|
||||
;
|
||||
DSPSendMailToDSP((u32)(0));
|
||||
while (DSPCheckMailToDSP())
|
||||
;
|
||||
DSPSendMailToDSP((u32)(0));
|
||||
while (DSPCheckMailToDSP())
|
||||
;
|
||||
}
|
||||
else {
|
||||
DSPSendMailToDSP((u32)(next->dsp_resume_vector));
|
||||
while (DSPCheckMailToDSP())
|
||||
;
|
||||
DSPSendMailToDSP((u32)(next->dram_mmem_addr));
|
||||
while (DSPCheckMailToDSP())
|
||||
;
|
||||
|
||||
DSPSendMailToDSP((u32)(next->dram_length));
|
||||
while (DSPCheckMailToDSP())
|
||||
;
|
||||
|
||||
DSPSendMailToDSP((u32)(next->dram_addr));
|
||||
while (DSPCheckMailToDSP())
|
||||
;
|
||||
}
|
||||
}
|
||||
|
||||
#define MSG_BASE 0x80F30000
|
||||
void __DSP_boot_task(DSPTaskInfo *task)
|
||||
{
|
||||
|
||||
volatile u32 mail;
|
||||
|
||||
while (!DSPCheckMailFromDSP())
|
||||
;
|
||||
|
||||
mail = DSPReadMailFromDSP();
|
||||
|
||||
DSPSendMailToDSP(MSG_BASE | 0xA001);
|
||||
while (DSPCheckMailToDSP()) { }
|
||||
DSPSendMailToDSP((u32)(task->iram_mmem_addr));
|
||||
while (DSPCheckMailToDSP()) { }
|
||||
|
||||
DSPSendMailToDSP(MSG_BASE | 0xC002);
|
||||
while (DSPCheckMailToDSP()) { }
|
||||
DSPSendMailToDSP((u32)(task->iram_addr & 0xffff));
|
||||
while (DSPCheckMailToDSP()) { }
|
||||
|
||||
DSPSendMailToDSP(MSG_BASE | 0xA002);
|
||||
while (DSPCheckMailToDSP()) { }
|
||||
DSPSendMailToDSP(task->iram_length);
|
||||
while (DSPCheckMailToDSP()) { }
|
||||
|
||||
DSPSendMailToDSP(MSG_BASE | 0xB002);
|
||||
while (DSPCheckMailToDSP()) { }
|
||||
DSPSendMailToDSP(0x00000000);
|
||||
while (DSPCheckMailToDSP()) { }
|
||||
|
||||
DSPSendMailToDSP(MSG_BASE | 0xD001);
|
||||
while (DSPCheckMailToDSP()) { }
|
||||
DSPSendMailToDSP((u32)(0xffff & task->dsp_init_vector));
|
||||
while (DSPCheckMailToDSP()) { }
|
||||
|
||||
__DSP_debug_printf("DSP is booting task: 0x%08X\n", task);
|
||||
__DSP_debug_printf("__DSP_boot_task() : IRAM MMEM ADDR: 0x%08X\n", (u32)(task->iram_mmem_addr));
|
||||
__DSP_debug_printf("__DSP_boot_task() : IRAM DSP ADDR : 0x%08X\n", (u32)(task->iram_addr));
|
||||
__DSP_debug_printf("__DSP_boot_task() : IRAM LENGTH : 0x%08X\n", (u32)(task->iram_length));
|
||||
__DSP_debug_printf("__DSP_boot_task() : DRAM MMEM ADDR: 0x%08X\n", (u32)(task->dram_length));
|
||||
__DSP_debug_printf("__DSP_boot_task() : Start Vector : 0x%08X\n", (u32)(task->dsp_init_vector));
|
||||
}
|
||||
|
||||
void __DSP_insert_task(DSPTaskInfo *task)
|
||||
{
|
||||
|
||||
DSPTaskInfo *temp;
|
||||
|
||||
if (__DSP_first_task == NULL) {
|
||||
__DSP_first_task = __DSP_last_task = __DSP_curr_task = task;
|
||||
task->next = task->prev = NULL;
|
||||
}
|
||||
else {
|
||||
temp = __DSP_first_task;
|
||||
|
||||
while (temp) {
|
||||
if (task->priority < temp->priority) {
|
||||
task->prev = temp->prev;
|
||||
temp->prev = task;
|
||||
task->next = temp;
|
||||
if (task->prev == NULL) {
|
||||
__DSP_first_task = task;
|
||||
}
|
||||
else {
|
||||
(task->prev)->next = task;
|
||||
}
|
||||
break;
|
||||
}
|
||||
temp = temp->next;
|
||||
}
|
||||
|
||||
if (temp == NULL) {
|
||||
__DSP_last_task->next = task;
|
||||
task->next = NULL;
|
||||
task->prev = __DSP_last_task;
|
||||
__DSP_last_task = task;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void __DSP_add_task(DSPTaskInfo *task)
|
||||
{
|
||||
if (__DSP_last_task == NULL) {
|
||||
__DSP_first_task = __DSP_last_task = __DSP_curr_task = task;
|
||||
task->next = task->prev = NULL;
|
||||
}
|
||||
else {
|
||||
__DSP_last_task->next = task;
|
||||
task->next = NULL;
|
||||
task->prev = __DSP_last_task;
|
||||
__DSP_last_task = task;
|
||||
}
|
||||
|
||||
task->state = DSP_TASK_STATE_INIT;
|
||||
|
||||
__DSP_debug_printf("__DSP_add_task() : Added task : 0x%08X\n", task);
|
||||
}
|
||||
|
||||
void __DSP_remove_task(DSPTaskInfo *task)
|
||||
{
|
||||
|
||||
task->flags = DSP_TASK_FLAG_CLEARALL;
|
||||
task->state = DSP_TASK_STATE_DONE;
|
||||
|
||||
if (__DSP_first_task == task) {
|
||||
if (task->next) {
|
||||
__DSP_first_task = (task->next);
|
||||
task->next->prev = NULL;
|
||||
}
|
||||
else {
|
||||
__DSP_first_task = __DSP_last_task = __DSP_curr_task = NULL;
|
||||
}
|
||||
}
|
||||
else if (__DSP_last_task == task) {
|
||||
__DSP_last_task = (task->prev);
|
||||
task->prev->next = NULL;
|
||||
__DSP_curr_task = __DSP_first_task;
|
||||
}
|
||||
else {
|
||||
__DSP_curr_task = task->next;
|
||||
task->prev->next = task->next;
|
||||
task->next->prev = task->prev;
|
||||
}
|
||||
}
|
||||
1431
src/dolphin/dvd/dvd.c
Normal file
1431
src/dolphin/dvd/dvd.c
Normal file
File diff suppressed because it is too large
Load diff
56
src/dolphin/dvd/dvderror.c
Normal file
56
src/dolphin/dvd/dvderror.c
Normal file
|
|
@ -0,0 +1,56 @@
|
|||
#include "dolphin/DVDPriv.h"
|
||||
#include "dolphin/OSRtcPriv.h"
|
||||
|
||||
static u32 ErrorTable[] = {
|
||||
0, 0x00023A00, 0x00062800, 0x00030200, 0x00031100, 0x00052000,
|
||||
0x00052001, 0x00052100, 0x00052400, 0x00052401, 0x00052402, 0x000B5A01,
|
||||
0x00056300, 0x00020401, 0x00020400, 0x00040800, 0x00100007, 0,
|
||||
};
|
||||
|
||||
static u8 ErrorCode2Num(u32 errorCode) {
|
||||
u32 i;
|
||||
|
||||
for (i = 0; i < sizeof(ErrorTable) / sizeof(ErrorTable[0]); i++) {
|
||||
if (ErrorTable[i] == errorCode) {
|
||||
return (u8)i;
|
||||
}
|
||||
}
|
||||
|
||||
if ((errorCode >= 0x00100000) && (errorCode <= 0x00100008)) {
|
||||
return 17;
|
||||
}
|
||||
|
||||
return 29;
|
||||
}
|
||||
|
||||
static u8 Convert(u32 error) {
|
||||
u32 statusCode;
|
||||
u32 errorCode;
|
||||
u8 errorNum;
|
||||
|
||||
if (error == 0x01234567)
|
||||
return 255;
|
||||
|
||||
if (error == 0x01234568)
|
||||
return 254;
|
||||
|
||||
statusCode = (error & 0xff000000) >> 24;
|
||||
errorCode = error & 0x00ffffff;
|
||||
|
||||
errorNum = ErrorCode2Num(errorCode);
|
||||
if (statusCode >= 6)
|
||||
statusCode = 6;
|
||||
|
||||
return (u8)(statusCode * 30 + errorNum);
|
||||
}
|
||||
|
||||
void __DVDStoreErrorCode(u32 error) {
|
||||
OSSramEx* sram;
|
||||
u8 num;
|
||||
|
||||
num = Convert(error);
|
||||
|
||||
sram = __OSLockSramEx();
|
||||
sram->dvdErrorCode = num;
|
||||
__OSUnlockSramEx(TRUE);
|
||||
}
|
||||
356
src/dolphin/dvd/dvdfs.c
Normal file
356
src/dolphin/dvd/dvdfs.c
Normal file
|
|
@ -0,0 +1,356 @@
|
|||
|
||||
#include "dolphin/DVDPriv.h"
|
||||
#include "dolphin/os.h"
|
||||
#include "dolphin/os/OSBootInfo.h"
|
||||
|
||||
typedef struct FSTEntry FSTEntry;
|
||||
|
||||
struct FSTEntry {
|
||||
unsigned int isDirAndStringOff;
|
||||
unsigned int parentOrPosition;
|
||||
unsigned int nextEntryOrLength;
|
||||
};
|
||||
|
||||
static OSBootInfo* BootInfo;
|
||||
static FSTEntry* FstStart;
|
||||
static char* FstStringStart;
|
||||
static u32 MaxEntryNum;
|
||||
static u32 currentDirectory = 0;
|
||||
OSThreadQueue __DVDThreadQueue;
|
||||
u32 __DVDLongFileNameFlag = 0;
|
||||
|
||||
static void cbForReadAsync(s32 result, DVDCommandBlock* block);
|
||||
static void cbForReadSync(s32 result, DVDCommandBlock* block);
|
||||
static void cbForSeekAsync(s32 result, DVDCommandBlock* block);
|
||||
static void cbForSeekSync(s32 result, DVDCommandBlock* block);
|
||||
static void cbForPrepareStreamAsync(s32 result, DVDCommandBlock* block);
|
||||
static void cbForPrepareStreamSync(s32 result, DVDCommandBlock* block);
|
||||
|
||||
void __DVDFSInit() {
|
||||
BootInfo = (OSBootInfo*)OSPhysicalToCached(0);
|
||||
FstStart = (FSTEntry*)BootInfo->FSTLocation;
|
||||
|
||||
if (FstStart) {
|
||||
MaxEntryNum = FstStart[0].nextEntryOrLength;
|
||||
FstStringStart = (char*)&(FstStart[MaxEntryNum]);
|
||||
}
|
||||
}
|
||||
|
||||
/* For convenience */
|
||||
#define entryIsDir(i) (((FstStart[i].isDirAndStringOff & 0xff000000) == 0) ? FALSE : TRUE)
|
||||
#define stringOff(i) (FstStart[i].isDirAndStringOff & ~0xff000000)
|
||||
#define parentDir(i) (FstStart[i].parentOrPosition)
|
||||
#define nextDir(i) (FstStart[i].nextEntryOrLength)
|
||||
#define filePosition(i) (FstStart[i].parentOrPosition)
|
||||
#define fileLength(i) (FstStart[i].nextEntryOrLength)
|
||||
|
||||
static BOOL isSame(const char* path, const char* string) {
|
||||
while (*string != '\0') {
|
||||
if (tolower(*path++) != tolower(*string++)) {
|
||||
return FALSE;
|
||||
}
|
||||
}
|
||||
|
||||
if ((*path == '/') || (*path == '\0')) {
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
s32 DVDConvertPathToEntrynum(char* pathPtr) {
|
||||
const char* ptr;
|
||||
char* stringPtr;
|
||||
BOOL isDir;
|
||||
u32 length;
|
||||
u32 dirLookAt;
|
||||
u32 i;
|
||||
const char* origPathPtr = pathPtr;
|
||||
const char* extentionStart;
|
||||
BOOL illegal;
|
||||
BOOL extention;
|
||||
|
||||
dirLookAt = currentDirectory;
|
||||
|
||||
while (1) {
|
||||
|
||||
if (*pathPtr == '\0') {
|
||||
return (s32)dirLookAt;
|
||||
} else if (*pathPtr == '/') {
|
||||
dirLookAt = 0;
|
||||
pathPtr++;
|
||||
continue;
|
||||
} else if (*pathPtr == '.') {
|
||||
if (*(pathPtr + 1) == '.') {
|
||||
if (*(pathPtr + 2) == '/') {
|
||||
dirLookAt = parentDir(dirLookAt);
|
||||
pathPtr += 3;
|
||||
continue;
|
||||
} else if (*(pathPtr + 2) == '\0') {
|
||||
return (s32)parentDir(dirLookAt);
|
||||
}
|
||||
} else if (*(pathPtr + 1) == '/') {
|
||||
pathPtr += 2;
|
||||
continue;
|
||||
} else if (*(pathPtr + 1) == '\0') {
|
||||
return (s32)dirLookAt;
|
||||
}
|
||||
}
|
||||
|
||||
if (__DVDLongFileNameFlag == 0) {
|
||||
extention = FALSE;
|
||||
illegal = FALSE;
|
||||
|
||||
for (ptr = pathPtr; (*ptr != '\0') && (*ptr != '/'); ptr++) {
|
||||
if (*ptr == '.') {
|
||||
if ((ptr - pathPtr > 8) || (extention == TRUE)) {
|
||||
illegal = TRUE;
|
||||
break;
|
||||
}
|
||||
extention = TRUE;
|
||||
extentionStart = ptr + 1;
|
||||
|
||||
} else if (*ptr == ' ')
|
||||
illegal = TRUE;
|
||||
}
|
||||
|
||||
if ((extention == TRUE) && (ptr - extentionStart > 3))
|
||||
illegal = TRUE;
|
||||
|
||||
if (illegal)
|
||||
OSPanic(__FILE__, 376,
|
||||
"DVDConvertEntrynumToPath(possibly DVDOpen or DVDChangeDir or DVDOpenDir): "
|
||||
"specified directory or file (%s) doesn't match standard 8.3 format. This is a "
|
||||
"temporary restriction and will be removed soon\n",
|
||||
origPathPtr);
|
||||
} else {
|
||||
for (ptr = pathPtr; (*ptr != '\0') && (*ptr != '/'); ptr++)
|
||||
;
|
||||
}
|
||||
|
||||
isDir = (*ptr == '\0') ? FALSE : TRUE;
|
||||
length = (u32)(ptr - pathPtr);
|
||||
|
||||
ptr = pathPtr;
|
||||
|
||||
for (i = dirLookAt + 1; i < nextDir(dirLookAt); i = entryIsDir(i) ? nextDir(i) : (i + 1)) {
|
||||
if ((entryIsDir(i) == FALSE) && (isDir == TRUE)) {
|
||||
continue;
|
||||
}
|
||||
|
||||
stringPtr = FstStringStart + stringOff(i);
|
||||
|
||||
if (isSame(ptr, stringPtr) == TRUE) {
|
||||
goto next_hier;
|
||||
}
|
||||
}
|
||||
|
||||
return -1;
|
||||
|
||||
next_hier:
|
||||
if (!isDir) {
|
||||
return (s32)i;
|
||||
}
|
||||
|
||||
dirLookAt = i;
|
||||
pathPtr += length + 1;
|
||||
}
|
||||
}
|
||||
|
||||
BOOL DVDFastOpen(s32 entrynum, DVDFileInfo* fileInfo) {
|
||||
if ((entrynum < 0) || (entrynum >= MaxEntryNum) || entryIsDir(entrynum)) {
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
fileInfo->startAddr = filePosition(entrynum);
|
||||
fileInfo->length = fileLength(entrynum);
|
||||
fileInfo->callback = (DVDCallback)NULL;
|
||||
fileInfo->cb.state = DVD_STATE_END;
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
BOOL DVDOpen(char* fileName, DVDFileInfo* fileInfo) {
|
||||
s32 entry;
|
||||
char currentDir[128];
|
||||
|
||||
entry = DVDConvertPathToEntrynum(fileName);
|
||||
|
||||
if (0 > entry) {
|
||||
DVDGetCurrentDir(currentDir, 128);
|
||||
OSReport("Warning: DVDOpen(): file '%s' was not found under %s.\n", fileName, currentDir);
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
if (entryIsDir(entry)) {
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
fileInfo->startAddr = filePosition(entry);
|
||||
fileInfo->length = fileLength(entry);
|
||||
fileInfo->callback = (DVDCallback)NULL;
|
||||
fileInfo->cb.state = DVD_STATE_END;
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
BOOL DVDClose(DVDFileInfo* fileInfo) {
|
||||
DVDCancel(&(fileInfo->cb));
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
static u32 myStrncpy(char* dest, char* src, u32 maxlen) {
|
||||
u32 i = maxlen;
|
||||
|
||||
while ((i > 0) && (*src != 0)) {
|
||||
*dest++ = *src++;
|
||||
i--;
|
||||
}
|
||||
|
||||
return (maxlen - i);
|
||||
}
|
||||
|
||||
static u32 entryToPath(u32 entry, char* path, u32 maxlen) {
|
||||
char* name;
|
||||
u32 loc;
|
||||
|
||||
if (entry == 0) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
name = FstStringStart + stringOff(entry);
|
||||
|
||||
loc = entryToPath(parentDir(entry), path, maxlen);
|
||||
|
||||
if (loc == maxlen) {
|
||||
return loc;
|
||||
}
|
||||
|
||||
*(path + loc++) = '/';
|
||||
|
||||
loc += myStrncpy(path + loc, name, maxlen - loc);
|
||||
|
||||
return loc;
|
||||
}
|
||||
|
||||
static BOOL DVDConvertEntrynumToPath(s32 entrynum, char* path, u32 maxlen) {
|
||||
u32 loc;
|
||||
|
||||
loc = entryToPath((u32)entrynum, path, maxlen);
|
||||
|
||||
if (loc == maxlen) {
|
||||
path[maxlen - 1] = '\0';
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
if (entryIsDir(entrynum)) {
|
||||
if (loc == maxlen - 1) {
|
||||
path[loc] = '\0';
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
path[loc++] = '/';
|
||||
}
|
||||
|
||||
path[loc] = '\0';
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
BOOL DVDGetCurrentDir(char* path, u32 maxlen) {
|
||||
return DVDConvertEntrynumToPath((s32)currentDirectory, path, maxlen);
|
||||
}
|
||||
|
||||
BOOL DVDChangeDir(char* dirName) {
|
||||
s32 entry;
|
||||
entry = DVDConvertPathToEntrynum(dirName);
|
||||
if ((entry < 0) || (entryIsDir(entry) == FALSE)) {
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
currentDirectory = (u32)entry;
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
BOOL DVDReadAsyncPrio(DVDFileInfo* fileInfo, void* addr, s32 length, s32 offset,
|
||||
DVDCallback callback, s32 prio) {
|
||||
|
||||
if (!((0 <= offset) && (offset < fileInfo->length))) {
|
||||
OSPanic(__FILE__, 739, "DVDReadAsync(): specified area is out of the file ");
|
||||
}
|
||||
|
||||
if (!((0 <= offset + length) && (offset + length < fileInfo->length + DVD_MIN_TRANSFER_SIZE))) {
|
||||
OSPanic(__FILE__, 745, "DVDReadAsync(): specified area is out of the file ");
|
||||
}
|
||||
|
||||
fileInfo->callback = callback;
|
||||
DVDReadAbsAsyncPrio(&(fileInfo->cb), addr, length, (s32)(fileInfo->startAddr + offset),
|
||||
cbForReadAsync, prio);
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
#ifndef offsetof
|
||||
#define offsetof(type, memb) ((u32) & ((type*)0)->memb)
|
||||
#endif
|
||||
|
||||
static void cbForReadAsync(s32 result, DVDCommandBlock* block) {
|
||||
DVDFileInfo* fileInfo;
|
||||
|
||||
fileInfo = (DVDFileInfo*)((char*)block - offsetof(DVDFileInfo, cb));
|
||||
if (fileInfo->callback) {
|
||||
(fileInfo->callback)(result, fileInfo);
|
||||
}
|
||||
}
|
||||
|
||||
/* This is based on the revolution SDK, these may not match in all cases I have also left the line numbers at 0 */
|
||||
BOOL DVDReadPrio(DVDFileInfo* fileInfo, void* addr, s32 length, s32 offset, s32 prio) {
|
||||
BOOL result;
|
||||
DVDCommandBlock* block;
|
||||
s32 state;
|
||||
BOOL enabled;
|
||||
s32 retVal;
|
||||
|
||||
if (!((0 <= offset) && (offset < fileInfo->length))) {
|
||||
OSPanic(__FILE__, 809, "DVDRead(): specified area is out of the file ");
|
||||
}
|
||||
|
||||
if (!((0 <= offset + length) && (offset + length < fileInfo->length + DVD_MIN_TRANSFER_SIZE))) {
|
||||
OSPanic(__FILE__, 815, "DVDRead(): specified area is out of the file ");
|
||||
}
|
||||
|
||||
block = &(fileInfo->cb);
|
||||
|
||||
result = DVDReadAbsAsyncPrio(block, addr, length, (s32)(fileInfo->startAddr + offset),
|
||||
cbForReadSync, prio);
|
||||
|
||||
if (result == FALSE) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
enabled = OSDisableInterrupts();
|
||||
|
||||
while(1) {
|
||||
state = ((volatile DVDCommandBlock*)block)->state;
|
||||
|
||||
if (state == DVD_STATE_END) {
|
||||
retVal = (s32)block->transferredSize;
|
||||
break;
|
||||
}
|
||||
if (state == DVD_STATE_FATAL_ERROR) {
|
||||
retVal = DVD_RESULT_FATAL_ERROR;
|
||||
break;
|
||||
}
|
||||
if (state == DVD_STATE_CANCELED) {
|
||||
retVal = DVD_RESULT_CANCELED;
|
||||
break;
|
||||
}
|
||||
|
||||
OSSleepThread(&__DVDThreadQueue);
|
||||
}
|
||||
|
||||
OSRestoreInterrupts(enabled);
|
||||
return retVal;
|
||||
}
|
||||
|
||||
/* This is based on the revolution SDK, these may not match in all cases */
|
||||
static void cbForReadSync(s32 result, DVDCommandBlock* block) { OSWakeupThread(&__DVDThreadQueue); }
|
||||
436
src/dolphin/dvd/dvdlow.c
Normal file
436
src/dolphin/dvd/dvdlow.c
Normal file
|
|
@ -0,0 +1,436 @@
|
|||
#include "dolphin/DVDPriv.h"
|
||||
#include "dolphin/os.h"
|
||||
|
||||
extern DVDDiskID* DVDGetCurrentDiskID();
|
||||
|
||||
extern OSTime __OSGetSystemTime();
|
||||
|
||||
static BOOL FirstRead = TRUE;
|
||||
static volatile BOOL StopAtNextInt = FALSE;
|
||||
static u32 LastLength = 0;
|
||||
static DVDLowCallback Callback = NULL;
|
||||
static DVDLowCallback ResetCoverCallback = NULL;
|
||||
static volatile OSTime LastResetEnd = 0;
|
||||
static volatile u32 ResetOccurred = FALSE;
|
||||
static volatile BOOL WaitingCoverClose = FALSE;
|
||||
static BOOL Breaking = FALSE;
|
||||
static volatile u32 WorkAroundType = 0;
|
||||
static u32 WorkAroundSeekLocation = 0;
|
||||
static volatile OSTime LastReadFinished = 0;
|
||||
static OSTime LastReadIssued = 0;
|
||||
static volatile BOOL LastCommandWasRead = FALSE;
|
||||
static vu32 NextCommandNumber = 0;
|
||||
|
||||
typedef struct DVDBuffer {
|
||||
void* addr;
|
||||
u32 length;
|
||||
u32 offset;
|
||||
} DVDBuffer;
|
||||
|
||||
typedef struct DVDCommand {
|
||||
s32 cmd;
|
||||
void* addr;
|
||||
u32 length;
|
||||
u32 offset;
|
||||
DVDLowCallback callback;
|
||||
} DVDCommand;
|
||||
|
||||
static DVDCommand CommandList[3];
|
||||
static OSAlarm AlarmForWA;
|
||||
static OSAlarm AlarmForTimeout;
|
||||
static OSAlarm AlarmForBreak;
|
||||
static DVDBuffer Prev;
|
||||
static DVDBuffer Curr;
|
||||
|
||||
void __DVDInitWA() {
|
||||
NextCommandNumber = 0;
|
||||
CommandList[0].cmd = -1;
|
||||
__DVDLowSetWAType(0, 0);
|
||||
OSInitAlarm();
|
||||
}
|
||||
|
||||
static void Read(void* addr, u32 length, u32 offset, DVDLowCallback callback);
|
||||
|
||||
static BOOL ProcessNextCommand() {
|
||||
s32 n = NextCommandNumber;
|
||||
ASSERT(n < 3);
|
||||
|
||||
if (CommandList[n].cmd == 1) {
|
||||
++NextCommandNumber;
|
||||
Read(CommandList[n].addr, CommandList[n].length, CommandList[n].offset,
|
||||
CommandList[n].callback);
|
||||
return TRUE;
|
||||
} else if (CommandList[n].cmd == 2) {
|
||||
++NextCommandNumber;
|
||||
DVDLowSeek(CommandList[n].offset, CommandList[n].callback);
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
void __DVDInterruptHandler(__OSInterrupt interrupt, OSContext* context) {
|
||||
DVDLowCallback cb;
|
||||
OSContext exceptionContext;
|
||||
u32 cause = 0;
|
||||
u32 reg;
|
||||
u32 intr;
|
||||
u32 mask;
|
||||
|
||||
OSCancelAlarm(&AlarmForTimeout);
|
||||
|
||||
if (LastCommandWasRead) {
|
||||
LastReadFinished = __OSGetSystemTime();
|
||||
FirstRead = FALSE;
|
||||
Prev.addr = Curr.addr;
|
||||
Prev.length = Curr.length;
|
||||
Prev.offset = Curr.offset;
|
||||
if (StopAtNextInt == TRUE) {
|
||||
cause |= 8;
|
||||
}
|
||||
}
|
||||
|
||||
LastCommandWasRead = FALSE;
|
||||
StopAtNextInt = FALSE;
|
||||
reg = __DIRegs[0];
|
||||
mask = reg & 0x2a;
|
||||
intr = (reg & 0x54) & (mask << 1);
|
||||
|
||||
if (intr & 0x40) {
|
||||
cause |= 8;
|
||||
}
|
||||
|
||||
if (intr & 0x10) {
|
||||
cause |= 1;
|
||||
}
|
||||
|
||||
if (intr & 4) {
|
||||
cause |= 2;
|
||||
}
|
||||
|
||||
if (cause) {
|
||||
ResetOccurred = FALSE;
|
||||
|
||||
}
|
||||
|
||||
__DIRegs[0] = intr | mask;
|
||||
|
||||
if (ResetOccurred && (__OSGetSystemTime() - LastResetEnd) < OSMillisecondsToTicks(200)) {
|
||||
reg = __DIRegs[1];
|
||||
mask = reg & 0x2;
|
||||
intr = (reg & 4) & (mask << 1);
|
||||
if (intr & 4) {
|
||||
if (ResetCoverCallback) {
|
||||
ResetCoverCallback(4);
|
||||
}
|
||||
ResetCoverCallback = NULL;
|
||||
}
|
||||
|
||||
__DIRegs[1] = __DIRegs[1];
|
||||
} else if (WaitingCoverClose) {
|
||||
reg = __DIRegs[1];
|
||||
mask = reg & 2;
|
||||
intr = (reg & 4) & (mask << 1);
|
||||
|
||||
if (intr & 4) {
|
||||
cause |= 4;
|
||||
}
|
||||
|
||||
__DIRegs[1] = intr | mask;
|
||||
WaitingCoverClose = FALSE;
|
||||
} else {
|
||||
__DIRegs[1] = 0;
|
||||
}
|
||||
|
||||
if ((cause & 8) && !Breaking) {
|
||||
cause &= ~8;
|
||||
}
|
||||
|
||||
if ((cause & 1)) {
|
||||
if (ProcessNextCommand()) {
|
||||
return;
|
||||
}
|
||||
} else {
|
||||
CommandList[0].cmd = -1;
|
||||
NextCommandNumber = 0;
|
||||
}
|
||||
|
||||
OSClearContext(&exceptionContext);
|
||||
OSSetCurrentContext(&exceptionContext);
|
||||
|
||||
if (cause) {
|
||||
cb = Callback;
|
||||
Callback = NULL;
|
||||
if (cb) {
|
||||
cb(cause);
|
||||
}
|
||||
|
||||
Breaking = FALSE;
|
||||
}
|
||||
|
||||
OSClearContext(&exceptionContext);
|
||||
OSSetCurrentContext(context);
|
||||
}
|
||||
|
||||
static void AlarmHandler(OSAlarm* alarm, OSContext* context) {
|
||||
BOOL error = ProcessNextCommand();
|
||||
ASSERTMSG(error != FALSE, "Failed assertion processed");
|
||||
}
|
||||
|
||||
static void AlarmHandlerForTimeout(OSAlarm* alarm, OSContext* context) {
|
||||
OSContext tmpContext;
|
||||
DVDLowCallback callback;
|
||||
__OSMaskInterrupts(0x400);
|
||||
OSClearContext(&tmpContext);
|
||||
OSSetCurrentContext(&tmpContext);
|
||||
callback = Callback;
|
||||
Callback = NULL;
|
||||
if (callback != NULL) {
|
||||
callback(0x10);
|
||||
}
|
||||
OSClearContext(&tmpContext);
|
||||
OSSetCurrentContext(context);
|
||||
}
|
||||
|
||||
static void SetTimeoutAlarm(OSTime timeout) {
|
||||
OSCreateAlarm(&AlarmForTimeout);
|
||||
OSSetAlarm(&AlarmForTimeout, timeout, AlarmHandlerForTimeout);
|
||||
}
|
||||
|
||||
static void Read(void* addr, u32 length, u32 offset, DVDLowCallback callback) {
|
||||
StopAtNextInt = FALSE;
|
||||
LastCommandWasRead = TRUE;
|
||||
Callback = callback;
|
||||
LastReadIssued = __OSGetSystemTime();
|
||||
|
||||
__DIRegs[2] = 0xa8000000;
|
||||
__DIRegs[3] = offset / 4;
|
||||
__DIRegs[4] = length;
|
||||
__DIRegs[5] = (u32)addr;
|
||||
__DIRegs[6] = length;
|
||||
LastLength = length;
|
||||
__DIRegs[7] = 3;
|
||||
|
||||
if (length > 0xa00000) {
|
||||
SetTimeoutAlarm(OSSecondsToTicks(20));
|
||||
} else {
|
||||
SetTimeoutAlarm(OSSecondsToTicks(10));
|
||||
}
|
||||
}
|
||||
|
||||
BOOL HitCache(DVDBuffer* cur, DVDBuffer* prev) {
|
||||
u32 uVar1 = (prev->offset + prev->length - 1) >> 15;
|
||||
u32 uVar2 = (cur->offset >> 15);
|
||||
u32 iVar3 = (DVDGetCurrentDiskID()->streaming ? TRUE : FALSE) ? 5 : 15;
|
||||
|
||||
if ((uVar2 > uVar1 - 2) || (uVar2 < uVar1 + iVar3 + 3)) {
|
||||
return TRUE;
|
||||
}
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
static void DoJustRead(void* addr, u32 length, u32 offset, DVDLowCallback callback) {
|
||||
CommandList[0].cmd = -1;
|
||||
NextCommandNumber = 0;
|
||||
Read(addr, length, offset, callback);
|
||||
}
|
||||
|
||||
static void SeekTwiceBeforeRead(void* addr, u32 length, u32 offset, DVDLowCallback callback) {
|
||||
u32 newOffset = offset & ~0x7FFF;
|
||||
if (!newOffset) {
|
||||
newOffset = 0;
|
||||
} else {
|
||||
newOffset += WorkAroundSeekLocation;
|
||||
}
|
||||
CommandList[0].cmd = 2;
|
||||
CommandList[0].offset = newOffset;
|
||||
CommandList[0].callback = callback;
|
||||
CommandList[1].cmd = 1;
|
||||
CommandList[1].addr = addr;
|
||||
CommandList[1].length = length;
|
||||
CommandList[1].offset = offset;
|
||||
CommandList[1].callback = callback;
|
||||
CommandList[2].cmd = -1;
|
||||
NextCommandNumber = 0;
|
||||
DVDLowSeek(newOffset, callback);
|
||||
}
|
||||
|
||||
static void WaitBeforeRead(void* addr, u32 length, u32 offset, DVDLowCallback callback,
|
||||
OSTime timeout) {
|
||||
CommandList[0].cmd = 1;
|
||||
CommandList[0].addr = addr;
|
||||
CommandList[0].length = length;
|
||||
CommandList[0].offset = offset;
|
||||
CommandList[0].callback = callback;
|
||||
CommandList[1].cmd = -1;
|
||||
NextCommandNumber = 0;
|
||||
OSCreateAlarm(&AlarmForWA);
|
||||
OSSetAlarm(&AlarmForWA, timeout, AlarmHandler);
|
||||
}
|
||||
|
||||
|
||||
BOOL DVDLowRead(void* addr, u32 length, u32 offset, DVDLowCallback callback) {
|
||||
OSTime diff;
|
||||
u32 prev;
|
||||
|
||||
__DIRegs[6] = length;
|
||||
Curr.addr = addr;
|
||||
Curr.length = length;
|
||||
Curr.offset = offset;
|
||||
|
||||
if (WorkAroundType == 0) {
|
||||
DoJustRead(addr, length, offset, callback);
|
||||
} else if (WorkAroundType == 1) {
|
||||
if (FirstRead) {
|
||||
SeekTwiceBeforeRead(addr, length, offset, callback);
|
||||
} else {
|
||||
if (!HitCache(&Curr, &Prev)) {
|
||||
DoJustRead(addr, length, offset, callback);
|
||||
} else {
|
||||
prev = (Prev.offset + Prev.length - 1) >> 15;
|
||||
if (prev == Curr.offset >> 15 || prev + 1 == Curr.offset >> 15) {
|
||||
diff = __OSGetSystemTime() - LastReadFinished;
|
||||
if (OSMillisecondsToTicks(5) < diff) {
|
||||
DoJustRead(addr, length, offset, callback);
|
||||
} else {
|
||||
WaitBeforeRead(addr, length, offset, callback,
|
||||
OSMillisecondsToTicks(5) - diff + OSMicrosecondsToTicks(500));
|
||||
}
|
||||
} else {
|
||||
SeekTwiceBeforeRead(addr, length, offset, callback);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
BOOL DVDLowSeek(u32 offset, DVDLowCallback callback) {
|
||||
ASSERTMSG(offset & 3, "DVDLowSeek(): offset must be a multiple of 4.");
|
||||
StopAtNextInt = FALSE;
|
||||
Callback = callback;
|
||||
__DIRegs[2] = 0xab000000;
|
||||
__DIRegs[3] = offset / 4;
|
||||
__DIRegs[7] = 1;
|
||||
SetTimeoutAlarm(OSSecondsToTicks(10));
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
BOOL DVDLowWaitCoverClose(DVDLowCallback callback) {
|
||||
Callback = callback;
|
||||
WaitingCoverClose = TRUE;
|
||||
StopAtNextInt = FALSE;
|
||||
__DIRegs[1] = 2;
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
BOOL DVDLowReadDiskID(DVDDiskID* diskID, DVDLowCallback callback) {
|
||||
StopAtNextInt = FALSE;
|
||||
Callback = callback;
|
||||
__DIRegs[2] = 0xa8000040;
|
||||
__DIRegs[3] = 0;
|
||||
__DIRegs[4] = sizeof(DVDDiskID);
|
||||
__DIRegs[5] = (u32)diskID;
|
||||
__DIRegs[6] = sizeof(DVDDiskID);
|
||||
__DIRegs[7] = 3;
|
||||
SetTimeoutAlarm(OSSecondsToTicks(10));
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
BOOL DVDLowStopMotor(DVDLowCallback callback) {
|
||||
StopAtNextInt = FALSE;
|
||||
Callback = callback;
|
||||
__DIRegs[2] = 0xe3000000;
|
||||
__DIRegs[7] = 1;
|
||||
SetTimeoutAlarm(OSSecondsToTicks(10));
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
BOOL DVDLowRequestError(DVDLowCallback callback) {
|
||||
StopAtNextInt = FALSE;
|
||||
Callback = callback;
|
||||
__DIRegs[2] = 0xe0000000;
|
||||
__DIRegs[7] = 1;
|
||||
SetTimeoutAlarm(OSSecondsToTicks(10));
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
BOOL DVDLowInquiry(DVDDriveInfo* info, DVDLowCallback callback) {
|
||||
StopAtNextInt = FALSE;
|
||||
Callback = callback;
|
||||
__DIRegs[2] = 0x12000000;
|
||||
__DIRegs[4] = sizeof(DVDDriveInfo);
|
||||
__DIRegs[5] = (u32)info;
|
||||
__DIRegs[6] = sizeof(DVDDriveInfo);
|
||||
__DIRegs[7] = 3;
|
||||
SetTimeoutAlarm(OSSecondsToTicks(10));
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
BOOL DVDLowAudioStream(u32 subcmd, u32 length, u32 offset, DVDLowCallback callback) {
|
||||
StopAtNextInt = FALSE;
|
||||
Callback = callback;
|
||||
__DIRegs[2] = subcmd | 0xe1000000;
|
||||
__DIRegs[3] = offset >> 2;
|
||||
__DIRegs[4] = length;
|
||||
__DIRegs[7] = 1;
|
||||
SetTimeoutAlarm(OSSecondsToTicks(10));
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
BOOL DVDLowRequestAudioStatus(u32 subcmd, DVDLowCallback callback) {
|
||||
StopAtNextInt = FALSE;
|
||||
Callback = callback;
|
||||
__DIRegs[2] = subcmd | 0xe2000000;
|
||||
__DIRegs[7] = 1;
|
||||
SetTimeoutAlarm(OSSecondsToTicks(10));
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
BOOL DVDLowAudioBufferConfig(BOOL enable, u32 size, DVDLowCallback callback) {
|
||||
StopAtNextInt = FALSE;
|
||||
Callback = callback;
|
||||
__DIRegs[2] = 0xe4000000 | (enable != 0 ? 0x10000 : 0) | size;
|
||||
__DIRegs[7] = 1;
|
||||
SetTimeoutAlarm(OSSecondsToTicks(10));
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
void DVDLowReset() {
|
||||
u32 reg;
|
||||
OSTime resetStart;
|
||||
|
||||
__DIRegs[1] = 2;
|
||||
reg = __PIRegs[9];
|
||||
__PIRegs[9] = (reg & ~4) | 1;
|
||||
|
||||
resetStart = __OSGetSystemTime();
|
||||
while ((__OSGetSystemTime() - resetStart) < OSMicrosecondsToTicks(12))
|
||||
;
|
||||
|
||||
__PIRegs[9] = reg | 5;
|
||||
ResetOccurred = TRUE;
|
||||
LastResetEnd = __OSGetSystemTime();
|
||||
}
|
||||
|
||||
BOOL DVDLowBreak() {
|
||||
StopAtNextInt = TRUE;
|
||||
Breaking = TRUE;
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
DVDLowCallback DVDLowClearCallback() {
|
||||
DVDLowCallback old;
|
||||
__DIRegs[1] = 0;
|
||||
old = Callback;
|
||||
Callback = NULL;
|
||||
return old;
|
||||
}
|
||||
|
||||
void __DVDLowSetWAType(u32 type, u32 location) {
|
||||
BOOL enabled;
|
||||
enabled = OSDisableInterrupts();
|
||||
WorkAroundType = type;
|
||||
WorkAroundSeekLocation = location;
|
||||
OSRestoreInterrupts(enabled);
|
||||
}
|
||||
142
src/dolphin/dvd/dvdqueue.c
Normal file
142
src/dolphin/dvd/dvdqueue.c
Normal file
|
|
@ -0,0 +1,142 @@
|
|||
#include "dolphin/DVDPriv.h"
|
||||
|
||||
#define MAX_QUEUES 4
|
||||
typedef struct {
|
||||
DVDCommandBlock* next;
|
||||
DVDCommandBlock* prev;
|
||||
} DVDQueue;
|
||||
|
||||
static DVDQueue WaitingQueue[MAX_QUEUES];
|
||||
|
||||
void __DVDClearWaitingQueue(void) {
|
||||
u32 i;
|
||||
|
||||
for (i = 0; i < MAX_QUEUES; i++) {
|
||||
DVDCommandBlock* q;
|
||||
|
||||
q = (DVDCommandBlock*)&(WaitingQueue[i]);
|
||||
q->next = q;
|
||||
q->prev = q;
|
||||
}
|
||||
}
|
||||
|
||||
BOOL __DVDPushWaitingQueue(s32 prio, DVDCommandBlock* block) {
|
||||
BOOL enabled;
|
||||
DVDCommandBlock* q;
|
||||
|
||||
enabled = OSDisableInterrupts();
|
||||
|
||||
q = (DVDCommandBlock*)&(WaitingQueue[prio]);
|
||||
|
||||
q->prev->next = block;
|
||||
block->prev = q->prev;
|
||||
block->next = q;
|
||||
q->prev = block;
|
||||
|
||||
OSRestoreInterrupts(enabled);
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
static DVDCommandBlock* PopWaitingQueuePrio(s32 prio) {
|
||||
DVDCommandBlock* tmp;
|
||||
BOOL enabled;
|
||||
DVDCommandBlock* q;
|
||||
|
||||
enabled = OSDisableInterrupts();
|
||||
|
||||
q = (DVDCommandBlock*)&(WaitingQueue[prio]);
|
||||
|
||||
tmp = q->next;
|
||||
q->next = tmp->next;
|
||||
tmp->next->prev = q;
|
||||
|
||||
OSRestoreInterrupts(enabled);
|
||||
|
||||
tmp->next = (DVDCommandBlock*)NULL;
|
||||
tmp->prev = (DVDCommandBlock*)NULL;
|
||||
|
||||
return tmp;
|
||||
}
|
||||
|
||||
DVDCommandBlock* __DVDPopWaitingQueue(void) {
|
||||
u32 i;
|
||||
BOOL enabled;
|
||||
DVDCommandBlock* q;
|
||||
|
||||
enabled = OSDisableInterrupts();
|
||||
|
||||
for (i = 0; i < MAX_QUEUES; i++) {
|
||||
q = (DVDCommandBlock*)&(WaitingQueue[i]);
|
||||
if (q->next != q) {
|
||||
OSRestoreInterrupts(enabled);
|
||||
return PopWaitingQueuePrio((s32)i);
|
||||
}
|
||||
}
|
||||
|
||||
OSRestoreInterrupts(enabled);
|
||||
|
||||
return (DVDCommandBlock*)NULL;
|
||||
}
|
||||
|
||||
BOOL __DVDCheckWaitingQueue(void) {
|
||||
u32 i;
|
||||
BOOL enabled;
|
||||
DVDCommandBlock* q;
|
||||
|
||||
enabled = OSDisableInterrupts();
|
||||
|
||||
for (i = 0; i < MAX_QUEUES; i++) {
|
||||
q = (DVDCommandBlock*)&(WaitingQueue[i]);
|
||||
if (q->next != q) {
|
||||
OSRestoreInterrupts(enabled);
|
||||
return TRUE;
|
||||
}
|
||||
}
|
||||
|
||||
OSRestoreInterrupts(enabled);
|
||||
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
BOOL __DVDDequeueWaitingQueue(DVDCommandBlock* block) {
|
||||
BOOL enabled;
|
||||
DVDCommandBlock* prev;
|
||||
DVDCommandBlock* next;
|
||||
|
||||
enabled = OSDisableInterrupts();
|
||||
|
||||
prev = block->prev;
|
||||
next = block->next;
|
||||
|
||||
if ((prev == (DVDCommandBlock*)NULL) || (next == (DVDCommandBlock*)NULL)) {
|
||||
OSRestoreInterrupts(enabled);
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
prev->next = next;
|
||||
next->prev = prev;
|
||||
|
||||
OSRestoreInterrupts(enabled);
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
BOOL __DVDIsBlockInWaitingQueue(DVDCommandBlock* block) {
|
||||
u32 i;
|
||||
DVDCommandBlock* start;
|
||||
DVDCommandBlock* q;
|
||||
|
||||
for (i = 0; i < MAX_QUEUES; i++) {
|
||||
start = (DVDCommandBlock*)&(WaitingQueue[i]);
|
||||
|
||||
if (start->next != start) {
|
||||
for (q = start->next; q != start; q = q->next) {
|
||||
if (q == block)
|
||||
return TRUE;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return FALSE;
|
||||
}
|
||||
68
src/dolphin/dvd/fstload.c
Normal file
68
src/dolphin/dvd/fstload.c
Normal file
|
|
@ -0,0 +1,68 @@
|
|||
|
||||
#include <dolphin/DVDPriv.h>
|
||||
#include <dolphin/dvd.h>
|
||||
#include <dolphin/hw_regs.h>
|
||||
#include <dolphin/os.h>
|
||||
#include <dolphin/os/OSBootInfo.h>
|
||||
#include <string.h>
|
||||
|
||||
static s32 status = 0;
|
||||
|
||||
static u8 bb2Buf[OSRoundUp32B(sizeof(DVDBB2)) + 31];
|
||||
static DVDBB2* bb2 = 0;
|
||||
static DVDDiskID* idTmp = NULL;
|
||||
|
||||
static void cb(s32 result, DVDCommandBlock* block) {
|
||||
if (result > 0) {
|
||||
switch (status) {
|
||||
case 0:
|
||||
status = 1;
|
||||
DVDReadAbsAsyncForBS(block, bb2, OSRoundUp32B(sizeof(bb2)), 0x420, cb);
|
||||
break;
|
||||
case 1:
|
||||
status = 2;
|
||||
DVDReadAbsAsyncForBS(block, bb2->FSTAddress, OSRoundUp32B(bb2->FSTLength), bb2->FSTPosition,
|
||||
cb);
|
||||
}
|
||||
} else if (result == -1) {
|
||||
|
||||
} else if (result == -4) {
|
||||
status = 0;
|
||||
DVDReset();
|
||||
DVDReadDiskID(block, idTmp, cb);
|
||||
}
|
||||
}
|
||||
|
||||
void __fstLoad() {
|
||||
OSBootInfo* bootInfo;
|
||||
DVDDiskID* id;
|
||||
u8 idTmpBuf[sizeof(DVDDiskID) + 31];
|
||||
static DVDCommandBlock block;
|
||||
void* arenaHi;
|
||||
|
||||
arenaHi = OSGetArenaHi();
|
||||
bootInfo = (OSBootInfo*)OSPhysicalToCached(0);
|
||||
|
||||
idTmp = (DVDDiskID*)(OSRoundUp32B(idTmpBuf));
|
||||
bb2 = (DVDBB2*)(OSRoundUp32B(bb2Buf));
|
||||
|
||||
DVDReset();
|
||||
DVDReadDiskID(&block, idTmp, cb);
|
||||
while (DVDGetDriveStatus() != 0);
|
||||
|
||||
bootInfo->FSTLocation = bb2->FSTAddress;
|
||||
bootInfo->FSTMaxLength = bb2->FSTMaxLength;
|
||||
|
||||
id = &bootInfo->DVDDiskID;
|
||||
|
||||
memcpy(id, idTmp, sizeof(DVDDiskID));
|
||||
OSReport("\n");
|
||||
OSReport(" Game Name ... %c%c%c%c\n", id->gameName[0], id->gameName[1], id->gameName[2],
|
||||
id->gameName[3]);
|
||||
OSReport(" Company ..... %c%c\n", id->company[0], id->company[1]);
|
||||
OSReport(" Disk # ...... %d\n", id->diskNumber);
|
||||
OSReport(" Game ver .... %d\n", id->gameVersion);
|
||||
OSReport(" Streaming ... %s\n", (id->streaming == 0) ? "OFF" : "ON");
|
||||
OSReport("\n");
|
||||
OSSetArenaHi(bb2->FSTAddress);
|
||||
}
|
||||
686
src/dolphin/exi/EXIBios.c
Normal file
686
src/dolphin/exi/EXIBios.c
Normal file
|
|
@ -0,0 +1,686 @@
|
|||
#include <dolphin/exi.h>
|
||||
#include <dolphin/hw_regs.h>
|
||||
#include <dolphin/os.h>
|
||||
|
||||
#define MAX_DEV 3
|
||||
#define MAX_CHAN 3
|
||||
|
||||
#define REG_MAX 5
|
||||
#define REG(chan, idx) (__EXIRegs[((chan)*REG_MAX) + (idx)])
|
||||
|
||||
#define STATE_IDLE 0x00
|
||||
#define STATE_DMA 0x01
|
||||
#define STATE_IMM 0x02
|
||||
#define STATE_BUSY (STATE_DMA | STATE_IMM)
|
||||
#define STATE_SELECTED 0x04
|
||||
#define STATE_ATTACHED 0x08
|
||||
#define STATE_LOCKED 0x10
|
||||
|
||||
#define EXI_0CR(tstart, dma, rw, tlen) ((((u32)(tstart)) << 0) | (((u32)(dma)) << 1) | (((u32)(rw)) << 2) | (((u32)(tlen)) << 4))
|
||||
|
||||
#define CPR_CS(x) ((1u << (x)) << 7)
|
||||
#define CPR_CLK(x) ((x) << 4)
|
||||
|
||||
static BOOL __EXIProbe(s32 chan);
|
||||
|
||||
typedef struct EXIControl {
|
||||
EXICallback exiCallback;
|
||||
EXICallback tcCallback;
|
||||
EXICallback extCallback;
|
||||
vu32 state;
|
||||
int immLen;
|
||||
u8 *immBuf;
|
||||
u32 dev;
|
||||
u32 id;
|
||||
s32 idTime;
|
||||
int items;
|
||||
struct {
|
||||
u32 dev;
|
||||
EXICallback callback;
|
||||
} queue[MAX_DEV];
|
||||
} EXIControl;
|
||||
|
||||
static EXIControl Ecb[MAX_CHAN];
|
||||
|
||||
s32 __EXIProbeStartTime[2] : (OS_BASE_CACHED | 0x30C0);
|
||||
|
||||
static void SetExiInterruptMask(s32 chan, EXIControl *exi)
|
||||
{
|
||||
EXIControl *exi2;
|
||||
|
||||
exi2 = &Ecb[2];
|
||||
switch (chan) {
|
||||
case 0:
|
||||
if ((exi->exiCallback == 0 && exi2->exiCallback == 0) || (exi->state & STATE_LOCKED)) {
|
||||
__OSMaskInterrupts(OS_INTERRUPTMASK_EXI_0_EXI | OS_INTERRUPTMASK_EXI_2_EXI);
|
||||
}
|
||||
else {
|
||||
__OSUnmaskInterrupts(OS_INTERRUPTMASK_EXI_0_EXI | OS_INTERRUPTMASK_EXI_2_EXI);
|
||||
}
|
||||
break;
|
||||
case 1:
|
||||
if (exi->exiCallback == 0 || (exi->state & STATE_LOCKED)) {
|
||||
__OSMaskInterrupts(OS_INTERRUPTMASK_EXI_1_EXI);
|
||||
}
|
||||
else {
|
||||
__OSUnmaskInterrupts(OS_INTERRUPTMASK_EXI_1_EXI);
|
||||
}
|
||||
break;
|
||||
case 2:
|
||||
if (__OSGetInterruptHandler(__OS_INTERRUPT_PI_DEBUG) == 0 || (exi->state & STATE_LOCKED)) {
|
||||
__OSMaskInterrupts(OS_INTERRUPTMASK_PI_DEBUG);
|
||||
}
|
||||
else {
|
||||
__OSUnmaskInterrupts(OS_INTERRUPTMASK_PI_DEBUG);
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
static void CompleteTransfer(s32 chan)
|
||||
{
|
||||
EXIControl *exi = &Ecb[chan];
|
||||
u8 *buf;
|
||||
u32 data;
|
||||
int i;
|
||||
int len;
|
||||
|
||||
if (exi->state & STATE_BUSY) {
|
||||
if ((exi->state & STATE_IMM) && (len = exi->immLen)) {
|
||||
buf = exi->immBuf;
|
||||
data = REG(chan, 4);
|
||||
for (i = 0; i < len; i++) {
|
||||
*buf++ = (u8)((data >> ((3 - i) * 8)) & 0xff);
|
||||
}
|
||||
}
|
||||
exi->state &= ~STATE_BUSY;
|
||||
}
|
||||
}
|
||||
|
||||
BOOL EXIImm(s32 chan, void *buf, s32 len, u32 type, EXICallback callback)
|
||||
{
|
||||
EXIControl *exi = &Ecb[chan];
|
||||
BOOL enabled;
|
||||
|
||||
enabled = OSDisableInterrupts();
|
||||
if ((exi->state & STATE_BUSY) || !(exi->state & STATE_SELECTED)) {
|
||||
OSRestoreInterrupts(enabled);
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
exi->tcCallback = callback;
|
||||
if (exi->tcCallback) {
|
||||
EXIClearInterrupts(chan, FALSE, TRUE, FALSE);
|
||||
__OSUnmaskInterrupts(OS_INTERRUPTMASK_EXI_0_TC >> (3 * chan));
|
||||
}
|
||||
|
||||
exi->state |= STATE_IMM;
|
||||
|
||||
if (type != EXI_READ) {
|
||||
u32 data;
|
||||
int i;
|
||||
|
||||
data = 0;
|
||||
for (i = 0; i < len; i++) {
|
||||
data |= ((u8 *)buf)[i] << ((3 - i) * 8);
|
||||
}
|
||||
REG(chan, 4) = data;
|
||||
}
|
||||
|
||||
exi->immBuf = buf;
|
||||
exi->immLen = (type != EXI_WRITE) ? len : 0;
|
||||
|
||||
REG(chan, 3) = EXI_0CR(1, 0, type, len - 1);
|
||||
|
||||
OSRestoreInterrupts(enabled);
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
BOOL EXIImmEx(s32 chan, void *buf, s32 len, u32 mode)
|
||||
{
|
||||
s32 xLen;
|
||||
|
||||
while (len) {
|
||||
xLen = (len < 4) ? len : 4;
|
||||
if (!EXIImm(chan, buf, xLen, mode, NULL)) {
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
if (!EXISync(chan)) {
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
(u8 *)buf += xLen;
|
||||
len -= xLen;
|
||||
}
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
BOOL EXIDma(s32 chan, void *buf, s32 len, u32 type, EXICallback callback)
|
||||
{
|
||||
EXIControl *exi = &Ecb[chan];
|
||||
BOOL enabled;
|
||||
|
||||
enabled = OSDisableInterrupts();
|
||||
if ((exi->state & STATE_BUSY) || !(exi->state & STATE_SELECTED)) {
|
||||
OSRestoreInterrupts(enabled);
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
exi->tcCallback = callback;
|
||||
if (exi->tcCallback) {
|
||||
EXIClearInterrupts(chan, FALSE, TRUE, FALSE);
|
||||
__OSUnmaskInterrupts(OS_INTERRUPTMASK_EXI_0_TC >> (3 * chan));
|
||||
}
|
||||
|
||||
exi->state |= STATE_DMA;
|
||||
|
||||
REG(chan, 1) = (u32)buf & 0x3ffffe0;
|
||||
REG(chan, 2) = (u32)len;
|
||||
REG(chan, 3) = EXI_0CR(1, 1, type, 0);
|
||||
|
||||
OSRestoreInterrupts(enabled);
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
extern u32 __OSGetDIConfig(void);
|
||||
|
||||
vu16 __OSDeviceCode : (OS_BASE_CACHED | 0x30E6);
|
||||
|
||||
BOOL EXISync(s32 chan)
|
||||
{
|
||||
EXIControl *exi = &Ecb[chan];
|
||||
BOOL rc = FALSE;
|
||||
BOOL enabled;
|
||||
|
||||
while (exi->state & STATE_SELECTED) {
|
||||
if (((REG(chan, 3) & 1) >> 0) == 0) {
|
||||
enabled = OSDisableInterrupts();
|
||||
if (exi->state & STATE_SELECTED) {
|
||||
CompleteTransfer(chan);
|
||||
if (__OSGetDIConfig() != 0xff || exi->immLen != 4 || (REG(chan, 0) & 0x00000070) != (EXI_FREQ_1M << 4)
|
||||
|| (REG(chan, 4) != EXI_USB_ADAPTER && REG(chan, 4) != EXI_IS_VIEWER && REG(chan, 4) != 0x04220001) || __OSDeviceCode == 0x8200) {
|
||||
rc = TRUE;
|
||||
}
|
||||
}
|
||||
OSRestoreInterrupts(enabled);
|
||||
break;
|
||||
}
|
||||
}
|
||||
return rc;
|
||||
}
|
||||
|
||||
u32 EXIClearInterrupts(s32 chan, BOOL exi, BOOL tc, BOOL ext)
|
||||
{
|
||||
u32 cpr;
|
||||
u32 prev;
|
||||
|
||||
prev = cpr = REG(chan, 0);
|
||||
cpr &= 0x7f5;
|
||||
if (exi)
|
||||
cpr |= 2;
|
||||
if (tc)
|
||||
cpr |= 8;
|
||||
if (ext)
|
||||
cpr |= 0x800;
|
||||
REG(chan, 0) = cpr;
|
||||
return prev;
|
||||
}
|
||||
|
||||
EXICallback EXISetExiCallback(s32 chan, EXICallback exiCallback)
|
||||
{
|
||||
EXIControl *exi = &Ecb[chan];
|
||||
EXICallback prev;
|
||||
BOOL enabled;
|
||||
|
||||
enabled = OSDisableInterrupts();
|
||||
prev = exi->exiCallback;
|
||||
exi->exiCallback = exiCallback;
|
||||
|
||||
if (chan != 2) {
|
||||
SetExiInterruptMask(chan, exi);
|
||||
}
|
||||
else {
|
||||
SetExiInterruptMask(0, &Ecb[0]);
|
||||
}
|
||||
|
||||
OSRestoreInterrupts(enabled);
|
||||
return prev;
|
||||
}
|
||||
|
||||
void EXIProbeReset(void)
|
||||
{
|
||||
__EXIProbeStartTime[0] = __EXIProbeStartTime[1] = 0;
|
||||
Ecb[0].idTime = Ecb[1].idTime = 0;
|
||||
__EXIProbe(0);
|
||||
__EXIProbe(1);
|
||||
}
|
||||
|
||||
static BOOL __EXIProbe(s32 chan)
|
||||
{
|
||||
EXIControl *exi = &Ecb[chan];
|
||||
BOOL enabled;
|
||||
BOOL rc;
|
||||
u32 cpr;
|
||||
s32 t;
|
||||
|
||||
if (chan == 2) {
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
rc = TRUE;
|
||||
enabled = OSDisableInterrupts();
|
||||
cpr = REG(chan, 0);
|
||||
if (!(exi->state & EXI_STATE_ATTACHED)) {
|
||||
if (cpr & 0x00000800) {
|
||||
EXIClearInterrupts(chan, FALSE, FALSE, TRUE);
|
||||
__EXIProbeStartTime[chan] = exi->idTime = 0;
|
||||
}
|
||||
|
||||
if (cpr & 0x00001000) {
|
||||
t = (s32)(OSTicksToMilliseconds(OSGetTime()) / 100) + 1;
|
||||
if (__EXIProbeStartTime[chan] == 0) {
|
||||
__EXIProbeStartTime[chan] = t;
|
||||
}
|
||||
if (t - __EXIProbeStartTime[chan] < 300 / 100) {
|
||||
rc = FALSE;
|
||||
}
|
||||
}
|
||||
else {
|
||||
__EXIProbeStartTime[chan] = exi->idTime = 0;
|
||||
rc = FALSE;
|
||||
}
|
||||
}
|
||||
else if (!(cpr & 0x00001000) || (cpr & 0x00000800)) {
|
||||
__EXIProbeStartTime[chan] = exi->idTime = 0;
|
||||
rc = FALSE;
|
||||
}
|
||||
OSRestoreInterrupts(enabled);
|
||||
|
||||
return rc;
|
||||
}
|
||||
|
||||
BOOL EXIProbe(s32 chan)
|
||||
{
|
||||
EXIControl *exi = &Ecb[chan];
|
||||
BOOL rc;
|
||||
u32 id;
|
||||
|
||||
rc = __EXIProbe(chan);
|
||||
if (rc && exi->idTime == 0) {
|
||||
rc = EXIGetID(chan, 0, &id) ? TRUE : FALSE;
|
||||
}
|
||||
return rc;
|
||||
}
|
||||
|
||||
s32 EXIProbeEx(s32 chan)
|
||||
{
|
||||
if (EXIProbe(chan)) {
|
||||
return 1;
|
||||
}
|
||||
else if (__EXIProbeStartTime[chan] != 0) {
|
||||
return 0;
|
||||
}
|
||||
else {
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
|
||||
static BOOL __EXIAttach(s32 chan, EXICallback extCallback)
|
||||
{
|
||||
EXIControl *exi = &Ecb[chan];
|
||||
BOOL enabled;
|
||||
|
||||
enabled = OSDisableInterrupts();
|
||||
if ((exi->state & EXI_STATE_ATTACHED) || __EXIProbe(chan) == FALSE) {
|
||||
OSRestoreInterrupts(enabled);
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
EXIClearInterrupts(chan, TRUE, FALSE, FALSE);
|
||||
|
||||
exi->extCallback = extCallback;
|
||||
__OSUnmaskInterrupts(OS_INTERRUPTMASK_EXI_0_EXT >> (3 * chan));
|
||||
exi->state |= STATE_ATTACHED;
|
||||
OSRestoreInterrupts(enabled);
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
BOOL EXIAttach(s32 chan, EXICallback extCallback)
|
||||
{
|
||||
EXIControl *exi = &Ecb[chan];
|
||||
BOOL enabled;
|
||||
BOOL rc;
|
||||
|
||||
EXIProbe(chan);
|
||||
|
||||
enabled = OSDisableInterrupts();
|
||||
if (exi->idTime == 0) {
|
||||
OSRestoreInterrupts(enabled);
|
||||
return FALSE;
|
||||
}
|
||||
rc = __EXIAttach(chan, extCallback);
|
||||
OSRestoreInterrupts(enabled);
|
||||
return rc;
|
||||
}
|
||||
|
||||
BOOL EXIDetach(s32 chan)
|
||||
{
|
||||
EXIControl *exi = &Ecb[chan];
|
||||
BOOL enabled;
|
||||
|
||||
enabled = OSDisableInterrupts();
|
||||
if (!(exi->state & STATE_ATTACHED)) {
|
||||
OSRestoreInterrupts(enabled);
|
||||
return TRUE;
|
||||
}
|
||||
if ((exi->state & STATE_LOCKED) && exi->dev == 0) {
|
||||
OSRestoreInterrupts(enabled);
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
exi->state &= ~STATE_ATTACHED;
|
||||
__OSMaskInterrupts((OS_INTERRUPTMASK_EXI_0_EXT | OS_INTERRUPTMASK_EXI_0_EXI) >> (3 * chan));
|
||||
OSRestoreInterrupts(enabled);
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
BOOL EXISelect(s32 chan, u32 dev, u32 freq)
|
||||
{
|
||||
EXIControl *exi = &Ecb[chan];
|
||||
u32 cpr;
|
||||
BOOL enabled;
|
||||
|
||||
enabled = OSDisableInterrupts();
|
||||
if ((exi->state & STATE_SELECTED)
|
||||
|| chan != 2 && (dev == 0 && !(exi->state & STATE_ATTACHED) && !__EXIProbe(chan) || !(exi->state & STATE_LOCKED) || (exi->dev != dev))) {
|
||||
OSRestoreInterrupts(enabled);
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
exi->state |= STATE_SELECTED;
|
||||
cpr = REG(chan, 0);
|
||||
cpr &= 0x405;
|
||||
cpr |= CPR_CS(dev) | CPR_CLK(freq);
|
||||
REG(chan, 0) = cpr;
|
||||
|
||||
if (exi->state & STATE_ATTACHED) {
|
||||
switch (chan) {
|
||||
case 0:
|
||||
__OSMaskInterrupts(OS_INTERRUPTMASK_EXI_0_EXT);
|
||||
break;
|
||||
case 1:
|
||||
__OSMaskInterrupts(OS_INTERRUPTMASK_EXI_1_EXT);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
OSRestoreInterrupts(enabled);
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
BOOL EXIDeselect(s32 chan)
|
||||
{
|
||||
EXIControl *exi = &Ecb[chan];
|
||||
u32 cpr;
|
||||
BOOL enabled;
|
||||
|
||||
enabled = OSDisableInterrupts();
|
||||
if (!(exi->state & STATE_SELECTED)) {
|
||||
OSRestoreInterrupts(enabled);
|
||||
return FALSE;
|
||||
}
|
||||
exi->state &= ~STATE_SELECTED;
|
||||
cpr = REG(chan, 0);
|
||||
REG(chan, 0) = cpr & 0x405;
|
||||
|
||||
if (exi->state & STATE_ATTACHED) {
|
||||
switch (chan) {
|
||||
case 0:
|
||||
__OSUnmaskInterrupts(OS_INTERRUPTMASK_EXI_0_EXT);
|
||||
break;
|
||||
case 1:
|
||||
__OSUnmaskInterrupts(OS_INTERRUPTMASK_EXI_1_EXT);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
OSRestoreInterrupts(enabled);
|
||||
|
||||
if (chan != 2 && (cpr & CPR_CS(0))) {
|
||||
return __EXIProbe(chan) ? TRUE : FALSE;
|
||||
}
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
static void EXIIntrruptHandler(__OSInterrupt interrupt, OSContext *context)
|
||||
{
|
||||
s32 chan;
|
||||
EXIControl *exi;
|
||||
EXICallback callback;
|
||||
|
||||
chan = (interrupt - __OS_INTERRUPT_EXI_0_EXI) / 3;
|
||||
exi = &Ecb[chan];
|
||||
EXIClearInterrupts(chan, TRUE, FALSE, FALSE);
|
||||
callback = exi->exiCallback;
|
||||
if (callback) {
|
||||
OSContext exceptionContext;
|
||||
|
||||
OSClearContext(&exceptionContext);
|
||||
OSSetCurrentContext(&exceptionContext);
|
||||
|
||||
callback(chan, context);
|
||||
|
||||
OSClearContext(&exceptionContext);
|
||||
OSSetCurrentContext(context);
|
||||
}
|
||||
}
|
||||
|
||||
static void TCIntrruptHandler(__OSInterrupt interrupt, OSContext *context)
|
||||
{
|
||||
OSContext exceptionContext;
|
||||
s32 chan;
|
||||
EXIControl *exi;
|
||||
EXICallback callback;
|
||||
|
||||
chan = (interrupt - __OS_INTERRUPT_EXI_0_TC) / 3;
|
||||
exi = &Ecb[chan];
|
||||
__OSMaskInterrupts(OS_INTERRUPTMASK(interrupt));
|
||||
EXIClearInterrupts(chan, FALSE, TRUE, FALSE);
|
||||
callback = exi->tcCallback;
|
||||
if (callback) {
|
||||
exi->tcCallback = 0;
|
||||
CompleteTransfer(chan);
|
||||
|
||||
OSClearContext(&exceptionContext);
|
||||
OSSetCurrentContext(&exceptionContext);
|
||||
|
||||
callback(chan, context);
|
||||
|
||||
OSClearContext(&exceptionContext);
|
||||
OSSetCurrentContext(context);
|
||||
}
|
||||
}
|
||||
|
||||
static void EXTIntrruptHandler(__OSInterrupt interrupt, OSContext *context)
|
||||
{
|
||||
s32 chan;
|
||||
EXIControl *exi;
|
||||
EXICallback callback;
|
||||
|
||||
chan = (interrupt - __OS_INTERRUPT_EXI_0_EXT) / 3;
|
||||
__OSMaskInterrupts((OS_INTERRUPTMASK_EXI_0_EXT | OS_INTERRUPTMASK_EXI_0_EXI) >> (3 * chan));
|
||||
exi = &Ecb[chan];
|
||||
callback = exi->extCallback;
|
||||
exi->state &= ~STATE_ATTACHED;
|
||||
if (callback) {
|
||||
OSContext exceptionContext;
|
||||
|
||||
OSClearContext(&exceptionContext);
|
||||
OSSetCurrentContext(&exceptionContext);
|
||||
|
||||
exi->extCallback = 0;
|
||||
callback(chan, context);
|
||||
|
||||
OSClearContext(&exceptionContext);
|
||||
OSSetCurrentContext(context);
|
||||
}
|
||||
}
|
||||
|
||||
void EXIInit(void)
|
||||
{
|
||||
__OSMaskInterrupts(OS_INTERRUPTMASK_EXI_0_EXI | OS_INTERRUPTMASK_EXI_0_TC | OS_INTERRUPTMASK_EXI_0_EXT | OS_INTERRUPTMASK_EXI_1_EXI
|
||||
| OS_INTERRUPTMASK_EXI_1_TC | OS_INTERRUPTMASK_EXI_1_EXT | OS_INTERRUPTMASK_EXI_2_EXI | OS_INTERRUPTMASK_EXI_2_TC);
|
||||
|
||||
REG(0, 0) = 0;
|
||||
REG(1, 0) = 0;
|
||||
REG(2, 0) = 0;
|
||||
|
||||
REG(0, 0) = 0x00002000;
|
||||
|
||||
__OSSetInterruptHandler(__OS_INTERRUPT_EXI_0_EXI, EXIIntrruptHandler);
|
||||
__OSSetInterruptHandler(__OS_INTERRUPT_EXI_0_TC, TCIntrruptHandler);
|
||||
__OSSetInterruptHandler(__OS_INTERRUPT_EXI_0_EXT, EXTIntrruptHandler);
|
||||
__OSSetInterruptHandler(__OS_INTERRUPT_EXI_1_EXI, EXIIntrruptHandler);
|
||||
__OSSetInterruptHandler(__OS_INTERRUPT_EXI_1_TC, TCIntrruptHandler);
|
||||
__OSSetInterruptHandler(__OS_INTERRUPT_EXI_1_EXT, EXTIntrruptHandler);
|
||||
__OSSetInterruptHandler(__OS_INTERRUPT_EXI_2_EXI, EXIIntrruptHandler);
|
||||
__OSSetInterruptHandler(__OS_INTERRUPT_EXI_2_TC, TCIntrruptHandler);
|
||||
|
||||
if ((OSGetConsoleType() & 0x10000000) != 0) {
|
||||
__EXIProbeStartTime[0] = __EXIProbeStartTime[1] = 0;
|
||||
Ecb[0].idTime = Ecb[1].idTime = 0;
|
||||
__EXIProbe(0);
|
||||
__EXIProbe(1);
|
||||
}
|
||||
}
|
||||
|
||||
BOOL EXILock(s32 chan, u32 dev, EXICallback unlockedCallback)
|
||||
{
|
||||
EXIControl *exi = &Ecb[chan];
|
||||
BOOL enabled;
|
||||
int i;
|
||||
|
||||
enabled = OSDisableInterrupts();
|
||||
if (exi->state & STATE_LOCKED) {
|
||||
if (unlockedCallback) {
|
||||
for (i = 0; i < exi->items; i++) {
|
||||
if (exi->queue[i].dev == dev) {
|
||||
OSRestoreInterrupts(enabled);
|
||||
return FALSE;
|
||||
}
|
||||
}
|
||||
exi->queue[exi->items].callback = unlockedCallback;
|
||||
exi->queue[exi->items].dev = dev;
|
||||
exi->items++;
|
||||
}
|
||||
OSRestoreInterrupts(enabled);
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
exi->state |= STATE_LOCKED;
|
||||
exi->dev = dev;
|
||||
SetExiInterruptMask(chan, exi);
|
||||
|
||||
OSRestoreInterrupts(enabled);
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
BOOL EXIUnlock(s32 chan)
|
||||
{
|
||||
EXIControl *exi = &Ecb[chan];
|
||||
BOOL enabled;
|
||||
EXICallback unlockedCallback;
|
||||
|
||||
enabled = OSDisableInterrupts();
|
||||
if (!(exi->state & STATE_LOCKED)) {
|
||||
OSRestoreInterrupts(enabled);
|
||||
return FALSE;
|
||||
}
|
||||
exi->state &= ~STATE_LOCKED;
|
||||
SetExiInterruptMask(chan, exi);
|
||||
|
||||
if (0 < exi->items) {
|
||||
unlockedCallback = exi->queue[0].callback;
|
||||
if (0 < --exi->items) {
|
||||
memmove(&exi->queue[0], &exi->queue[1], sizeof(exi->queue[0]) * exi->items);
|
||||
}
|
||||
unlockedCallback(chan, 0);
|
||||
}
|
||||
|
||||
OSRestoreInterrupts(enabled);
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
u32 EXIGetState(s32 chan)
|
||||
{
|
||||
EXIControl *exi = &Ecb[chan];
|
||||
|
||||
return (u32)exi->state;
|
||||
}
|
||||
|
||||
static void UnlockedHandler(s32 chan, OSContext *context)
|
||||
{
|
||||
u32 id;
|
||||
|
||||
EXIGetID(chan, 0, &id);
|
||||
}
|
||||
|
||||
s32 EXIGetID(s32 chan, u32 dev, u32 *id)
|
||||
{
|
||||
EXIControl *exi = &Ecb[chan];
|
||||
BOOL err;
|
||||
u32 cmd;
|
||||
s32 startTime;
|
||||
BOOL enabled;
|
||||
|
||||
if (chan < 2 && dev == 0) {
|
||||
if (!__EXIProbe(chan)) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (exi->idTime == __EXIProbeStartTime[chan]) {
|
||||
*id = exi->id;
|
||||
return exi->idTime;
|
||||
}
|
||||
|
||||
if (!__EXIAttach(chan, NULL)) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
startTime = __EXIProbeStartTime[chan];
|
||||
}
|
||||
|
||||
err = !EXILock(chan, dev, (chan < 2 && dev == 0) ? UnlockedHandler : NULL);
|
||||
if (!err) {
|
||||
err = !EXISelect(chan, dev, EXI_FREQ_1M);
|
||||
if (!err) {
|
||||
cmd = 0;
|
||||
err |= !EXIImm(chan, &cmd, 2, EXI_WRITE, NULL);
|
||||
err |= !EXISync(chan);
|
||||
err |= !EXIImm(chan, id, 4, EXI_READ, NULL);
|
||||
err |= !EXISync(chan);
|
||||
err |= !EXIDeselect(chan);
|
||||
}
|
||||
EXIUnlock(chan);
|
||||
}
|
||||
|
||||
if (chan < 2 && dev == 0) {
|
||||
EXIDetach(chan);
|
||||
enabled = OSDisableInterrupts();
|
||||
err |= (startTime != __EXIProbeStartTime[chan]);
|
||||
if (!err) {
|
||||
exi->id = *id;
|
||||
exi->idTime = startTime;
|
||||
}
|
||||
OSRestoreInterrupts(enabled);
|
||||
|
||||
return err ? 0 : exi->idTime;
|
||||
}
|
||||
|
||||
return err ? 0 : !0;
|
||||
}
|
||||
184
src/dolphin/exi/EXIUart.c
Normal file
184
src/dolphin/exi/EXIUart.c
Normal file
|
|
@ -0,0 +1,184 @@
|
|||
#include <dolphin/os.h>
|
||||
#include <dolphin/exi.h>
|
||||
|
||||
#define EXI_TX 0x800400u
|
||||
#define EXI_MAGIC 0xa5ff005a
|
||||
|
||||
static s32 Chan;
|
||||
static u32 Dev;
|
||||
static u32 Enabled = 0;
|
||||
static u32 BarnacleEnabled = 0;
|
||||
|
||||
static BOOL ProbeBarnacle(s32 chan, u32 dev, u32 *revision)
|
||||
{
|
||||
BOOL err;
|
||||
u32 cmd;
|
||||
|
||||
if (chan != 2 && dev == 0 && !EXIAttach(chan, NULL)) {
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
err = !EXILock(chan, dev, NULL);
|
||||
if (!err) {
|
||||
err = !EXISelect(chan, dev, EXI_FREQ_1M);
|
||||
if (!err) {
|
||||
cmd = 0x20011300;
|
||||
err = FALSE;
|
||||
err |= !EXIImm(chan, &cmd, 4, EXI_WRITE, NULL);
|
||||
err |= !EXISync(chan);
|
||||
err |= !EXIImm(chan, revision, 4, EXI_READ, NULL);
|
||||
err |= !EXISync(chan);
|
||||
err |= !EXIDeselect(chan);
|
||||
}
|
||||
EXIUnlock(chan);
|
||||
}
|
||||
|
||||
if (chan != 2 && dev == 0) {
|
||||
EXIDetach(chan);
|
||||
}
|
||||
|
||||
if (err) {
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
return (*revision != 0xFFFFFFFF) ? TRUE : FALSE;
|
||||
}
|
||||
|
||||
void __OSEnableBarnacle(s32 chan, u32 dev)
|
||||
{
|
||||
u32 id;
|
||||
|
||||
if (EXIGetID(chan, dev, &id)) {
|
||||
switch (id) {
|
||||
case 0xffffffff:
|
||||
case EXI_MEMORY_CARD_59:
|
||||
case EXI_MEMORY_CARD_123:
|
||||
case EXI_MEMORY_CARD_251:
|
||||
case EXI_MEMORY_CARD_507:
|
||||
case EXI_USB_ADAPTER:
|
||||
case EXI_NPDP_GDEV:
|
||||
case EXI_MODEM:
|
||||
case EXI_MARLIN:
|
||||
case 0x04220000:
|
||||
case 0x04020100:
|
||||
case 0x04020200:
|
||||
case 0x04020300:
|
||||
case 0x04040404:
|
||||
case 0x04060000:
|
||||
case 0x04120000:
|
||||
case 0x04130000:
|
||||
case 0x80000000 | EXI_MEMORY_CARD_59:
|
||||
case 0x80000000 | EXI_MEMORY_CARD_123:
|
||||
case 0x80000000 | EXI_MEMORY_CARD_251:
|
||||
case 0x80000000 | EXI_MEMORY_CARD_507:
|
||||
break;
|
||||
default:
|
||||
if (ProbeBarnacle(chan, dev, &id)) {
|
||||
Chan = chan;
|
||||
Dev = dev;
|
||||
Enabled = BarnacleEnabled = EXI_MAGIC;
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
u32 InitializeUART(u32 baudRate)
|
||||
{
|
||||
if (BarnacleEnabled == EXI_MAGIC) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (!(OSGetConsoleType() & OS_CONSOLE_DEVELOPMENT)) {
|
||||
Enabled = 0;
|
||||
return 2;
|
||||
}
|
||||
else {
|
||||
Chan = 0;
|
||||
Dev = 1;
|
||||
Enabled = EXI_MAGIC;
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
u32 ReadUARTN(void *bytes, unsigned long length)
|
||||
{
|
||||
return 4;
|
||||
}
|
||||
|
||||
static int QueueLength(void)
|
||||
{
|
||||
u32 cmd;
|
||||
|
||||
if (!EXISelect(Chan, Dev, EXI_FREQ_8M))
|
||||
return -1;
|
||||
|
||||
cmd = EXI_TX << 6;
|
||||
EXIImm(Chan, &cmd, 4, EXI_WRITE, NULL);
|
||||
EXISync(Chan);
|
||||
|
||||
EXIImm(Chan, &cmd, 1, EXI_READ, NULL);
|
||||
EXISync(Chan);
|
||||
EXIDeselect(Chan);
|
||||
|
||||
return 16 - (int)((cmd >> 24) & 0xff);
|
||||
}
|
||||
|
||||
u32 WriteUARTN(const void *buf, unsigned long len)
|
||||
{
|
||||
u32 cmd;
|
||||
int qLen;
|
||||
long xLen;
|
||||
char *ptr;
|
||||
BOOL locked;
|
||||
u32 error;
|
||||
|
||||
if (Enabled != EXI_MAGIC)
|
||||
return 2;
|
||||
|
||||
locked = EXILock(Chan, Dev, 0);
|
||||
if (!locked) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
for (ptr = (char *)buf; ptr - buf < len; ptr++) {
|
||||
if (*ptr == '\n')
|
||||
*ptr = '\r';
|
||||
}
|
||||
|
||||
error = 0;
|
||||
cmd = (EXI_TX | 0x2000000) << 6;
|
||||
while (len) {
|
||||
qLen = QueueLength();
|
||||
if (qLen < 0) {
|
||||
error = 3;
|
||||
break;
|
||||
}
|
||||
|
||||
if (qLen < 12 && qLen < len)
|
||||
continue;
|
||||
|
||||
if (!EXISelect(Chan, Dev, EXI_FREQ_8M)) {
|
||||
error = 3;
|
||||
break;
|
||||
}
|
||||
|
||||
EXIImm(Chan, &cmd, 4, EXI_WRITE, NULL);
|
||||
EXISync(Chan);
|
||||
|
||||
while (qLen && len) {
|
||||
if (qLen < 4 && qLen < len)
|
||||
break;
|
||||
xLen = (len < 4) ? (long)len : 4;
|
||||
EXIImm(Chan, (void *)buf, xLen, EXI_WRITE, NULL);
|
||||
(u8 *)buf += xLen;
|
||||
len -= xLen;
|
||||
qLen -= xLen;
|
||||
EXISync(Chan);
|
||||
}
|
||||
EXIDeselect(Chan);
|
||||
}
|
||||
|
||||
EXIUnlock(Chan);
|
||||
return error;
|
||||
}
|
||||
1315
src/dolphin/mtx/mtx.c
Normal file
1315
src/dolphin/mtx/mtx.c
Normal file
File diff suppressed because it is too large
Load diff
Some files were not shown because too many files have changed in this diff Show more
Loading…
Add table
Add a link
Reference in a new issue