This commit is contained in:
CreateSource 2024-11-13 20:39:47 -05:00
commit 0606d9677b
197 changed files with 31800 additions and 2022 deletions

View 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) { }

View file

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

View file

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

View file

@ -1,5 +1,5 @@
#include "REL/board_executor.h"
#include "rel_sqrt_consts.h"
#include "math.h"
static void ObjectSetup(void) {
BoardObjectSetup(BoardCreate, BoardDestroy);

View file

@ -15,7 +15,6 @@
#include "game/wipe.h"
#include "math.h"
#include "rel_sqrt_consts.h"
#include "data_num/title.h"

View file

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

View file

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

View file

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

View file

@ -17,7 +17,6 @@
#include "game/wipe.h"
#include "ext_math.h"
#include "rel_sqrt_consts.h"
typedef struct {
/* 0x000 */ u8 unk00;

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

@ -18,7 +18,6 @@
#include "dolphin.h"
#include "ext_math.h"
#include "rel_sqrt_consts.h"
typedef struct {
/* 0x00 */ s16 unk00;

View file

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

View file

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

View file

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

View file

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

View file

@ -17,8 +17,6 @@
#include "REL/m416Dll.h"
#include "rel_sqrt_consts.h"
typedef struct camera_view_params {
float zoom;
Vec pos;

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

@ -20,8 +20,6 @@
#include "ext_math.h"
#include "rel_sqrt_consts.h"
#include "REL/m439data.h"
typedef struct camera_params {

View file

@ -12,7 +12,7 @@
#include "game/sprite.h"
#include "game/wipe.h"
#include "math.h"
#include "rel_sqrt_consts.h"
#include "string.h"
// bss

View file

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

View file

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

View file

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

View file

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

View file

@ -18,7 +18,6 @@
#include "dolphin.h"
#include "ext_math.h"
#include "rel_sqrt_consts.h"
typedef struct {
/* 0x00 */ s16 unk00;

View file

@ -1,5 +1,5 @@
#include "REL/m446Dll.h"
#include "rel_sqrt_consts.h"
#include "math.h"
#include "game/audio.h"
#include "game/frand.h"

View file

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

View file

@ -20,7 +20,6 @@
#include "dolphin.h"
#include "ext_math.h"
#include "rel_sqrt_consts.h"
typedef struct {
/* 0x00 */ s32 unk00;

View file

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

View file

@ -17,8 +17,6 @@
#include "game/gamework_data.h"
#include "rel_sqrt_consts.h"
typedef struct bss_348_data {
s16 unk0[5];
s16 unkA;

View file

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

View file

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

View file

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

View file

@ -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[];

View file

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

View file

@ -6,7 +6,6 @@
#include "game/wipe.h"
#include "ext_math.h"
#include "rel_sqrt_consts.h"
typedef struct camera_view_params {
Vec rot;

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

@ -13,7 +13,6 @@
#include "game/saveload.h"
#include "game/window.h"
#include "game/wipe.h"
#include "rel_sqrt_consts.h"
#include "math.h"

View file

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

View file

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

View file

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

View file

@ -5,7 +5,7 @@
#include "game/pad.h"
#include "game/wipe.h"
#include "rel_sqrt_consts.h"
#include "math.h"
static void SubchrMain(void);

View file

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

View 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
View 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
View 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
View 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
View 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
View 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;
}

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

View 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, &currentDir);
errors += VerifyFAT(card, &currentFat);
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;
}

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

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

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

View 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;
}

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

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

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

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

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

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

File diff suppressed because it is too large Load diff

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

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