copy over a bunch of sdk stuff (#1066)

* most of dolsdk copied over

* add some gf stuff

* trk wip

* ode/amc stuff

* build fix
This commit is contained in:
TakaRikka
2026-06-26 08:03:34 -07:00
committed by GitHub
parent 0f2521d9a7
commit d489dc996b
124 changed files with 14914 additions and 209 deletions
+1 -1
View File
@@ -3993,7 +3993,7 @@ TRK_MINNOW_DOLPHIN/ppc/Generic/targimpl.c:
TRK_MINNOW_DOLPHIN/ppc/Export/targsupp.s: comment:0
.text start:0x80335DB0 end:0x80335DD0 align:16
TRK_MINNOW_DOLPHIN/ppc/Generic/__exception.c: comment:0
TRK_MINNOW_DOLPHIN/ppc/Generic/exception.s: comment:0
.init start:0x80003534 end:0x80005468
TRK_MINNOW_DOLPHIN/Os/dolphin/dolphin_trk.c:
+1 -1
View File
@@ -4021,7 +4021,7 @@ TRK_MINNOW_DOLPHIN/ppc/Generic/targimpl.c:
TRK_MINNOW_DOLPHIN/ppc/Export/targsupp.s: comment:0
.text start:0x80337020 end:0x80337040 align:16
TRK_MINNOW_DOLPHIN/ppc/Generic/__exception.c: comment:0
TRK_MINNOW_DOLPHIN/ppc/Generic/exception.s: comment:0
.init start:0x80003534 end:0x80005468
TRK_MINNOW_DOLPHIN/Os/dolphin/dolphin_trk.c:
+1 -1
View File
@@ -4017,7 +4017,7 @@ TRK_MINNOW_DOLPHIN/ppc/Generic/targimpl.c:
TRK_MINNOW_DOLPHIN/ppc/Export/targsupp.s: comment:0
.text start:0x80334A20 end:0x80334A40 align:16
TRK_MINNOW_DOLPHIN/ppc/Generic/__exception.c: comment:0
TRK_MINNOW_DOLPHIN/ppc/Generic/exception.s: comment:0
.init start:0x80003534 end:0x80005468
TRK_MINNOW_DOLPHIN/Os/dolphin/dolphin_trk.c:
+1 -1
View File
@@ -4021,7 +4021,7 @@ TRK_MINNOW_DOLPHIN/ppc/Generic/targimpl.c:
TRK_MINNOW_DOLPHIN/ppc/Export/targsupp.s: comment:0
.text start:0x8033C570 end:0x8033C590 align:16
TRK_MINNOW_DOLPHIN/ppc/Generic/__exception.c: comment:0
TRK_MINNOW_DOLPHIN/ppc/Generic/exception.s: comment:0
.init start:0x80003534 end:0x80005468
TRK_MINNOW_DOLPHIN/Os/dolphin/dolphin_trk.c:
+86 -63
View File
@@ -216,7 +216,7 @@ cflags_base = [
"-fp hardware",
"-Cpp_exceptions off",
# "-W all",
"-O4,p",
# "-O4,p",
"-inline auto",
'-pragma "cats off"',
'-pragma "warn_notinlined off"',
@@ -235,6 +235,7 @@ cflags_base = [
"-i src/PowerPC_EABI_Support/MSL/MSL_C/PPC_EABI/Include",
"-i src/PowerPC_EABI_Support/MSL/MSL_C++/MSL_Common/Include",
"-i src/PowerPC_EABI_Support/Runtime/Inc",
"-i src/PowerPC_EABI_Support/MetroTRK",
f"-DVERSION={version_num}",
]
@@ -258,17 +259,31 @@ elif args.warn == "error":
# Metrowerks library flags
cflags_runtime = [
*cflags_base,
"-O4,p",
"-use_lmw_stmw on",
"-str reuse,pool,readonly",
"-gccinc",
"-common off",
"-inline deferred,auto",
"-char signed",
]
cflags_trk = [
*cflags_base,
"-O4,p",
"-use_lmw_stmw on",
"-rostr",
"-str reuse",
"-common off",
"-inline deferred,auto",
"-char signed",
"-sdata 0",
"-sdata2 0",
]
# Dolphin library flags
cflags_dolphin = [
*cflags_base,
"-O4,p",
"-fp_contract off",
]
@@ -923,16 +938,20 @@ config.libs = [
Object(Matching, "JAZelAudio/JAIZelSound.cpp"),
],
},
DolphinLib(
"gf",
[
{
"lib": "gf",
"mw_version": "GC/1.3.2",
"cflags": [*cflags_base, "-O3"],
"progress_category": "sdk",
"host": False,
"objects": [
Object(NonMatching, "dolphin/gf/GFGeometry.cpp"),
Object(NonMatching, "dolphin/gf/GFLight.cpp"),
Object(NonMatching, "dolphin/gf/GFPixel.cpp"),
Object(MatchingFor("GZLJ01", "GZLE01", "GZLP01"), "dolphin/gf/GFPixel.cpp"),
Object(NonMatching, "dolphin/gf/GFTev.cpp"),
Object(NonMatching, "dolphin/gf/GFTransform.cpp"),
],
),
},
JSystemLib(
"JKernel",
[
@@ -1078,7 +1097,7 @@ config.libs = [
DolphinLib(
"base",
[
Object(NonMatching, "dolphin/base/PPCArch.c"),
Object(Matching, "dolphin/base/PPCArch.c"),
],
),
DolphinLib(
@@ -1109,24 +1128,28 @@ config.libs = [
Object(Matching, "dolphin/os/__ppc_eabi_init.cpp"),
],
),
DolphinLib(
"exi",
[
Object(NonMatching, "dolphin/exi/EXIBios.c"),
Object(NonMatching, "dolphin/exi/EXIUart.c"),
{
"lib": "exi",
"mw_version": "GC/1.2.5n",
"cflags": [*cflags_base],
"progress_category": "sdk",
"host": False,
"objects": [
Object(Matching, "dolphin/exi/EXIBios.c", extra_cflags=["-O3,p"]),
Object(Matching, "dolphin/exi/EXIUart.c", extra_cflags=["-O4,p"]),
],
),
},
DolphinLib(
"si",
[
Object(NonMatching, "dolphin/si/SIBios.c"),
Object(NonMatching, "dolphin/si/SISamplingRate.c"),
Object(Matching, "dolphin/si/SIBios.c"),
Object(Matching, "dolphin/si/SISamplingRate.c"),
],
),
DolphinLib(
"db",
[
Object(NonMatching, "dolphin/db/db.c"),
Object(Matching, "dolphin/db/db.c"),
],
),
DolphinLib(
@@ -1155,54 +1178,54 @@ config.libs = [
DolphinLib(
"vi",
[
Object(NonMatching, "dolphin/vi/vi.c"),
Object(MatchingFor("GZLJ01", "GZLE01"), "dolphin/vi/vi.c"),
],
),
DolphinLib(
"pad",
[
Object(NonMatching, "dolphin/pad/Padclamp.c"),
Object(NonMatching, "dolphin/pad/Pad.c"),
Object(Matching, "dolphin/pad/Padclamp.c"),
Object(Matching, "dolphin/pad/Pad.c"),
],
),
DolphinLib(
"ai",
[
Object(NonMatching, "dolphin/ai/ai.c"),
Object(NonMatching, "dolphin/ar/ar.c"),
Object(Matching, "dolphin/ai/ai.c"),
Object(Matching, "dolphin/ar/ar.c"),
],
),
DolphinLib(
"ar",
[
Object(NonMatching, "dolphin/ar/arq.c"),
Object(Matching, "dolphin/ar/arq.c"),
],
),
DolphinLib(
"dsp",
[
Object(NonMatching, "dolphin/dsp/dsp.c"),
Object(NonMatching, "dolphin/dsp/dsp_debug.c"),
Object(NonMatching, "dolphin/dsp/dsp_task.c"),
Object(Matching, "dolphin/dsp/dsp.c"),
Object(Matching, "dolphin/dsp/dsp_debug.c"),
Object(Matching, "dolphin/dsp/dsp_task.c"),
],
),
DolphinLib(
"card",
[
Object(NonMatching, "dolphin/card/CARDBios.c"),
Object(NonMatching, "dolphin/card/CARDUnlock.c"),
Object(NonMatching, "dolphin/card/CARDRdwr.c"),
Object(NonMatching, "dolphin/card/CARDBlock.c"),
Object(NonMatching, "dolphin/card/CARDDir.c"),
Object(NonMatching, "dolphin/card/CARDCheck.c"),
Object(NonMatching, "dolphin/card/CARDMount.c"),
Object(NonMatching, "dolphin/card/CARDFormat.c"),
Object(NonMatching, "dolphin/card/CARDOpen.c"),
Object(NonMatching, "dolphin/card/CARDCreate.c"),
Object(NonMatching, "dolphin/card/CARDRead.c"),
Object(NonMatching, "dolphin/card/CARDWrite.c"),
Object(NonMatching, "dolphin/card/CARDStat.c"),
Object(NonMatching, "dolphin/card/CARDNet.c"),
Object(Matching, "dolphin/card/CARDBios.c"),
Object(Matching, "dolphin/card/CARDUnlock.c"),
Object(Matching, "dolphin/card/CARDRdwr.c"),
Object(Matching, "dolphin/card/CARDBlock.c"),
Object(Matching, "dolphin/card/CARDDir.c"),
Object(Matching, "dolphin/card/CARDCheck.c"),
Object(Matching, "dolphin/card/CARDMount.c"),
Object(Matching, "dolphin/card/CARDFormat.c"),
Object(Matching, "dolphin/card/CARDOpen.c"),
Object(Matching, "dolphin/card/CARDCreate.c"),
Object(Matching, "dolphin/card/CARDRead.c"),
Object(Matching, "dolphin/card/CARDWrite.c"),
Object(Matching, "dolphin/card/CARDStat.c"),
Object(Matching, "dolphin/card/CARDNet.c"),
],
),
DolphinLib(
@@ -1219,7 +1242,7 @@ config.libs = [
Object(NonMatching, "dolphin/gx/GXBump.c"),
Object(NonMatching, "dolphin/gx/GXTev.c"),
Object(NonMatching, "dolphin/gx/GXPixel.c"),
Object(NonMatching, "dolphin/gx/GXStubs.c"),
Object(Matching, "dolphin/gx/GXStubs.c"),
Object(Matching, "dolphin/gx/GXDisplayList.c"),
Object(NonMatching, "dolphin/gx/GXTransform.c", extra_cflags=["-fp_contract off"]),
Object(Matching, "dolphin/gx/GXPerf.c"),
@@ -1228,8 +1251,8 @@ config.libs = [
DolphinLib(
"gd",
[
Object(NonMatching, "dolphin/gd/GDBase.c"),
Object(NonMatching, "dolphin/gd/GDGeometry.c"),
Object(Matching, "dolphin/gd/GDBase.c"),
Object(Matching, "dolphin/gd/GDGeometry.c"),
],
),
{
@@ -1243,7 +1266,7 @@ config.libs = [
Object(Matching, "PowerPC_EABI_Support/Runtime/Src/__va_arg.c"),
Object(Matching, "PowerPC_EABI_Support/Runtime/Src/global_destructor_chain.c"),
Object(Matching, "PowerPC_EABI_Support/Runtime/Src/CPlusLibPPC.cp"),
Object(NonMatching, "PowerPC_EABI_Support/Runtime/Src/NMWException.cp"),
Object(Matching, "PowerPC_EABI_Support/Runtime/Src/NMWException.cp", extra_cflags=["-Cpp_exceptions on"]),
Object(Matching, "PowerPC_EABI_Support/Runtime/Src/ptmf.c"),
Object(Matching, "PowerPC_EABI_Support/Runtime/Src/runtime.c"),
Object(Matching, "PowerPC_EABI_Support/Runtime/Src/__init_cpp_exceptions.cpp"),
@@ -1313,64 +1336,64 @@ config.libs = [
{
"lib": "TRK_MINNOW_DOLPHIN",
"mw_version": "GC/1.3.2",
"cflags": cflags_runtime,
"cflags": cflags_trk,
"progress_category": "sdk",
"host": False,
"objects": [
Object(NonMatching, "TRK_MINNOW_DOLPHIN/Portable/mainloop.c"),
Object(NonMatching, "TRK_MINNOW_DOLPHIN/Portable/nubevent.c"),
Object(Matching, "TRK_MINNOW_DOLPHIN/Portable/mainloop.c", extra_cflags=["-enum min"]),
Object(Matching, "TRK_MINNOW_DOLPHIN/Portable/nubevent.c", extra_cflags=["-enum min"]),
Object(NonMatching, "TRK_MINNOW_DOLPHIN/Portable/nubinit.c"),
Object(NonMatching, "TRK_MINNOW_DOLPHIN/Portable/msg.c"),
Object(NonMatching, "TRK_MINNOW_DOLPHIN/Portable/msgbuf.c"),
Object(NonMatching, "TRK_MINNOW_DOLPHIN/Portable/serpoll.c"),
Object(NonMatching, "TRK_MINNOW_DOLPHIN/Portable/usr_put.c"),
Object(Matching, "TRK_MINNOW_DOLPHIN/Portable/usr_put.c"),
Object(NonMatching, "TRK_MINNOW_DOLPHIN/Portable/dispatch.c"),
Object(NonMatching, "TRK_MINNOW_DOLPHIN/Portable/msghndlr.c"),
Object(NonMatching, "TRK_MINNOW_DOLPHIN/Portable/support.c"),
Object(NonMatching, "TRK_MINNOW_DOLPHIN/Portable/mutex_TRK.c"),
Object(Matching, "TRK_MINNOW_DOLPHIN/Portable/mutex_TRK.c"),
Object(NonMatching, "TRK_MINNOW_DOLPHIN/Portable/notify.c"),
Object(NonMatching, "TRK_MINNOW_DOLPHIN/ppc/Generic/flush_cache.c"),
Object(Matching, "TRK_MINNOW_DOLPHIN/ppc/Generic/flush_cache.c"),
Object(NonMatching, "TRK_MINNOW_DOLPHIN/Portable/mem_TRK.c"),
Object(NonMatching, "TRK_MINNOW_DOLPHIN/ppc/Generic/targimpl.c"),
Object(NonMatching, "TRK_MINNOW_DOLPHIN/ppc/Export/targsupp.s"),
Object(NonMatching, "TRK_MINNOW_DOLPHIN/ppc/Generic/__exception.c"),
Object(Matching, "TRK_MINNOW_DOLPHIN/ppc/Export/targsupp.s"),
Object(NonMatching, "TRK_MINNOW_DOLPHIN/ppc/Generic/exception.s"),
Object(NonMatching, "TRK_MINNOW_DOLPHIN/Os/dolphin/dolphin_trk.c"),
Object(NonMatching, "TRK_MINNOW_DOLPHIN/ppc/Generic/mpc_7xx_603e.c"),
Object(NonMatching, "TRK_MINNOW_DOLPHIN/Portable/main_TRK.c"),
Object(Matching, "TRK_MINNOW_DOLPHIN/ppc/Generic/mpc_7xx_603e.c"),
Object(Matching, "TRK_MINNOW_DOLPHIN/Portable/main_TRK.c"),
Object(NonMatching, "TRK_MINNOW_DOLPHIN/Os/dolphin/dolphin_trk_glue.c"),
Object(NonMatching, "TRK_MINNOW_DOLPHIN/Os/dolphin/targcont.c"),
Object(NonMatching, "TRK_MINNOW_DOLPHIN/Os/dolphin/target_options.c"),
Object(NonMatching, "TRK_MINNOW_DOLPHIN/MetroTRK/Export/mslsupp.c"),
Object(Matching, "TRK_MINNOW_DOLPHIN/Os/dolphin/targcont.c"),
Object(Matching, "TRK_MINNOW_DOLPHIN/Os/dolphin/target_options.c"),
Object(Matching, "TRK_MINNOW_DOLPHIN/MetroTRK/Export/mslsupp.c"),
],
},
{
"lib": "amcstubs",
"mw_version": "GC/1.3.2",
"cflags": cflags_runtime,
"cflags": cflags_dolphin,
"progress_category": "sdk",
"host": False,
"objects": [
Object(NonMatching, "amcstubs/AmcExi2Stubs.c"),
Object(Matching, "amcstubs/AmcExi2Stubs.c"),
],
},
{
"lib": "OdemuExi2",
"mw_version": "GC/1.3.2",
"mw_version": "GC/1.2.5n",
"cflags": cflags_runtime,
"progress_category": "sdk",
"host": False,
"objects": [
Object(NonMatching, "OdemuExi2/DebuggerDriver.c"),
Object(Matching, "OdemuExi2/DebuggerDriver.c"),
],
},
{
"lib": "odenotstub",
"mw_version": "GC/1.3.2",
"cflags": cflags_runtime,
"cflags": cflags_dolphin,
"progress_category": "sdk",
"host": False,
"objects": [
Object(NonMatching, "odenotstub/odenotstub.c"),
Object(Matching, "odenotstub/odenotstub.c"),
],
},
+1 -1
View File
@@ -190,7 +190,7 @@ public:
CRumble(JUTGamePad* pad) { clear(pad); }
static u8 mStatus[4];
static PADMask mEnabled;
static u32 mEnabled;
enum ERumble {
LOOP_ONCE = 0,
@@ -0,0 +1,5 @@
#ifndef GCN_EXI2_DDH_GCN_MAIN_H
#define GCN_EXI2_DDH_GCN_MAIN_H
#endif /* GCN_EXI2_DDH_GCN_MAIN_H */
@@ -0,0 +1,5 @@
#ifndef GCN_EXI2_GDEV_GCN_MAIN_H
#define GCN_EXI2_GDEV_GCN_MAIN_H
#endif /* GCN_EXI2_GDEV_GCN_MAIN_H */
@@ -0,0 +1,5 @@
#ifndef METROTRK_EXPORT_MSLSUPP_H
#define METROTRK_EXPORT_MSLSUPP_H
#endif /* METROTRK_EXPORT_MSLSUPP_H */
@@ -0,0 +1,33 @@
#ifndef METROTRK_PORTABLE_DISPATCH_H
#define METROTRK_PORTABLE_DISPATCH_H
#include "dolphin/types.h"
#ifdef __cplusplus
extern "C" {
#endif
#define TRK_DISPATCH_CMD_CONNECT 1 /* Connect to the console */
#define TRK_DISPATCH_CMD_DISCONNECT 2 /* Disconnect from the console */
#define TRK_DISPATCH_CMD_RESET 3 /* Reset the debugger */
#define TRK_DISPATCH_CMD_GETVERSION 4 /* Get debugger version */
#define TRK_DISPATCH_CMD_GETSUPPORTMASK 5 /* Get Support Mask */
#define TRK_DISPATCH_CMD_OVERRIDE 7 /* Override? */
#define TRK_DISPATCH_CMD_READMEM 16 /* Reading from memory */
#define TRK_DISPATCH_CMD_WRITEMEM 17 /* Writing to memory */
#define TRK_DISPATCH_CMD_READREGS 18 /* Read a register value */
#define TRK_DISPATCH_CMD_WRITEREGS 19 /* Set a register */
#define TRK_DISPATCH_CMD_SETOPTION 23 /* Set an option? */
#define TRK_DISPATCH_CMD_CONTINUE 24 /* Continue debugging */
#define TRK_DISPATCH_CMD_STEP 25 /* Step through an instruction */
#define TRK_DISPATCH_CMD_STOP 26 /* Stop the debugger */
typedef struct TRKBuffer TRKBuffer;
BOOL TRKDispatchMessage(TRKBuffer* buffer);
#ifdef __cplusplus
}
#endif
#endif /* METROTRK_PORTABLE_DISPATCH_H */
@@ -0,0 +1,16 @@
#ifndef METROTRK_PORTABLE_MAIN_TRK_H
#define METROTRK_PORTABLE_MAIN_TRK_H
#include "trk.h"
#ifdef __cplusplus
extern "C" {
#endif
DSError TRK_main(void);
#ifdef __cplusplus
}
#endif
#endif /* METROTRK_PORTABLE_MAIN_TRK_H */
@@ -0,0 +1,7 @@
#ifndef METROTRK_PORTABLE_MAINLOOP_H
#define METROTRK_PORTABLE_MAINLOOP_H
void TRKNubMainLoop(void);
#endif /* METROTRK_PORTABLE_MAINLOOP_H */
@@ -0,0 +1,10 @@
#ifndef METROTRK_PORTABLE_MEM_TRK_H
#define METROTRK_PORTABLE_MEM_TRK_H
#include "dolphin/types.h"
void* TRK_memset(void* dest, int val, size_t count);
void* TRK_memcpy(void* dest, const void* src, size_t count);
void TRK_fill_mem(void* dest, int val, size_t count);
#endif /* METROTRK_PORTABLE_MEM_TRK_H */
@@ -0,0 +1,13 @@
#ifndef METROTRK_PORTABLE_MSG_H
#define METROTRK_PORTABLE_MSG_H
#include "dolphin/types.h"
typedef struct _TRK_Msg {
u8 _00[8];
u32 m_msgLength;
u32 _0C;
u32 m_msg;
} TRK_Msg;
#endif /* METROTRK_PORTABLE_MSG_H */
@@ -0,0 +1,37 @@
#ifndef METROTRK_PORTABLE_MSGBUF_H
#define METROTRK_PORTABLE_MSGBUF_H
#include "trk.h"
#ifdef __cplusplus
extern "C" {
#endif
DSError TRKSetBufferPosition(TRKBuffer* msg, u32 pos);
void* TRKGetBuffer(int);
void TRKResetBuffer(TRKBuffer* msg, BOOL keepData);
DSError TRKAppendBuffer1_ui16(TRKBuffer* buffer, const u16 data);
DSError TRKAppendBuffer1_ui32(TRKBuffer* buffer, const u32 data);
DSError TRKAppendBuffer1_ui64(TRKBuffer* buffer, const u64 data);
DSError TRKAppendBuffer_ui8(TRKBuffer* buffer, const u8* data, int count);
DSError TRKAppendBuffer_ui16(TRKBuffer* buffer, const u16* data, int count);
DSError TRKAppendBuffer_ui32(TRKBuffer* buffer, const u32* data, int count);
DSError TRKAppendBuffer_ui64(TRKBuffer* buffer, const u64* data, int count);
DSError TRKReadBuffer1_ui8(TRKBuffer* buffer, u8* data);
DSError TRKReadBuffer1_ui16(TRKBuffer* buffer, u16* data);
DSError TRKReadBuffer1_ui32(TRKBuffer* buffer, u32* data);
DSError TRKReadBuffer1_ui64(TRKBuffer* buffer, u64* data);
DSError TRKReadBuffer_ui8(TRKBuffer* buffer, u8* data, int count);
DSError TRKReadBuffer_ui16(TRKBuffer* buffer, u16* data, int count);
DSError TRKReadBuffer_ui32(TRKBuffer* buffer, u32* data, int count);
DSError TRKReadBuffer_ui64(TRKBuffer* buffer, u64* data, int count);
#ifdef __cplusplus
}
#endif
#endif /* METROTRK_PORTABLE_MSGBUF_H */
@@ -0,0 +1,23 @@
#ifndef METROTRK_PORTABLE_MSGHNDLR_H
#define METROTRK_PORTABLE_MSGHNDLR_H
#include "trk.h"
void SetTRKConnected(BOOL);
BOOL GetTRKConnected(void);
DSError TRKDoSetOption(TRKBuffer*);
DSError TRKDoStop(TRKBuffer*);
DSError TRKDoStep(TRKBuffer*);
DSError TRKDoContinue(TRKBuffer*);
DSError TRKDoWriteRegisters(TRKBuffer*);
DSError TRKDoReadRegisters(TRKBuffer*);
DSError TRKDoWriteMemory(TRKBuffer*);
DSError TRKDoReadMemory(TRKBuffer*);
DSError TRKDoSupportMask(TRKBuffer*);
DSError TRKDoVersions(TRKBuffer*);
DSError TRKDoOverride(TRKBuffer*);
DSError TRKDoReset(TRKBuffer*);
DSError TRKDoDisconnect(TRKBuffer*);
DSError TRKDoConnect(TRKBuffer*);
#endif /* METROTRK_PORTABLE_MSGHNDLR_H */
@@ -0,0 +1,10 @@
#ifndef METROTRK_PORTABLE_MUTEX_TRK_H
#define METROTRK_PORTABLE_MUTEX_TRK_H
#include "dolphin/types.h"
u8 TRKReleaseMutex();
u8 TRKAcquireMutex();
u8 TRKInitializeMutex();
#endif /* METROTRK_PORTABLE_MUTEX_TRK_H */
@@ -0,0 +1,5 @@
#ifndef METROTRK_PORTABLE_NOTIFY_H
#define METROTRK_PORTABLE_NOTIFY_H
#endif /* METROTRK_PORTABLE_NOTIFY_H */
@@ -0,0 +1,37 @@
#ifndef METROTRK_PORTABLE_NUBEVENT_H
#define METROTRK_PORTABLE_NUBEVENT_H
#include "TRK_MINNOW_DOLPHIN/MetroTRK/Portable/msgbuf.h"
#ifdef __cplusplus
extern "C" {
#endif
typedef u32 NubEventID;
typedef struct TRKEvent {
NubEventType eventType;
NubEventID eventID;
MessageBufferID msgBufID;
} TRKEvent;
typedef struct TRKEventQueue {
int _00;
int count;
int next;
TRKEvent events[2];
NubEventID eventID;
} TRKEventQueue;
extern TRKEventQueue gTRKEventQueue;
BOOL TRKGetNextEvent(TRKEvent* event);
void TRKDestructEvent(TRKEvent*);
void TRKConstructEvent(TRKEvent*, NubEventType);
DSError TRKPostEvent(TRKEvent*);
DSError TRKInitializeEventQueue();
#ifdef __cplusplus
}
#endif
#endif /* METROTRK_PORTABLE_NUBEVENT_H */
@@ -0,0 +1,21 @@
#ifndef METROTRK_PORTABLE_NUBINIT_H
#define METROTRK_PORTABLE_NUBINIT_H
#include "trk.h"
#ifdef __cplusplus
extern "C" {
#endif
void TRKNubWelcome(void);
void TRKNubMainLoop(void);
DSError TRKTerminateNub(void);
DSError TRKInitializeNub(void);
extern BOOL gTRKBigEndian;
#ifdef __cplusplus
}
#endif
#endif /* METROTRK_PORTABLE_NUBINIT_H */
@@ -0,0 +1,17 @@
#ifndef METROTRK_PORTABLE_SERPOLL_H
#define METROTRK_PORTABLE_SERPOLL_H
#ifdef __cplusplus
extern "C" {
#endif
void TRKGetInput(void);
extern void* gTRKInputPendingPtr;
#ifdef __cplusplus
}
#endif
#endif /* METROTRK_PORTABLE_SERPOLL_H */
@@ -0,0 +1,6 @@
#ifndef METROTRK_PORTABLE_STRING_TRK_H
#define METROTRK_PORTABLE_STRING_TRK_H
int TRK_strlen(const char* str);
#endif /* METROTRK_PORTABLE_STRING_TRK_H */
@@ -0,0 +1,18 @@
#ifndef METROTRK_PORTABLE_SUPPORT_H
#define METROTRK_PORTABLE_SUPPORT_H
#include "trk.h"
#ifdef __cplusplus
extern "C" {
#endif
typedef struct TRKBuffer TRKBuffer;
DSError TRKRequestSend(TRKBuffer* msgBuf, int* bufferId, u32 p1, u32 p2, int p3);
#ifdef __cplusplus
}
#endif
#endif /* METROTRK_PORTABLE_SUPPORT_H */
@@ -0,0 +1,25 @@
#ifndef OS_DOLPHIN_DDH_STUBS_H
#define OS_DOLPHIN_DDH_STUBS_H
#include "dolphin/exi/EXIBios.h"
#ifdef __cplusplus
extern "C" {
#endif
int ddh_cc_initialize(void* inputPendingPtrRef, EXICallback monitorCallback);
int ddh_cc_shutdown();
int ddh_cc_open();
int ddh_cc_close();
int ddh_cc_read(u8* data, int size);
int ddh_cc_write(const u8* bytes, int length);
int ddh_cc_pre_continue();
int ddh_cc_post_stop();
int ddh_cc_peek();
int ddh_cc_initinterrupts();
#ifdef __cplusplus
}
#endif
#endif /* OS_DOLPHIN_DDH_STUBS_H */
@@ -0,0 +1,25 @@
#ifndef OS_DOLPHIN_GDEV_STUBS_H
#define OS_DOLPHIN_GDEV_STUBS_H
#include "dolphin/exi/EXIBios.h"
#ifdef __cplusplus
extern "C" {
#endif
int gdev_cc_initialize(void* inputPendingPtrRef, EXICallback monitorCallback);
int gdev_cc_shutdown();
int gdev_cc_open();
int gdev_cc_close();
int gdev_cc_read(u8* data, int size);
int gdev_cc_write(const u8* bytes, int length);
int gdev_cc_pre_continue();
int gdev_cc_post_stop();
int gdev_cc_peek();
int gdev_cc_initinterrupts();
#ifdef __cplusplus
}
#endif
#endif /* OS_DOLPHIN_GDEV_STUBS_H */
@@ -0,0 +1,24 @@
#ifndef OS_DOLPHIN_UDP_STUBS_H
#define OS_DOLPHIN_UDP_STUBS_H
#include "dolphin/os/OS.h"
#ifdef __cplusplus
extern "C" {
#endif
int udp_cc_initialize(void* flagOut, __OSInterruptHandler handler);
int udp_cc_shutdown(void);
int udp_cc_open(void);
int udp_cc_close(void);
int udp_cc_read(u8* dest, int size);
int udp_cc_write(const u8* src, int size);
int udp_cc_peek(void);
int udp_cc_pre_continue(void);
int udp_cc_post_stop(void);
#ifdef __cplusplus
}
#endif
#endif /* OS_DOLPHIN_UDP_STUBS_H */
@@ -0,0 +1,6 @@
#ifndef OS_DOLPHIN_DOLPHIN_TRK_H
#define OS_DOLPHIN_DOLPHIN_TRK_H
void EnableMetroTRKInterrupts();
#endif /* OS_DOLPHIN_DOLPHIN_TRK_H */
@@ -0,0 +1,40 @@
#ifndef OS_DOLPHIN_DOLPHIN_TRK_GLUE_H
#define OS_DOLPHIN_DOLPHIN_TRK_GLUE_H
#include "trk.h"
#include "dolphin/os/OS.h"
#ifdef __cplusplus
extern "C" {
#endif
typedef int (*DBCommFunc)();
typedef int (*DBCommInitFunc)(void*, __OSInterruptHandler);
typedef int (*DBCommReadFunc)(u8*, int);
typedef int (*DBCommWriteFunc)(const u8*, int);
typedef struct DBCommTable {
DBCommInitFunc initialize_func;
DBCommFunc init_interrupts_func;
DBCommFunc shutdown_func;
DBCommFunc peek_func;
DBCommReadFunc read_func;
DBCommWriteFunc write_func;
DBCommFunc open_func;
DBCommFunc close_func;
DBCommFunc pre_continue_func;
DBCommFunc post_stop_func;
} DBCommTable;
void UnreserveEXI2Port();
void ReserveEXI2Port();
UARTError TRKWriteUARTN(const void*, u32);
void TRKLoadContext(OSContext* ctx, u32 r4);
int InitMetroTRKCommTable(int hwId);
#ifdef __cplusplus
}
#endif
#endif /* OS_DOLPHIN_DOLPHIN_TRK_GLUE_H */
@@ -0,0 +1,16 @@
#ifndef OS_DOLPHIN_TARGCONT_H
#define OS_DOLPHIN_TARGCONT_H
#include "trk.h"
#ifdef __cplusplus
extern "C" {
#endif
DSError TRKTargetContinue(void);
#ifdef __cplusplus
}
#endif
#endif /* OS_DOLPHIN_TARGCONT_H */
@@ -0,0 +1,17 @@
#ifndef OS_DOLPHIN_TARGET_OPTIONS_H
#define OS_DOLPHIN_TARGET_OPTIONS_H
#include "dolphin/types.h"
#ifdef __cplusplus
extern "C" {
#endif
u8 GetUseSerialIO(void);
void SetUseSerialIO(u8);
#ifdef __cplusplus
}
#endif
#endif /* OS_DOLPHIN_TARGET_OPTIONS_H */
@@ -0,0 +1,6 @@
#ifndef OS_DOLPHIN_USR_PUT_H
#define OS_DOLPHIN_USR_PUT_H
#include "dolphin/types.h"
#endif /* OS_DOLPHIN_USR_PUT_H */
@@ -0,0 +1,19 @@
#ifndef PPC_EXPORT_TARGSUPP_H
#define PPC_EXPORT_TARGSUPP_H
#include "dolphin/types.h"
#ifdef __cplusplus
extern "C" {
#endif
u32 TRKAccessFile(u32, u32, u32*, u8*);
u32 TRKOpenFile(u32, u32, u32*, u8*);
u32 TRKCloseFile(u32, u32);
u32 TRKPositionFile(u32, u32, u32*, u8*);
#ifdef __cplusplus
}
#endif
#endif /* PPC_EXPORT_TARGSUPP_H */
@@ -0,0 +1,5 @@
#ifndef PPC_GENERIC_FLUSH_CACHE_H
#define PPC_GENERIC_FLUSH_CACHE_H
#endif /* PPC_GENERIC_FLUSH_CACHE_H */
@@ -0,0 +1,5 @@
#ifndef PPC_GENERIC_MPC_7XX_603E_H
#define PPC_GENERIC_MPC_7XX_603E_H
#endif /* PPC_GENERIC_MPC_7XX_603E_H */
@@ -0,0 +1,143 @@
#ifndef PPC_GENERIC_TARGIMPL_H
#define PPC_GENERIC_TARGIMPL_H
#include "TRK_MINNOW_DOLPHIN/MetroTRK/Portable/nubevent.h"
#ifdef __cplusplus
extern "C" {
#endif
void TRKSwapAndGo();
void TRKTargetSetStopped(unsigned int);
DSError TRKTargetInterrupt(TRKEvent*);
DSError TRKTargetSupportRequest();
void TRKDestructEvent(TRKEvent*);
BOOL TRKTargetStopped(void);
typedef struct Default_PPC {
u32 GPR[32];
u32 PC;
u32 LR;
u32 CR;
u32 CTR;
u32 XER;
} Default_PPC;
typedef struct Float_PPC {
u64 FPR[32];
u64 FPSCR;
u64 FPECR;
} Float_PPC;
typedef struct Extended1_PPC_6xx_7xx {
u32 SR[16];
u32 TBL;
u32 TBU;
u32 HID0;
u32 HID1;
u32 MSR;
u32 PVR;
u32 IBAT0U;
u32 IBAT0L;
u32 IBAT1U;
u32 IBAT1L;
u32 IBAT2U;
u32 IBAT2L;
u32 IBAT3U;
u32 IBAT3L;
u32 DBAT0U;
u32 DBAT0L;
u32 DBAT1U;
u32 DBAT1L;
u32 DBAT2U;
u32 DBAT2L;
u32 DBAT3U;
u32 DBAT3L;
u32 DMISS;
u32 DCMP;
u32 HASH1;
u32 HASH2;
u32 IMISS;
u32 ICMP;
u32 RPA;
u32 SDR1;
u32 DAR;
u32 DSISR;
u32 SPRG0;
u32 SPRG1;
u32 SPRG2;
u32 SPRG3;
u32 DEC;
u32 IABR;
u32 EAR;
u32 DABR;
u32 PMC1;
u32 PMC2;
u32 PMC3;
u32 PMC4;
u32 SIA;
u32 MMCR0;
u32 MMCR1;
u32 THRM1;
u32 THRM2;
u32 THRM3;
u32 ICTC;
u32 L2CR;
u32 UMMCR2;
u32 UBAMR;
u32 UMMCR0;
u32 UPMC1;
u32 UPMC2;
u32 USIA;
u32 UMMCR1;
u32 UPMC3;
u32 UPMC4;
u32 USDA;
u32 MMCR2;
u32 BAMR;
u32 SDA;
u32 MSSCR0;
u32 MSSCR1;
u32 PIR;
u32 exceptionID;
u32 GQR[8];
u32 HID_G;
u32 WPAR;
u32 DMA_U;
u32 DMA_L;
} Extended1_PPC_6xx_7xx;
typedef struct Extended2_PPC_6xx_7xx {
u32 PSR[32][2];
} Extended2_PPC_6xx_7xx;
typedef struct ProcessorState_PPC_6xx_7xx {
Default_PPC Default;
Float_PPC Float;
Extended1_PPC_6xx_7xx Extended1;
Extended2_PPC_6xx_7xx Extended2;
u32 transport_handler_saved_ra;
} ProcessorState_PPC_6xx_7xx;
typedef ProcessorState_PPC_6xx_7xx ProcessorState_PPC;
extern ProcessorState_PPC gTRKCPUState;
typedef struct TRKState {
u32 gpr[32]; // _00
u32 lr; // _80
u32 ctr; // _84
u32 xer; // _88
u32 msr; // _8C
u32 dar; // _90
u32 dsisr; // _94
BOOL isStopped; // _98
BOOL inputActivated; // _9C
void* inputPendingPtr; // _A0
} TRKState;
extern TRKState gTRKState;
#ifdef __cplusplus
}
#endif
#endif /* PPC_GENERIC_TARGIMPL_H */
@@ -0,0 +1,29 @@
#ifndef UTILS_COMMON_CIRCLEBUFFER_H
#define UTILS_COMMON_CIRCLEBUFFER_H
#include "dolphin/types.h"
#ifdef __cplusplus
extern "C" {
#endif
typedef struct CircleBuffer {
u8* read_ptr;
u8* write_ptr;
u8* start_ptr;
u32 size;
s32 mBytesToRead;
u32 mBytesToWrite;
u32 mCriticalSection;
} CircleBuffer;
int CircleBufferReadBytes(CircleBuffer*, u8*, u32);
int CircleBufferWriteBytes(CircleBuffer*, u8*, u32);
void CircleBufferInitialize(CircleBuffer*, u8*, s32);
u32 CBGetBytesAvailableForRead(CircleBuffer*);
#ifdef __cplusplus
}
#endif
#endif /* UTILS_COMMON_CIRCLEBUFFER_H */
@@ -0,0 +1,8 @@
#ifndef UTILS_COMMON_MWTRACE_H
#define UTILS_COMMON_MWTRACE_H
#include "dolphin/types.h"
void MWTRACE(u8, char*, ...);
#endif /* UTILS_COMMON_MWTRACE_H */
@@ -0,0 +1,18 @@
#ifndef UTILS_GC_MWCRITICALSECTION_GC_H
#define UTILS_GC_MWCRITICALSECTION_GC_H
#include "dolphin/types.h"
#ifdef __cplusplus
extern "C" {
#endif
void MWExitCriticalSection(unsigned int* section);
void MWEnterCriticalSection(unsigned int* section);
void MWInitializeCriticalSection(unsigned int*);
#ifdef __cplusplus
}
#endif
#endif /* UTILS_GC_MWCRITICALSECTION_GC_H */
+194 -25
View File
@@ -1,12 +1,19 @@
#ifndef CARD_H
#define CARD_H
#include "dolphin/types.h"
#include "dolphin/dsp.h"
#include "dolphin/os/OS.h"
#ifdef __cplusplus
extern "C" {
#endif
#define CARD_FILENAME_MAX 32
#define CARD_MAX_FILE 127
#define CARD_ICON_MAX 8
typedef void (*CARDCallback)(s32 chan, s32 result);
typedef struct CARDFileInfo {
/* 0x00 */ s32 chan;
/* 0x04 */ s32 fileNo;
@@ -17,35 +24,139 @@ typedef struct CARDFileInfo {
} CARDFileInfo;
typedef struct CARDStat {
u8 fileName[32];
u32 dataLength;
u32 lastModified;
u8 gameCode[4];
u8 company[2];
u8 bannerFmt;
u32 iconAddr;
u16 iconFormat;
u16 iconSpeed;
u32 commentAddr;
u32 offsetBanner;
u32 offsetBannerTlut;
u32 offsetIcon[8];
u32 offsetIconTlut;
u32 offsetData;
/* 0x00 */ char fileName[CARD_FILENAME_MAX];
/* 0x20 */ u32 length;
/* 0x24 */ u32 time;
/* 0x28 */ u8 gameName[4];
/* 0x2C */ u8 company[2];
/* 0x2E */ u8 bannerFormat;
/* 0x30 */ u32 iconAddr;
/* 0x34 */ u16 iconFormat;
/* 0x36 */ u16 iconSpeed;
/* 0x38 */ u32 commentAddr;
/* 0x3C */ u32 offsetBanner;
/* 0x40 */ u32 offsetBannerTlut;
/* 0x44 */ u32 offsetIcon[CARD_ICON_MAX];
/* 0x64 */ u32 offsetIconTlut;
/* 0x68 */ u32 offsetData;
} CARDStat;
#define CARDGetBannerFormat(stat) ((stat)->bannerFmt & 0x03)
#define CARDGetIconAnim(stat) ((stat)->bannerFmt & 0x04)
typedef struct CARDDir {
u8 gameName[4];
u8 company[2];
u8 _padding0;
u8 bannerFormat;
u8 fileName[CARD_FILENAME_MAX];
u32 time; // seconds since 01/01/2000 midnight
u32 iconAddr; // 0xffffffff if not used
u16 iconFormat;
u16 iconSpeed;
u8 permission;
u8 copyTimes;
u16 startBlock;
u16 length;
u8 _padding1[2];
u32 commentAddr; // 0xffffffff if not used
} CARDDir;
typedef struct CARDID {
/* 0x000 */ u8 serial[32];
/* 0x020 */ u16 deviceID;
/* 0x022 */ u16 size;
/* 0x024 */ u16 encode;
/* 0x026 */ u8 padding[470];
/* 0x1FC */ u16 checkSum;
/* 0x1FE */ u16 checkSumInv;
} CARDID;
typedef struct CARDDecParam {
/* 0x00 */ u8* inputAddr;
/* 0x04 */ u32 inputLength;
/* 0x08 */ u32 aramAddr;
/* 0x0C */ u8* outputAddr;
} CARDDecParam;
typedef struct CARDControl {
/* 0x000 */ BOOL attached;
/* 0x004 */ s32 result;
/* 0x008 */ u16 size;
/* 0x00A */ u16 pageSize;
/* 0x00C */ s32 sectorSize;
/* 0x010 */ u16 cBlock;
/* 0x012 */ u16 vendorID;
/* 0x014 */ s32 latency;
/* 0x018 */ u8 id[12];
/* 0x024 */ int mountStep;
/* 0x028 */ int formatStep;
/* 0x028 */ u32 scramble;
/* 0x02C */ DSPTaskInfo task;
/* 0x080 */ void* workArea;
/* 0x084 */ CARDDir* currentDir;
/* 0x088 */ u16* currentFat;
/* 0x08C */ OSThreadQueue threadQueue;
/* 0x094 */ u8 cmd[9];
/* 0x0A0 */ s32 cmdlen;
/* 0x0A4 */ volatile u32 mode;
/* 0x0A8 */ int retry;
/* 0x0AC */ int repeat;
/* 0x0B0 */ u32 addr;
/* 0x0B4 */ void* buffer;
/* 0x0B8 */ s32 xferred;
/* 0x0BC */ u16 freeNo;
/* 0x0BE */ u16 startBlock;
/* 0x0C0 */ CARDFileInfo* fileInfo;
/* 0x0C4 */ CARDCallback extCallback;
/* 0x0C8 */ CARDCallback txCallback;
/* 0x0CC */ CARDCallback exiCallback;
/* 0x0D0 */ CARDCallback apiCallback;
/* 0x0D4 */ CARDCallback xferCallback;
/* 0x0D8 */ CARDCallback eraseCallback;
/* 0x0DC */ CARDCallback unlockCallback;
/* 0x0E0 */ OSAlarm alarm;
/* 0x108 */ u32 cid;
/* 0x10C */ const DVDDiskID* diskID;
} CARDControl;
typedef struct CARDDirCheck {
/* 0x00 */ u8 padding0[56];
/* 0x38 */ u16 padding1;
/* 0x3A */ s16 checkCode;
/* 0x3C */ u16 checkSum;
/* 0x3E */ u16 checkSumInv;
} CARDDirCheck;
#define CARDGetBannerFormat(stat) ((stat)->bannerFormat & 0x03)
#define CARDGetIconAnim(stat) ((stat)->bannerFormat & 0x04)
#define CARDGetIconFormat(stat, n) ((stat)->iconFormat >> (2 * (n)) & 0x03)
#define CARDGetIconSpeed(stat, n) ((stat)->iconSpeed >> (2 * (n)) & 0x03)
#define CARDSetBannerFormat(stat, v) ((stat)->bannerFmt = (u8)(((stat)->bannerFmt & ~0x03) | (v)))
#define CARDSetIconAnim(stat, v) ((stat)->bannerFmt = (u8)(((stat)->bannerFmt & ~0x04) | (v)))
#define CARDSetBannerFormat(stat, v) ((stat)->bannerFormat = (u8)(((stat)->bannerFormat & ~0x03) | (v)))
#define CARDSetIconAnim(stat, v) ((stat)->bannerFormat = (u8)(((stat)->bannerFormat & ~0x04) | (v)))
#define CARDSetIconFormat(stat, n, v) ((stat)->iconFormat = (u16)(((stat)->iconFormat & ~(0x03 << (2 * (n)))) | ((v) << (2 * (n)))))
#define CARDSetIconSpeed(stat, n, v) ((stat)->iconSpeed = (u16)(((stat)->iconSpeed & ~(0x03 << (2 * (n)))) | ((v) << (2 * (n)))))
#define CARD_ENCODE_ANSI 0
#define CARD_ENCODE_SJIS 1
#define CARD_READ_SIZE 512
#define CARD_COMMENT_SIZE 64
#define CARD_ICON_WIDTH 32
#define CARD_ICON_HEIGHT 32
#define CARD_BANNER_WIDTH 96
#define CARD_BANNER_HEIGHT 32
#define CARD_STAT_ICON_NONE 0
#define CARD_STAT_ICON_C8 1
#define CARD_STAT_ICON_RGB5A3 2
#define CARD_STAT_ICON_MASK 3
#define CARD_STAT_BANNER_NONE 0
#define CARD_STAT_BANNER_C8 1
#define CARD_STAT_BANNER_RGB5A3 2
#define CARD_STAT_BANNER_MASK 3
enum {
CARD_ERROR_UNLOCKED = 1,
CARD_ERROR_READY = 0,
@@ -66,23 +177,81 @@ enum {
CARD_ERROR_FATAL_ERROR = -128,
};
#define CARD_ATTR_PUBLIC 0x04u
#define CARD_ATTR_NO_COPY 0x08u
#define CARD_ATTR_NO_MOVE 0x10u
#define CARD_ATTR_GLOBAL 0x20u
#define CARD_ATTR_COMPANY 0x40u
#define CARD_FAT_AVAIL 0x0000u
#define CARD_FAT_CHECKSUM 0x0000u
#define CARD_FAT_CHECKSUMINV 0x0001u
#define CARD_FAT_CHECKCODE 0x0002u
#define CARD_FAT_FREEBLOCKS 0x0003u
#define CARD_FAT_LASTSLOT 0x0004u
#define CARD_WORKAREA_SIZE (5 * 8 * 1024)
#define CARD_SEG_SIZE 0x200u
#define CARD_PAGE_SIZE 0x80u
#define CARD_MAX_SIZE 0x01000000U
#define CARD_NUM_SYSTEM_BLOCK 5
#define CARD_SYSTEM_BLOCK_SIZE (8 * 1024u)
#define CARD_MAX_MOUNT_STEP (CARD_NUM_SYSTEM_BLOCK + 2)
#define CARD_STAT_SPEED_END 0
#define CARD_STAT_SPEED_FAST 1
#define CARD_STAT_SPEED_MIDDLE 2
#define CARD_STAT_SPEED_SLOW 3
#define CARD_STAT_SPEED_MASK 3
#define CARD_STAT_ANIM_LOOP 0
#define CARD_STAT_ANIM_BOUNCE 4
#define CARD_STAT_ANIM_MASK 0x4
#define CARD_RESULT_UNLOCKED 1
#define CARD_RESULT_READY 0
#define CARD_RESULT_BUSY -1
#define CARD_RESULT_WRONGDEVICE -2
#define CARD_RESULT_NOCARD -3
#define CARD_RESULT_NOFILE -4
#define CARD_RESULT_IOERROR -5
#define CARD_RESULT_BROKEN -6
#define CARD_RESULT_EXIST -7
#define CARD_RESULT_NOENT -8
#define CARD_RESULT_INSSPACE -9
#define CARD_RESULT_NOPERM -10
#define CARD_RESULT_LIMIT -11
#define CARD_RESULT_NAMETOOLONG -12
#define CARD_RESULT_ENCODING -13
#define CARD_RESULT_CANCELED -14
#define CARD_RESULT_FATAL_ERROR -128
#define CARDIsValidBlockNo(card, blockNo) ((blockNo) >= CARD_NUM_SYSTEM_BLOCK && (blockNo) < (card)->cBlock)
#define CARDGetDirCheck(dir) ((CARDDirCheck*)&(dir)[CARD_MAX_FILE])
void CARDInit();
BOOL CARDProbe(s32);
s32 CARDGetStatus(s32, s32, CARDStat*);
s32 CARDSetStatus(s32, s32, CARDStat*);
s32 CARDOpen(s32, const char*, CARDFileInfo*);
s32 CARDClose(CARDFileInfo*);
s32 CARDCreate(s32, const char*, s32, CARDFileInfo*);
s32 CARDCreate(s32, const char*, u32, CARDFileInfo*);
s32 CARDFormat(s32);
s32 CARDProbeEx(s32, s32*, s32*);
s32 CARDUnmount(s32);
s32 CARDMount(s32, void*, void*);
s32 CARDMount(s32 chan, void* workArea, CARDCallback detachCallback);
s32 CARDCheck(s32);
s32 CARDFreeBlocks(s32, s32*, s32*);
s32 CARDRead(CARDFileInfo* fileInfo, void* buf, s32 length, s32 offset);
s32 CARDWrite(CARDFileInfo* fileInfo, const void* buf, s32 length, s32 offset);
s32 CARDWrite(CARDFileInfo* fileInfo, void* buf, s32 length, s32 offset);
s32 CARDGetSerialNo(s32, u64*);
extern CARDControl __CARDBlock[2];
extern DVDDiskID __CARDDiskNone;
#ifdef __cplusplus
}
#endif
+59 -3
View File
@@ -8,18 +8,26 @@
extern "C" {
#endif
#define GX_LOAD_CP_REG 0x08
#define GX_LOAD_XF_REG 0x10
#define GX_LOAD_INDX_A 0x20
#define GX_LOAD_INDX_B 0x28
#define GX_LOAD_INDX_C 0x30
#define GX_LOAD_INDX_D 0x38
#define GX_LOAD_BP_REG 0x61
typedef struct _GDLObj {
/* 0x0 */ u8* start;
/* 0x4 */ u32 length;
/* 0x8 */ u8* ptr;
/* 0xC */ u8* end;
/* 0xC */ u8* top;
} GDLObj; // Size: 0x10
extern GDLObj* __GDCurrentDL;
typedef void (*GDOverflowCallback)(void);
void GDInitGDLObj(GDLObj*, u8*, u32);
void GDInitGDLObj(GDLObj*, void*, u32);
void GDFlushCurrToMem(void);
void GDPadCurr32(void);
void GDOverflowed(void);
@@ -59,7 +67,7 @@ inline GDLObj* GDGetCurrent() {
} */
inline void GDOverflowCheck(u32 len) {
if (__GDCurrentDL->ptr + len > __GDCurrentDL->end) {
if (__GDCurrentDL->ptr + len > __GDCurrentDL->top) {
GDOverflowed();
}
}
@@ -83,6 +91,54 @@ inline void GDWrite_u8(u8 v) {
__GDWrite(v);
}
inline static void GDWriteXFCmdHdr(u16 addr, u8 len) {
GDWrite_u8(GX_LOAD_XF_REG);
GDWrite_u16(len - 1);
GDWrite_u16(addr);
}
inline static void GDWriteXFCmd(u16 addr, u32 val) {
GDWrite_u8(GX_LOAD_XF_REG);
GDWrite_u16(0);
GDWrite_u16(addr);
GDWrite_u32(val);
}
inline static void GDWriteXFIndxDCmd(u16 addr, u8 len, u16 index) {
GDWrite_u8(GX_LOAD_INDX_D);
GDWrite_u16(index);
GDWrite_u16((len - 1) << 12 | addr);
}
inline static void GDWriteXFIndxACmd(u16 addr, u8 len, u16 index) {
GDWrite_u8(GX_LOAD_INDX_A);
GDWrite_u16(index);
GDWrite_u16(((len - 1) << 12) | addr);
}
inline static void GDWriteXFIndxBCmd(u16 addr, u8 len, u16 index) {
GDWrite_u8(GX_LOAD_INDX_B);
GDWrite_u16(index);
GDWrite_u16(((len - 1) << 12) | addr);
}
inline static void GDWriteXFIndxCCmd(u16 addr, u8 len, u16 index) {
GDWrite_u8(GX_LOAD_INDX_C);
GDWrite_u16(index);
GDWrite_u16(((len - 1) << 12) | addr);
}
inline static void GDWriteCPCmd(u8 addr, u32 val) {
GDWrite_u8(GX_LOAD_CP_REG);
GDWrite_u8(addr);
GDWrite_u32(val);
}
inline static void GDWriteBPCmd(u32 regval) {
GDWrite_u8(GX_LOAD_BP_REG);
GDWrite_u32(regval);
}
#ifdef __cplusplus
};
#endif
+499 -1
View File
@@ -7,10 +7,508 @@
extern "C" {
#endif
// Command processor register IDs
#define CP_REG_MTXIDXA_ID 0x30 // Matrix index A
#define CP_REG_MTXIDXB_ID 0x40 // Matrix index B
#define CP_REG_VCD_LO_ID 0x50 // Vertex descriptor (lo)
#define CP_REG_VCD_HI_ID 0x60 // Vertex descriptor (hi)
#define CP_REG_VAT_GRP0_ID 0x70 // Vertex attribute table (group 0)
#define CP_REG_VAT_GRP1_ID 0x80 // Vertex attribute table (group 1)
#define CP_REG_VAT_GRP2_ID 0x90 // Vertex attribute table (group 2)
#define CP_REG_ARRAYBASE_ID 0xA0 // Vertex array start/base
#define CP_REG_ARRAYSTRIDE_ID 0xB0 // Vertex array stride
// XF locators for textures
// Projection type [30-30]
#define GX_XF_TEX_PROJTYPE_ST 30
#define GX_XF_TEX_PROJTYPE_END 30
// Input format [29-29]
#define GX_XF_TEX_INPUTFORM_ST 29
#define GX_XF_TEX_INPUTFORM_END 29
// Texture gen type [25-27]
#define GX_XF_TEX_TEXGENTYPE_ST 25
#define GX_XF_TEX_TEXGENTYPE_END 27
// Source row [20-24]
#define GX_XF_TEX_SRCROW_ST 20
#define GX_XF_TEX_SRCROW_END 24
// Bump source texture [17-19]
#define GX_XF_TEX_BUMPSRCTEX_ST 17
#define GX_XF_TEX_BUMPSRCTEX_END 19
// Bump source light [14-16]
#define GX_XF_TEX_BUMPSRCLIGHT_ST 14
#define GX_XF_TEX_BUMPSRCLIGHT_END 16
// Blitting processor registers.
#define GX_BP_REG_GENMODE 0x0 // gen mode
// display copy filters
#define GX_BP_REG_DISPCOPYFILTER0 0x1 // display copy filter 0
#define GX_BP_REG_DISPCOPYFILTER1 0x2 // display copy filter 1
#define GX_BP_REG_DISPCOPYFILTER2 0x3 // display copy filter 2
#define GX_BP_REG_DISPCOPYFILTER3 0x4 // display copy filter 3
// indirect matrices
#define GX_BP_REG_INDMTX0A 0x6 // indirect matrix 0A
#define GX_BP_REG_INDMTX0B 0x7 // indirect matrix 0B
#define GX_BP_REG_INDMTX0C 0x8 // indirect matrix 0C
#define GX_BP_REG_INDMTX1A 0x9 // indirect matrix 1A
#define GX_BP_REG_INDMTX1B 0xA // indirect matrix 1B
#define GX_BP_REG_INDMTX1C 0xB // indirect matrix 1C
#define GX_BP_REG_INDMTX2A 0xC // indirect matrix 2A
#define GX_BP_REG_INDMTX2B 0xD // indirect matrix 2B
#define GX_BP_REG_INDMTX2C 0xE // indirect matrix 2C
#define GX_BP_REG_INDIMASK 0xF // indirect mask
// indirect TEV stages
#define GX_BP_REG_INDTEVSTAGE0 0x10 // indirect TEV stage 0
#define GX_BP_REG_INDTEVSTAGE1 0x11 // indirect TEV stage 1
#define GX_BP_REG_INDTEVSTAGE2 0x12 // indirect TEV stage 2
#define GX_BP_REG_INDTEVSTAGE3 0x13 // indirect TEV stage 3
#define GX_BP_REG_INDTEVSTAGE4 0x14 // indirect TEV stage 4
#define GX_BP_REG_INDTEVSTAGE5 0x15 // indirect TEV stage 5
#define GX_BP_REG_INDTEVSTAGE6 0x16 // indirect TEV stage 6
#define GX_BP_REG_INDTEVSTAGE7 0x17 // indirect TEV stage 7
#define GX_BP_REG_INDTEVSTAGE8 0x18 // indirect TEV stage 8
#define GX_BP_REG_INDTEVSTAGE9 0x19 // indirect TEV stage 9
#define GX_BP_REG_INDTEVSTAGE10 0x1A // indirect TEV stage 10
#define GX_BP_REG_INDTEVSTAGE11 0x1B // indirect TEV stage 11
#define GX_BP_REG_INDTEVSTAGE12 0x1C // indirect TEV stage 12
#define GX_BP_REG_INDTEVSTAGE13 0x1D // indirect TEV stage 13
#define GX_BP_REG_INDTEVSTAGE14 0x1E // indirect TEV stage 14
#define GX_BP_REG_INDTEVSTAGE15 0x1F // indirect TEV stage 15
// performance manips
#define GX_BP_REG_SCISSORTL 0x20 // scissor top left
#define GX_BP_REG_SCISSORBR 0x21 // scissor bottom right
#define GX_BP_REG_LINEPTWIDTH 0x22 // line point width
#define GX_BP_REG_PERF0TRI 0x23 // performance 0 (triangle)
#define GX_BP_REG_PERF0QUAD 0x24 // performance 0 (quad)
// rasters
#define GX_BP_REG_RAS1_SS0 0x25
#define GX_BP_REG_RAS1_SS1 0x26
#define GX_BP_REG_RAS1_IREF 0x27
#define GX_BP_REG_RAS1_TREF0 0x28
#define GX_BP_REG_RAS1_TREF1 0x29
#define GX_BP_REG_RAS1_TREF2 0x2A
#define GX_BP_REG_RAS1_TREF3 0x2B
#define GX_BP_REG_RAS1_TREF4 0x2C
#define GX_BP_REG_RAS1_TREF5 0x2D
#define GX_BP_REG_RAS1_TREF6 0x2E
#define GX_BP_REG_RAS1_TREF7 0x2F
// setup sizes
#define GX_BP_REG_SU_SSIZE0 0x30
#define GX_BP_REG_SU_TSIZE0 0x31
#define GX_BP_REG_SU_SSIZE1 0x32
#define GX_BP_REG_SU_TSIZE1 0x33
#define GX_BP_REG_SU_SSIZE2 0x34
#define GX_BP_REG_SU_TSIZE2 0x35
#define GX_BP_REG_SU_SSIZE3 0x36
#define GX_BP_REG_SU_TSIZE3 0x37
#define GX_BP_REG_SU_SSIZE4 0x38
#define GX_BP_REG_SU_TSIZE4 0x39
#define GX_BP_REG_SU_SSIZE5 0x3A
#define GX_BP_REG_SU_TSIZE5 0x3B
#define GX_BP_REG_SU_SSIZE6 0x3C
#define GX_BP_REG_SU_TSIZE6 0x3D
#define GX_BP_REG_SU_SSIZE7 0x3E
#define GX_BP_REG_SU_TSIZE7 0x3F
// Z and blend controls
#define GX_BP_REG_ZMODE 0x40
#define GX_BP_REG_BLENDMODE 0x41
#define GX_BP_REG_DSTALPHA 0x42
#define GX_BP_REG_ZCONTROL 0x43
#define GX_BP_REG_FIELDMASK 0x44
#define GX_BP_REG_DRAWDONE 0x45
#define GX_BP_REG_PETOKEN 0x47
#define GX_BP_REG_PETOKENINT 0x48
// copying
#define GX_BP_REG_TEXCOPYSRCXY 0x49
#define GX_BP_REG_TEXCOPYSRCWH 0x4A
#define GX_BP_REG_TEXCOPYDST 0x4B
#define GX_BP_REG_DISPCOPYSTRIDE 0x4D
#define GX_BP_REG_DISPCOPYSCALEY 0x4E
#define GX_BP_REG_COPYCLEARAR 0x4F
#define GX_BP_REG_COPYCLEARGB 0x50
#define GX_BP_REG_COPYCLEARZ 0x51
#define GX_BP_REG_COPYFILTER0 0x53
#define GX_BP_REG_COPYFILTER1 0x54
//
#define GX_BP_REG_BOUNDINGBOX0 0x55
#define GX_BP_REG_BOUNDINGBOX1 0x56
#define GX_BP_REG_SCISSOROFFSET 0x59
// texture memory
#define GX_BP_REG_TMEMPRELOADADDR 0x60
#define GX_BP_REG_TMEMPRELOADEVEN 0x61
#define GX_BP_REG_TMEMPRELOADODD 0x62
#define GX_BP_REG_TMEMPRELOADMODE 0x63
#define GX_BP_REG_TMEMTLUTSRC 0x64
#define GX_BP_REG_TMEMTLUTDST 0x65
#define GX_BP_REG_TMEMTEXINVALIDATE 0x66
// performance 1
#define GX_BP_REG_PERF1 0x67
#define GX_BP_REG_FIELDMODE 0x68
// set modes
#define GX_BP_REG_SETMODE0_TEX0 0x80
#define GX_BP_REG_SETMODE0_TEX1 0x81
#define GX_BP_REG_SETMODE0_TEX2 0x82
#define GX_BP_REG_SETMODE0_TEX3 0x83
#define GX_BP_REG_SETMODE1_TEX0 0x84
#define GX_BP_REG_SETMODE1_TEX1 0x85
#define GX_BP_REG_SETMODE1_TEX2 0x86
#define GX_BP_REG_SETMODE1_TEX3 0x87
// set images
#define GX_BP_REG_SETIMAGE0_TEX0 0x88
#define GX_BP_REG_SETIMAGE0_TEX1 0x89
#define GX_BP_REG_SETIMAGE0_TEX2 0x8A
#define GX_BP_REG_SETIMAGE0_TEX3 0x8B
#define GX_BP_REG_SETIMAGE1_TEX0 0x8C
#define GX_BP_REG_SETIMAGE1_TEX1 0x8D
#define GX_BP_REG_SETIMAGE1_TEX2 0x8E
#define GX_BP_REG_SETIMAGE1_TEX3 0x8F
#define GX_BP_REG_SETIMAGE2_TEX0 0x90
#define GX_BP_REG_SETIMAGE2_TEX1 0x91
#define GX_BP_REG_SETIMAGE2_TEX2 0x92
#define GX_BP_REG_SETIMAGE2_TEX3 0x93
#define GX_BP_REG_SETIMAGE3_TEX0 0x94
#define GX_BP_REG_SETIMAGE3_TEX1 0x95
#define GX_BP_REG_SETIMAGE3_TEX2 0x96
#define GX_BP_REG_SETIMAGE3_TEX3 0x97
// set texture lookups
#define GX_BP_REG_SETTLUT_TEX0 0x98
#define GX_BP_REG_SETTLUT_TEX1 0x99
#define GX_BP_REG_SETTLUT_TEX2 0x9A
#define GX_BP_REG_SETTLUT_TEX3 0x9B
// set modes continued
#define GX_BP_REG_SETMODE0_TEX4 0xA0
#define GX_BP_REG_SETMODE0_TEX5 0xA1
#define GX_BP_REG_SETMODE0_TEX6 0xA2
#define GX_BP_REG_SETMODE0_TEX7 0xA3
#define GX_BP_REG_SETMODE1_TEX4 0xA4
#define GX_BP_REG_SETMODE1_TEX5 0xA5
#define GX_BP_REG_SETMODE1_TEX6 0xA6
#define GX_BP_REG_SETMODE1_TEX7 0xA7
// set images continued
#define GX_BP_REG_SETIMAGE0_TEX4 0xA8
#define GX_BP_REG_SETIMAGE0_TEX5 0xA9
#define GX_BP_REG_SETIMAGE0_TEX6 0xAA
#define GX_BP_REG_SETIMAGE0_TEX7 0xAB
#define GX_BP_REG_SETIMAGE1_TEX4 0xAC
#define GX_BP_REG_SETIMAGE1_TEX5 0xAD
#define GX_BP_REG_SETIMAGE1_TEX6 0xAE
#define GX_BP_REG_SETIMAGE1_TEX7 0xAF
#define GX_BP_REG_SETIMAGE2_TEX4 0xB0
#define GX_BP_REG_SETIMAGE2_TEX5 0xB1
#define GX_BP_REG_SETIMAGE2_TEX6 0xB2
#define GX_BP_REG_SETIMAGE2_TEX7 0xB3
#define GX_BP_REG_SETIMAGE3_TEX4 0xB4
#define GX_BP_REG_SETIMAGE3_TEX5 0xB5
#define GX_BP_REG_SETIMAGE3_TEX6 0xB6
#define GX_BP_REG_SETIMAGE3_TEX7 0xB7
// set texture lookups continued
#define GX_BP_REG_SETTLUT_TEX4 0xB8
#define GX_BP_REG_SETTLUT_TEX5 0xB9
#define GX_BP_REG_SETTLUT_TEX6 0xBA
#define GX_BP_REG_SETTLUT_TEX7 0xBB
// TEV color manips
#define GX_BP_REG_TEVCOLORCOMBINER0 0xC0
#define GX_BP_REG_TEVALPHACOMBINER0 0xC1
#define GX_BP_REG_TEVCOLORCOMBINER1 0xC2
#define GX_BP_REG_TEVALPHACOMBINER1 0xC3
#define GX_BP_REG_TEVCOLORCOMBINER2 0xC4
#define GX_BP_REG_TEVALPHACOMBINER2 0xC5
#define GX_BP_REG_TEVCOLORCOMBINER3 0xC6
#define GX_BP_REG_TEVALPHACOMBINER3 0xC7
#define GX_BP_REG_TEVCOLORCOMBINER4 0xC8
#define GX_BP_REG_TEVALPHACOMBINER4 0xC9
#define GX_BP_REG_TEVCOLORCOMBINER5 0xCA
#define GX_BP_REG_TEVALPHACOMBINER5 0xCB
#define GX_BP_REG_TEVCOLORCOMBINER6 0xCC
#define GX_BP_REG_TEVALPHACOMBINER6 0xCD
#define GX_BP_REG_TEVCOLORCOMBINER7 0xCE
#define GX_BP_REG_TEVALPHACOMBINER7 0xCF
#define GX_BP_REG_TEVCOLORCOMBINER8 0xD0
#define GX_BP_REG_TEVALPHACOMBINER8 0xD1
#define GX_BP_REG_TEVCOLORCOMBINER9 0xD2
#define GX_BP_REG_TEVALPHACOMBINER9 0xD3
#define GX_BP_REG_TEVCOLORCOMBINER10 0xD4
#define GX_BP_REG_TEVALPHACOMBINER10 0xD5
#define GX_BP_REG_TEVCOLORCOMBINER11 0xD6
#define GX_BP_REG_TEVALPHACOMBINER11 0xD7
#define GX_BP_REG_TEVCOLORCOMBINER12 0xD8
#define GX_BP_REG_TEVALPHACOMBINER12 0xD9
#define GX_BP_REG_TEVCOLORCOMBINER13 0xDA
#define GX_BP_REG_TEVALPHACOMBINER13 0xDB
#define GX_BP_REG_TEVCOLORCOMBINER14 0xDC
#define GX_BP_REG_TEVALPHACOMBINER14 0xDD
#define GX_BP_REG_TEVCOLORCOMBINER15 0xDE
#define GX_BP_REG_TEVALPHACOMBINER15 0xDF
// TEV registers
#define GX_BP_REG_TEVREG0LO 0xE0
#define GX_BP_REG_TEVREG0HI 0xE1
#define GX_BP_REG_TEVREG1LO 0xE2
#define GX_BP_REG_TEVREG1HI 0xE3
#define GX_BP_REG_TEVREG2LO 0xE4
#define GX_BP_REG_TEVREG2HI 0xE5
#define GX_BP_REG_TEVREG3LO 0xE6
#define GX_BP_REG_TEVREG3HI 0xE7
// fog registers
#define GX_BP_REG_FOGRANGE 0xE8
#define GX_BP_REG_FOGRANGEK0 0xE9
#define GX_BP_REG_FOGRANGEK1 0xEA
#define GX_BP_REG_FOGRANGEK2 0xEB
#define GX_BP_REG_FOGRANGEK3 0xEC
#define GX_BP_REG_FOGRANGEK4 0xED
#define GX_BP_REG_FOGPARAM0 0xEE
#define GX_BP_REG_FOGPARAM1 0xEF
#define GX_BP_REG_FOGPARAM2 0xF0
#define GX_BP_REG_FOGPARAM3 0xF1
#define GX_BP_REG_FOGCOLOR 0xF2
// performance manip registers
#define GX_BP_REG_ALPHACOMPARE 0xF3
#define GX_BP_REG_ZTEXTURE0 0xF4
#define GX_BP_REG_ZTEXTURE1 0xF5
// TEV K selectors
#define GX_BP_REG_TEVKSEL0 0xF6
#define GX_BP_REG_TEVKSEL1 0xF7
#define GX_BP_REG_TEVKSEL2 0xF8
#define GX_BP_REG_TEVKSEL3 0xF9
#define GX_BP_REG_TEVKSEL4 0xFA
#define GX_BP_REG_TEVKSEL5 0xFB
#define GX_BP_REG_TEVKSEL6 0xFC
#define GX_BP_REG_TEVKSEL7 0xFD
// SS mask
#define GX_BP_REG_SSMASK 0xFE
// Transform Unit Registers
#define GX_XF_REG_ERROR 0x1000
#define GX_XF_REG_DIAGNOSTICS 0x1001
#define GX_XF_REG_STATE0 0x1002
#define GX_XF_REG_STATE1 0x1003
#define GX_XF_REG_CLOCK 0x1004
#define GX_XF_REG_CLIPDISABLE 0x1005
#define GX_XF_REG_PERF0 0x1006
#define GX_XF_REG_PERF1 0x1007
#define GX_XF_REG_INVERTEXSPEC 0x1008
#define GX_XF_REG_NUMCOLORS 0x1009
#define GX_XF_REG_AMBIENT0 0x100A
#define GX_XF_REG_AMBIENT1 0x100B
#define GX_XF_REG_MATERIAL0 0x100C
#define GX_XF_REG_MATERIAL1 0x100D
#define GX_XF_REG_COLOR0CNTRL 0x100E
#define GX_XF_REG_COLOR1CNTRL 0x100F
#define GX_XF_REG_ALPHA0CNTRL 0x1010
#define GX_XF_REG_ALPHA1CNTRL 0x1011
#define GX_XF_REG_DUALTEXTRAN 0x1012
#define GX_XF_REG_MATRIXINDEX0 0x1018
#define GX_XF_REG_MATRIXINDEX1 0x1019
#define GX_XF_REG_SCALEX 0x101A
#define GX_XF_REG_SCALEY 0x101B
#define GX_XF_REG_SCALEZ 0x101C
#define GX_XF_REG_OFFSETX 0x101D
#define GX_XF_REG_OFFSETY 0x101E
#define GX_XF_REG_OFFSETZ 0x101F
#define GX_XF_REG_PROJECTIONA 0x1020
#define GX_XF_REG_PROJECTIONB 0x1021
#define GX_XF_REG_PROJECTIONC 0x1022
#define GX_XF_REG_PROJECTIOND 0x1023
#define GX_XF_REG_PROJECTIONE 0x1024
#define GX_XF_REG_PROJECTIONF 0x1025
#define GX_XF_REG_PROJECTORTHO 0x1026
#define GX_XF_REG_NUMTEX 0x103F
#define GX_XF_REG_TEX0 0x1040
#define GX_XF_REG_TEX1 0x1041
#define GX_XF_REG_TEX2 0x1042
#define GX_XF_REG_TEX3 0x1043
#define GX_XF_REG_TEX4 0x1044
#define GX_XF_REG_TEX5 0x1045
#define GX_XF_REG_TEX6 0x1046
#define GX_XF_REG_TEX7 0x1047
#define GX_XF_REG_DUALTEX0 0x1050
#define GX_XF_REG_DUALTEX1 0x1051
#define GX_XF_REG_DUALTEX2 0x1052
#define GX_XF_REG_DUALTEX3 0x1053
#define GX_XF_REG_DUALTEX4 0x1054
#define GX_XF_REG_DUALTEX5 0x1055
#define GX_XF_REG_DUALTEX6 0x1056
#define GX_XF_REG_DUALTEX7 0x1057
#define CP_REG_VCD_LO(pnMtxIdx, txMtxIdxMask, posn, norm, col0, col1) \
( \
(pnMtxIdx) << 0 | \
(txMtxIdxMask) << 1 | \
(posn) << 9 | \
(norm) << 11 | \
(col0) << 13 | \
(col1) << 15 \
)
#define CP_REG_VCD_HI(tex0, tex1, tex2, tex3, tex4, tex5, tex6, tex7) \
( \
(tex0) << 0 | \
(tex1) << 2 | \
(tex2) << 4 | \
(tex3) << 6 | \
(tex4) << 8 | \
(tex5) << 10 | \
(tex6) << 12 | \
(tex7) << 14 \
)
#define CP_REG_VAT_GRP0(posCnt, posType, posFrac, nrmCnt, nrmType, c0Cnt, c0Type, c1Cnt, c1Type, tx0Cnt, tx0Type, tx0Frac, p12, nrmIdx3) \
( \
(posCnt) << 0 | \
(posType) << 1 | \
(posFrac) << 4 | \
(nrmCnt) << 9 | \
(nrmType) << 10 | \
(c0Cnt) << 13 | \
(c0Type) << 14 | \
(c1Cnt) << 17 | \
(c1Type) << 18 | \
(tx0Cnt) << 21 | \
(tx0Type) << 22 | \
(tx0Frac) << 25 | \
(p12) << 30 | \
(nrmIdx3) << 31 \
)
#define CP_REG_VAT_GRP1(tx1Cnt, tx1Type, tx1Frac, tx2Cnt, tx2Type, tx2Frac, tx3Cnt, tx3Type, tx3Frac, tx4Cnt, tx4Type, p11) \
( \
(tx1Cnt) << 0 | \
(tx1Type) << 1 | \
(tx1Frac) << 4 | \
(tx2Cnt) << 9 | \
(tx2Type) << 10 | \
(tx2Frac) << 13 | \
(tx3Cnt) << 18 | \
(tx3Type) << 19 | \
(tx3Frac) << 22 | \
(tx4Cnt) << 27 | \
(tx4Type) << 28 | \
p11 << 31 \
)
#define CP_REG_VAT_GRP2(tx4Frac, tx5Cnt, tx5Type, tx5Frac, tx6Cnt, tx6Type, tx6Frac, tx7Cnt, tx7Type, tx7Frac) \
( \
(tx4Frac) << 0 | \
(tx5Cnt) << 5 | \
(tx5Type) << 6 | \
(tx5Frac) << 9 | \
(tx6Cnt) << 14 | \
(tx6Type) << 15 | \
(tx6Frac) << 18 | \
(tx7Cnt) << 23 | \
(tx7Type) << 24 | \
(tx7Frac) << 27 \
)
// Transform unit register IDs
#define XF_REG_ERROR_ID 0x1000
#define XF_REG_DIAGNOSTICS_ID 0x1001
#define XF_REG_STATE0_ID 0x1002
#define XF_REG_STATE1_ID 0x1003
#define XF_REG_CLOCK_ID 0x1004
#define XF_REG_CLIPDISABLE_ID 0x1005
#define XF_REG_PERF0_ID 0x1006
#define XF_REG_PERF1_ID 0x1007
#define XF_REG_INVERTEXSPEC_ID 0x1008
#define XF_REG_NUMCOLORS_ID 0x1009
#define XF_REG_DUALTEXTRAN_ID 0x1012
#define XF_REG_SCALEX_ID 0x101A
#define XF_REG_SCALEY_ID 0x101B
#define XF_REG_SCALEZ_ID 0x101C
#define XF_REG_OFFSETX_ID 0x101D
#define XF_REG_OFFSETY_ID 0x101E
#define XF_REG_OFFSETZ_ID 0x101F
#define XF_REG_NUMTEX_ID 0x103F
#define XF_REG_TEX0_ID 0x1040
#define XF_REG_TEX1_ID 0x1041
#define XF_REG_TEX2_ID 0x1042
#define XF_REG_TEX3_ID 0x1043
#define XF_REG_TEX4_ID 0x1044
#define XF_REG_TEX5_ID 0x1045
#define XF_REG_TEX6_ID 0x1046
#define XF_REG_TEX7_ID 0x1047
#define XF_REG_DUALTEX0_ID 0x1050
#define XF_REG_DUALTEX1_ID 0x1051
#define XF_REG_DUALTEX2_ID 0x1052
#define XF_REG_DUALTEX3_ID 0x1053
#define XF_REG_DUALTEX4_ID 0x1054
#define XF_REG_DUALTEX5_ID 0x1055
#define XF_REG_DUALTEX6_ID 0x1056
#define XF_REG_DUALTEX7_ID 0x1057
#define XF_REG_INVTXSPEC(ncols, nnorms, ntexs) \
( \
(ncols) << 0 | \
(nnorms) << 2 | \
(ntexs) << 4 \
)
#define XF_REG_TEX(proj, form, tgType, row, embossRow, embossLit) \
( \
(proj) << 1 | \
(form) << 2 | \
(tgType) << 4 | \
(row) << 7 | \
(embossRow) << 12 | \
(embossLit) << 15 \
)
#define XF_REG_DUALTEX(mtx, normalize) \
( \
(mtx) << 0 | \
(normalize) << 8 \
)
#define BP_GEN_MODE(nTexGens, nChans, nTevs, p4, nInds) \
( \
(u32)(nTexGens) << 0 | \
(u32)(nChans) << 4 | \
(u32)(nTevs) << 10 | \
(u32)(p4) << 14 | \
(u32)(nInds) << 16 \
)
#define BP_LP_SIZE(lineWidth, pointSize, lineOffset, pointOffset, lineHalfAspect, p5) \
( \
(u32)(lineWidth) << 0 | \
(u32)(pointSize) << 8 | \
(u32)(lineOffset) << 16 | \
(u32)(pointOffset) << 19 | \
(u32)(lineHalfAspect) << 22 | \
(u32)(p5) << 24 \
)
typedef struct _GXVtxDescList GXVtxDescList;
void GDSetVtxDescv(GXVtxDescList*);
void GDSetArray(GXAttr attr, const void* data, u8 stride);
void GDSetArray(GXAttr attr, void* data, u8 stride);
void GDSetArrayRaw(GXAttr attr, u32 data, u8 stride);
#ifdef __cplusplus
+69
View File
@@ -4,6 +4,75 @@
#include "dolphin/gx/GXEnum.h"
#include "dolphin/gx/GXStruct.h"
#define BP_FOG_UNK0(a, id) \
( \
(u32)(a) << 0 | \
(u32)(id) << 24 \
)
#define BP_FOG_UNK1(b_m, id) \
( \
(u32)(b_m) << 0 | \
(u32)(id) << 24 \
)
#define BP_FOG_UNK2(b_expn, id) \
( \
(u32)(b_expn) << 0 | \
(u32)(id) << 24 \
)
#define BP_FOG_UNK3(c, proj, fsel, id) \
( \
(u32)(c) << 0 | \
(u32)(proj) << 20 | \
(u32)(fsel) << 21 | \
(u32)(id) << 24 \
)
#define BP_FOG_COLOR(r, g, b, id) \
( \
(u32)(b) << 0 | \
(u32)(g) << 8 | \
(u32)(r) << 16 | \
(u32)(id) << 24 \
)
#define BP_BLEND_MODE(enable, enable_logic, enable_dither, enable_color_update, enable_alpha_update, dst_factor, src_factor, blend_sub, logic_op, id) \
( \
(u32)(enable) << 0 | \
(u32)(enable_logic) << 1 | \
(u32)(enable_dither) << 2 | \
(u32)(enable_color_update) << 3 | \
(u32)(enable_alpha_update) << 4 | \
(u32)(dst_factor) << 5 | \
(u32)(src_factor) << 8 | \
(u32)(blend_sub) << 11 | \
(u32)(logic_op) << 12 | \
(u32)(id) << 24 \
)
#define BP_Z_MODE(enable_compare, compare_fn, enable_update, id) \
( \
(u32)(enable_compare) << 0 | \
(u32)(compare_fn) << 1 | \
(u32)(enable_update) << 4 | \
(u32)(id) << 24 \
)
#define BP_DST_ALPHA(alpha, enable, id) \
( \
(u32)(alpha) << 0 | \
(u32)(enable) << 8 | \
(u32)(id) << 24 \
)
#define BP_TOKEN(token, id) \
( \
(u32)(token) << 0 | \
(u32)(id) << 24 \
)
void GFSetFog(GXFogType type, f32 startZ, f32 endZ, f32 nearZ, f32 farZ, GXColor color);
void GFSetBlendModeEtc(GXBlendMode, GXBlendFactor, GXBlendFactor, GXLogicOp, u8, u8, u8);
void GFSetDstAlpha(u8, u8);
+93
View File
@@ -4,6 +4,99 @@
#include "dolphin/gx/GXEnum.h"
#include "dolphin/gx/GXStruct.h"
#define BP_TEV_COLOR(d, c, b, a, bias, op, clamp, scale, out, id) \
( \
(u32)(d) << 0 | \
(u32)(c) << 4 | \
(u32)(b) << 8 | \
(u32)(a) << 12 | \
(u32)(bias) << 16 | \
(u32)(op) << 18 | \
(u32)(clamp) << 19 | \
(u32)(scale) << 20 | \
(u32)(out) << 22 | \
(u32)(id) << 24 \
)
#define BP_TEV_ALPHA(ras_sel, tex_sel, d, c, b, a, bias, op, clamp, scale, out, id) \
( \
(u32)(ras_sel) << 0 | \
(u32)(tex_sel) << 2 | \
(u32)(d) << 4 | \
(u32)(c) << 7 | \
(u32)(b) << 10 | \
(u32)(a) << 13 | \
(u32)(bias) << 16 | \
(u32)(op) << 18 | \
(u32)(clamp) << 19 | \
(u32)(scale) << 20 | \
(u32)(out) << 22 | \
(u32)(id) << 24 \
)
#define BP_TEV_COLOR_REG_RA(r, a, reg, id) \
( \
(u32)(r) << 0 | \
(u32)(a) << 12 | \
(u32)(reg) << 23 | \
(u32)(id) << 24 \
)
#define BP_TEV_COLOR_REG_BG(b, g, reg, id) \
( \
(u32)(b) << 0 | \
(u32)(g) << 12 | \
(u32)(reg) << 23 | \
(u32)(id) << 24 \
)
#define BP_TEV_KSEL(rb, ga, kcsel0, kasel0, kcsel1, kasel1, id) \
( \
(u32)(rb) << 0 | \
(u32)(ga) << 2 | \
(u32)(kcsel0) << 4 | \
(u32)(kasel0) << 9 | \
(u32)(kcsel1) << 14 | \
(u32)(kasel1) << 19 | \
(u32)(id) << 24 \
)
#define BP_ALPHA_COMPARE(ref0, ref1, comp0, comp1, op, id) \
( \
(u32)(ref0) << 0 | \
(u32)(ref1) << 8 | \
(u32)(comp0) << 16 | \
(u32)(comp1) << 19 | \
(u32)(op) << 22 | \
(u32)(id) << 24 \
)
#define BP_ZTEX_PARAMS_0(bias, id) \
( \
(u32)(bias) << 0 | \
(u32)(id) << 24 \
)
#define BP_ZTEX_PARAMS_1(zfmt, op, id) \
( \
(u32)(zfmt) << 0 | \
(u32)(op) << 2 | \
(u32)(id) << 24 \
)
#define BP_TEV_ORDER(map0, coord0, enable0, color0, map1, coord1, enable1, color1, id) \
( \
(u32)(map0) << 0 | \
(u32)(coord0) << 3 | \
(u32)(enable0) << 6 | \
(u32)(color0) << 7 | \
(u32)(map1) << 12 | \
(u32)(coord1) << 15 | \
(u32)(enable1) << 18 | \
(u32)(color1) << 19 | \
(u32)(id) << 24 \
)
void GFSetTevColor(GXTevRegID, GXColor);
void GFSetTevColorS10(GXTevRegID, GXColorS10);
void GFSetAlphaCompare(GXCompare, u8, GXAlphaOp, GXCompare, u8);
+3
View File
@@ -234,6 +234,9 @@ inline void GXEnd() {}
#define GX_WRITE_F32(f) \
GXFIFO.f32 = (f32)(f);
#define VERIF_RAS_REG(v)
#define VERIF_XF_REG(r, v)
#define GX_WRITE_XF_REG(addr, value) \
do { \
GX_WRITE_U8(0x10); \
+4 -4
View File
@@ -13,10 +13,10 @@ typedef struct _GXVtxDescList {
} GXVtxDescList; // Size: 0x08
typedef struct _GXVtxAttrFmtList {
/* 0x00 */ GXAttr mAttrib;
/* 0x04 */ GXCompCnt mCompCnt;
/* 0x08 */ GXCompType mCompType;
/* 0x0C */ u8 mCompShift;
GXAttr attr;
GXCompCnt cnt;
GXCompType type;
u8 frac;
} GXVtxAttrFmtList; // Size: 0x10
void GXSetVtxDesc(GXAttr attr, GXAttrType type);
+1
View File
@@ -93,6 +93,7 @@ extern BOOL __OSIsGcam;
extern u32 BOOT_REGION_START AT_ADDRESS(0x812FDFF0);
extern u32 BOOT_REGION_END AT_ADDRESS(0x812FDFEC);
extern u8 __gUnknown800030E3 AT_ADDRESS(OS_BASE_CACHED | 0x30E3);
u8* OSGetStackPointer(void);
void __OSFPRInit(void);
+29 -16
View File
@@ -9,12 +9,10 @@ extern "C" {
typedef struct OSContext OSContext;
typedef enum PADMask {
PAD_CHAN3_BIT = (1 << 28),
PAD_CHAN2_BIT = (1 << 29),
PAD_CHAN1_BIT = (1 << 30),
PAD_CHAN0_BIT = (1 << 31),
} PADMask;
#define PAD_CHAN0_BIT 0x80000000
#define PAD_CHAN1_BIT 0x40000000
#define PAD_CHAN2_BIT 0x20000000
#define PAD_CHAN3_BIT 0x10000000
#define PAD_SPEC_0 0
#define PAD_SPEC_1 1
@@ -47,18 +45,31 @@ typedef enum PADMask {
#define PAD_BUTTON_START 0x1000
typedef struct PADStatus {
/* 0x0 */ u16 button;
/* 0x2 */ s8 stick_x;
/* 0x3 */ s8 stick_y;
/* 0x4 */ s8 substick_x;
/* 0x5 */ s8 substick_y;
/* 0x6 */ u8 trigger_left;
/* 0x7 */ u8 trigger_right;
/* 0x8 */ u8 analog_a;
/* 0x9 */ u8 analog_b;
/* 0xA */ s8 error;
/* 0x00 */ u16 button;
/* 0x02 */ s8 stickX;
/* 0x03 */ s8 stickY;
/* 0x04 */ s8 substickX;
/* 0x05 */ s8 substickY;
/* 0x06 */ u8 triggerLeft;
/* 0x07 */ u8 triggerRight;
/* 0x08 */ u8 analogA;
/* 0x09 */ u8 analogB;
/* 0x0A */ s8 err;
} PADStatus;
typedef struct PADClampRegion {
u8 minTrigger;
u8 maxTrigger;
s8 minStick;
s8 maxStick;
s8 xyStick;
s8 minSubstick;
s8 maxSubstick;
s8 xySubstick;
s8 radStick;
s8 radSubstick;
} PADClampRegion;
typedef void (*PADSamplingCallback)(void);
BOOL PADInit(void);
@@ -70,6 +81,7 @@ void PADClamp(PADStatus* status);
u32 PADRead(PADStatus* status);
void PADControlMotor(s32 channel, u32 command);
BOOL PADRecalibrate(u32 mask);
PADSamplingCallback PADSetSamplingCallback(PADSamplingCallback callback);
static void PADOriginCallback(s32 chan, u32 error, OSContext* context);
static void PADOriginUpdateCallback(s32 chan, u32 error, OSContext* context);
static void PADProbeCallback(s32 chan, u32 error, OSContext* context);
@@ -77,6 +89,7 @@ static void PADTypeAndStatusCallback(s32 chan, u32 type);
static void PADReceiveCheckCallback(s32 chan, u32 type);
extern u32 __PADSpec;
extern u32 __PADFixBits;
#ifdef __cplusplus
};
+37 -2
View File
@@ -9,6 +9,41 @@
extern "C" {
#endif
#define SI_MAX_TYPE 4
#define SI_COMCSR_IDX 13
#define SI_STATUS_IDX 14
#define SI_COMCSR_TCINT_MASK (1 << 31)
#define SI_COMCSR_TCINTMSK_MASK (1 << 30)
#define SI_COMCSR_COMERR_MASK (1 << 29)
#define SI_COMCSR_RDSTINT_MASK (1 << 28)
#define SI_COMCSR_RDSTINTMSK_MASK (1 << 27)
// 4 bits of padding
#define SI_COMCSR_OUTLNGTH_MASK (1 << 22) \
| (1 << 21) \
| (1 << 20) \
| (1 << 19) \
| (1 << 18) \
| (1 << 17) \
| (1 << 16)
// 1 bit of padding
#define SI_COMCSR_INLNGTH_MASK (1 << 14) \
| (1 << 13) \
| (1 << 12) \
| (1 << 11) \
| (1 << 10) \
| (1 << 9) \
| (1 << 8)
// 5 bits of padding
#define SI_COMCSR_CHANNEL_MASK (1 << 2) \
| (1 << 1)
#define SI_COMCSR_TSTART_MASK (1 << 0)
#define SI_MAX_CHAN 4
#define SI_MAX_COMCSR_INLNGTH 128
#define SI_MAX_COMCSR_OUTLNGTH 128
@@ -61,7 +96,7 @@ extern "C" {
#define SI_GC_STEERING (SI_TYPE_GC | 0x00000000)
typedef void (*SICallback)(s32 chan, u32 sr, OSContext* context);
typedef void (*SITypeAndStatusCallback)(s32 chan, u32 type);
typedef void (*SITypeCallback)(s32 chan, u32 type);
typedef struct SIPacket {
s32 chan;
@@ -119,7 +154,7 @@ BOOL SIGetResponse(s32 chan, void* data);
BOOL SITransfer(s32 chan, void* output, u32 outputBytes, void* input, u32 inputBytes,
SICallback callback, OSTime delay);
u32 SIGetType(s32 chan);
u32 SIGetTypeAsync(s32 chan, SITypeAndStatusCallback callback);
u32 SIGetTypeAsync(s32 chan, SITypeCallback callback);
u32 SIProbe(s32 chan);
vu32 __SIRegs[64] AT_ADDRESS(0xCC006400);
+49
View File
@@ -35,6 +35,55 @@ typedef unsigned int uint;
(((u32)ptr[offset] << 24) | ((u32)ptr[offset + 1] << 16) | ((u32)ptr[offset + 2] << 8) | \
(u32)ptr[offset + 3]);
#if defined(__MWERKS__)
#define AT_ADDRESS(addr) : (addr)
#elif defined(__GNUC__)
//#define AT_ADDRESS(addr) __attribute__((address((addr))))
#define AT_ADDRESS(addr) // was removed in GCC. define in linker script instead.
#else
#define AT_ADDRESS(addr)
#endif
#ifndef ATTRIBUTE_ALIGN
#if defined(__MWERKS__) || defined(__GNUC__)
#define ATTRIBUTE_ALIGN(num) __attribute__((aligned(num)))
#elif defined(_MSC_VER)
#define ATTRIBUTE_ALIGN(num)
#else
#error unknown compiler
#endif
#endif
#ifndef DECL_WEAK
#if defined(__MWERKS__)
#define DECL_WEAK __declspec(weak)
#elif defined(__GNUC__)
#define DECL_WEAK __attribute__((weak))
#elif defined(_MSC_VER)
#define DECL_WEAK
#else
#error unknown compiler
#endif
#endif
#ifndef NULL
#ifdef __cplusplus
#if __cplusplus >= 201103L
#define NULL nullptr
#else
#define NULL 0
#endif
#else
#define NULL ((void*)0)
#endif
#endif
#ifdef __MWERKS__
#define __REGISTER register
#else
#define __REGISTER
#endif
#include "stddef.h" // IWYU pragma: export
#define INT32_MAX (0x7fffffff)
+22
View File
@@ -0,0 +1,22 @@
#ifndef ODEMUEXI_DEBUGGERDRIVER_H
#define ODEMUEXI_DEBUGGERDRIVER_H
#include "dolphin/types.h"
typedef void (*MTRCallbackType)(int);
void DBInitComm(u8** a, MTRCallbackType b);
void DBInitInterrupts(void);
u32 DBQueryData(void);
BOOL DBRead(u32* buffer, s32 count);
BOOL DBWrite(void* src, u32 size);
void DBOpen(void);
void DBClose(void);
#endif /* ODEMUEXI_DEBUGGERDRIVER_H */
@@ -150,10 +150,10 @@ void J3DModelData::indexToPtr() {
bool J3DModelData::isDeformablePositionFormat() const {
GXVtxAttrFmtList *vtxAttr = getVtxAttrFmtList();
for (; vtxAttr->mAttrib != GX_VA_NULL; vtxAttr++) {
switch (vtxAttr->mAttrib) {
for (; vtxAttr->attr != GX_VA_NULL; vtxAttr++) {
switch (vtxAttr->attr) {
case GX_VA_POS:
if (vtxAttr->mCompType == GX_F32 && vtxAttr->mCompCnt == GX_POS_XYZ)
if (vtxAttr->type == GX_F32 && vtxAttr->cnt == GX_POS_XYZ)
return true;
break;
default:
+38 -38
View File
@@ -179,73 +179,73 @@ void J3DGDSetVtxAttrFmtv(GXVtxFmt fmt, GXVtxAttrFmtList* vtxAttr, bool forceNBT)
GXCompType tex7CompType = GX_F32;
u32 tex7CompShift = 0;
for (; vtxAttr->mAttrib != GX_VA_NULL; vtxAttr++) {
switch (vtxAttr->mAttrib) {
for (; vtxAttr->attr != GX_VA_NULL; vtxAttr++) {
switch (vtxAttr->attr) {
case GX_VA_POS:
posCompCnt = vtxAttr->mCompCnt;
posCompType = vtxAttr->mCompType;
posCompShift = vtxAttr->mCompShift;
posCompCnt = vtxAttr->cnt;
posCompType = vtxAttr->type;
posCompShift = vtxAttr->frac;
break;
case GX_VA_NRM:
case GX_VA_NBT:
nrmCompType = vtxAttr->mCompType;
if (vtxAttr->mCompCnt == GX_NRM_NBT3) {
nrmCompType = vtxAttr->type;
if (vtxAttr->cnt == GX_NRM_NBT3) {
nrmCompCnt = GX_NRM_NBT;
nbt3 = true;
} else {
// possible fakematch? need to cast vtxAttr->mCompCnt to int to put value in r0 temporarily
// nrmCompCnt = forceNBT ? GX_NRM_NBT : vtxAttr->mCompCnt;
nrmCompCnt = (GXCompCnt)(forceNBT ? GX_NRM_NBT : (int)(vtxAttr->mCompCnt));
// possible fakematch? need to cast vtxAttr->cnt to int to put value in r0 temporarily
// nrmCompCnt = forceNBT ? GX_NRM_NBT : vtxAttr->cnt;
nrmCompCnt = (GXCompCnt)(forceNBT ? GX_NRM_NBT : (int)(vtxAttr->cnt));
nbt3 = false;
}
break;
case GX_VA_CLR0:
clr0CompCnt = vtxAttr->mCompCnt;
clr0CompType = vtxAttr->mCompType;
clr0CompCnt = vtxAttr->cnt;
clr0CompType = vtxAttr->type;
break;
case GX_VA_CLR1:
clr1CompCnt = vtxAttr->mCompCnt;
clr1CompType = vtxAttr->mCompType;
clr1CompCnt = vtxAttr->cnt;
clr1CompType = vtxAttr->type;
break;
case GX_VA_TEX0:
tex0CompCnt = vtxAttr->mCompCnt;
tex0CompType = vtxAttr->mCompType;
tex0CompShift = vtxAttr->mCompShift;
tex0CompCnt = vtxAttr->cnt;
tex0CompType = vtxAttr->type;
tex0CompShift = vtxAttr->frac;
break;
case GX_VA_TEX1:
tex1CompCnt = vtxAttr->mCompCnt;
tex1CompType = vtxAttr->mCompType;
tex1CompShift = vtxAttr->mCompShift;
tex1CompCnt = vtxAttr->cnt;
tex1CompType = vtxAttr->type;
tex1CompShift = vtxAttr->frac;
break;
case GX_VA_TEX2:
tex2CompCnt = vtxAttr->mCompCnt;
tex2CompType = vtxAttr->mCompType;
tex2CompShift = vtxAttr->mCompShift;
tex2CompCnt = vtxAttr->cnt;
tex2CompType = vtxAttr->type;
tex2CompShift = vtxAttr->frac;
break;
case GX_VA_TEX3:
tex3CompCnt = vtxAttr->mCompCnt;
tex3CompType = vtxAttr->mCompType;
tex3CompShift = vtxAttr->mCompShift;
tex3CompCnt = vtxAttr->cnt;
tex3CompType = vtxAttr->type;
tex3CompShift = vtxAttr->frac;
break;
case GX_VA_TEX4:
tex4CompCnt = vtxAttr->mCompCnt;
tex4CompType = vtxAttr->mCompType;
tex4CompShift = vtxAttr->mCompShift;
tex4CompCnt = vtxAttr->cnt;
tex4CompType = vtxAttr->type;
tex4CompShift = vtxAttr->frac;
break;
case GX_VA_TEX5:
tex5CompCnt = vtxAttr->mCompCnt;
tex5CompType = vtxAttr->mCompType;
tex5CompShift = vtxAttr->mCompShift;
tex5CompCnt = vtxAttr->cnt;
tex5CompType = vtxAttr->type;
tex5CompShift = vtxAttr->frac;
break;
case GX_VA_TEX6:
tex6CompCnt = vtxAttr->mCompCnt;
tex6CompType = vtxAttr->mCompType;
tex6CompShift = vtxAttr->mCompShift;
tex6CompCnt = vtxAttr->cnt;
tex6CompType = vtxAttr->type;
tex6CompShift = vtxAttr->frac;
break;
case GX_VA_TEX7:
tex7CompCnt = vtxAttr->mCompCnt;
tex7CompType = vtxAttr->mCompType;
tex7CompShift = vtxAttr->mCompShift;
tex7CompCnt = vtxAttr->cnt;
tex7CompType = vtxAttr->type;
tex7CompShift = vtxAttr->frac;
break;
default:
break;
+21 -21
View File
@@ -97,31 +97,31 @@ void J3DShape::makeVtxArrayCmd() {
array[i] = 0;
}
for (; vtxAttr->mAttrib != GX_VA_NULL; vtxAttr++) {
switch (vtxAttr->mAttrib) {
for (; vtxAttr->attr != GX_VA_NULL; vtxAttr++) {
switch (vtxAttr->attr) {
case GX_VA_POS: {
if (vtxAttr->mCompType == GX_F32)
stride[vtxAttr->mAttrib - GX_VA_POS] = 0x0C;
if (vtxAttr->type == GX_F32)
stride[vtxAttr->attr - GX_VA_POS] = 0x0C;
else
stride[vtxAttr->mAttrib - GX_VA_POS] = 0x06;
array[vtxAttr->mAttrib - GX_VA_POS] = mVertexData->getVtxPosArray();
mVertexData->setVtxPosFrac(vtxAttr->mCompShift);
mVertexData->setVtxPosType((GXCompType)vtxAttr->mCompType);
stride[vtxAttr->attr - GX_VA_POS] = 0x06;
array[vtxAttr->attr - GX_VA_POS] = mVertexData->getVtxPosArray();
mVertexData->setVtxPosFrac(vtxAttr->frac);
mVertexData->setVtxPosType((GXCompType)vtxAttr->type);
} break;
case GX_VA_NRM: {
if (vtxAttr->mCompType == GX_F32)
stride[vtxAttr->mAttrib - GX_VA_POS] = 0x0C;
if (vtxAttr->type == GX_F32)
stride[vtxAttr->attr - GX_VA_POS] = 0x0C;
else
stride[vtxAttr->mAttrib - GX_VA_POS] = 0x06;
array[vtxAttr->mAttrib - GX_VA_POS] = mVertexData->getVtxNrmArray();
mVertexData->setVtxNrmFrac(vtxAttr->mCompShift);
mVertexData->setVtxNrmType((GXCompType)vtxAttr->mCompType);
stride[vtxAttr->attr - GX_VA_POS] = 0x06;
array[vtxAttr->attr - GX_VA_POS] = mVertexData->getVtxNrmArray();
mVertexData->setVtxNrmFrac(vtxAttr->frac);
mVertexData->setVtxNrmType((GXCompType)vtxAttr->type);
} break;
case GX_VA_CLR0:
case GX_VA_CLR1: {
stride[vtxAttr->mAttrib - GX_VA_POS] = 0x04;
array[vtxAttr->mAttrib - GX_VA_POS] =
mVertexData->getVtxColorArray(vtxAttr->mAttrib - GX_VA_CLR0);
stride[vtxAttr->attr - GX_VA_POS] = 0x04;
array[vtxAttr->attr - GX_VA_POS] =
mVertexData->getVtxColorArray(vtxAttr->attr - GX_VA_CLR0);
} break;
case GX_VA_TEX0:
case GX_VA_TEX1:
@@ -131,11 +131,11 @@ void J3DShape::makeVtxArrayCmd() {
case GX_VA_TEX5:
case GX_VA_TEX6:
case GX_VA_TEX7: {
if (vtxAttr->mCompType == GX_F32)
stride[vtxAttr->mAttrib - GX_VA_POS] = 0x08;
if (vtxAttr->type == GX_F32)
stride[vtxAttr->attr - GX_VA_POS] = 0x08;
else
stride[vtxAttr->mAttrib - GX_VA_POS] = 0x04;
array[vtxAttr->mAttrib - GX_VA_POS] = mVertexData->getVtxTexCoordArray(vtxAttr->mAttrib - GX_VA_TEX0);
stride[vtxAttr->attr - GX_VA_POS] = 0x04;
array[vtxAttr->attr - GX_VA_POS] = mVertexData->getVtxTexCoordArray(vtxAttr->attr - GX_VA_TEX0);
} break;
default:
break;
@@ -270,9 +270,9 @@ void J3DModelLoader::readInformation(const J3DModelInfoBlock* i_block, u32 i_fla
/* 802FC3E4-802FC410 .text getFmtType__FP17_GXVtxAttrFmtList7_GXAttr */
static GXCompType getFmtType(GXVtxAttrFmtList* i_fmtList, GXAttr i_attr) {
for (; i_fmtList->mAttrib != GX_VA_NULL; i_fmtList++) {
if (i_fmtList->mAttrib == i_attr) {
return i_fmtList->mCompType;
for (; i_fmtList->attr != GX_VA_NULL; i_fmtList++) {
if (i_fmtList->attr == i_attr) {
return i_fmtList->type;
}
}
return GX_F32;
+19 -19
View File
@@ -71,11 +71,11 @@ u32 JUTGamePad::read() {
u32 mask = 0;
for (int i = 0; i < 4; i++) {
u32 mask_tmp = 0x80000000 >> i;
if (mPadStatus[i].error == 0) {
u32 local_2c = mPadMStick[i].update(mPadStatus[i].stick_x, mPadStatus[i].stick_y, sStickMode, WS_MAIN_STICK) << 0x18;
local_2c |= (mPadSStick[i].update(mPadStatus[i].substick_x, mPadStatus[i].substick_y, sStickMode, WS_SUB_STICK) << 0x10);
if (mPadStatus[i].err == 0) {
u32 local_2c = mPadMStick[i].update(mPadStatus[i].stickX, mPadStatus[i].stickY, sStickMode, WS_MAIN_STICK) << 0x18;
local_2c |= (mPadSStick[i].update(mPadStatus[i].substickX, mPadStatus[i].substickY, sStickMode, WS_SUB_STICK) << 0x10);
mPadButton[i].update(&mPadStatus[i], local_2c);
} else if (mPadStatus[i].error == -1) {
} else if (mPadStatus[i].err == -1) {
mPadMStick[i].update(0, 0, sStickMode, WS_MAIN_STICK);
mPadSStick[i].update(0, 0, sStickMode, WS_SUB_STICK);
mPadButton[i].update(NULL, 0);
@@ -84,8 +84,8 @@ u32 JUTGamePad::read() {
mask |= mask_tmp;
}
} else {
if (mPadStatus[i].error != -3) {
OSReport("game pad read error (%d)\n", mPadStatus[i].error);
if (mPadStatus[i].err != -3) {
OSReport("game pad read error (%d)\n", mPadStatus[i].err);
}
mPadButton[i].mTrigger = 0;
mPadButton[i].mRelease = 0;
@@ -97,10 +97,10 @@ u32 JUTGamePad::read() {
if (pad->getPadReplay()) {
PADStatus status;
pad->getPadReplay()->unk1(&status);
u32 m_stick = pad->mMainStick.update(status.stick_x, status.stick_y, sStickMode,
u32 m_stick = pad->mMainStick.update(status.stickX, status.stickY, sStickMode,
WS_MAIN_STICK)
<< 0x18;
u32 s_stick = pad->mSubStick.update(status.substick_x, status.substick_y, sStickMode,
u32 s_stick = pad->mSubStick.update(status.substickX, status.substickY, sStickMode,
WS_SUB_STICK)
<< 0x10;
m_stick |= s_stick;
@@ -114,7 +114,7 @@ u32 JUTGamePad::read() {
if (pad->getPadRecord() && pad->mPortNum != -1) {
s32 port = pad->mPortNum;
if (mPadStatus[port].error == 0) {
if (mPadStatus[port].err == 0) {
pad->getPadRecord()->write(&mPadStatus[port]);
}
}
@@ -131,7 +131,7 @@ u32 JUTGamePad::read() {
/* 802C3C14-802C3CC4 .text assign__10JUTGamePadFv */
void JUTGamePad::assign() {
for (int i = 0; i < 4; i++) {
if (mPadStatus[i].error == 0 && mPadAssign[i] == 0) {
if (mPadStatus[i].err == 0 && mPadAssign[i] == 0) {
mPortNum = i;
mPadAssign[i] = 1;
mPadButton[i].setRepeat(mButton.field_0x24, mButton.field_0x28, mButton.field_0x2c);
@@ -142,7 +142,7 @@ void JUTGamePad::assign() {
}
u8 JUTGamePad::CRumble::mStatus[4];
PADMask JUTGamePad::CRumble::mEnabled;
u32 JUTGamePad::CRumble::mEnabled;
callbackFn JUTGamePad::C3ButtonReset::sCallback;
void* JUTGamePad::C3ButtonReset::sCallbackArg;
OSTime JUTGamePad::C3ButtonReset::sThreshold = (OSTime)((OS_BUS_CLOCK / 4) / 60) * 30;
@@ -176,7 +176,7 @@ void JUTGamePad::update() {
mButton = mPadButton[mPortNum];
mMainStick = mPadMStick[mPortNum];
mSubStick = mPadSStick[mPortNum];
mErrorStatus = mPadStatus[mPortNum].error;
mErrorStatus = mPadStatus[mPortNum].err;
if ((mButton.mButton & C3ButtonReset::sResetMaskPattern) != C3ButtonReset::sResetPattern)
{
@@ -276,10 +276,10 @@ void JUTGamePad::CButton::update(const PADStatus* padStatus, u32 stickStatus) {
mRepeat |= (field_0x24 ^ 0xFFFFFFFF) & mTrigger;
if (padStatus != NULL) {
mAnalogA = padStatus->analog_a;
mAnalogB = padStatus->analog_b;
mAnalogL = padStatus->trigger_left;
mAnalogR = padStatus->trigger_right;
mAnalogA = padStatus->analogA;
mAnalogB = padStatus->analogB;
mAnalogL = padStatus->triggerLeft;
mAnalogR = padStatus->triggerRight;
} else {
mAnalogA = 0;
mAnalogB = 0;
@@ -362,7 +362,7 @@ void JUTGamePad::CRumble::clear() {
mLength = 0;
mData = 0;
mFrameCount = 0;
mEnabled = (PADMask)(PAD_CHAN3_BIT | PAD_CHAN2_BIT | PAD_CHAN1_BIT | PAD_CHAN0_BIT);
mEnabled = (PAD_CHAN3_BIT | PAD_CHAN2_BIT | PAD_CHAN1_BIT | PAD_CHAN0_BIT);
}
/* 802C4444-802C449C .text clear__Q210JUTGamePad7CRumbleFP10JUTGamePad */
@@ -495,7 +495,7 @@ void JUTGamePad::CRumble::setEnabled(u32 mask) {
}
}
}
mEnabled = (PADMask)(mask & (PAD_CHAN3_BIT | PAD_CHAN2_BIT | PAD_CHAN1_BIT | PAD_CHAN0_BIT));
mEnabled = (mask & (PAD_CHAN3_BIT | PAD_CHAN2_BIT | PAD_CHAN1_BIT | PAD_CHAN0_BIT));
}
/* 802C489C-802C48B8 .text setRepeat__Q210JUTGamePad7CButtonFUlUlUl */
@@ -517,7 +517,7 @@ bool JUTGamePad::recalibrate(u32 mask) {
}
}
return PADRecalibrate((PADMask)mask);
return PADRecalibrate(mask);
}
static void dummy() {
+378
View File
@@ -0,0 +1,378 @@
#ifndef __METROTRK_TRK_H__
#define __METROTRK_TRK_H__
#include "dolphin/types.h"
#ifdef __cplusplus
extern "C" {
#endif
//////////// TRK ENUMS /////////////
// Hardware types.
typedef enum {
HARDWARE_AMC_DDH = 0,
HARDWARE_GDEV = 1,
HARDWARE_BBA = 2,
} HardwareType;
// DS Error returns.
typedef enum {
DS_NoError = 0x0,
DS_StepError = 0x1,
DS_ParameterError = 0x2,
DS_EventQueueFull = 0x100,
DS_NoMessageBufferAvailable = 0x300,
DS_MessageBufferOverflow = 0x301,
DS_MessageBufferReadError = 0x302,
DS_DispatchError = 0x500,
DS_InvalidMemory = 0x700,
DS_InvalidRegister = 0x701,
DS_CWDSException = 0x702,
DS_UnsupportedError = 0x703,
DS_InvalidProcessID = 0x704,
DS_InvalidThreadID = 0x705,
DS_OSError = 0x706,
DS_Error800 = 0x800,
} DSError;
// Where to read/write.
typedef enum {
DS_Stdin = 0,
DS_Stdout = 1,
DS_Stderr = 2,
} DSFileHandle;
// IO returns.
typedef enum {
DS_IONoError = 0,
DS_IOError = 1,
DS_IOEOF = 2,
} DSIOResult;
// Message command IDs
typedef enum {
DSMSG_Ping = 0x0,
DSMSG_Connect = 0x1,
DSMSG_Disconnect = 0x2,
DSMSG_Reset = 0x3,
DSMSG_Versions = 0x4,
DSMSG_SupportMask = 0x5,
DSMSG_Override = 0x7,
DSMSG_ReadMemory = 0x10,
DSMSG_WriteMemory = 0x11,
DSMSG_ReadRegisters = 0x12,
DSMSG_WriteRegisters = 0x13,
DSMSG_SetOption = 0x17,
DSMSG_Continue = 0x18,
DSMSG_Step = 0x19,
DSMSG_Stop = 0x1A,
DSMSG_ReplyACK = 0x80,
DSMSG_NotifyStopped = 0x90,
DSMSG_NotifyException = 0x91,
DSMSG_WriteFile = 0xD0,
DSMSG_ReadFile = 0xD1,
DSMSG_OpenFile = 0xD2,
DSMSG_CloseFile = 0xD3,
DSMSG_PositionFile = 0xD4,
DSMSG_ReplyNAK = 0xFF,
} MessageCommandID;
// Register commands.
typedef enum {
DSREG_Default = 0,
DSREG_FP = 1,
DSREG_Extended1 = 2,
DSREG_Extended2 = 3,
} DSMessageRegisterOptions;
// Step commands.
typedef enum {
DSSTEP_IntoCount = 0x0,
DSSTEP_IntoRange = 0x1,
DSSTEP_OverCount = 0x10,
DSSTEP_OverRange = 0x11,
} DSMessageStepOptions;
typedef enum {
DSREPLY_NoError = 0x0,
DSREPLY_Error = 0x1,
DSREPLY_PacketSizeError = 0x2,
DSREPLY_CWDSError = 0x3,
DSREPLY_EscapeError = 0x4,
DSREPLY_BadFCS = 0x5,
DSREPLY_Overflow = 0x6,
DSREPLY_SequenceMissing = 0x7,
DSREPLY_UnsupportedCommandError = 0x10,
DSREPLY_ParameterError = 0x11,
DSREPLY_UnsupportedOptionError = 0x12,
DSREPLY_InvalidMemoryRange = 0x13,
DSREPLY_InvalidRegisterRange = 0x14,
DSREPLY_CWDSException = 0x15,
DSREPLY_NotStopped = 0x16,
DSREPLY_BreakpointsFull = 0x17,
DSREPLY_BreakpointConflict = 0x18,
DSREPLY_OSError = 0x20,
DSREPLY_InvalidProcessID = 0x21,
DSREPLY_InvalidThreadID = 0x22,
DSREPLY_DebugSecurityError = 0x23,
} DSReplyError;
typedef enum {
DSRECV_Wait = 0,
DSRECV_Found = 1,
DSRECV_InFrame = 2,
DSRECV_FrameOverflow = 3,
} ReceiverState;
typedef enum {
DSMSGMEMORY_Segmented = 0x01, /* non-flat addr space */
DSMSGMEMORY_Extended = 0x02, /* > 32-bit data addr */
DSMSGMEMORY_Protected = 0x04, /* non-user memory */
DSMSGMEMORY_Userview = 0x08, /* breakpoints are invisible */
DSMSGMEMORY_Space_program = 0x00,
DSMSGMEMORY_Space_data = 0x40,
DSMSGMEMORY_Space_io = 0x80
};
typedef enum {
NUBEVENT_Null = 0,
NUBEVENT_Shutdown = 1,
NUBEVENT_Request = 2,
NUBEVENT_Breakpoint = 3,
NUBEVENT_Exception = 4,
NUBEVENT_Support = 5,
} NubEventType;
typedef enum {
VALIDMEM_Readable = 0,
VALIDMEM_Writeable = 1,
} ValidMemoryOptions;
typedef enum {
MEMACCESS_UserMemory = 0,
MEMACCESS_DebuggerMemory = 1,
} MemoryAccessOptions;
typedef int UARTError;
typedef enum {
UART_NoError = 0,
UART_UnknownBaudRate = 1,
UART_ConfigurationError = 2,
UART_BufferOverflow = 3, // specified buffer was too small
UART_NoData = 4, // no data available from polling
} UARTErrorOptions;
typedef enum {
kBaudHWSet = -1, // use HW settings such as DIP switches
kBaud300 = 300, // valid baud rates
kBaud600 = 600,
kBaud1200 = 1200,
kBaud1800 = 1800,
kBaud2000 = 2000,
kBaud2400 = 2400,
kBaud3600 = 3600,
kBaud4800 = 4800,
kBaud7200 = 7200,
kBaud9600 = 9600,
kBaud19200 = 19200,
kBaud38400 = 38400,
kBaud57600 = 57600,
kBaud115200 = 115200,
kBaud230400 = 230400
} UARTBaudRate;
////////////////////////////////////
typedef int MessageBufferID;
#define TRKMSGBUF_SIZE (0x800 + 0x80)
typedef struct TRKBuffer {
/* 0x00 */ u32 _00;
/* 0x04 */ BOOL isInUse;
/* 0x08 */ u32 length;
/* 0x0C */ u32 position;
/* 0x10 */ u8 data[TRKMSGBUF_SIZE];
} TRKBuffer;
typedef struct TRKFramingState {
MessageBufferID msgBufID; // _00
TRKBuffer* buffer; // _04
ReceiverState receiveState; // _08
BOOL isEscape; // _0C
u8 fcsType; // _10
} TRKFramingState;
typedef struct TRKState_PPC {
u32 GPR[32]; // 0x0
u32 LR; // 0x80
u32 CTR; // 0x84
u32 XER; // 0x88
u32 MSR; // 0x8c
u32 DAR; // 0x90
u32 DSISR; // 0x94
BOOL stopped; // 0x98
BOOL inputActivated; // 0x9c
u8* inputPendingPtr; // 0xA0
} TRKState_PPC;
typedef struct CommandReply {
u32 _00; // _00
union {
u8 b;
MessageCommandID m;
} commandID; // _04, use MessageCommandID enum
union {
u8 b;
DSReplyError r;
} replyError; // _08, use DSReplyError enum - should be enum type? check size.
u32 _0C; // _0C
u8 _10[0x30]; // _10, unknown
} CommandReply;
typedef struct ProcessorRestoreFlags_PPC {
u8 TBR;
u8 DEC;
u8 linker_padding[0x9 - 0x2];
} ProcessorRestoreFlags_PPC;
void TRKSaveExtended1Block();
#define SPR_XER 1
#define SPR_LR 8
#define SPR_CTR 9
#define SPR_DSISR 18
#define SPR_DAR 19
#define SPR_DEC 22
#define SPR_SDR1 25
#define SPR_SRR0 26
#define SPR_SRR1 27
#define SPR_SPRG0 272
#define SPR_SPRG1 273
#define SPR_SPRG2 274
#define SPR_SPRG3 275
#define SPR_EAR 282
#define SPR_TBL 284
#define SPR_TBU 285
#define SPR_PVR 287
#define SPR_IBAT0U 528
#define SPR_IBAT0L 529
#define SPR_IBAT1U 530
#define SPR_IBAT1L 531
#define SPR_IBAT2U 532
#define SPR_IBAT2L 533
#define SPR_IBAT3U 534
#define SPR_IBAT3L 535
#define SPR_IBAT4U 560
#define SPR_IBAT4L 561
#define SPR_IBAT5U 562
#define SPR_IBAT5L 563
#define SPR_IBAT6U 564
#define SPR_IBAT6L 565
#define SPR_IBAT7U 566
#define SPR_IBAT7L 567
#define SPR_DBAT0U 536
#define SPR_DBAT0L 537
#define SPR_DBAT1U 538
#define SPR_DBAT1L 539
#define SPR_DBAT2U 540
#define SPR_DBAT2L 541
#define SPR_DBAT3U 542
#define SPR_DBAT3L 543
#define SPR_DBAT4U 568
#define SPR_DBAT4L 569
#define SPR_DBAT5U 570
#define SPR_DBAT5L 571
#define SPR_DBAT6U 572
#define SPR_DBAT6L 573
#define SPR_DBAT7U 574
#define SPR_DBAT7L 575
#define SPR_GQR0 912
#define SPR_GQR1 913
#define SPR_GQR2 914
#define SPR_GQR3 915
#define SPR_GQR4 916
#define SPR_GQR5 917
#define SPR_GQR6 918
#define SPR_GQR7 919
#define SPR_HID2 920
#define SPR_WPAR 921
#define SPR_DMA_U 922
#define SPR_DMA_L 923
#define SPR_UMMCR0 936
#define SPR_UPMC1 937
#define SPR_UPMC2 938
#define SPR_USIA 939
#define SPR_UMMCR1 940
#define SPR_UPMC3 941
#define SPR_UPMC4 942
#define SPR_USDA 943
#define SPR_MMCR0 952
#define SPR_PMC1 953
#define SPR_PMC2 954
#define SPR_SIA 955
#define SPR_MMCR1 956
#define SPR_PMC3 957
#define SPR_PMC4 958
#define SPR_SDA 959
#define SPR_HID0 1008
#define SPR_HID1 1009
#define SPR_IABR 1010
#define SPR_HID4 1011
#define SPR_DABR 1013
#define SPR_L2CR 1017
#define SPR_ICTC 1019
#define SPR_THRM1 1020
#define SPR_THRM2 1021
#define SPR_FPECR 1022
// PPC exceptions
// 0x000 is reserved
#define PPC_SystemReset 0x100
#define PPC_MachineCheck 0x200
#define PPC_DataStorage 0x300
#define PPC_InstructionStorage 0x400
#define PPC_ExternalInterrupt 0x500
#define PPC_Alignment 0x600
#define PPC_Program 0x700
#define PPC_FloatingPointUnavaiable 0x800
#define PPC_Decrementer 0x900
// 0xA00-0xB00 are reserved
#define PPC_SystemCall 0xC00
#define PPC_Trace 0xD00
#define PPC_FloatingPointAssist 0xE00 // unimplemented in 750CL
#define PPC_PerformanceMonitor 0xF00 // Dolphin/Broadway specific
// 0x1000-0x1200 are unimplemented in 750CL
#define PPC_InstructionAddressBreakpoint 0x1300 // Dolphin/Broadway specific
// 0x1400-0x2F00 are reserved, but TRK uses some
#define PPC_SystemManagementInterrupt 0x1400
// 0x1500-0x1600 are unimplemented in 750CL
#define PPC_ThermalManagementInterrupt 0x1700
#define PPC_1800Exception 0x1800
#define PPC_1900Exception 0x1900
#define PPC_1A00Exception 0x1A00
#define PPC_1B00Exception 0x1B00
#define PPC_1C00Exception 0x1C00 // Data breakpoint?
#define PPC_1D00Exception 0x1D00 // Instruction breakpoint?
#define PPC_1E00Exception 0x1E00 // Peripheral breakpoint?
#define PPC_1F00Exception 0x1F00 // Non maskable development port?
#define PPC_2000Exception 0x2000
#ifdef __cplusplus
}
#endif
#endif /* __METROTRK_TRK_H__ */
@@ -0,0 +1,33 @@
#ifndef MWCPLUSLIB_H
#define MWCPLUSLIB_H
#include "stddef.h"
#ifdef __cplusplus
extern "C" {
#endif
#define CTORARG_TYPE int
#define CTORARG_PARTIAL (0)
#define CTORARG_COMPLETE (1)
#define CTORCALL_COMPLETE(ctor, objptr) (((void (*)(void*, CTORARG_TYPE))ctor)(objptr, CTORARG_COMPLETE))
#define DTORARG_TYPE int
#define DTORCALL_COMPLETE(dtor, objptr) (((void (*)(void*, DTORARG_TYPE))dtor)(objptr, -1))
typedef void* ConstructorDestructor;
extern void __construct_array(void* ptr, ConstructorDestructor ctor, ConstructorDestructor dtor, size_t size, size_t n);
extern void __destroy_arr(void* block, ConstructorDestructor* dtor, size_t size, size_t n);
extern void* __construct_new_array(void* block, ConstructorDestructor ctor, ConstructorDestructor dtor_arg, size_t size, size_t n);
extern void __destroy_new_array(void* block, ConstructorDestructor dtor);
extern void __destroy_new_array2();
extern void __destroy_new_array3();
#ifdef __cplusplus
}
#endif
#endif /* MWCPLUSLIB_H */
@@ -1 +1,218 @@
#include "NMWException.h"
#include "MWCPlusLib.h"
typedef void (*unexpected_handler)();
unexpected_handler set_unexpected(unexpected_handler handler);
void unexpected();
typedef void (*terminate_handler)();
terminate_handler set_terminate(terminate_handler handler);
void terminate();
#define ARRAY_HEADER_SIZE 16
extern "C" {
extern void abort();
}
namespace std {
static void dthandler() { abort(); }
static terminate_handler thandler = dthandler;
static void duhandler() { terminate(); }
static unexpected_handler uhandler = duhandler;
extern terminate_handler set_terminate(terminate_handler handler) {
terminate_handler old = thandler;
thandler = handler;
return old;
}
extern void terminate() { thandler(); }
extern unexpected_handler set_unexpected(unexpected_handler handler) {
unexpected_handler old = uhandler;
uhandler = handler;
return old;
}
extern void unexpected() { uhandler(); }
} // namespace std
extern char __throw_catch_compare(const char* throwtype, const char* catchtype, long* offset_result) {
const char *cptr1, *cptr2;
*offset_result = 0;
if ((cptr2 = catchtype) == 0) {
return true;
}
cptr1 = throwtype;
if (*cptr2 == 'P') {
cptr2++;
if (*cptr2 == 'C')
cptr2++;
if (*cptr2 == 'V')
cptr2++;
if (*cptr2 == 'v') {
if (*cptr1 == 'P' || *cptr1 == '*') {
return true;
}
}
cptr2 = catchtype;
}
switch (*cptr1) {
case '*':
case '!':
if (*cptr1++ != *cptr2++)
return false;
for (;;) {
if (*cptr1 == *cptr2++) {
if (*cptr1++ == '!') {
long offset;
for (offset = 0; *cptr1 != '!';) {
offset = offset * 10 + *cptr1++ - '0';
}
*offset_result = offset;
return true;
}
} else {
while (*cptr1++ != '!') { }
while (*cptr1++ != '!') { }
if (*cptr1 == 0)
return false;
cptr2 = catchtype + 1;
}
}
return false;
}
while ((*cptr1 == 'P' || *cptr1 == 'R') && *cptr1 == *cptr2) {
cptr1++;
cptr2++;
if (*cptr2 == 'C') {
if (*cptr1 == 'C')
cptr1++;
cptr2++;
}
if (*cptr1 == 'C')
return false;
if (*cptr2 == 'V') {
if (*cptr1 == 'V')
cptr1++;
cptr2++;
}
if (*cptr1 == 'V')
return false;
}
for (; *cptr1 == *cptr2; cptr1++, cptr2++) {
if (*cptr1 == 0)
return true;
}
return false;
}
class __partial_array_destructor {
private:
void* p;
size_t size;
size_t n;
ConstructorDestructor dtor;
public:
size_t i;
__partial_array_destructor(void* array, size_t elementsize, size_t nelements, ConstructorDestructor destructor) {
p = array;
size = elementsize;
n = nelements;
dtor = destructor;
i = n;
}
~__partial_array_destructor() {
char* ptr;
if (i < n && dtor) {
for (ptr = (char*)p + size * i; i > 0; i--) {
ptr -= size;
DTORCALL_COMPLETE(dtor, ptr);
}
}
}
};
extern void* __construct_new_array(void* block, ConstructorDestructor ctor, ConstructorDestructor dtor, size_t size, size_t n) {
char* ptr;
if ((ptr = (char*)block) != 0L) {
size_t* p = (size_t*)ptr;
p[0] = size;
p[1] = n;
ptr += ARRAY_HEADER_SIZE;
if (ctor) {
__partial_array_destructor pad(ptr, size, n, dtor);
char* p;
for (pad.i = 0, p = (char*)ptr; pad.i < n; pad.i++, p += size) {
CTORCALL_COMPLETE(ctor, p);
}
}
}
return ptr;
}
extern void __construct_array(void* ptr, ConstructorDestructor ctor, ConstructorDestructor dtor, size_t size, size_t n) {
__partial_array_destructor pad(ptr, size, n, dtor);
char* p;
for (pad.i = 0, p = (char*)ptr; pad.i < n; pad.i++, p += size) {
CTORCALL_COMPLETE(ctor, p);
}
}
extern void __destroy_arr(void* block, ConstructorDestructor* dtor, size_t size, size_t n) {
char* p;
for (p = (char*)block + size * n; n > 0; n--) {
p -= size;
DTORCALL_COMPLETE(dtor, p);
}
}
extern void __destroy_new_array(void* block, ConstructorDestructor dtor) {
if (block) {
if (dtor) {
size_t i, objects, objectsize;
char* p;
objectsize = *(size_t*)((char*)block - ARRAY_HEADER_SIZE);
objects = ((size_t*)((char*)block - ARRAY_HEADER_SIZE))[1];
p = (char*)block + (objectsize * objects);
for (i = 0; i < objects; i++) {
p -= objectsize;
DTORCALL_COMPLETE(dtor, p);
}
}
::operator delete[]((char*)block - ARRAY_HEADER_SIZE);
}
}
void __destroy_new_array2(void) {}
void __destroy_new_array3(void) {}
@@ -0,0 +1,54 @@
#include "TRK_MINNOW_DOLPHIN/MetroTRK/Portable/msghndlr.h"
#include "TRK_MINNOW_DOLPHIN/Os/dolphin/target_options.h"
#include "TRK_MINNOW_DOLPHIN/ppc/Export/targsupp.h"
DSIOResult __read_file(u32 handle, u8* buffer, size_t* count, void* ref_con);
DSIOResult __write_file(u32 handle, u8* buffer, size_t* count, void* ref_con);
DSIOResult __close_file(u32 handle, u8* buffer, size_t* count, void* ref_con);
DSIOResult __access_file(u32 handle, u8* buffer, size_t* count, void* ref_con,
MessageCommandID cmd);
DSIOResult __read_console(u32 handle, u8* buffer, size_t* count, void* ref_con) {
if (GetUseSerialIO() == 0) {
return DS_IOError;
}
return __read_file(DS_Stdin, buffer, count, ref_con);
}
DSIOResult __TRK_write_console(u32 handle, u8* buffer, size_t* count, void* ref_con) {
if (GetUseSerialIO() == 0) {
return DS_IOError;
}
return __write_file(DS_Stdout, buffer, count, ref_con);
}
static DSIOResult __read_file(u32 handle, u8* buffer, size_t* count, void* ref_con) {
return __access_file(handle, buffer, count, ref_con, DSMSG_ReadFile);
}
static DSIOResult __write_file(u32 handle, u8* buffer, size_t* count, void* ref_con) {
return __access_file(handle, buffer, count, ref_con, DSMSG_WriteFile);
}
static DSIOResult __access_file(u32 handle, u8* buffer, size_t* count, void* ref_con,
MessageCommandID cmd) {
size_t countTemp;
u32 r0;
if (GetTRKConnected() == DS_NoError) {
return DS_IOError;
}
countTemp = *count;
r0 = TRKAccessFile(cmd, handle, &countTemp, buffer);
*count = countTemp;
switch ((u8)r0) {
case DS_IONoError:
return DS_IONoError;
case DS_IOEOF:
return DS_IOEOF;
}
return DS_IOError;
}
@@ -0,0 +1,148 @@
#include "TRK_MINNOW_DOLPHIN/ppc/Generic/targimpl.h"
#include "TRK_MINNOW_DOLPHIN/Os/dolphin/dolphin_trk.h"
#include "TRK_MINNOW_DOLPHIN/MetroTRK/Portable/main_TRK.h"
#include "TRK_MINNOW_DOLPHIN/MetroTRK/Portable/mem_TRK.h"
#include "TRK_MINNOW_DOLPHIN/Os/dolphin/dolphin_trk_glue.h"
#include "global.h"
#undef DBAT3U
#undef LR
extern u32 _db_stack_addr;
#define EXCEPTIONMASK_ADDR 0x80000044
static u32 lc_base;
static u32 TRK_ISR_OFFSETS[15] = {PPC_SystemReset,
PPC_MachineCheck,
PPC_DataStorage,
PPC_InstructionStorage,
PPC_ExternalInterrupt,
PPC_Alignment,
PPC_Program,
PPC_FloatingPointUnavaiable,
PPC_Decrementer,
PPC_SystemCall,
PPC_Trace,
PPC_PerformanceMonitor,
PPC_InstructionAddressBreakpoint,
PPC_SystemManagementInterrupt,
PPC_ThermalManagementInterrupt};
void __TRK_copy_vectors(void);
__declspec(section ".init") void __TRK_reset(void) { OSResetSystem(FALSE, 0, FALSE); }
void EnableMetroTRKInterrupts(void) {
EnableEXI2Interrupts();
}
u32 TRKTargetTranslate(u32 param_0) {
if (param_0 >= lc_base) {
if ((param_0 < lc_base + 0x4000) && ((gTRKCPUState.Extended1.DBAT3U & 3) != 0)) {
return param_0;
}
}
return param_0 & 0x3FFFFFFF | 0x80000000;
}
extern u8 gTRKInterruptVectorTable[];
__declspec(section ".init") void TRK_copy_vector(u32 offset) {
void* destPtr = (void*)TRKTargetTranslate(offset);
TRK_memcpy(destPtr, (void*)(gTRKInterruptVectorTable + offset), 0x100);
TRK_flush_cache(destPtr, 0x100);
}
void __TRK_copy_vectors(void) {
u32 r3 = lc_base;
u32* isrOffsetPtr;
int i;
u32 r29;
if (r3 <= 0x44 && r3 + 0x4000 > 0x44 && gTRKCPUState.Extended1.DBAT3U & 3) {
r3 = 0x44;
} else {
r3 = EXCEPTIONMASK_ADDR;
}
i = 0;
r29 = *(u32*)r3;
isrOffsetPtr = TRK_ISR_OFFSETS;
do {
if ((r29 & (1 << i)) && i != 4) {
TRK_copy_vector(isrOffsetPtr[i]);
}
i++;
} while (i <= 14);
}
DSError TRKInitializeTarget() {
gTRKState.isStopped = TRUE;
gTRKState.msr = __TRK_get_MSR();
lc_base = 0xE0000000;
return DS_NoError;
}
asm void InitMetroTRK() {
// clang-format off
nofralloc
addi r1, r1, -4
stw r3, 0(r1)
lis r3, gTRKCPUState@h
ori r3, r3, gTRKCPUState@l
stmw r0, ProcessorState_PPC.Default.GPR(r3) //Save the gprs
lwz r4, 0(r1)
addi r1, r1, 4
stw r1, ProcessorState_PPC.Default.GPR[1](r3)
stw r4, ProcessorState_PPC.Default.GPR[3](r3)
mflr r4
stw r4, ProcessorState_PPC.Default.LR(r3)
stw r4, ProcessorState_PPC.Default.PC(r3)
mfcr r4
stw r4, ProcessorState_PPC.Default.CR(r3)
//???
mfmsr r4
ori r3, r4, (1 << (31 - 16))
xori r3, r3, (1 << (31 - 16))
mtmsr r3
mtsrr1 r4 //Copy msr to srr1
//Save misc registers to gTRKCPUState
bl TRKSaveExtended1Block
lis r3, gTRKCPUState@h
ori r3, r3, gTRKCPUState@l
lmw r0, ProcessorState_PPC.Default.GPR(r3) //Restore the gprs
//Reset IABR and DABR
li r0, 0
mtspr 0x3f2, r0
mtspr 0x3f5, r0
//Restore stack pointer
lis r1, _db_stack_addr@h
ori r1, r1, _db_stack_addr@l
mr r3, r5
bl InitMetroTRKCommTable //Initialize comm table
/*
If InitMetroTRKCommTable returned 1 (failure), an invalid hardware
id or the id for GDEV was somehow passed. Since only BBA or NDEV
are supported, we return early. Otherwise, we proceed with
starting up TRK.
*/
cmpwi r3, 1
bne initCommTableSuccess
/*
BUG: The code probably orginally reloaded gTRKCPUState here, but
as is it will read the returned value of InitMetroTRKCommTable
as a TRKCPUState struct pointer, causing the CPU to return to
a garbage code address.
*/
lwz r4, ProcessorState_PPC.Default.LR(r3)
mtlr r4
lmw r0, ProcessorState_PPC.Default.GPR(r3) //Restore the gprs
blr
initCommTableSuccess:
b TRK_main //Jump to TRK_main
// clang-format on
}
@@ -0,0 +1,174 @@
#include "TRK_MINNOW_DOLPHIN/Os/dolphin/dolphin_trk_glue.h"
#include "TRK_MINNOW_DOLPHIN/Os/dolphin/DDH_Stubs.h"
#include "TRK_MINNOW_DOLPHIN/Os/dolphin/GDEV_Stubs.h"
#include "TRK_MINNOW_DOLPHIN/Os/dolphin/UDP_Stubs.h"
#include "dolphin/base/PPCArch.h"
#include "trk.h"
void TRKInterruptHandler();
BOOL _MetroTRK_Has_Framing;
u8 TRK_Use_BBA;
DBCommTable gDBCommTable = {};
void TRKEXICallBack(s16 param_0, OSContext* ctx) {
OSEnableScheduler();
TRKLoadContext(ctx, 0x500);
}
int InitMetroTRKCommTable(int hwId) {
int result = 1;
OSReport("Devkit set to : %ld\n", hwId);
TRK_Use_BBA = 0;
if (hwId == HARDWARE_BBA) { // BBA hardware
OSReport("MetroTRK : Set to BBA\n");
// Initialize gDBCommTable
TRK_Use_BBA = 1;
gDBCommTable.initialize_func = udp_cc_initialize;
gDBCommTable.open_func = udp_cc_open;
gDBCommTable.close_func = udp_cc_close;
gDBCommTable.read_func = udp_cc_read;
gDBCommTable.write_func = udp_cc_write;
gDBCommTable.shutdown_func = udp_cc_shutdown;
gDBCommTable.peek_func = udp_cc_peek;
gDBCommTable.pre_continue_func = udp_cc_pre_continue;
gDBCommTable.post_stop_func = udp_cc_post_stop;
gDBCommTable.init_interrupts_func = NULL;
return 0;
}
if (hwId == HARDWARE_GDEV) { // NDEV hardware
OSReport("MetroTRK : Set to GDEV hardware\n");
// Initialize gDBCommTable
result = Hu_IsStub();
gDBCommTable.initialize_func = (DBCommInitFunc)gdev_cc_initialize;
gDBCommTable.open_func = gdev_cc_open;
gDBCommTable.close_func = gdev_cc_close;
gDBCommTable.read_func = gdev_cc_read;
gDBCommTable.write_func = gdev_cc_write;
gDBCommTable.shutdown_func = gdev_cc_shutdown;
gDBCommTable.peek_func = gdev_cc_peek;
gDBCommTable.pre_continue_func = gdev_cc_pre_continue;
gDBCommTable.post_stop_func = gdev_cc_post_stop;
gDBCommTable.init_interrupts_func = gdev_cc_initinterrupts;
} else if (hwId == HARDWARE_AMC_DDH) {
OSReport("MetroTRK : Set to AMC DDH hardware\n");
result = AMC_IsStub();
// Initialize gDBCommTable
gDBCommTable.initialize_func = (DBCommInitFunc)ddh_cc_initialize;
gDBCommTable.open_func = ddh_cc_open;
gDBCommTable.close_func = ddh_cc_close;
gDBCommTable.read_func = ddh_cc_read;
gDBCommTable.write_func = ddh_cc_write;
gDBCommTable.shutdown_func = ddh_cc_shutdown;
gDBCommTable.peek_func = ddh_cc_peek;
gDBCommTable.pre_continue_func = ddh_cc_pre_continue;
gDBCommTable.post_stop_func = ddh_cc_post_stop;
gDBCommTable.init_interrupts_func = ddh_cc_initinterrupts;
} else { // unknown hardware
OSReport("MetroTRK : Set to UNKNOWN hardware. (%ld)\n", hwId);
OSReport("MetroTRK : Invalid hardware ID passed from OS\n");
OSReport("MetroTRK : Defaulting to GDEV Hardware\n");
}
return result;
}
DSError TRKInitializeIntDrivenUART(u32 param_0, u32 param_1, u32 param_2, void* param_3) {
gDBCommTable.initialize_func(param_3, TRKEXICallBack);
gDBCommTable.open_func();
return DS_NoError;
}
void EnableEXI2Interrupts(void) {
if (!TRK_Use_BBA) {
if (gDBCommTable.init_interrupts_func != NULL) {
gDBCommTable.init_interrupts_func();
}
}
}
int TRKPollUART(void) {
return gDBCommTable.peek_func();
}
UARTError TRKReadUARTN(void* bytes, u32 length) {
int readErr = gDBCommTable.read_func(bytes, length);
return ((-readErr | readErr) >> 31);
}
UARTError TRKWriteUARTN(const void* bytes, u32 length) {
int writeErr = gDBCommTable.write_func(bytes, length);
return ((-writeErr | writeErr) >> 31);
}
void ReserveEXI2Port(void) {
gDBCommTable.post_stop_func();
}
void UnreserveEXI2Port(void) {
gDBCommTable.pre_continue_func();
}
void TRK_board_display(char* str) {
OSReport("%s\n", str);
}
DSError InitializeProgramEndTrap(void) {
static const u32 EndofProgramInstruction = 'END';
u8* endOfProgramInstructionBytes = (u8*)&EndofProgramInstruction;
u8* ppcHaltPtr = (u8*)PPCHalt;
TRK_memcpy(ppcHaltPtr + 4, endOfProgramInstructionBytes, 4);
ICInvalidateRange(ppcHaltPtr + 4, 4);
DCFlushRange(ppcHaltPtr + 4, 4);
}
void TRKUARTInterruptHandler() {}
asm void TRKLoadContext(OSContext* ctx, u32) {
// clang-format off
nofralloc
lwz r0, OSContext.gpr[0](r3)
lwz r1, OSContext.gpr[1](r3)
lwz r2, OSContext.gpr[2](r3)
lhz r5, OSContext.state(r3)
rlwinm. r6, r5, 0, 0x1e, 0x1e
beq lbl_80371C1C
rlwinm r5, r5, 0, 0x1f, 0x1d
sth r5, OSContext.state(r3)
lmw r5, OSContext.gpr[5](r3)
b lbl_80371C20
lbl_80371C1C:
lmw r13, OSContext.gpr[13](r3)
lbl_80371C20:
mr r31, r3
mr r3, r4
lwz r4, OSContext.cr(r31)
mtcrf 0xff, r4
lwz r4, OSContext.lr(r31)
mtlr r4
lwz r4, OSContext.ctr(r31)
mtctr r4
lwz r4, OSContext.xer(r31)
mtxer r4
mfmsr r4
rlwinm r4, r4, 0, 0x11, 0xf //Turn off external exceptions
rlwinm r4, r4, 0, 0x1f, 0x1d //Turn off recoverable exception flag
mtmsr r4
mtsprg 1, r2
lwz r4, OSContext.gpr[3](r31)
mtsprg 2, r4
lwz r4, OSContext.gpr[4](r31)
mtsprg 3, r4
lwz r2, OSContext.srr0(r31)
lwz r4, OSContext.srr1(r31)
lwz r31, OSContext.gpr[31](r31)
b TRKInterruptHandler
// clang-format on
}
@@ -0,0 +1,14 @@
/**
* targcont.c
* Description:
*/
#include "TRK_MINNOW_DOLPHIN/Os/dolphin/targcont.h"
DSError TRKTargetContinue(void) {
TRKTargetSetStopped(0);
UnreserveEXI2Port();
TRKSwapAndGo();
ReserveEXI2Port();
return 0;
}
@@ -0,0 +1,16 @@
/**
* target_options.c
* Description:
*/
#include "TRK_MINNOW_DOLPHIN/Os/dolphin/target_options.h"
static u8 bUseSerialIO;
void SetUseSerialIO(u8 serialIO) {
bUseSerialIO = serialIO;
}
u8 GetUseSerialIO(void) {
return bUseSerialIO;
}
@@ -0,0 +1,62 @@
/**
* dispatch.c
* Description:
*/
#include "TRK_MINNOW_DOLPHIN/MetroTRK/Portable/dispatch.h"
#include "TRK_MINNOW_DOLPHIN/MetroTRK/Portable/msgbuf.h"
#include "TRK_MINNOW_DOLPHIN/utils/common/MWTrace.h"
u32 gTRKDispatchTableSize;
struct DispatchEntry {
int (*fn)(TRKBuffer*);
};
extern int TRKDoUnsupported(TRKBuffer*);
extern int TRKDoConnect(TRKBuffer*);
extern int TRKDoDisconnect(TRKBuffer*);
extern int TRKDoReset(TRKBuffer*);
extern int TRKDoVersions(TRKBuffer*);
extern int TRKDoSupportMask(TRKBuffer*);
extern int TRKDoCPUType(TRKBuffer*);
extern int TRKDoReadMemory(TRKBuffer*);
extern int TRKDoWriteMemory(TRKBuffer*);
extern int TRKDoReadRegisters(TRKBuffer*);
extern int TRKDoWriteRegisters(TRKBuffer*);
extern int TRKDoFlushCache(TRKBuffer*);
extern int TRKDoContinue(TRKBuffer*);
extern int TRKDoStep(TRKBuffer*);
extern int TRKDoStop(TRKBuffer*);
struct DispatchEntry gTRKDispatchTable[33] = {
{ &TRKDoUnsupported }, { &TRKDoConnect }, { &TRKDoDisconnect },
{ &TRKDoReset }, { &TRKDoVersions }, { &TRKDoSupportMask },
{ &TRKDoCPUType }, { &TRKDoUnsupported }, { &TRKDoUnsupported },
{ &TRKDoUnsupported }, { &TRKDoUnsupported }, { &TRKDoUnsupported },
{ &TRKDoUnsupported }, { &TRKDoUnsupported }, { &TRKDoUnsupported },
{ &TRKDoUnsupported }, { &TRKDoReadMemory }, { &TRKDoWriteMemory },
{ &TRKDoReadRegisters }, { &TRKDoWriteRegisters }, { &TRKDoUnsupported },
{ &TRKDoUnsupported }, { &TRKDoFlushCache }, { &TRKDoUnsupported },
{ &TRKDoContinue }, { &TRKDoStep }, { &TRKDoStop },
{ &TRKDoUnsupported }, { &TRKDoUnsupported }, { &TRKDoUnsupported },
{ &TRKDoUnsupported }, { &TRKDoUnsupported },
};
DSError TRKInitializeDispatcher() {
gTRKDispatchTableSize = 32;
return DS_NoError;
}
BOOL TRKDispatchMessage(TRKBuffer* buffer) {
DSError error;
u8 command;
error = DS_DispatchError;
TRKSetBufferPosition(buffer, 0);
TRKReadBuffer1_ui8(buffer, &command);
if (command < gTRKDispatchTableSize) {
error = gTRKDispatchTable[command].fn(buffer);
}
return error;
}
@@ -0,0 +1,21 @@
/**
* main_TRK.c
* Description:
*/
#include "TRK_MINNOW_DOLPHIN/MetroTRK/Portable/main_TRK.h"
#include "TRK_MINNOW_DOLPHIN/utils/common/MWTrace.h"
static DSError TRK_mainError;
DSError TRK_main(void) {
TRK_mainError = TRKInitializeNub();
if (TRK_mainError == DS_NoError) {
TRKNubWelcome();
TRKNubMainLoop();
}
TRK_mainError = TRKTerminateNub();
return TRK_mainError;
}
@@ -0,0 +1,55 @@
#include "TRK_MINNOW_DOLPHIN/MetroTRK/Portable/serpoll.h"
#include "TRK_MINNOW_DOLPHIN/ppc/Generic/targimpl.h"
#include "trk.h"
void TRKNubMainLoop(void) {
void* msg;
TRKEvent event;
BOOL isShutdownRequested;
BOOL isNewInput;
isShutdownRequested = FALSE;
isNewInput = FALSE;
while (isShutdownRequested == FALSE) {
if (TRKGetNextEvent(&event) != FALSE) {
isNewInput = FALSE;
switch (event.eventType) {
case NUBEVENT_Null:
break;
case NUBEVENT_Request:
msg = TRKGetBuffer(event.msgBufID);
TRKDispatchMessage(msg);
break;
case NUBEVENT_Shutdown:
isShutdownRequested = TRUE;
break;
case NUBEVENT_Breakpoint:
case NUBEVENT_Exception:
TRKTargetInterrupt(&event);
break;
case NUBEVENT_Support:
TRKTargetSupportRequest();
break;
}
TRKDestructEvent(&event);
continue;
}
if ((isNewInput == FALSE) || (*(u8*)gTRKInputPendingPtr != '\0')) {
isNewInput = TRUE;
TRKGetInput();
continue;
}
if (TRKTargetStopped() == FALSE) {
TRKTargetContinue();
}
isNewInput = FALSE;
}
}
+76
View File
@@ -0,0 +1,76 @@
/**
* mem_TRK.c
* Description:
*/
#include "TRK_MINNOW_DOLPHIN/MetroTRK/Portable/mem_TRK.h"
#include <stdint.h>
#pragma dont_inline on
void TRK_fill_mem(void* dst, int val, u32 n) {
u32 v, i, j;
v = (u8)val;
((u8*)dst) = ((u8*)dst) - 1;
if (n >= 32) {
i = (~(uintptr_t)dst) & 3;
if (i) {
n -= i;
do {
*++(((u8*)dst)) = v;
} while (--i);
}
if (v)
v |= v << 24 | v << 16 | v << 8;
((u32*)dst) = ((u32*)(((u8*)dst) + 4)) - 1;
((u32*)dst) = ((u32*)(((u8*)dst) + 1)) - 1;
i = n / 32;
if (i) {
do {
for (j = 0; j < 8; j++)
*++((u32*)dst) = v;
} while (--i);
}
i = (n / 4) % 8;
if (i) {
do {
*++((u32*)dst) = v;
} while (--i);
}
((u8*)dst) = ((u8*)(((u32*)dst) + 1)) - 1;
n %= 4;
}
if (n)
do {
*++((u8*)dst) = v;
} while (--n);
}
#pragma dont_inline reset
__declspec(section ".init") void* TRK_memcpy(void* dst, const void* src, size_t n) {
const unsigned char* s = (const unsigned char*)src - 1;
unsigned char* d = (unsigned char*)dst - 1;
n++;
while (--n != 0)
*++d = *++s;
return dst;
}
__declspec(section ".init") void* TRK_memset(void* dst, int val, size_t n) {
TRK_fill_mem(dst, val, n);
return dst;
}
+12
View File
@@ -0,0 +1,12 @@
/**
* msg.c
* Description:
*/
#include "TRK_MINNOW_DOLPHIN/MetroTRK/Portable/msg.h"
#include "TRK_MINNOW_DOLPHIN/Os/dolphin/dolphin_trk_glue.h"
#include "trk.h"
DSError TRKMessageSend(TRK_Msg* msg) {
return TRKWriteUARTN(&msg->m_msg, msg->m_msgLength);
}
+329
View File
@@ -0,0 +1,329 @@
#include "TRK_MINNOW_DOLPHIN/MetroTRK/Portable/msgbuf.h"
#include "TRK_MINNOW_DOLPHIN/MetroTRK/Portable/nubinit.h"
#include "TRK_MINNOW_DOLPHIN/MetroTRK/Portable/mutex_TRK.h"
TRKBuffer gTRKMsgBufs[3];
void TRKSetBufferUsed(TRKBuffer* msg, BOOL state) {
msg->isInUse = state;
}
DSError TRKInitializeMessageBuffers(void) {
int i;
for (i = 0; i < 3; i++) {
TRKInitializeMutex(&gTRKMsgBufs[i]);
TRKAcquireMutex(&gTRKMsgBufs[i]);
TRKSetBufferUsed(&gTRKMsgBufs[i], FALSE);
TRKReleaseMutex(&gTRKMsgBufs[i]);
}
return DS_NoError;
}
DSError TRKGetFreeBuffer(int* msgID, TRKBuffer** outMsg) {
TRKBuffer* buf;
DSError error = DS_NoMessageBufferAvailable;
int i;
*outMsg = NULL;
for (i = 0; i < 3; i++) {
buf = TRKGetBuffer(i);
TRKAcquireMutex(buf);
if (!buf->isInUse) {
TRKResetBuffer(buf, TRUE);
TRKSetBufferUsed(buf, TRUE);
error = DS_NoError;
*outMsg = buf;
*msgID = i;
i = 3; // why not break? weird choice
}
TRKReleaseMutex(buf);
}
if (error == DS_NoMessageBufferAvailable) {
usr_puts_serial("ERROR : No buffer available\n");
}
return error;
}
void* TRKGetBuffer(int idx) {
TRKBuffer* buf = NULL;
if (idx >= 0 && idx < 3) {
buf = &gTRKMsgBufs[idx];
}
return buf;
}
void TRKReleaseBuffer(int idx) {
TRKBuffer* msg;
if (idx != -1 && idx >= 0 && idx < 3) {
msg = &gTRKMsgBufs[idx];
TRKAcquireMutex(msg);
TRKSetBufferUsed(msg, FALSE);
TRKReleaseMutex(msg);
}
}
void TRKResetBuffer(TRKBuffer* msg, BOOL keepData) {
msg->length = 0;
msg->position = 0;
if (!(u8)keepData) {
TRK_memset(msg->data, 0, 0x880);
}
}
DSError TRKSetBufferPosition(TRKBuffer* msg, u32 pos) {
DSError error = DS_NoError;
if (pos > 0x880) {
error = DS_MessageBufferOverflow;
} else {
msg->position = pos;
// If the new position is past the current length,
// update the length
if (pos > msg->length) {
msg->length = pos;
}
}
return error;
}
DSError TRKAppendBuffer(TRKBuffer* msg, const void* data, size_t length) {
DSError error = DS_NoError; // r31
u32 bytesLeft;
// Return if no bytes to append
if (length == 0) {
return DS_NoError;
}
bytesLeft = 0x880 - msg->position;
// If there isn't enough space left in the buffer, change the number
// of bytes to append to the remaning number of bytes
if (bytesLeft < length) {
error = DS_MessageBufferOverflow;
length = bytesLeft;
}
if (length == 1) {
// If the length of bytes to append is 1, just copy the byte over
msg->data[msg->position] = ((u8*)data)[0];
} else {
// Otherwise, use memcpy
TRK_memcpy(msg->data + msg->position, data, length);
}
// Update the position and length
msg->position += length;
msg->length = msg->position;
return error;
}
DSError TRKReadBuffer(TRKBuffer* msg, void* data, size_t length) {
DSError error = DS_NoError;
unsigned int bytesLeft; // this has to be unsigned int not u32 to match lmfao.
// Return if no bytes to read
if (length == 0) {
return DS_NoError;
}
bytesLeft = msg->length - msg->position;
// If the number of bytes to read exceeds the buffer length, change
// the length to the remaining number of bytes
if (length > bytesLeft) {
error = DS_MessageBufferReadError;
length = bytesLeft;
}
TRK_memcpy(data, msg->data + msg->position, length);
msg->position += length;
return error;
}
DSError TRKAppendBuffer1_ui16(TRKBuffer* buffer, const u16 data) {
u8* bigEndianData;
u8* byteData;
u8 swapBuffer[sizeof(data)];
if (gTRKBigEndian) {
bigEndianData = (u8*)&data;
} else {
byteData = (u8*)&data;
bigEndianData = swapBuffer;
bigEndianData[0] = byteData[1];
bigEndianData[1] = byteData[0];
}
return TRKAppendBuffer(buffer, (const void*)bigEndianData, sizeof(data));
}
DSError TRKAppendBuffer1_ui8(TRKBuffer* buffer, const u8 data) {
if (buffer->position >= 0x880) {
return DS_MessageBufferOverflow;
}
buffer->data[buffer->position++] = data;
buffer->length++;
return DS_NoError;
}
DSError TRKAppendBuffer1_ui32(TRKBuffer* buffer, const u32 data) {
u8* bigEndianData;
u8* byteData;
u8 swapBuffer[sizeof(data)];
if (gTRKBigEndian) {
bigEndianData = (u8*)&data;
} else {
byteData = (u8*)&data;
bigEndianData = swapBuffer;
bigEndianData[0] = byteData[3];
bigEndianData[1] = byteData[2];
bigEndianData[2] = byteData[1];
bigEndianData[3] = byteData[0];
}
return TRKAppendBuffer(buffer, (const void*)bigEndianData, sizeof(data));
}
DSError TRKAppendBuffer1_ui64(TRKBuffer* buffer, const u64 data) {
u8* bigEndianData;
u8* byteData;
u8 swapBuffer[sizeof(data)];
if (gTRKBigEndian) {
bigEndianData = (u8*)&data;
} else {
byteData = (u8*)&data;
bigEndianData = swapBuffer;
bigEndianData[0] = byteData[7];
bigEndianData[1] = byteData[6];
bigEndianData[2] = byteData[5];
bigEndianData[3] = byteData[4];
bigEndianData[4] = byteData[3];
bigEndianData[5] = byteData[2];
bigEndianData[6] = byteData[1];
bigEndianData[7] = byteData[0];
}
return TRKAppendBuffer(buffer, (const void*)bigEndianData, sizeof(data));
}
DSError TRKAppendBuffer_ui8(TRKBuffer* buffer, const u8* data, int count) {
DSError err;
int i;
for (i = 0, err = DS_NoError; err == DS_NoError && i < count; i++) {
err = TRKAppendBuffer1_ui8(buffer, data[i]);
}
return err;
}
DSError TRKAppendBuffer_ui32(TRKBuffer* buffer, const u32* data, int count) {
DSError err;
int i;
for (i = 0, err = DS_NoError; err == DS_NoError && i < count; i++) {
err = TRKAppendBuffer1_ui32(buffer, data[i]);
}
return err;
}
DSError TRKReadBuffer1_ui8(TRKBuffer* buffer, u8* data) {
return TRKReadBuffer(buffer, (void*)data, 1);
}
DSError TRKReadBuffer1_ui32(TRKBuffer* buffer, u32* data) {
DSError err;
u8* bigEndianData;
u8* byteData;
u8 swapBuffer[sizeof(data)];
if (gTRKBigEndian) {
bigEndianData = (u8*)data;
} else {
bigEndianData = swapBuffer;
}
err = TRKReadBuffer(buffer, (void*)bigEndianData, sizeof(*data));
if (!gTRKBigEndian && err == DS_NoError) {
byteData = (u8*)data;
byteData[0] = bigEndianData[3];
byteData[1] = bigEndianData[2];
byteData[2] = bigEndianData[1];
byteData[3] = bigEndianData[0];
}
return err;
// UNUSED FUNCTION
}
DSError TRKReadBuffer1_ui64(TRKBuffer* buffer, u64* data) {
DSError err;
u8* bigEndianData;
u8* byteData;
u8 swapBuffer[sizeof(data)];
if (gTRKBigEndian) {
bigEndianData = (u8*)data;
} else {
bigEndianData = swapBuffer;
}
err = TRKReadBuffer(buffer, (void*)bigEndianData, sizeof(*data));
if (!gTRKBigEndian && err == 0) {
byteData = (u8*)data;
byteData[0] = bigEndianData[7];
byteData[1] = bigEndianData[6];
byteData[2] = bigEndianData[5];
byteData[3] = bigEndianData[4];
byteData[4] = bigEndianData[3];
byteData[5] = bigEndianData[2];
byteData[6] = bigEndianData[1];
byteData[7] = bigEndianData[0];
}
return err;
}
DSError TRKReadBuffer_ui8(TRKBuffer* buffer, u8* data, int count) {
DSError err;
int i;
for (i = 0, err = DS_NoError; err == DS_NoError && i < count; i++) {
err = TRKReadBuffer1_ui8(buffer, &(data[i]));
}
return err;
}
DSError TRKReadBuffer_ui32(TRKBuffer* buffer, u32* data, int count) {
DSError err;
s32 i;
for (i = 0, err = DS_NoError; err == DS_NoError && i < count; i++) {
err = TRKReadBuffer1_ui32(buffer, &(data[i]));
}
return err;
}
+469
View File
@@ -0,0 +1,469 @@
#include "TRK_MINNOW_DOLPHIN/MetroTRK/Portable/msghndlr.h"
#include "TRK_MINNOW_DOLPHIN/MetroTRK/Portable/nubevent.h"
#include "TRK_MINNOW_DOLPHIN/utils/common/MWTrace.h"
#include "trk.h"
#include "string.h"
static BOOL IsTRKConnected;
BOOL GetTRKConnected(void) {
return IsTRKConnected;
}
void SetTRKConnected(BOOL isTRKConnected) {
IsTRKConnected = isTRKConnected;
}
DSError TRKSendACK(TRKBuffer* buffer) {
DSError err;
err = TRKMessageSend(buffer);
return err;
}
DSError TRKStandardACK(TRKBuffer* buffer, MessageCommandID commandID,
DSReplyError replyError) {
CommandReply reply;
memset(&reply, 0, sizeof(CommandReply));
reply.commandID.b = commandID;
reply._00 = 0x40;
reply.replyError.b = replyError;
TRKWriteUARTN(&reply, sizeof(CommandReply));
return DS_NoError;
}
DSError TRKDoConnect(TRKBuffer* buffer) {
IsTRKConnected = TRUE;
return TRKStandardACK(buffer, 0x80, DSREPLY_NoError);
}
DSError TRKDoDisconnect(TRKBuffer* buffer) {
TRKEvent event;
IsTRKConnected = FALSE;
TRKStandardACK(buffer, 0x80, DSREPLY_NoError);
TRKConstructEvent(&event, 1);
TRKPostEvent(&event);
return DS_NoError;
}
DSError TRKDoReset(TRKBuffer* buffer) {
TRKStandardACK(buffer, 0x80, DSREPLY_NoError);
__TRK_reset();
return DS_NoError;
}
DSError TRKDoOverride(TRKBuffer* buffer) {
TRKStandardACK(buffer, 0x80, DSREPLY_NoError);
__TRK_copy_vectors();
return DS_NoError;
}
DSError TRKDoVersions(TRKBuffer*) {
return DS_NoError;
}
DSError TRKDoSupportMask(TRKBuffer*) {
return DS_NoError;
}
DSError TRKDoReadMemory(TRKBuffer* buffer) {
u8 buf[0x820] ATTRIBUTE_ALIGN(32);
size_t tempLength;
int result;
int replyErr;
int options;
size_t length;
u32 start;
start = *(u32*)(buffer->data + 16);
length = *(u16*)(buffer->data + 12);
options = buffer->data[8];
if (options & DSMSGMEMORY_Extended) {
return TRKStandardACK(buffer, DSMSG_ReplyACK, DSREPLY_UnsupportedOptionError);
}
tempLength = length;
if (options & DSMSGMEMORY_Space_data) {
result = TRKTargetAccessARAM(buf, start, &tempLength, TRUE);
} else {
result = TRKTargetAccessMemory(buf, start, &tempLength,
options & DSMSGMEMORY_Userview ? 0 : 1, TRUE);
}
TRKResetBuffer(buffer, 0);
if (result == DS_NoError) {
CommandReply reply;
memset(&reply, 0, sizeof(CommandReply));
reply.replyError.b = result;
reply._00 = tempLength + 0x40;
reply.commandID.b = DSMSG_ReplyACK;
TRKAppendBuffer(buffer, &reply, sizeof(CommandReply));
if (options & 0x40) {
result = TRKAppendBuffer(buffer, buf + (start & 0x1F), tempLength);
} else {
result = TRKAppendBuffer(buffer, buf, tempLength);
}
}
if (result) {
switch (result) {
case DS_CWDSException:
replyErr = DSREPLY_CWDSException;
break;
case DS_InvalidMemory:
replyErr = DSREPLY_InvalidMemoryRange;
break;
case DS_InvalidProcessID:
replyErr = DSREPLY_InvalidProcessID;
break;
case DS_InvalidThreadID:
replyErr = DSREPLY_InvalidThreadID;
break;
case DS_OSError:
replyErr = DSREPLY_OSError;
break;
default:
replyErr = DSREPLY_CWDSError;
break;
}
return TRKStandardACK(buffer, DSMSG_ReplyACK, replyErr);
}
return TRKSendACK(buffer);
}
DSError TRKDoWriteMemory(TRKBuffer* b) {
u8 buf[0x820] ATTRIBUTE_ALIGN(32);
size_t tempLength;
int options;
int result;
int replyErr;
size_t length;
u32 start;
start = *(u32*)(&b->data[16]);
length = *(u16*)(&b->data[12]);
options = b->data[8];
if (options & DSMSGMEMORY_Extended) {
return TRKStandardACK(b, DSMSG_ReplyACK, DSMSG_ReadRegisters);
}
tempLength = length;
TRKSetBufferPosition(b, DSMSGMEMORY_Space_data);
if (options & DSMSGMEMORY_Space_data) {
TRKReadBuffer(b, buf + (start & 0x1f), tempLength);
result = TRKTargetAccessARAM(buf, start, &tempLength, FALSE);
} else {
TRKReadBuffer(b, buf, tempLength);
result = TRKTargetAccessMemory(buf, start, &tempLength,
options & DSMSGMEMORY_Userview ? 0 : 1, FALSE);
}
TRKResetBuffer(b, 0);
if (result == DS_NoError) {
CommandReply reply;
memset(&reply, 0, sizeof(CommandReply));
reply._00 = 0x40;
reply.commandID.b = DSMSG_ReplyACK;
reply.replyError.b = result;
result = TRKAppendBuffer(b, &reply, sizeof(CommandReply));
}
if (result != DS_NoError) {
switch (result) {
case DS_CWDSException:
replyErr = DSREPLY_CWDSException;
break;
case DS_InvalidMemory:
replyErr = DSREPLY_InvalidMemoryRange;
break;
case DS_InvalidProcessID:
replyErr = DSREPLY_InvalidProcessID;
break;
case DS_InvalidThreadID:
replyErr = DSREPLY_InvalidThreadID;
break;
case DS_OSError:
replyErr = DSREPLY_OSError;
break;
default:
replyErr = DSREPLY_CWDSError;
break;
}
return TRKStandardACK(b, DSMSG_ReplyACK, replyErr);
}
return TRKSendACK(b);
}
DSError TRKDoReadRegisters(TRKBuffer* b) {
int error;
u8 options;
u16 firstRegister;
u16 lastRegister;
size_t registersLength;
CommandReply local_50;
options = b->data[8];
firstRegister = *(u16*)(b->data + 12);
lastRegister = *(u16*)(b->data + 16);
if (firstRegister > lastRegister) {
return TRKStandardACK(b, DSMSG_ReplyACK, DSREPLY_InvalidRegisterRange);
}
local_50.commandID.b = DSMSG_ReplyACK;
local_50._00 = 0x468;
TRKResetBuffer(b, 0);
TRKAppendBuffer_ui8(b, (u8*)&local_50, sizeof(CommandReply));
error = TRKTargetAccessDefault(0, 36, b, &registersLength, TRUE);
if (error == DS_NoError) {
error = TRKTargetAccessFP(0, 33, b, &registersLength, TRUE);
}
if (error == DS_NoError) {
error = TRKTargetAccessExtended1(0, 0x60, b, &registersLength, TRUE);
}
if (error == DS_NoError) {
error = TRKTargetAccessExtended2(0, 31, b, &registersLength, TRUE);
}
// Check if there was an error, and respond accordingly
if (error != DS_NoError) {
int replyError;
switch (error) {
case DS_UnsupportedError:
replyError = DSREPLY_UnsupportedOptionError;
break;
case DS_InvalidRegister:
replyError = DSREPLY_InvalidRegisterRange;
break;
case DS_CWDSException:
replyError = DSREPLY_CWDSException;
break;
case DS_InvalidProcessID:
replyError = DSREPLY_InvalidProcessID;
break;
case DS_InvalidThreadID:
replyError = DSREPLY_InvalidThreadID;
break;
case DS_OSError:
replyError = DSREPLY_OSError;
break;
default:
replyError = DSREPLY_CWDSError;
}
return TRKStandardACK(b, DSMSG_ReplyACK, replyError);
} else {
// No error, send ack
return TRKSendACK(b);
}
}
DSError TRKDoWriteRegisters(TRKBuffer* b) {
int error;
int replyError;
u8 options;
u16 firstRegister;
u16 lastRegister;
size_t registersLength;
options = b->data[8];
firstRegister = *(u16*)(b->data + 12);
lastRegister = *(u16*)(b->data + 16);
TRKSetBufferPosition(b, 0);
if (firstRegister > lastRegister) {
return TRKStandardACK(b, DSMSG_ReplyACK, DSREPLY_InvalidRegisterRange);
}
TRKSetBufferPosition(b, 0x40);
switch (options) {
case DSREG_Default:
error = TRKTargetAccessDefault(firstRegister, lastRegister, b, &registersLength, FALSE);
break;
case DSREG_FP:
error = TRKTargetAccessFP(firstRegister, lastRegister, b, &registersLength, FALSE);
break;
case DSREG_Extended1:
error = TRKTargetAccessExtended1(firstRegister, lastRegister, b, &registersLength, FALSE);
break;
case DSREG_Extended2:
error = TRKTargetAccessExtended2(firstRegister, lastRegister, b, &registersLength, FALSE);
break;
default:
// invalid option
error = DS_UnsupportedError;
break;
}
TRKResetBuffer(b, 0);
if (error == DS_NoError) {
CommandReply local_50;
memset(&local_50, 0, sizeof(CommandReply));
local_50._00 = 0x40;
local_50.commandID.b = DSMSG_ReplyACK;
local_50.replyError.b = error;
error = TRKAppendBuffer(b, (u8*)&local_50, sizeof(CommandReply));
}
// Check if there was an error, and respond accordingly
if (error != DS_NoError) {
switch (error) {
case DS_UnsupportedError:
replyError = DSREPLY_UnsupportedOptionError;
break;
case DS_InvalidRegister:
replyError = DSREPLY_InvalidRegisterRange;
break;
case DS_MessageBufferReadError:
replyError = DSREPLY_PacketSizeError;
break;
case DS_CWDSException:
replyError = DSREPLY_CWDSException;
break;
case DS_InvalidProcessID:
replyError = DSREPLY_InvalidProcessID;
break;
case DS_InvalidThreadID:
replyError = DSREPLY_InvalidThreadID;
break;
case DS_OSError:
replyError = DSREPLY_OSError;
break;
default:
replyError = DSREPLY_CWDSError;
}
return TRKStandardACK(b, DSMSG_ReplyACK, replyError);
} else {
// No error, send ack
return TRKSendACK(b);
}
}
void TRKDoFlushCache(void) {
// UNUSED FUNCTION
}
DSError TRKDoContinue(TRKBuffer*) {
if (!TRKTargetStopped()) {
u8 arr[0x40];
memset(arr, 0, 0x40);
arr[4] = 0x80;
*(u32*)arr = 0x40;
arr[8] = 0x16;
TRKWriteUARTN(arr, 0x40);
return DS_NoError;
} else {
u8 arr[0x40];
memset(arr, 0, 0x40);
arr[4] = 0x80;
*(u32*)arr = 0x40;
arr[8] = 0x00;
TRKWriteUARTN(arr, 0x40);
return TRKTargetContinue();
}
}
DSError TRKDoStep(TRKBuffer* b) {
DSError result;
u8 options;
u8 count;
u32 rangeStart;
u32 rangeEnd;
u32 pc;
TRKSetBufferPosition(b, 0);
options = *(u8*)&b->data[8];
rangeStart = *(u32*)&b->data[16];
rangeEnd = *(u32*)&b->data[20];
switch (options) {
case DSSTEP_IntoCount:
case DSSTEP_OverCount:
count = b->data[12];
if (count >= 1) {
break;
}
return TRKStandardACK(b, DSMSG_ReplyACK, DSREPLY_ParameterError);
case DSSTEP_IntoRange:
case DSSTEP_OverRange:
pc = TRKTargetGetPC();
if (pc >= rangeStart && pc <= rangeEnd) {
break;
}
return TRKStandardACK(b, DSMSG_ReplyACK, DSREPLY_ParameterError);
default:
return TRKStandardACK(b, DSMSG_ReplyACK, DSREPLY_UnsupportedOptionError);
}
if (!TRKTargetStopped()) {
return TRKStandardACK(b, DSMSG_ReplyACK, DSREPLY_NotStopped);
} else {
result = TRKStandardACK(b, DSMSG_ReplyACK, DSREPLY_NoError);
switch (options) {
case DSSTEP_IntoCount:
case DSSTEP_OverCount:
result = TRKTargetSingleStep(count, (options == DSSTEP_OverCount));
break;
case DSSTEP_IntoRange:
case DSSTEP_OverRange:
result = TRKTargetStepOutOfRange(rangeStart, rangeEnd, (options == DSSTEP_OverRange));
break;
}
return result;
}
}
DSError TRKDoStop(TRKBuffer* b) {
MessageCommandID c;
switch (TRKTargetStop()) {
case DS_NoError:
c = DSMSG_Ping;
break;
case DS_InvalidProcessID:
c = '!';
break;
case DS_InvalidThreadID:
c = '\"';
break;
case DS_OSError:
c = ' ';
break;
default:
c = DSMSG_Connect;
break;
}
TRKStandardACK(b, DSMSG_ReplyACK, c);
return DS_NoError;
}
DSError TRKDoSetOption(TRKBuffer* message) {
u8 enable = message->data[0xc];
TRKStandardACK(message, DSMSG_ReplyACK, DS_NoError);
return 0;
}
@@ -0,0 +1,18 @@
/**
* mutex_TRK.c
* Description:
*/
#include "trk.h"
DSError TRKInitializeMutex(void*) {
return DS_NoError;
}
DSError TRKAcquireMutex(void*) {
return DS_NoError;
}
DSError TRKReleaseMutex(void*) {
return DS_NoError;
}
+28
View File
@@ -0,0 +1,28 @@
#include "TRK_MINNOW_DOLPHIN/MetroTRK/Portable/notify.h"
#include "trk.h"
DSError TRKDoNotifyStopped(MessageCommandID cmd) {
int reqIdx;
int bufIdx;
TRKBuffer* msg;
DSError err;
DSError bufError;
bufError = TRKGetFreeBuffer(&bufIdx, &msg);
if ((err = bufError) == FALSE) {
if (err == DS_NoError) {
if (cmd == DSMSG_NotifyStopped) {
TRKTargetAddStopInfo(msg);
} else {
TRKTargetAddExceptionInfo(msg);
}
}
bufError = TRKRequestSend(msg, &reqIdx, 2, 3, 1);
err = bufError;
if (err == DS_NoError) {
TRKReleaseBuffer(reqIdx);
}
TRKReleaseBuffer(bufIdx);
}
return err;
}
@@ -0,0 +1,63 @@
#include "TRK_MINNOW_DOLPHIN/MetroTRK/Portable/nubevent.h"
TRKEventQueue gTRKEventQueue;
DSError TRKInitializeEventQueue() {
TRKInitializeMutex(&gTRKEventQueue);
TRKAcquireMutex(&gTRKEventQueue);
gTRKEventQueue.count = 0;
gTRKEventQueue.next = 0;
gTRKEventQueue.eventID = 0x100;
TRKReleaseMutex(&gTRKEventQueue);
return DS_NoError;
}
BOOL TRKGetNextEvent(TRKEvent* event) {
BOOL status = 0;
TRKAcquireMutex(&gTRKEventQueue);
if (0 < gTRKEventQueue.count) {
TRK_memcpy(event, &gTRKEventQueue.events[gTRKEventQueue.next], sizeof(TRKEvent));
gTRKEventQueue.count--;
if (++gTRKEventQueue.next == 2) {
gTRKEventQueue.next = 0;
}
status = 1;
}
TRKReleaseMutex(&gTRKEventQueue);
return status;
}
DSError TRKPostEvent(TRKEvent* event) {
DSError ret = DS_NoError;
int nextEventID;
TRKAcquireMutex(&gTRKEventQueue);
if (gTRKEventQueue.count == 2) {
ret = DS_EventQueueFull;
} else {
nextEventID = (gTRKEventQueue.next + gTRKEventQueue.count) % 2;
TRK_memcpy(&gTRKEventQueue.events[nextEventID], event, sizeof(TRKEvent));
gTRKEventQueue.events[nextEventID].eventID = gTRKEventQueue.eventID;
if (++gTRKEventQueue.eventID < 0x100) {
gTRKEventQueue.eventID = 0x100;
}
gTRKEventQueue.count++;
}
TRKReleaseMutex(&gTRKEventQueue);
return ret;
}
void TRKConstructEvent(TRKEvent* event, NubEventType eventType) {
event->eventType = eventType;
event->eventID = 0;
event->msgBufID = -1;
}
void TRKDestructEvent(TRKEvent* event) {
TRKReleaseBuffer(event->msgBufID);
}
+69
View File
@@ -0,0 +1,69 @@
#include "TRK_MINNOW_DOLPHIN/MetroTRK/Portable/nubinit.h"
#include "TRK_MINNOW_DOLPHIN/MetroTRK/Portable/serpoll.h"
#include "TRK_MINNOW_DOLPHIN/utils/common/MWTrace.h"
BOOL gTRKBigEndian;
DSError TRKInitializeNub(void) {
DSError ret;
DSError uartErr;
ret = TRKInitializeEndian();
if (ret == DS_NoError) {
usr_put_initialize();
}
if (ret == DS_NoError) {
ret = TRKInitializeEventQueue();
}
if (ret == DS_NoError) {
ret = TRKInitializeMessageBuffers();
}
if (ret == DS_NoError) {
ret = TRKInitializeDispatcher();
}
if (ret == DS_NoError) {
uartErr = TRKInitializeIntDrivenUART(0x0000e100, 1, 0, &gTRKInputPendingPtr);
TRKTargetSetInputPendingPtr(gTRKInputPendingPtr);
if (uartErr != DS_NoError) {
ret = uartErr;
}
}
if (ret == DS_NoError) {
ret = TRKInitializeSerialHandler();
}
if (ret == DS_NoError) {
ret = TRKInitializeTarget();
}
return ret;
}
DSError TRKTerminateNub(void) {
TRKTerminateSerialHandler();
return DS_NoError;
}
void TRKNubWelcome(void) {
TRK_board_display("MetroTRK for GAMECUBE v0.10");
return;
}
BOOL TRKInitializeEndian(void) {
u8 bendian[4];
BOOL result = FALSE;
gTRKBigEndian = TRUE;
bendian[0] = 0x12;
bendian[1] = 0x34;
bendian[2] = 0x56;
bendian[3] = 0x78;
if (*(u32*)bendian == 0x12345678) {
gTRKBigEndian = TRUE;
} else if (*(u32*)bendian == 0x78563412) {
gTRKBigEndian = FALSE;
} else {
result = TRUE;
}
return result;
}
+79
View File
@@ -0,0 +1,79 @@
#include "TRK_MINNOW_DOLPHIN/MetroTRK/Portable/serpoll.h"
#include "TRK_MINNOW_DOLPHIN/MetroTRK/Portable/nubevent.h"
#include "trk.h"
static TRKFramingState gTRKFramingState;
void* gTRKInputPendingPtr;
extern int TRKPollUART(void);
MessageBufferID TRKTestForPacket() {
u8 payloadBuf[0x880];
u8 packetBuf[0x40];
int bufID;
TRKBuffer* msg;
MessageBufferID result;
if (TRKPollUART() <= 0) {
return -1;
}
result = TRKGetFreeBuffer(&bufID, &msg);
TRKSetBufferPosition(msg, 0);
if (TRKReadUARTN(packetBuf, 0x40) == UART_NoError) {
int readSize;
TRKAppendBuffer_ui8(msg, packetBuf, 0x40);
readSize = ((u32*)packetBuf)[0] - 0x40;
result = bufID;
if (readSize > 0) {
if (TRKReadUARTN(payloadBuf, ((u32*)packetBuf)[0] - 0x40) == UART_NoError) {
TRKAppendBuffer_ui8(msg, payloadBuf, ((u32*)packetBuf)[0]);
} else {
TRKReleaseBuffer(result);
result = -1;
}
}
} else {
TRKReleaseBuffer(result);
result = -1;
}
return result;
}
void TRKGetInput(void) {
MessageBufferID id = TRKTestForPacket();
if (id != -1) {
TRKEvent event;
TRKGetBuffer(id);
TRKConstructEvent(&event, NUBEVENT_Request);
event.msgBufID = id;
gTRKFramingState.msgBufID = -1;
TRKPostEvent(&event);
}
}
void TRKProcessInput(int bufferIdx) {
TRKEvent event;
TRKConstructEvent(&event, NUBEVENT_Request);
event.msgBufID = bufferIdx;
gTRKFramingState.msgBufID = -1;
TRKPostEvent(&event);
}
DSError TRKInitializeSerialHandler() {
gTRKFramingState.msgBufID = -1;
gTRKFramingState.receiveState = DSRECV_Wait;
gTRKFramingState.isEscape = FALSE;
return DS_NoError;
}
DSError TRKTerminateSerialHandler(void) {
return DS_NoError;
}
+278
View File
@@ -0,0 +1,278 @@
#include "TRK_MINNOW_DOLPHIN/MetroTRK/Portable/support.h"
#include "TRK_MINNOW_DOLPHIN/utils/common/MWTrace.h"
#include "TRK_MINNOW_DOLPHIN/MetroTRK/Portable/msgbuf.h"
#include "string.h"
DSError TRKSuppAccessFile(u32 file_handle, u8* data, size_t* count, DSIOResult* io_result,
BOOL need_reply, BOOL read) {
DSError error;
int replyBufferId;
TRKBuffer* replyBuffer;
u32 length;
int bufferId;
TRKBuffer* buffer;
u32 i;
u8 replyIOResult;
u32 replyLength;
BOOL exit;
CommandReply reply;
if (data == NULL || *count == 0) {
return DS_ParameterError;
}
exit = FALSE;
*io_result = DS_IONoError;
i = 0;
error = DS_NoError;
while (!exit && i < *count && error == DS_NoError && *io_result == 0) {
memset(&reply, 0, sizeof(CommandReply));
if (*count - i <= 0x800) {
length = *count - i;
} else {
length = 0x800;
}
reply.commandID.b = read ? DSMSG_ReadFile : DSMSG_WriteFile;
if (read) {
reply._00 = 0x40;
} else {
reply._00 = length + 0x40;
}
reply.replyError.r = file_handle;
*(u16*)&reply._0C = length;
TRKGetFreeBuffer(&bufferId, &buffer);
error = TRKAppendBuffer_ui8(buffer, (u8*)&reply, 0x40);
if (!read && error == DS_NoError) {
error = TRKAppendBuffer_ui8(buffer, data + i, length);
}
if (error == DS_NoError) {
if (need_reply) {
BOOL b = read && file_handle == 0;
error = TRKRequestSend(buffer, &replyBufferId, read ? 5 : 5, 3, !b);
if (error == DS_NoError) {
replyBuffer = (TRKBuffer*)TRKGetBuffer(replyBufferId);
}
replyIOResult = *(u32*)(replyBuffer->data + 0x10);
replyLength = *(u16*)(replyBuffer->data + 0x14);
if (read && error == DS_NoError && replyLength <= length) {
TRKSetBufferPosition(replyBuffer, 0x40);
error = TRKReadBuffer_ui8(replyBuffer, data + i, replyLength);
if (error == DS_MessageBufferReadError) {
error = DS_NoError;
}
}
if (replyLength != length) {
length = replyLength;
exit = TRUE;
}
*io_result = (DSIOResult)replyIOResult;
TRKReleaseBuffer(replyBufferId);
} else {
error = TRKMessageSend(buffer);
}
}
TRKReleaseBuffer(bufferId);
i += length;
}
*count = i;
return error;
}
DSError TRKRequestSend(TRKBuffer* msgBuf, int* bufferId, u32 p1, u32 p2, int p3) {
int error = DS_NoError;
TRKBuffer* buffer;
u32 counter;
int count;
u8 msgCmd;
int msgReplyError;
BOOL badReply = TRUE;
*bufferId = -1;
for (count = p2 + 1; count != 0 && *bufferId == -1 && error == DS_NoError; count--) {
error = TRKMessageSend(msgBuf);
if (error == DS_NoError) {
if (p3) {
counter = 0;
}
while (TRUE) {
do {
*bufferId = TRKTestForPacket();
if (*bufferId != -1)
break;
} while (!p3 || ++counter < 79999980);
if (*bufferId == -1)
break;
badReply = 0;
buffer = TRKGetBuffer(*bufferId);
TRKSetBufferPosition(buffer, 0);
OutputData(&buffer->data[0], buffer->length);
msgCmd = buffer->data[4];
if (msgCmd >= DSMSG_ReplyACK)
break;
TRKProcessInput(*bufferId);
*bufferId = -1;
}
if (*bufferId != -1) {
if (buffer->length < 0x40) {
// OSReport("MetroTRK - bad reply size %ld\n", buffer->length);
badReply = TRUE;
}
if (error == DS_NoError && !badReply) {
msgReplyError = buffer->data[8];
}
if (error == DS_NoError && !badReply) {
if ((int)msgCmd != DSMSG_ReplyACK || msgReplyError != DSREPLY_NoError) {
badReply = TRUE;
}
}
if (error != DS_NoError || badReply) {
TRKReleaseBuffer(*bufferId);
*bufferId = -1;
}
}
}
}
if (*bufferId == -1) {
error = DS_Error800;
}
return error;
}
DSError HandleOpenFileSupportRequest(const char* path, u8 replyError, u32* param_3,
DSIOResult* ioResult) {
DSError error;
int bufferId2;
int bufferId1;
TRKBuffer* tempBuffer;
TRKBuffer* buffer;
CommandReply reply;
memset(&reply, 0, sizeof(CommandReply));
*param_3 = 0;
reply.commandID.b = DSMSG_OpenFile;
reply._00 = strlen(path) + 0x40 + 1;
reply.replyError.b = replyError;
*(u16*)&reply._0C = strlen(path) + 1;
TRKGetFreeBuffer(&bufferId1, &buffer);
error = TRKAppendBuffer_ui8(buffer, (u8*)&reply, 0x40);
if (error == DS_NoError) {
error = TRKAppendBuffer_ui8(buffer, (u8*)path, strlen(path) + 1);
}
if (error == DS_NoError) {
*ioResult = DS_IONoError;
error = TRKRequestSend(buffer, &bufferId2, 7, 3, 0);
if (error == DS_NoError) {
tempBuffer = TRKGetBuffer(bufferId2);
}
*ioResult = *(u32*)(tempBuffer->data + 0x10);
*param_3 = *(u32*)(tempBuffer->data + 0x8);
TRKReleaseBuffer(bufferId2);
}
TRKReleaseBuffer(bufferId1);
return error;
}
DSError HandleCloseFileSupportRequest(int replyError, DSIOResult* ioResult) {
DSError error;
int replyBufferId;
int bufferId;
TRKBuffer* buffer1;
TRKBuffer* buffer2;
CommandReply reply;
memset(&reply, 0, sizeof(CommandReply));
reply.commandID.b = DSMSG_CloseFile;
reply._00 = 0x40;
reply.replyError.r = replyError;
error = TRKGetFreeBuffer(&bufferId, &buffer1);
if (error == DS_NoError) {
error = TRKAppendBuffer_ui8(buffer1, (u8*)&reply, sizeof(CommandReply));
}
if (error == DS_NoError) {
*ioResult = DS_IONoError;
error = TRKRequestSend(buffer1, &replyBufferId, 3, 3, 0);
if (error == DS_NoError) {
buffer2 = TRKGetBuffer(replyBufferId);
}
if (error == DS_NoError) {
*ioResult = *(u32*)(buffer2->data + 0x10);
}
TRKReleaseBuffer(replyBufferId);
}
TRKReleaseBuffer(bufferId);
return error;
}
DSError HandlePositionFileSupportRequest(DSReplyError replyErr, u32* param_2, u8 param_3,
DSIOResult* ioResult) {
DSError error;
int bufferId2;
int bufferId1;
TRKBuffer* buffer1;
TRKBuffer* buffer2;
CommandReply reply;
memset(&reply, 0, sizeof(CommandReply));
reply.commandID.b = DSMSG_PositionFile;
reply._00 = 0x40;
reply.replyError.r = replyErr;
reply._0C = *param_2;
reply._10[0] = param_3;
error = TRKGetFreeBuffer(&bufferId1, &buffer1);
if (error == DS_NoError) {
error = TRKAppendBuffer_ui8(buffer1, (u8*)&reply, sizeof(CommandReply));
}
if (error == DS_NoError) {
*ioResult = DS_IONoError;
*param_2 = -1;
error = TRKRequestSend(buffer1, &bufferId2, 3, 3, 0);
if (error == DS_NoError) {
buffer2 = TRKGetBuffer(bufferId2);
if (buffer2 != NULL) {
*ioResult = *(u32*)(buffer2->data + 0x10);
*param_2 = *(u32*)(buffer2->data + 0x18);
}
}
TRKReleaseBuffer(bufferId2);
}
TRKReleaseBuffer(bufferId1);
return error;
}
+34
View File
@@ -0,0 +1,34 @@
/**
* usr_put.c
* Description:
*/
#include "TRK_MINNOW_DOLPHIN/Os/dolphin/usr_put.h"
// #include <os.h>
// void OSReport(char* fmt, ...) causes extra crclr instruction.
// look into issue later
extern void OSReport(char* fmt);
BOOL usr_puts_serial(const char* msg) {
BOOL connect_ = FALSE;
char c;
char buf[2];
while (!connect_ && (c = *msg++) != '\0') {
BOOL connect = GetTRKConnected();
buf[0] = c;
buf[1] = '\0';
SetTRKConnected(FALSE);
OSReport(buf);
SetTRKConnected(connect);
connect_ = FALSE;
}
return connect_;
}
void usr_put_initialize(void) {}
@@ -0,0 +1,25 @@
.include "macros.inc"
# .file "targsupp.s"
.text
.balign 16
.fn TRKAccessFile, global
twui r0, 0x0
blr
.endfn TRKAccessFile
.fn TRKOpenFile, global
twui r0, 0x0
blr
.endfn TRKOpenFile
.fn TRKCloseFile, global
twui r0, 0x0
blr
.endfn TRKCloseFile
.fn TRKPositionFile, global
twui r0, 0x0
blr
.endfn TRKPositionFile
@@ -0,0 +1,476 @@
.include "macros.inc"
.section .init, "ax" # 0x80003100 - 0x80005600
.global gTRKInterruptVectorTable
gTRKInterruptVectorTable:
.asciz "Metrowerks Target Resident Kernel for PowerPC"
.balign 4
.fill 0xD0
#############################################
# Interrupt vector slot 0x0000 is reserved. #
#############################################
# Slot 0x0100: System Reset Exception
b __TRK_reset
.fill 0xFC
# Slot 0x0200: Machine Check Exception
/* 80003354 00000354 7C 51 43 A6 */ mtspr 0x111, r2
/* 80003358 00000358 7C 5A 02 A6 */ mfspr r2, 0x1a
/* 8000335C 0000035C 7C 00 17 AC */ icbi 0, r2
/* 80003360 00000360 7C 53 02 A6 */ mfdar r2
/* 80003364 00000364 7C 00 13 AC */ dcbi 0, r2
/* 80003368 00000368 7C 51 42 A6 */ mfspr r2, 0x111
/* 8000336C 0000036C 7C 51 43 A6 */ mtspr 0x111, r2
/* 80003370 00000370 7C 72 43 A6 */ mtspr 0x112, r3
/* 80003374 00000374 7C 93 43 A6 */ mtspr 0x113, r4
/* 80003378 00000378 7C 5A 02 A6 */ mfspr r2, 0x1a
/* 8000337C 0000037C 7C 9B 02 A6 */ mfspr r4, 0x1b
/* 80003380 00000380 7C 60 00 A6 */ mfmsr r3
/* 80003384 00000384 60 63 00 30 */ ori r3, r3, 0x30
/* 80003388 00000388 7C 7B 03 A6 */ mtspr 0x1b, r3
/* 8000338C 0000038C 3C 60 80 0B */ lis r3, TRKInterruptHandler@h
/* 80003390 00000390 60 63 DE F4 */ ori r3, r3, TRKInterruptHandler@l
/* 80003394 00000394 7C 7A 03 A6 */ mtspr 0x1a, r3
/* 80003398 00000398 38 60 02 00 */ li r3, 0x200
/* 8000339C 0000039C 4C 00 00 64 */ rfi
.fill 0xB4
# Slot 0x0300: DSI Exception
/* 80003454 00000454 7C 51 43 A6 */ mtspr 0x111, r2
/* 80003458 00000458 7C 72 43 A6 */ mtspr 0x112, r3
/* 8000345C 0000045C 7C 93 43 A6 */ mtspr 0x113, r4
/* 80003460 00000460 7C 5A 02 A6 */ mfspr r2, 0x1a
/* 80003464 00000464 7C 9B 02 A6 */ mfspr r4, 0x1b
/* 80003468 00000468 7C 60 00 A6 */ mfmsr r3
/* 8000346C 0000046C 60 63 00 30 */ ori r3, r3, 0x30
/* 80003470 00000470 7C 7B 03 A6 */ mtspr 0x1b, r3
/* 80003474 00000474 3C 60 80 0B */ lis r3, TRKInterruptHandler@h
/* 80003478 00000478 60 63 DE F4 */ ori r3, r3, TRKInterruptHandler@l
/* 8000347C 0000047C 7C 7A 03 A6 */ mtspr 0x1a, r3
/* 80003480 00000480 38 60 03 00 */ li r3, 0x300
/* 80003484 00000484 4C 00 00 64 */ rfi
.fill 0xCC
# Slot 0x0400: ISI Exception
/* 80003554 00000554 7C 51 43 A6 */ mtspr 0x111, r2
/* 80003558 00000558 7C 72 43 A6 */ mtspr 0x112, r3
/* 8000355C 0000055C 7C 93 43 A6 */ mtspr 0x113, r4
/* 80003560 00000560 7C 5A 02 A6 */ mfspr r2, 0x1a
/* 80003564 00000564 7C 9B 02 A6 */ mfspr r4, 0x1b
/* 80003568 00000568 7C 60 00 A6 */ mfmsr r3
/* 8000356C 0000056C 60 63 00 30 */ ori r3, r3, 0x30
/* 80003570 00000570 7C 7B 03 A6 */ mtspr 0x1b, r3
/* 80003574 00000574 3C 60 80 0B */ lis r3, TRKInterruptHandler@h
/* 80003578 00000578 60 63 DE F4 */ ori r3, r3, TRKInterruptHandler@l
/* 8000357C 0000057C 7C 7A 03 A6 */ mtspr 0x1a, r3
/* 80003580 00000580 38 60 04 00 */ li r3, 0x400
/* 80003584 00000584 4C 00 00 64 */ rfi
.fill 0xCC
# Slot 0x0500: External Interrupt Exception
/* 80003654 00000654 7C 51 43 A6 */ mtspr 0x111, r2
/* 80003658 00000658 7C 72 43 A6 */ mtspr 0x112, r3
/* 8000365C 0000065C 7C 93 43 A6 */ mtspr 0x113, r4
/* 80003660 00000660 7C 5A 02 A6 */ mfspr r2, 0x1a
/* 80003664 00000664 7C 9B 02 A6 */ mfspr r4, 0x1b
/* 80003668 00000668 7C 60 00 A6 */ mfmsr r3
/* 8000366C 0000066C 60 63 00 30 */ ori r3, r3, 0x30
/* 80003670 00000670 7C 7B 03 A6 */ mtspr 0x1b, r3
/* 80003674 00000674 3C 60 80 0B */ lis r3, TRKInterruptHandler@h
/* 80003678 00000678 60 63 DE F4 */ ori r3, r3, TRKInterruptHandler@l
/* 8000367C 0000067C 7C 7A 03 A6 */ mtspr 0x1a, r3
/* 80003680 00000680 38 60 05 00 */ li r3, 0x500
/* 80003684 00000684 4C 00 00 64 */ rfi
.fill 0xCC
# Slot 0x0600: Alignment Exception
/* 80003754 00000754 7C 51 43 A6 */ mtspr 0x111, r2
/* 80003758 00000758 7C 72 43 A6 */ mtspr 0x112, r3
/* 8000375C 0000075C 7C 93 43 A6 */ mtspr 0x113, r4
/* 80003760 00000760 7C 5A 02 A6 */ mfspr r2, 0x1a
/* 80003764 00000764 7C 9B 02 A6 */ mfspr r4, 0x1b
/* 80003768 00000768 7C 60 00 A6 */ mfmsr r3
/* 8000376C 0000076C 60 63 00 30 */ ori r3, r3, 0x30
/* 80003770 00000770 7C 7B 03 A6 */ mtspr 0x1b, r3
/* 80003774 00000774 3C 60 80 0B */ lis r3, TRKInterruptHandler@h
/* 80003778 00000778 60 63 DE F4 */ ori r3, r3, TRKInterruptHandler@l
/* 8000377C 0000077C 7C 7A 03 A6 */ mtspr 0x1a, r3
/* 80003780 00000780 38 60 06 00 */ li r3, 0x600
/* 80003784 00000784 4C 00 00 64 */ rfi
.fill 0xCC
# Slot 0x0700: Program Exception
/* 80003854 00000854 7C 51 43 A6 */ mtspr 0x111, r2
/* 80003858 00000858 7C 72 43 A6 */ mtspr 0x112, r3
/* 8000385C 0000085C 7C 93 43 A6 */ mtspr 0x113, r4
/* 80003860 00000860 7C 5A 02 A6 */ mfspr r2, 0x1a
/* 80003864 00000864 7C 9B 02 A6 */ mfspr r4, 0x1b
/* 80003868 00000868 7C 60 00 A6 */ mfmsr r3
/* 8000386C 0000086C 60 63 00 30 */ ori r3, r3, 0x30
/* 80003870 00000870 7C 7B 03 A6 */ mtspr 0x1b, r3
/* 80003874 00000874 3C 60 80 0B */ lis r3, TRKInterruptHandler@h
/* 80003878 00000878 60 63 DE F4 */ ori r3, r3, TRKInterruptHandler@l
/* 8000387C 0000087C 7C 7A 03 A6 */ mtspr 0x1a, r3
/* 80003880 00000880 38 60 07 00 */ li r3, 0x700
/* 80003884 00000884 4C 00 00 64 */ rfi
.fill 0xCC
# Slot 0x0800: Floating Point Unavailable Exception
/* 80003954 00000954 7C 51 43 A6 */ mtspr 0x111, r2
/* 80003958 00000958 7C 72 43 A6 */ mtspr 0x112, r3
/* 8000395C 0000095C 7C 93 43 A6 */ mtspr 0x113, r4
/* 80003960 00000960 7C 5A 02 A6 */ mfspr r2, 0x1a
/* 80003964 00000964 7C 9B 02 A6 */ mfspr r4, 0x1b
/* 80003968 00000968 7C 60 00 A6 */ mfmsr r3
/* 8000396C 0000096C 60 63 00 30 */ ori r3, r3, 0x30
/* 80003970 00000970 7C 7B 03 A6 */ mtspr 0x1b, r3
/* 80003974 00000974 3C 60 80 0B */ lis r3, TRKInterruptHandler@h
/* 80003978 00000978 60 63 DE F4 */ ori r3, r3, TRKInterruptHandler@l
/* 8000397C 0000097C 7C 7A 03 A6 */ mtspr 0x1a, r3
/* 80003980 00000980 38 60 08 00 */ li r3, 0x800
/* 80003984 00000984 4C 00 00 64 */ rfi
.fill 0xCC
# Slot 0x0900: Decrementer Exception
/* 80003A54 00000A54 7C 51 43 A6 */ mtspr 0x111, r2
/* 80003A58 00000A58 7C 72 43 A6 */ mtspr 0x112, r3
/* 80003A5C 00000A5C 7C 93 43 A6 */ mtspr 0x113, r4
/* 80003A60 00000A60 7C 5A 02 A6 */ mfspr r2, 0x1a
/* 80003A64 00000A64 7C 9B 02 A6 */ mfspr r4, 0x1b
/* 80003A68 00000A68 7C 60 00 A6 */ mfmsr r3
/* 80003A6C 00000A6C 60 63 00 30 */ ori r3, r3, 0x30
/* 80003A70 00000A70 7C 7B 03 A6 */ mtspr 0x1b, r3
/* 80003A74 00000A74 3C 60 80 0B */ lis r3, TRKInterruptHandler@h
/* 80003A78 00000A78 60 63 DE F4 */ ori r3, r3, TRKInterruptHandler@l
/* 80003A7C 00000A7C 7C 7A 03 A6 */ mtspr 0x1a, r3
/* 80003A80 00000A80 38 60 09 00 */ li r3, 0x900
/* 80003A84 00000A84 4C 00 00 64 */ rfi
.fill 0xCC
######################################################
# Interrupt vector slots 0x0A00 & 0x0B00 are reserved.
.fill 0x100
.fill 0x100
######################################################
# Slot 0x0C00: System Call Exception
/* 80003D54 00000D54 7C 51 43 A6 */ mtspr 0x111, r2
/* 80003D58 00000D58 7C 72 43 A6 */ mtspr 0x112, r3
/* 80003D5C 00000D5C 7C 93 43 A6 */ mtspr 0x113, r4
/* 80003D60 00000D60 7C 5A 02 A6 */ mfspr r2, 0x1a
/* 80003D64 00000D64 7C 9B 02 A6 */ mfspr r4, 0x1b
/* 80003D68 00000D68 7C 60 00 A6 */ mfmsr r3
/* 80003D6C 00000D6C 60 63 00 30 */ ori r3, r3, 0x30
/* 80003D70 00000D70 7C 7B 03 A6 */ mtspr 0x1b, r3
/* 80003D74 00000D74 3C 60 80 0B */ lis r3, TRKInterruptHandler@h
/* 80003D78 00000D78 60 63 DE F4 */ ori r3, r3, TRKInterruptHandler@l
/* 80003D7C 00000D7C 7C 7A 03 A6 */ mtspr 0x1a, r3
/* 80003D80 00000D80 38 60 0C 00 */ li r3, 0xc00
/* 80003D84 00000D84 4C 00 00 64 */ rfi
.fill 0xCC
# Slot 0x0D00: Trace Exception
/* 80003E54 00000E54 7C 51 43 A6 */ mtspr 0x111, r2
/* 80003E58 00000E58 7C 72 43 A6 */ mtspr 0x112, r3
/* 80003E5C 00000E5C 7C 93 43 A6 */ mtspr 0x113, r4
/* 80003E60 00000E60 7C 5A 02 A6 */ mfspr r2, 0x1a
/* 80003E64 00000E64 7C 9B 02 A6 */ mfspr r4, 0x1b
/* 80003E68 00000E68 7C 60 00 A6 */ mfmsr r3
/* 80003E6C 00000E6C 60 63 00 30 */ ori r3, r3, 0x30
/* 80003E70 00000E70 7C 7B 03 A6 */ mtspr 0x1b, r3
/* 80003E74 00000E74 3C 60 80 0B */ lis r3, TRKInterruptHandler@h
/* 80003E78 00000E78 60 63 DE F4 */ ori r3, r3, TRKInterruptHandler@l
/* 80003E7C 00000E7C 7C 7A 03 A6 */ mtspr 0x1a, r3
/* 80003E80 00000E80 38 60 0D 00 */ li r3, 0xd00
/* 80003E84 00000E84 4C 00 00 64 */ rfi
.fill 0xCC
############################################################################
# Slot 0x0E00 is usually for the Floating Point Assist Exception Handler, #
# however that exception is not implemented in the PPC 750CL architecture. #
############################################################################
# Slot 0x0F00: Performance Monitor Exception
/* 80003F54 00000F54 7C 51 43 A6 */ mtspr 0x111, r2
/* 80003F58 00000F58 7C 72 43 A6 */ mtspr 0x112, r3
/* 80003F5C 00000F5C 7C 93 43 A6 */ mtspr 0x113, r4
/* 80003F60 00000F60 7C 5A 02 A6 */ mfspr r2, 0x1a
/* 80003F64 00000F64 7C 9B 02 A6 */ mfspr r4, 0x1b
/* 80003F68 00000F68 7C 60 00 A6 */ mfmsr r3
/* 80003F6C 00000F6C 60 63 00 30 */ ori r3, r3, 0x30
/* 80003F70 00000F70 7C 7B 03 A6 */ mtspr 0x1b, r3
/* 80003F74 00000F74 3C 60 80 0B */ lis r3, TRKInterruptHandler@h
/* 80003F78 00000F78 60 63 DE F4 */ ori r3, r3, TRKInterruptHandler@l
/* 80003F7C 00000F7C 7C 7A 03 A6 */ mtspr 0x1a, r3
/* 80003F80 00000F80 38 60 0E 00 */ li r3, 0xe00
/* 80003F84 00000F84 4C 00 00 64 */ rfi
.fill 0xCC
##################################################################################
# Interrupt vector slots 0x1000 through 0x1200 are not implemented in the 750CL. #
##################################################################################
# Slot 0x1300: Instruction Address Breakpoint Exception
/* 80004054 00001054 48 00 00 54 */ b .L_800040A8
.fill 0x1C
/* 80004074 00001074 7C 51 43 A6 */ mtspr 0x111, r2
/* 80004078 00001078 7C 72 43 A6 */ mtspr 0x112, r3
/* 8000407C 0000107C 7C 93 43 A6 */ mtspr 0x113, r4
/* 80004080 00001080 7C 5A 02 A6 */ mfspr r2, 0x1a
/* 80004084 00001084 7C 9B 02 A6 */ mfspr r4, 0x1b
/* 80004088 00001088 7C 60 00 A6 */ mfmsr r3
/* 8000408C 0000108C 60 63 00 30 */ ori r3, r3, 0x30
/* 80004090 00001090 7C 7B 03 A6 */ mtspr 0x1b, r3
/* 80004094 00001094 3C 60 80 0B */ lis r3, TRKInterruptHandler@h
/* 80004098 00001098 60 63 DE F4 */ ori r3, r3, TRKInterruptHandler@l
/* 8000409C 0000109C 7C 7A 03 A6 */ mtspr 0x1a, r3
/* 800040A0 000010A0 38 60 0F 20 */ li r3, 0xf20
/* 800040A4 000010A4 4C 00 00 64 */ rfi
.L_800040A8:
/* 800040A8 000010A8 7C 51 43 A6 */ mtspr 0x111, r2
/* 800040AC 000010AC 7C 72 43 A6 */ mtspr 0x112, r3
/* 800040B0 000010B0 7C 93 43 A6 */ mtspr 0x113, r4
/* 800040B4 000010B4 7C 5A 02 A6 */ mfspr r2, 0x1a
/* 800040B8 000010B8 7C 9B 02 A6 */ mfspr r4, 0x1b
/* 800040BC 000010BC 7C 60 00 A6 */ mfmsr r3
/* 800040C0 000010C0 60 63 00 30 */ ori r3, r3, 0x30
/* 800040C4 000010C4 7C 7B 03 A6 */ mtspr 0x1b, r3
/* 800040C8 000010C8 3C 60 80 0B */ lis r3, TRKInterruptHandler@h
/* 800040CC 000010CC 60 63 DE F4 */ ori r3, r3, TRKInterruptHandler@l
/* 800040D0 000010D0 7C 7A 03 A6 */ mtspr 0x1a, r3
/* 800040D4 000010D4 38 60 0F 00 */ li r3, 0xf00
/* 800040D8 000010D8 4C 00 00 64 */ rfi
.fill 0x78
# Slot 0x1400: System Management Interrupt Exception
/* 80004154 00001154 7C 51 43 A6 */ mtspr 0x111, r2
/* 80004158 00001158 7C 40 00 26 */ mfcr r2
/* 8000415C 0000115C 7C 52 43 A6 */ mtspr 0x112, r2
/* 80004160 00001160 7C 40 00 A6 */ mfmsr r2
/* 80004164 00001164 74 42 00 02 */ andis. r2, r2, 2
/* 80004168 00001168 41 82 00 1C */ beq .L_80004184
/* 8000416C 0000116C 7C 40 00 A6 */ mfmsr r2
/* 80004170 00001170 6C 42 00 02 */ xoris r2, r2, 2
/* 80004174 00001174 7C 00 04 AC */ sync 0
/* 80004178 00001178 7C 40 01 24 */ mtmsr r2
/* 8000417C 0000117C 7C 00 04 AC */ sync 0
/* 80004180 00001180 7C 51 43 A6 */ mtspr 0x111, r2
.L_80004184:
/* 80004184 00001184 7C 52 42 A6 */ mfspr r2, 0x112
/* 80004188 00001188 7C 4F F1 20 */ mtcrf 0xff, r2
/* 8000418C 0000118C 7C 51 42 A6 */ mfspr r2, 0x111
/* 80004190 00001190 7C 51 43 A6 */ mtspr 0x111, r2
/* 80004194 00001194 7C 72 43 A6 */ mtspr 0x112, r3
/* 80004198 00001198 7C 93 43 A6 */ mtspr 0x113, r4
/* 8000419C 0000119C 7C 5A 02 A6 */ mfspr r2, 0x1a
/* 800041A0 000011A0 7C 9B 02 A6 */ mfspr r4, 0x1b
/* 800041A4 000011A4 7C 60 00 A6 */ mfmsr r3
/* 800041A8 000011A8 60 63 00 30 */ ori r3, r3, 0x30
/* 800041AC 000011AC 7C 7B 03 A6 */ mtspr 0x1b, r3
/* 800041B0 000011B0 3C 60 80 0B */ lis r3, TRKInterruptHandler@h
/* 800041B4 000011B4 60 63 DE F4 */ ori r3, r3, TRKInterruptHandler@l
/* 800041B8 000011B8 7C 7A 03 A6 */ mtspr 0x1a, r3
/* 800041BC 000011BC 38 60 10 00 */ li r3, 0x1000
/* 800041C0 000011C0 4C 00 00 64 */ rfi
.fill 0x90
##############################################################################
# Interrupt vector slots 0x1500 and 0x1600 are not implemented in the 750CL. #
##############################################################################
# Slot 0x1700: Thermal-Management Interrupt Exception
/* 80004254 00001254 7C 51 43 A6 */ mtspr 0x111, r2
/* 80004258 00001258 7C 40 00 26 */ mfcr r2
/* 8000425C 0000125C 7C 52 43 A6 */ mtspr 0x112, r2
/* 80004260 00001260 7C 40 00 A6 */ mfmsr r2
/* 80004264 00001264 74 42 00 02 */ andis. r2, r2, 2
/* 80004268 00001268 41 82 00 1C */ beq .L_80004284
/* 8000426C 0000126C 7C 40 00 A6 */ mfmsr r2
/* 80004270 00001270 6C 42 00 02 */ xoris r2, r2, 2
/* 80004274 00001274 7C 00 04 AC */ sync 0
/* 80004278 00001278 7C 40 01 24 */ mtmsr r2
/* 8000427C 0000127C 7C 00 04 AC */ sync 0
/* 80004280 00001280 7C 51 43 A6 */ mtspr 0x111, r2
.L_80004284:
/* 80004284 00001284 7C 52 42 A6 */ mfspr r2, 0x112
/* 80004288 00001288 7C 4F F1 20 */ mtcrf 0xff, r2
/* 8000428C 0000128C 7C 51 42 A6 */ mfspr r2, 0x111
/* 80004290 00001290 7C 51 43 A6 */ mtspr 0x111, r2
/* 80004294 00001294 7C 72 43 A6 */ mtspr 0x112, r3
/* 80004298 00001298 7C 93 43 A6 */ mtspr 0x113, r4
/* 8000429C 0000129C 7C 5A 02 A6 */ mfspr r2, 0x1a
/* 800042A0 000012A0 7C 9B 02 A6 */ mfspr r4, 0x1b
/* 800042A4 000012A4 7C 60 00 A6 */ mfmsr r3
/* 800042A8 000012A8 60 63 00 30 */ ori r3, r3, 0x30
/* 800042AC 000012AC 7C 7B 03 A6 */ mtspr 0x1b, r3
/* 800042B0 000012B0 3C 60 80 0B */ lis r3, TRKInterruptHandler@h
/* 800042B4 000012B4 60 63 DE F4 */ ori r3, r3, TRKInterruptHandler@l
/* 800042B8 000012B8 7C 7A 03 A6 */ mtspr 0x1a, r3
/* 800042BC 000012BC 38 60 11 00 */ li r3, 0x1100
/* 800042C0 000012C0 4C 00 00 64 */ rfi
.fill 0x90
# Slot 0x1800(?)
/* 80004354 00001354 7C 51 43 A6 */ mtspr 0x111, r2
/* 80004358 00001358 7C 40 00 26 */ mfcr r2
/* 8000435C 0000135C 7C 52 43 A6 */ mtspr 0x112, r2
/* 80004360 00001360 7C 40 00 A6 */ mfmsr r2
/* 80004364 00001364 74 42 00 02 */ andis. r2, r2, 2
/* 80004368 00001368 41 82 00 1C */ beq .L_80004384
/* 8000436C 0000136C 7C 40 00 A6 */ mfmsr r2
/* 80004370 00001370 6C 42 00 02 */ xoris r2, r2, 2
/* 80004374 00001374 7C 00 04 AC */ sync 0
/* 80004378 00001378 7C 40 01 24 */ mtmsr r2
/* 8000437C 0000137C 7C 00 04 AC */ sync 0
/* 80004380 00001380 7C 51 43 A6 */ mtspr 0x111, r2
.L_80004384:
/* 80004384 00001384 7C 52 42 A6 */ mfspr r2, 0x112
/* 80004388 00001388 7C 4F F1 20 */ mtcrf 0xff, r2
/* 8000438C 0000138C 7C 51 42 A6 */ mfspr r2, 0x111
/* 80004390 00001390 7C 51 43 A6 */ mtspr 0x111, r2
/* 80004394 00001394 7C 72 43 A6 */ mtspr 0x112, r3
/* 80004398 00001398 7C 93 43 A6 */ mtspr 0x113, r4
/* 8000439C 0000139C 7C 5A 02 A6 */ mfspr r2, 0x1a
/* 800043A0 000013A0 7C 9B 02 A6 */ mfspr r4, 0x1b
/* 800043A4 000013A4 7C 60 00 A6 */ mfmsr r3
/* 800043A8 000013A8 60 63 00 30 */ ori r3, r3, 0x30
/* 800043AC 000013AC 7C 7B 03 A6 */ mtspr 0x1b, r3
/* 800043B0 000013B0 3C 60 80 0B */ lis r3, TRKInterruptHandler@h
/* 800043B4 000013B4 60 63 DE F4 */ ori r3, r3, TRKInterruptHandler@l
/* 800043B8 000013B8 7C 7A 03 A6 */ mtspr 0x1a, r3
/* 800043BC 000013BC 38 60 12 00 */ li r3, 0x1200
/* 800043C0 000013C0 4C 00 00 64 */ rfi
.fill 0x90
# Slot 0x1900(?)
/* 80004454 00001454 7C 51 43 A6 */ mtspr 0x111, r2
/* 80004458 00001458 7C 72 43 A6 */ mtspr 0x112, r3
/* 8000445C 0000145C 7C 93 43 A6 */ mtspr 0x113, r4
/* 80004460 00001460 7C 5A 02 A6 */ mfspr r2, 0x1a
/* 80004464 00001464 7C 9B 02 A6 */ mfspr r4, 0x1b
/* 80004468 00001468 7C 60 00 A6 */ mfmsr r3
/* 8000446C 0000146C 60 63 00 30 */ ori r3, r3, 0x30
/* 80004470 00001470 7C 7B 03 A6 */ mtspr 0x1b, r3
/* 80004474 00001474 3C 60 80 0B */ lis r3, TRKInterruptHandler@h
/* 80004478 00001478 60 63 DE F4 */ ori r3, r3, TRKInterruptHandler@l
/* 8000447C 0000147C 7C 7A 03 A6 */ mtspr 0x1a, r3
/* 80004480 00001480 38 60 13 00 */ li r3, 0x1300
/* 80004484 00001484 4C 00 00 64 */ rfi
.fill 0xCC
# Slot 0x1A00(?)
/* 80004554 00001554 7C 51 43 A6 */ mtspr 0x111, r2
/* 80004558 00001558 7C 72 43 A6 */ mtspr 0x112, r3
/* 8000455C 0000155C 7C 93 43 A6 */ mtspr 0x113, r4
/* 80004560 00001560 7C 5A 02 A6 */ mfspr r2, 0x1a
/* 80004564 00001564 7C 9B 02 A6 */ mfspr r4, 0x1b
/* 80004568 00001568 7C 60 00 A6 */ mfmsr r3
/* 8000456C 0000156C 60 63 00 30 */ ori r3, r3, 0x30
/* 80004570 00001570 7C 7B 03 A6 */ mtspr 0x1b, r3
/* 80004574 00001574 3C 60 80 0B */ lis r3, TRKInterruptHandler@h
/* 80004578 00001578 60 63 DE F4 */ ori r3, r3, TRKInterruptHandler@l
/* 8000457C 0000157C 7C 7A 03 A6 */ mtspr 0x1a, r3
/* 80004580 00001580 38 60 14 00 */ li r3, 0x1400
/* 80004584 00001584 4C 00 00 64 */ rfi
.fill 0x1CC
# Slot 0x1B00(?)
/* 80004754 00001754 7C 51 43 A6 */ mtspr 0x111, r2
/* 80004758 00001758 7C 72 43 A6 */ mtspr 0x112, r3
/* 8000475C 0000175C 7C 93 43 A6 */ mtspr 0x113, r4
/* 80004760 00001760 7C 5A 02 A6 */ mfspr r2, 0x1a
/* 80004764 00001764 7C 9B 02 A6 */ mfspr r4, 0x1b
/* 80004768 00001768 7C 60 00 A6 */ mfmsr r3
/* 8000476C 0000176C 60 63 00 30 */ ori r3, r3, 0x30
/* 80004770 00001770 7C 7B 03 A6 */ mtspr 0x1b, r3
/* 80004774 00001774 3C 60 80 0B */ lis r3, TRKInterruptHandler@h
/* 80004778 00001778 60 63 DE F4 */ ori r3, r3, TRKInterruptHandler@l
/* 8000477C 0000177C 7C 7A 03 A6 */ mtspr 0x1a, r3
/* 80004780 00001780 38 60 16 00 */ li r3, 0x1600
/* 80004784 00001784 4C 00 00 64 */ rfi
.fill 0xCC
# Slot 0x1C00(?)
/* 80004854 00001854 7C 51 43 A6 */ mtspr 0x111, r2
/* 80004858 00001858 7C 72 43 A6 */ mtspr 0x112, r3
/* 8000485C 0000185C 7C 93 43 A6 */ mtspr 0x113, r4
/* 80004860 00001860 7C 5A 02 A6 */ mfspr r2, 0x1a
/* 80004864 00001864 7C 9B 02 A6 */ mfspr r4, 0x1b
/* 80004868 00001868 7C 60 00 A6 */ mfmsr r3
/* 8000486C 0000186C 60 63 00 30 */ ori r3, r3, 0x30
/* 80004870 00001870 7C 7B 03 A6 */ mtspr 0x1b, r3
/* 80004874 00001874 3C 60 80 0B */ lis r3, TRKInterruptHandler@h
/* 80004878 00001878 60 63 DE F4 */ ori r3, r3, TRKInterruptHandler@l
/* 8000487C 0000187C 7C 7A 03 A6 */ mtspr 0x1a, r3
/* 80004880 00001880 38 60 17 00 */ li r3, 0x1700
/* 80004884 00001884 4C 00 00 64 */ rfi
.fill 0x4CC
# Slot 0x1D00(?)
/* 80004D54 00001D54 7C 51 43 A6 */ mtspr 0x111, r2
/* 80004D58 00001D58 7C 72 43 A6 */ mtspr 0x112, r3
/* 80004D5C 00001D5C 7C 93 43 A6 */ mtspr 0x113, r4
/* 80004D60 00001D60 7C 5A 02 A6 */ mfspr r2, 0x1a
/* 80004D64 00001D64 7C 9B 02 A6 */ mfspr r4, 0x1b
/* 80004D68 00001D68 7C 60 00 A6 */ mfmsr r3
/* 80004D6C 00001D6C 60 63 00 30 */ ori r3, r3, 0x30
/* 80004D70 00001D70 7C 7B 03 A6 */ mtspr 0x1b, r3
/* 80004D74 00001D74 3C 60 80 0B */ lis r3, TRKInterruptHandler@h
/* 80004D78 00001D78 60 63 DE F4 */ ori r3, r3, TRKInterruptHandler@l
/* 80004D7C 00001D7C 7C 7A 03 A6 */ mtspr 0x1a, r3
/* 80004D80 00001D80 38 60 1C 00 */ li r3, 0x1c00
/* 80004D84 00001D84 4C 00 00 64 */ rfi
.fill 0xCC
# Slot 0x1E00(?)
/* 80004E54 00001E54 7C 51 43 A6 */ mtspr 0x111, r2
/* 80004E58 00001E58 7C 72 43 A6 */ mtspr 0x112, r3
/* 80004E5C 00001E5C 7C 93 43 A6 */ mtspr 0x113, r4
/* 80004E60 00001E60 7C 5A 02 A6 */ mfspr r2, 0x1a
/* 80004E64 00001E64 7C 9B 02 A6 */ mfspr r4, 0x1b
/* 80004E68 00001E68 7C 60 00 A6 */ mfmsr r3
/* 80004E6C 00001E6C 60 63 00 30 */ ori r3, r3, 0x30
/* 80004E70 00001E70 7C 7B 03 A6 */ mtspr 0x1b, r3
/* 80004E74 00001E74 3C 60 80 0B */ lis r3, TRKInterruptHandler@h
/* 80004E78 00001E78 60 63 DE F4 */ ori r3, r3, TRKInterruptHandler@l
/* 80004E7C 00001E7C 7C 7A 03 A6 */ mtspr 0x1a, r3
/* 80004E80 00001E80 38 60 1D 00 */ li r3, 0x1d00
/* 80004E84 00001E84 4C 00 00 64 */ rfi
.fill 0xCC
# Slot 0x1F00(?)
/* 80004F54 00001F54 7C 51 43 A6 */ mtspr 0x111, r2
/* 80004F58 00001F58 7C 72 43 A6 */ mtspr 0x112, r3
/* 80004F5C 00001F5C 7C 93 43 A6 */ mtspr 0x113, r4
/* 80004F60 00001F60 7C 5A 02 A6 */ mfspr r2, 0x1a
/* 80004F64 00001F64 7C 9B 02 A6 */ mfspr r4, 0x1b
/* 80004F68 00001F68 7C 60 00 A6 */ mfmsr r3
/* 80004F6C 00001F6C 60 63 00 30 */ ori r3, r3, 0x30
/* 80004F70 00001F70 7C 7B 03 A6 */ mtspr 0x1b, r3
/* 80004F74 00001F74 3C 60 80 0B */ lis r3, TRKInterruptHandler@h
/* 80004F78 00001F78 60 63 DE F4 */ ori r3, r3, TRKInterruptHandler@l
/* 80004F7C 00001F7C 7C 7A 03 A6 */ mtspr 0x1a, r3
/* 80004F80 00001F80 38 60 1E 00 */ li r3, 0x1e00
/* 80004F84 00001F84 4C 00 00 64 */ rfi
.fill 0xCC
# Slot 0x2000(?)
/* 80005054 00002054 7C 51 43 A6 */ mtspr 0x111, r2
/* 80005058 00002058 7C 72 43 A6 */ mtspr 0x112, r3
/* 8000505C 0000205C 7C 93 43 A6 */ mtspr 0x113, r4
/* 80005060 00002060 7C 5A 02 A6 */ mfspr r2, 0x1a
/* 80005064 00002064 7C 9B 02 A6 */ mfspr r4, 0x1b
/* 80005068 00002068 7C 60 00 A6 */ mfmsr r3
/* 8000506C 0000206C 60 63 00 30 */ ori r3, r3, 0x30
/* 80005070 00002070 7C 7B 03 A6 */ mtspr 0x1b, r3
/* 80005074 00002074 3C 60 80 0B */ lis r3, TRKInterruptHandler@h
/* 80005078 00002078 60 63 DE F4 */ ori r3, r3, TRKInterruptHandler@l
/* 8000507C 0000207C 7C 7A 03 A6 */ mtspr 0x1a, r3
/* 80005080 00002080 38 60 1F 00 */ li r3, 0x1f00
/* 80005084 00002084 4C 00 00 64 */ rfi
.global gTRKInterruptVectorTableEnd
gTRKInterruptVectorTableEnd:
@@ -0,0 +1,30 @@
/**
* flush_cache.c
* Description:
*/
#include "dolphin/types.h"
asm void TRK_flush_cache(u32, int) {
// clang-format off
nofralloc
lis r5, 0xFFFF
ori r5, r5, 0xFFF1
and r5, r5, r3
subf r3, r5, r3
add r4, r4, r3
loop:
dcbst 0, r5
dcbf 0, r5
sync
icbi 0, r5
addic r5, r5, 8
addic. r4, r4, -8
bge loop
isync
blr
// clang-format on
}
@@ -0,0 +1,244 @@
#include "TRK_MINNOW_DOLPHIN/ppc/Generic/mpc_7xx_603e.h"
#include "TRK_MINNOW_DOLPHIN/ppc/Generic/targimpl.h"
extern u8 gTRKRestoreFlags[9 + 3 /* padding */];
asm void TRKSaveExtended1Block() {
// clang-format off
nofralloc
lis r2, gTRKCPUState@h /* 0x8044F338@h */
ori r2, r2, gTRKCPUState@l /* 0x8044F338@l */
mfsr r16, 0
mfsr r17, 1
mfsr r18, 2
mfsr r19, 3
mfsr r20, 4
mfsr r21, 5
mfsr r22, 6
mfsr r23, 7
mfsr r24, 8
mfsr r25, 9
mfsr r26, 0xa
mfsr r27, 0xb
mfsr r28, 0xc
mfsr r29, 0xd
mfsr r30, 0xe
mfsr r31, 0xf
stmw r16, 0x1a8(r2)
mftb r10, 0x10c
mftbu r11
mfspr r12, 0x3f0
mfspr r13, 0x3f1
mfspr r14, 0x1b
mfpvr r15
mfibatu r16, 0
mfibatl r17, 0
mfibatu r18, 1
mfibatl r19, 1
mfibatu r20, 2
mfibatl r21, 2
mfibatu r22, 3
mfibatl r23, 3
mfdbatu r24, 0
mfdbatl r25, 0
mfdbatu r26, 1
mfdbatl r27, 1
mfdbatu r28, 2
mfdbatl r29, 2
mfdbatu r30, 3
mfdbatl r31, 3
stmw r10, 0x1e8(r2)
mfspr r22, 0x19
mfdar r23
mfdsisr r24
mfspr r25, 0x110
mfspr r26, 0x111
mfspr r27, 0x112
mfspr r28, 0x113
li r29, 0
mfspr r30, 0x3f2
mfspr r31, 0x11a
stmw r22, 0x25c(r2)
mfspr r20, 0x390
mfspr r21, 0x391
mfspr r22, 0x392
mfspr r23, 0x393
mfspr r24, 0x394
mfspr r25, 0x395
mfspr r26, 0x396
mfspr r27, 0x397
mfspr r28, 0x398
mfspr r29, 0x399
mfspr r30, 0x39a
mfspr r31, 0x39b
stmw r20, 0x2fc(r2)
b lbl_80371340
mfspr r16, 0x3a0
mfspr r17, 0x3a7
mfspr r18, 0x3a8
mfspr r19, 0x3a9
mfspr r20, 0x3aa
mfspr r21, 0x3ab
mfspr r22, 0x3ac
mfspr r23, 0x3ad
mfspr r24, 0x3ae
mfspr r25, 0x3af
mfspr r26, 0x3b0
mfspr r27, 0x3b7
mfspr r28, 0x3bf
mfspr r29, 0x3f6
mfspr r30, 0x3f7
mfspr r31, 0x3ff
stmw r16, 0x2b8(r2)
lbl_80371340:
mfspr r19, 0x3f5
mfspr r20, 0x3b9
mfspr r21, 0x3ba
mfspr r22, 0x3bd
mfspr r23, 0x3be
mfspr r24, 0x3bb
mfspr r25, 0x3b8
mfspr r26, 0x3bc
mfspr r27, 0x3fc
mfspr r28, 0x3fd
mfspr r29, 0x3fe
mfspr r30, 0x3FB
mfspr r31, 0x3f9
stmw r19, 0x284(r2)
blr
mfspr r25, 0x3d0
mfspr r26, 0x3d1
mfspr r27, 0x3d2
mfspr r28, 0x3d3
mfspr r29, 0x3D4
mfspr r30, 0x3D5
mfspr r31, 0x3d6
stmw r25, 0x240(r2)
mfspr r31, 0x16
stw r31, 0x278(r2)
blr
// clang-format on
}
asm void TRKRestoreExtended1Block() {
// clang-format off
nofralloc
lis r2, gTRKCPUState@h /* 0x8044F338@h */
ori r2, r2, gTRKCPUState@l /* 0x8044F338@l */
lis r5, gTRKRestoreFlags@h /* 0x803D3238@h */
ori r5, r5, gTRKRestoreFlags@l /* 0x803D3238@l */
lbz r3, 0(r5)
lbz r6, 1(r5)
li r0, 0
stb r0, 0(r5)
stb r0, 1(r5)
cmpwi r3, 0
beq lbl_803713E4
lwz r24, 0x1e8(r2)
lwz r25, 0x1ec(r2)
mttbl r24
mttbu r25
lbl_803713E4:
lmw r20, 0x2fc(r2)
mtspr 0x390, r20
mtspr 0x391, r21
mtspr 0x392, r22
mtspr 0x393, r23
mtspr 0x394, r24
mtspr 0x395, r25
mtspr 0x396, r26
mtspr 0x397, r27
mtspr 0x398, r28
mtspr 0x39a, r30
mtspr 0x39b, r31
b lbl_80371430
lmw r26, 0x2e0(r2)
mtspr 0x3b0, r26
mtspr 0x3b7, r27
mtspr 0x3f6, r29
mtspr 0x3f7, r30
mtspr 0x3ff, r31
lbl_80371430:
lmw r19, 0x284(r2)
mtspr 0x3f5, r19
mtspr 0x3b9, r20
mtspr 0x3ba, r21
mtspr 0x3bd, r22
mtspr 0x3be, r23
mtspr 0x3bb, r24
mtspr 0x3b8, r25
mtspr 0x3bc, r26
mtspr 0x3fc, r27
mtspr 0x3fd, r28
mtspr 0x3fe, r29
mtspr 0x3FB, r30
mtspr 0x3f9, r31
b lbl_8037149C
cmpwi r6, 0
beq lbl_8037147C
lwz r26, 0x278(r2)
mtspr 0x16, r26
lbl_8037147C:
lmw r25, 0x240(r2)
mtspr 0x3d0, r25
mtspr 0x3d1, r26
mtspr 0x3d2, r27
mtspr 0x3d3, r28
mtspr 0x3D4, r29
mtspr 0x3D5, r30
mtspr 0x3d6, r31
lbl_8037149C:
lmw r16, 0x1a8(r2)
mtsr 0, r16
mtsr 1, r17
mtsr 2, r18
mtsr 3, r19
mtsr 4, r20
mtsr 5, r21
mtsr 6, r22
mtsr 7, r23
mtsr 8, r24
mtsr 9, r25
mtsr 0xa, r26
mtsr 0xb, r27
mtsr 0xc, r28
mtsr 0xd, r29
mtsr 0xe, r30
mtsr 0xf, r31
lmw r12, 0x1f0(r2)
mtspr 0x3f0, r12
mtspr 0x3f1, r13
mtspr 0x1b, r14
mtspr 0x11f, r15
mtibatu 0, r16
mtibatl 0, r17
mtibatu 1, r18
mtibatl 1, r19
mtibatu 2, r20
mtibatl 2, r21
mtibatu 3, r22
mtibatl 3, r23
mtdbatu 0, r24
mtdbatl 0, r25
mtdbatu 1, r26
mtdbatl 1, r27
mtdbatu 2, r28
mtdbatl 2, r29
mtdbatu 3, r30
mtdbatl 3, r31
lmw r22, 0x25c(r2)
mtspr 0x19, r22
mtdar r23
mtdsisr r24
mtspr 0x110, r25
mtspr 0x111, r26
mtspr 0x112, r27
mtspr 0x113, r28
mtspr 0x3f2, r30
mtspr 0x11a, r31
blr
// clang-format on
}
u8 TRKTargetCPUMinorType(void) { return 0x54; }
File diff suppressed because it is too large Load Diff
+28
View File
@@ -0,0 +1,28 @@
#include "dolphin/amcstubs/AmcExi2Stubs.h"
// prototypes
int AMC_IsStub(void);
void EXI2_Init(volatile unsigned char **inputPendingPtrRef, AmcEXICallback monitorCallback) {}
void EXI2_EnableInterrupts(void) {}
int EXI2_Poll(void) {
return 0;
}
AmcExiError EXI2_ReadN(void *bytes, unsigned long length) {
return AMC_EXI_NO_ERROR;
}
AmcExiError EXI2_WriteN(const void *bytes, unsigned long length) {
return AMC_EXI_NO_ERROR;
}
void EXI2_Reserve(void) {}
void EXI2_Unreserve(void) {}
int AMC_IsStub(void) {
return 1;
}
+334
View File
@@ -0,0 +1,334 @@
#include "dolphin/os/OS.h"
#include "dolphin/gx/GX.h"
#include "dolphin/ai/ai.h"
#include "dolphin/dsp.h"
const char* __AIVersion = "<< Dolphin SDK - AI\trelease build: Sep 5 2002 05:34:25 (0x2301) >>";
static AISCallback __AIS_Callback;
static AIDCallback __AID_Callback;
static u8* __CallbackStack;
static u8* __OldStack;
static BOOL __AI_init_flag;
static BOOL __AID_Active;
static OSTime bound_32KHz;
static OSTime bound_48KHz;
static OSTime min_wait;
static OSTime max_wait;
static OSTime buffer;
// prototypes
void __AI_DEBUG_set_stream_sample_rate(u32 rate);
static void __AI_set_stream_sample_rate(u32 rate);
static void __AIDHandler(__OSInterrupt interrupt, OSContext* context);
static void __AISHandler(__OSInterrupt interrupt, OSContext* context);
static void __AICallbackStackSwitch(void* cb);
static void __AI_SRC_INIT(void);
AIDCallback AIRegisterDMACallback(AIDCallback callback) {
AIDCallback old_callback;
BOOL old;
old_callback = __AID_Callback;
old = OSDisableInterrupts();
__AID_Callback = callback;
OSRestoreInterrupts(old);
return old_callback;
}
void AIInitDMA(u32 start_addr, u32 length) {
BOOL old;
old = OSDisableInterrupts();
__DSPRegs[24] = (__DSPRegs[24] & 0xFFFFFC00) | (start_addr >> 16);
__DSPRegs[25] = (__DSPRegs[25] & 0xFFFF001F) | (start_addr & 0xFFFF);
ASSERTMSGLINE(316, (length & 0x1F) == 0, "AIStartDMA: length must be multiple of 32 bytes");
__DSPRegs[27] = (__DSPRegs[27] & 0xFFFF8000) | ((length >> 5) & 0xFFFF);
OSRestoreInterrupts(old);
}
void AIStartDMA(void) {
__DSPRegs[27] = __DSPRegs[27] | 0x8000;
}
void AIResetStreamSampleCount(void) {
__AIRegs[0] = (__AIRegs[0] & ~0x20) | 0x20;
}
void AISetStreamTrigger(u32 trigger) {
__AIRegs[3] = trigger;
}
void AISetStreamPlayState(u32 state) {
BOOL old;
u8 vol_left;
u8 vol_right;
if (state != AIGetStreamPlayState()) {
if (AIGetStreamSampleRate() == 0 && state == 1) {
vol_left = AIGetStreamVolRight();
vol_right = AIGetStreamVolLeft();
AISetStreamVolRight(0);
AISetStreamVolLeft(0);
old = OSDisableInterrupts();
__AI_SRC_INIT();
SET_REG_FIELD(__AIRegs[0], 1, 5, 1);
SET_REG_FIELD(__AIRegs[0], 1, 0, 1);
OSRestoreInterrupts(old);
AISetStreamVolLeft(vol_left);
AISetStreamVolRight(vol_right);
return;
}
SET_REG_FIELD(__AIRegs[0], 1, 0, state);
}
}
u32 AIGetStreamPlayState(void) {
return __AIRegs[0] & 1;
}
void AISetDSPSampleRate(u32 rate) {
BOOL old;
u32 play_state;
u32 afr_state;
u8 vol_left;
u8 vol_right;
if (rate != AIGetDSPSampleRate()) {
__AIRegs[0] = (__AIRegs[0] & 0xFFFFFFBF);
if (rate == 0) {
vol_left = AIGetStreamVolLeft();
vol_right = AIGetStreamVolRight();
play_state = AIGetStreamPlayState();
afr_state = AIGetStreamSampleRate();
AISetStreamVolLeft(0U);
AISetStreamVolRight(0U);
old = OSDisableInterrupts();
__AI_SRC_INIT();
SET_REG_FIELD(__AIRegs[0], 1, 5, 1);
SET_REG_FIELD(__AIRegs[0], 1, 1, afr_state);
SET_REG_FIELD(__AIRegs[0], 1, 0, play_state);
__AIRegs[0] |= 0x40;
OSRestoreInterrupts(old);
AISetStreamVolLeft(vol_left);
AISetStreamVolRight(vol_right);
}
}
}
u32 AIGetDSPSampleRate(void) {
return ((__AIRegs[0] >> 6) & 1) ^ 1;
}
void AISetStreamSampleRate(u32 rate) {
if (rate == 1) {
__AI_set_stream_sample_rate(rate);
return;
}
#if DEBUG
OSReport("AISetStreamSampleRate(): OBSOLETED. Only 48KHz streaming from disk is supported!\n");
#endif
}
static void __AI_set_stream_sample_rate(u32 rate) {
BOOL old;
u32 play_state;
u8 vol_left;
u8 vol_right;
u32 dsp_src_state;
if (rate != AIGetStreamSampleRate()) {
play_state = AIGetStreamPlayState();
vol_left = AIGetStreamVolLeft();
vol_right = AIGetStreamVolRight();
AISetStreamVolRight(0);
AISetStreamVolLeft(0);
dsp_src_state = __AIRegs[0] & 0x40;
SET_REG_FIELD(__AIRegs[0], 1, 6, 0);
old = OSDisableInterrupts();
__AI_SRC_INIT();
__AIRegs[0] |= dsp_src_state;
SET_REG_FIELD(__AIRegs[0], 1, 5, 1);
SET_REG_FIELD(__AIRegs[0], 1, 1, rate);
OSRestoreInterrupts(old);
AISetStreamPlayState(play_state);
AISetStreamVolLeft(vol_left);
AISetStreamVolRight(vol_right);
}
}
u32 AIGetStreamSampleRate(void) {
return (__AIRegs[0] >> 1) & 1;
}
void AISetStreamVolLeft(u8 vol) {
SET_REG_FIELD(__AIRegs[1], 8, 0, vol);
}
u8 AIGetStreamVolLeft(void) {
return __AIRegs[1];
}
void AISetStreamVolRight(u8 vol) {
SET_REG_FIELD(__AIRegs[1], 8, 8, vol);
}
u8 AIGetStreamVolRight(void) {
return (__AIRegs[1] & (0xFF << 8)) >> 8;
}
void AIInit(u8* stack) {
if (__AI_init_flag != TRUE) {
OSRegisterVersion(__AIVersion);
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);
#if DEBUG
OSReport("AIInit(): DSP is 32KHz\n");
#endif
__AIS_Callback = NULL;
__AID_Callback = NULL;
__CallbackStack = stack;
if (stack) {
ASSERTMSGLINE(1107, ((u32)stack & 7) == 0, "AIInit: stack must be 8-byte aligned");
}
__OSSetInterruptHandler(5, __AIDHandler);
__OSUnmaskInterrupts(0x04000000);
__OSSetInterruptHandler(8, __AISHandler);
__OSUnmaskInterrupts(0x800000);
__AI_init_flag = TRUE;
}
}
static void __AISHandler(__OSInterrupt interrupt, OSContext* context) {
OSContext exceptionContext;
__AIRegs[0] |= 8;
OSClearContext(&exceptionContext);
OSSetCurrentContext(&exceptionContext);
if (__AIS_Callback) {
__AIS_Callback(__AIRegs[2]);
}
OSClearContext(&exceptionContext);
OSSetCurrentContext(context);
}
static void __AIDHandler(__OSInterrupt interrupt, OSContext* context) {
OSContext exceptionContext;
u16 tmp;
tmp = __DSPRegs[5];
tmp = (tmp & ~0xA0) | 8;
__DSPRegs[5] = tmp;
OSClearContext(&exceptionContext);
OSSetCurrentContext(&exceptionContext);
if (__AID_Callback && !__AID_Active) {
__AID_Active = TRUE;
if (__CallbackStack) {
__AICallbackStackSwitch(__AID_Callback);
} else {
__AID_Callback();
}
__AID_Active = FALSE;
}
OSClearContext(&exceptionContext);
OSSetCurrentContext(context);
}
// clang-format off
static asm void __AICallbackStackSwitch(__REGISTER void* cb) {
nofralloc
mflr r0
stw r0, 0x4(r1)
stwu r1, -0x18(r1)
stw r31, 0x14(r1)
mr r31, r3
lis r5, __OldStack@ha
addi r5, r5, __OldStack@l
stw r1, 0x0(r5)
lis r5, __CallbackStack@ha
addi r5, r5, __CallbackStack@l
lwz r1, 0x0(r5)
subi r1, r1, 0x8
mtlr r31
blrl
lis r5, __OldStack@ha
addi r5, r5, __OldStack@l
lwz r1, 0x0(r5)
lwz r0, 0x1c(r1)
lwz r31, 0x14(r1)
addi r1, r1, 0x18
mtlr r0
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())
;
}
+342
View File
@@ -0,0 +1,342 @@
#include "dolphin/os/OS.h"
#include "dolphin/ar/ar.h"
#include "dolphin/ar/arq.h"
#include "dolphin/dsp.h"
const char* __ARVersion = "<< Dolphin SDK - AR\trelease build: Sep 5 2002 05:34:27 (0x2301) >>";
static void (*__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 BOOL __AR_init_flag;
// prototypes
static void __ARHandler(__OSInterrupt exception, OSContext* context);
static void __ARWaitForDMA(void);
static void __ARWriteDMA(u32 mmem_addr, u32 aram_addr, u32 length);
static void __ARReadDMA(u32 mmem_addr, u32 aram_addr, u32 length);
static void __ARChecksize(void);
static void __ARClearArea(u32 start_addr, u32 length);
ARCallback ARRegisterDMACallback(ARCallback callback) {
ARCallback old_callback;
BOOL old;
old_callback = __AR_Callback;
old = OSDisableInterrupts();
__AR_Callback = callback;
OSRestoreInterrupts(old);
return old_callback;
}
void ARStartDMA(u32 type, u32 mainmem_addr, u32 aram_addr, u32 length) {
BOOL old;
old = OSDisableInterrupts();
ASSERTMSGLINE(376, !(__DSPRegs[5] & 0x200), "ARAM DMA already in progress\n");
ASSERTMSGLINE(377, !(mainmem_addr & 0x1F), "AR: Main memory address is not a multiple of 32 bytes!\n");
ASSERTMSGLINE(378, !(length & 0x1F), "AR: DMA transfer length is not a multiple of 32 bytes!\n");
__DSPRegs[16] = (__DSPRegs[16] & 0xFFFFFC00 | (mainmem_addr >> 0x10));
__DSPRegs[17] = (__DSPRegs[17] & 0xFFFF001F | ((u16)mainmem_addr));
__DSPRegs[18] = (__DSPRegs[18] & 0xFFFFFC00 | (aram_addr >> 0x10));
__DSPRegs[19] = (__DSPRegs[19] & 0xFFFF001F | ((u16)aram_addr));
__DSPRegs[20] = __DSPRegs[20] & ~0x8000 | ((type << 0xF) & ~0x7FFF);
__DSPRegs[20] = (__DSPRegs[20] & 0xFFFFFC00) | (length >> 0x10);
__DSPRegs[21] = (__DSPRegs[21] & 0xFFFF001F) | (length & 0x0000FFFF);
OSRestoreInterrupts(old);
}
u32 ARAlloc(u32 length) {
u32 tmp;
BOOL old;
old = OSDisableInterrupts();
ASSERTMSGLINE(430, !(length & 0x1F), "ARAlloc(): length is not multiple of 32bytes!");
ASSERTMSGLINE(434, length <= (__AR_Size - __AR_StackPointer), "ARAlloc(): Out of ARAM!");
ASSERTMSGLINE(435, __AR_FreeBlocks, "ARAlloc(): No more free blocks!");
tmp = __AR_StackPointer;
__AR_StackPointer += length;
*__AR_BlockLength = length;
__AR_BlockLength += 1;
__AR_FreeBlocks -= 1;
OSRestoreInterrupts(old);
return tmp;
}
u32 ARInit(u32* stack_index_addr, u32 num_entries) {
BOOL old;
u16 refresh;
if (__AR_init_flag == TRUE) {
return 0x4000;
}
OSRegisterVersion(__ARVersion);
old = OSDisableInterrupts();
__AR_Callback = NULL;
__OSSetInterruptHandler(6, __ARHandler);
__OSUnmaskInterrupts(0x02000000);
__AR_StackPointer = 0x4000;
__AR_FreeBlocks = num_entries;
__AR_BlockLength = stack_index_addr;
refresh = __DSPRegs[13] & 0xFF;
ASSERTMSGLINE(590, (refresh <= 196.0f), "ARInit(): ILLEGAL SDRAM REFRESH VALUE\n");
__DSPRegs[13] = (u16)((__DSPRegs[13] & ~0xFF) | (refresh & 0xFF));
__ARChecksize();
__AR_init_flag = TRUE;
OSRestoreInterrupts(old);
return __AR_StackPointer;
}
u32 ARGetBaseAddress(void) {
return 0x4000;
}
u32 ARGetSize(void) {
return __AR_Size;
}
static void __ARHandler(__OSInterrupt exception, OSContext* context) {
OSContext exceptionContext;
u16 tmp;
tmp = __DSPRegs[5];
tmp = (tmp & ~0x88) | 0x20;
__DSPRegs[5] = (tmp);
OSClearContext(&exceptionContext);
OSSetCurrentContext(&exceptionContext);
if (__AR_Callback) {
__AR_Callback();
}
OSClearContext(&exceptionContext);
OSSetCurrentContext(context);
}
void __ARClearInterrupt(void) {
u16 tmp;
tmp = __DSPRegs[5];
tmp = (tmp & ~0x88) | 0x20;
__DSPRegs[5] = (tmp);
}
static void __ARWaitForDMA(void) {
while (__DSPRegs[5] & 0x200);
}
static void __ARWriteDMA(u32 mmem_addr, u32 aram_addr, u32 length) {
// Main mem address
__DSPRegs[DSP_ARAM_DMA_MM_HI] = (u16)((__DSPRegs[DSP_ARAM_DMA_MM_HI] & ~0x03ff) | (u16)(mmem_addr >> 16));
__DSPRegs[DSP_ARAM_DMA_MM_LO] = (u16)((__DSPRegs[DSP_ARAM_DMA_MM_LO] & ~0xffe0) | (u16)(mmem_addr & 0xffff));
// ARAM address
__DSPRegs[DSP_ARAM_DMA_ARAM_HI] = (u16)((__DSPRegs[DSP_ARAM_DMA_ARAM_HI] & ~0x03ff) | (u16)(aram_addr >> 16));
__DSPRegs[DSP_ARAM_DMA_ARAM_LO] = (u16)((__DSPRegs[DSP_ARAM_DMA_ARAM_LO] & ~0xffe0) | (u16)(aram_addr & 0xffff));
// DMA buffer size
__DSPRegs[DSP_ARAM_DMA_SIZE_HI] = (u16)(__DSPRegs[DSP_ARAM_DMA_SIZE_HI] & ~0x8000);
__DSPRegs[DSP_ARAM_DMA_SIZE_HI] = (u16)((__DSPRegs[DSP_ARAM_DMA_SIZE_HI] & ~0x03ff) | (u16)(length >> 16));
__DSPRegs[DSP_ARAM_DMA_SIZE_LO] = (u16)((__DSPRegs[DSP_ARAM_DMA_SIZE_LO] & ~0xffe0) | (u16)(length & 0xffff));
__ARWaitForDMA();
__ARClearInterrupt();
}
static void __ARReadDMA(u32 mmem_addr, u32 aram_addr, u32 length) {
// Main mem address
__DSPRegs[DSP_ARAM_DMA_MM_HI] = (u16)((__DSPRegs[DSP_ARAM_DMA_MM_HI] & ~0x03ff) | (u16)(mmem_addr >> 16));
__DSPRegs[DSP_ARAM_DMA_MM_LO] = (u16)((__DSPRegs[DSP_ARAM_DMA_MM_LO] & ~0xffe0) | (u16)(mmem_addr & 0xffff));
// ARAM address
__DSPRegs[DSP_ARAM_DMA_ARAM_HI] = (u16)((__DSPRegs[DSP_ARAM_DMA_ARAM_HI] & ~0x03ff) | (u16)(aram_addr >> 16));
__DSPRegs[DSP_ARAM_DMA_ARAM_LO] = (u16)((__DSPRegs[DSP_ARAM_DMA_ARAM_LO] & ~0xffe0) | (u16)(aram_addr & 0xffff));
// DMA buffer size
__DSPRegs[DSP_ARAM_DMA_SIZE_HI] = (u16)(__DSPRegs[DSP_ARAM_DMA_SIZE_HI] | 0x8000);
__DSPRegs[DSP_ARAM_DMA_SIZE_HI] = (u16)((__DSPRegs[DSP_ARAM_DMA_SIZE_HI] & ~0x03ff) | (u16)(length >> 16));
__DSPRegs[DSP_ARAM_DMA_SIZE_LO] = (u16)((__DSPRegs[DSP_ARAM_DMA_SIZE_LO] & ~0xffe0) | (u16)(length & 0xffff));
__ARWaitForDMA();
__ARClearInterrupt();
}
static void __ARChecksize(void) {
u8 test_data_pad[63];
u8 dummy_data_pad[63];
u8 buffer_pad[63];
u8 save_pad_1[63];
u8 save_pad_2[63];
u8 save_pad_3[63];
u8 save_pad_4[63];
u8 save_pad_5[63];
u32* test_data;
u32* dummy_data;
u32* buffer;
u32* save1;
u32* save2;
u32* save3;
u32* save4;
u32* save5;
u16 ARAM_mode = 0;
u32 ARAM_size = 0;
u32 i;
do {} while(!(__DSPRegs[11] & 1));
ARAM_mode = 3;
ARAM_size = __AR_InternalSize = 0x1000000;
__DSPRegs[9] = ((__DSPRegs[9] & 0xFFFFFFC0) | 3) | 0x20;
test_data = (u32*)(OSRoundUp32B((u32)(test_data_pad)));
dummy_data = (u32*)(OSRoundUp32B((u32)(dummy_data_pad)));
buffer = (u32*)(OSRoundUp32B((u32)(buffer_pad)));
save1 = (u32*)(OSRoundUp32B((u32)(save_pad_1)));
save2 = (u32*)(OSRoundUp32B((u32)(save_pad_2)));
save3 = (u32*)(OSRoundUp32B((u32)(save_pad_3)));
save4 = (u32*)(OSRoundUp32B((u32)(save_pad_4)));
save5 = (u32*)(OSRoundUp32B((u32)(save_pad_5)));
for (i = 0; i < 8; i++) {
*(test_data + i) = 0xDEADBEEF;
*(dummy_data + i) = 0xBAD0BAD0;
}
DCFlushRange((void*)test_data, 0x20);
DCFlushRange((void*)dummy_data, 0x20);
__AR_ExpansionSize = 0;
DCInvalidateRange((void*)save1, 0x20);
__ARReadDMA((u32)save1, ARAM_size + 0, 0x20);
PPCSync();
__ARWriteDMA((u32)test_data, ARAM_size + 0x0000000, 0x20);
memset((void*)buffer, 0, 0x20);
DCFlushRange((void*)buffer, 0x20);
__ARReadDMA((u32)buffer, ARAM_size + 0x0000000, 0x20);
PPCSync();
if (buffer[0] == test_data[0]) {
DCInvalidateRange((void*)save2, 0x20);
__ARReadDMA((u32)save2, ARAM_size + 0x0200000, 0x20);
PPCSync();
DCInvalidateRange((void*)save3, 0x20);
__ARReadDMA((u32)save3, ARAM_size + 0x1000000, 0x20);
PPCSync();
DCInvalidateRange((void*)save4, 0x20);
__ARReadDMA((u32)save4, ARAM_size + 0x0000200, 0x20);
PPCSync();
DCInvalidateRange((void*)save5, 0x20);
__ARReadDMA((u32)save5, ARAM_size + 0x0400000, 0x20);
PPCSync();
__ARWriteDMA((u32)dummy_data, ARAM_size + 0x0200000, 0x20);
__ARWriteDMA((u32)test_data, ARAM_size + 0x0000000, 0x20);
memset((void*)buffer, 0, 0x20);
DCFlushRange((void*)buffer, 0x20);
__ARReadDMA((u32)buffer, ARAM_size + 0x0200000, 0x20);
PPCSync();
if (buffer[0] == test_data[0]) {
__ARWriteDMA((u32)save1, ARAM_size + 0x0000000, 0x20);
ARAM_mode |= 0 << 1;
ARAM_size += 0x0200000;
__AR_ExpansionSize = 0x0200000;
} else {
__ARWriteDMA((u32)dummy_data, ARAM_size + 0x1000000, 0x20);
__ARWriteDMA((u32)test_data, ARAM_size + 0x0000000, 0x20);
memset((void*)buffer, 0, 0x20);
DCFlushRange((void*)buffer, 0x20);
__ARReadDMA((u32)buffer, ARAM_size + 0x1000000, 0x20);
PPCSync();
if (buffer[0] == test_data[0]) {
__ARWriteDMA((u32)save1, ARAM_size + 0x0000000, 0x20);
__ARWriteDMA((u32)save2, ARAM_size + 0x0200000, 0x20);
ARAM_mode |= 4 << 1;
ARAM_size += 0x0400000;
__AR_ExpansionSize = 0x0400000;
} else {
__ARWriteDMA((u32)dummy_data, ARAM_size + 0x0000200, 0x20);
__ARWriteDMA((u32)test_data, ARAM_size + 0x0000000, 0x20);
memset((void*)buffer, 0, 0x20);
DCFlushRange((void*)buffer, 0x20);
__ARReadDMA((u32)buffer, ARAM_size + 0x0000200, 0x20);
PPCSync();
if (buffer[0] == test_data[0]) {
__ARWriteDMA((u32)save1, ARAM_size + 0x0000000, 0x20);
__ARWriteDMA((u32)save2, ARAM_size + 0x0200000, 0x20);
__ARWriteDMA((u32)save3, ARAM_size + 0x1000000, 0x20);
ARAM_mode |= 8 << 1;
ARAM_size += 0x0800000;
__AR_ExpansionSize = 0x0800000;
} else {
__ARWriteDMA((u32)dummy_data, ARAM_size + 0x0400000, 0x20);
__ARWriteDMA((u32)test_data, ARAM_size + 0x0000000, 0x20);
memset((void*)buffer, 0, 0x20);
DCFlushRange((void*)buffer, 0x20);
__ARReadDMA((u32)buffer, ARAM_size + 0x0400000, 0x20);
PPCSync();
if (buffer[0] == test_data[0]) {
__ARWriteDMA((u32)save1, ARAM_size + 0x0000000, 0x20);
__ARWriteDMA((u32)save2, ARAM_size + 0x0200000, 0x20);
__ARWriteDMA((u32)save3, ARAM_size + 0x1000000, 0x20);
__ARWriteDMA((u32)save4, ARAM_size + 0x0000200, 0x20);
ARAM_mode |= 12 << 1;
ARAM_size += 0x1000000;
__AR_ExpansionSize = 0x1000000;
} else {
__ARWriteDMA((u32)save1, ARAM_size + 0x0000000, 0x20);
__ARWriteDMA((u32)save2, ARAM_size + 0x0200000, 0x20);
__ARWriteDMA((u32)save3, ARAM_size + 0x1000000, 0x20);
__ARWriteDMA((u32)save4, ARAM_size + 0x0000200, 0x20);
__ARWriteDMA((u32)save5, ARAM_size + 0x0400000, 0x20);
ARAM_mode |= 16 << 1;
ARAM_size += 0x2000000;
__AR_ExpansionSize = 0x2000000;
}
}
}
}
#if DEBUG
OSReport("__ARChecksize(): ARAM Expansion present.\n");
#endif
__DSPRegs[9] = (u16)((__DSPRegs[9] & ~(0x07 | 0x38)) | ARAM_mode);
}
*(u32*)OSPhysicalToUncached(0x00D0) = ARAM_size;
__AR_Size = ARAM_size;
}
+140
View File
@@ -0,0 +1,140 @@
#include "dolphin/os/OS.h"
#include "dolphin/ar/ar.h"
#include "dolphin/ar/arq.h"
const char* __ARQVersion = "<< Dolphin SDK - ARQ\trelease build: Sep 5 2002 05:34:29 (0x2301) >>";
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 BOOL __ARQ_init_flag;
void __ARQPopTaskQueueHi(void) {
if (__ARQRequestQueueHi) {
if (__ARQRequestQueueHi->type == 0) {
ARStartDMA(__ARQRequestQueueHi->type, __ARQRequestQueueHi->source, __ARQRequestQueueHi->destination, __ARQRequestQueueHi->length);
} else {
ARStartDMA(__ARQRequestQueueHi->type, __ARQRequestQueueHi->destination, __ARQRequestQueueHi->source, __ARQRequestQueueHi->length);
}
__ARQCallbackHi = __ARQRequestQueueHi->callback;
__ARQRequestPendingHi = __ARQRequestQueueHi;
__ARQRequestQueueHi = __ARQRequestQueueHi->next;
}
}
void __ARQServiceQueueLo(void) {
if (__ARQRequestPendingLo == 0 && __ARQRequestQueueLo) {
__ARQRequestPendingLo = __ARQRequestQueueLo;
__ARQRequestQueueLo = __ARQRequestQueueLo->next;
}
if (__ARQRequestPendingLo) {
if (__ARQRequestPendingLo->length <= __ARQChunkSize) {
if (__ARQRequestPendingLo->type == 0) {
ARStartDMA(__ARQRequestPendingLo->type, __ARQRequestPendingLo->source, __ARQRequestPendingLo->destination, __ARQRequestPendingLo->length);
} else {
ARStartDMA(__ARQRequestPendingLo->type, __ARQRequestPendingLo->destination, __ARQRequestPendingLo->source, __ARQRequestPendingLo->length);
}
__ARQCallbackLo = __ARQRequestPendingLo->callback;
} else if (__ARQRequestPendingLo->type == 0) {
ARStartDMA(__ARQRequestPendingLo->type, __ARQRequestPendingLo->source, __ARQRequestPendingLo->destination, __ARQChunkSize);
} else {
ARStartDMA(__ARQRequestPendingLo->type, __ARQRequestPendingLo->destination, __ARQRequestPendingLo->source, __ARQChunkSize);
}
__ARQRequestPendingLo->length -= __ARQChunkSize;
__ARQRequestPendingLo->source += __ARQChunkSize;
__ARQRequestPendingLo->destination += __ARQChunkSize;
}
}
void __ARQCallbackHack(u32 unused) {}
void __ARQInterruptServiceRoutine() {
if (__ARQCallbackHi) {
__ARQCallbackHi((u32)__ARQRequestPendingHi);
__ARQRequestPendingHi = NULL;
__ARQCallbackHi = NULL;
} else if (__ARQCallbackLo) {
__ARQCallbackLo((u32)__ARQRequestPendingLo);
__ARQRequestPendingLo = NULL;
__ARQCallbackLo = NULL;
}
__ARQPopTaskQueueHi();
if (__ARQRequestPendingHi == 0) {
__ARQServiceQueueLo();
}
}
void ARQInit(void) {
if (__ARQ_init_flag != TRUE) {
OSRegisterVersion(__ARQVersion);
__ARQRequestQueueHi = __ARQRequestQueueLo = NULL;
__ARQChunkSize = 0x1000;
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 level;
ASSERTLINE(437, request);
ASSERTLINE(438, (type == ARQ_TYPE_MRAM_TO_ARAM) || (type == ARQ_TYPE_ARAM_TO_MRAM));
ASSERTLINE(439, (priority == ARQ_PRIORITY_LOW) || (priority == ARQ_PRIORITY_HIGH));
ASSERTLINE(442, (length % ARQ_DMA_ALIGNMENT) == 0);
request->next = NULL;
request->owner = owner;
request->type = type;
request->source = source;
request->destination = dest;
request->length = length;
if (callback) {
request->callback = callback;
} else {
request->callback = __ARQCallbackHack;
}
level = 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 == 0) && ( __ARQRequestPendingLo == 0)) {
__ARQPopTaskQueueHi();
if ( __ARQRequestPendingHi == 0) {
__ARQServiceQueueLo();
}
}
OSRestoreInterrupts(level);
}
+110
View File
@@ -0,0 +1,110 @@
#include "dolphin/base/PPCArch.h"
asm u32 PPCMfmsr() {
nofralloc
mfmsr r3
blr
}
asm void PPCMtmsr(__REGISTER u32 newMSR) {
nofralloc
mtmsr newMSR
blr
}
asm u32 PPCMfhid0() {
nofralloc
mfspr r3, HID0
blr
}
asm void PPCMthid0(__REGISTER u32 newHID0) {
nofralloc
mtspr HID0, newHID0
blr
}
asm u32 PPCMfl2cr() {
nofralloc
mfspr r3, L2CR
blr
}
asm void PPCMtl2cr(__REGISTER u32 newL2cr) {
nofralloc
mtspr L2CR, newL2cr
blr
}
asm void PPCMtdec(__REGISTER u32 newDec) {
nofralloc
mtdec newDec
blr
}
asm void PPCSync() {
nofralloc
sc
blr
}
asm void PPCHalt() {
nofralloc
sync
loop:
nop
li r3, 0
nop
b loop
}
u32 PPCMffpscr() {
union FpscrUnion m;
asm {
mffs fp31
stfd fp31, m.f;
}
return m.u.fpscr;
}
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
}
}
asm u32 PPCMfhid2() {
nofralloc
mfspr r3, HID2
blr
}
asm void PPCMthid2(__REGISTER u32 newhid2) {
nofralloc
mtspr HID2, newhid2
blr
}
asm void PPCMtwpar(__REGISTER u32 newwpar) {
nofralloc
mtspr WPAR, newwpar
blr
}
void PPCDisableSpeculation(void) {
PPCMthid0(PPCMfhid0() | HID0_SPD);
}
asm void PPCSetFpNonIEEEMode() {
nofralloc
mtfsb1 29
blr
}
+634
View File
@@ -0,0 +1,634 @@
#include "dolphin/card.h"
const char* __CARDVersion = "<< Dolphin SDK - CARD\trelease build: Sep 5 2002 05:35:20 (0x2301) >>";
CARDControl __CARDBlock[2];
static u16 __CARDEncode;
DVDDiskID __CARDDiskNone;
// prototypes
static void TimeoutHandler(OSAlarm* alarm, OSContext* context);
static void SetupTimeoutAlarm(CARDControl* card);
static s32 Retry(s32 chan);
static void UnlockedCallback(s32 chan, s32 result);
static BOOL OnReset(BOOL f);
s32 __CARDReadStatus(s32 chan, u8* status);
s32 __CARDClearStatus(s32 chan);
void __CARDSetDiskID(const DVDDiskID* id);
void* __CARDGetFatBlock(CARDControl* card);
CARDDir* __CARDGetDirBlock(CARDControl* card);
static OSResetFunctionInfo ResetFunctionInfo = {OnReset, 127};
void __CARDDefaultApiCallback(s32 chan, s32 result) {}
void __CARDSyncCallback(s32 chan, s32 result) {
CARDControl* card;
card = &__CARDBlock[chan];
OSWakeupThread(&card->threadQueue);
}
void __CARDExtHandler(s32 chan, OSContext* context) {
CARDControl* card;
CARDCallback callback;
ASSERTLINE(232, 0 <= chan && chan < 2);
card = &__CARDBlock[chan];
if (card->attached) {
ASSERTLINE(239, card->txCallback == 0);
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;
ASSERTLINE(283, 0 <= chan && chan < 2);
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;
int err;
ASSERTLINE(365, 0 <= chan && chan < 2);
card = &__CARDBlock[chan];
err = !EXIDeselect(chan);
EXIUnlock(chan);
callback = card->txCallback;
if (callback) {
card->txCallback = NULL;
callback(chan, (!err && EXIProbe(chan)) ? CARD_RESULT_READY : CARD_RESULT_NOCARD);
}
}
void __CARDUnlockedHandler(s32 chan, OSContext* context) {
CARDControl* card;
CARDCallback callback;
ASSERTLINE(412, 0 <= chan && chan < 2);
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;
ASSERTLINE(431, 0 <= chan && chan < 2);
if (!EXISelect(chan, 0, 4)) {
return CARD_RESULT_NOCARD;
}
cmd = enable ? 0x81010000 : 0x81000000;
err = FALSE;
err |= !EXIImm(chan, &cmd, 2, EXI_WRITE, 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;
ASSERTLINE(450, 0 <= chan && chan < 2);
if (!EXISelect(chan, 0, 4)) {
return CARD_RESULT_NOCARD;
}
cmd = 0x83000000;
err = FALSE;
err |= !EXIImm(chan, &cmd, 2, EXI_WRITE, NULL);
err |= !EXISync(chan);
err |= !EXIImm(chan, status, 1, EXI_READ, NULL);
err |= !EXISync(chan);
err |= !EXIDeselect(chan);
return err ? CARD_RESULT_NOCARD : CARD_RESULT_READY;
}
s32 __CARDClearStatus(s32 chan) {
BOOL err;
u32 cmd;
ASSERTLINE(492, 0 <= chan && chan < 2);
if (!EXISelect(chan, 0, 4)) {
return CARD_RESULT_NOCARD;
}
cmd = 0x89000000;
err = FALSE;
err |= !EXIImm(chan, &cmd, 1, EXI_WRITE, 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;
}
}
ASSERTLINE(578, 0 <= chan && chan < 2);
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;
ASSERTLINE(654, 0 <= chan && chan < 2);
card = &__CARDBlock[chan];
if (!EXISelect(chan, 0, 4)) {
EXIUnlock(chan);
return CARD_RESULT_NOCARD;
}
SetupTimeoutAlarm(card);
if (!EXIImmEx(chan, card->cmd, card->cmdlen, EXI_WRITE)) {
EXIDeselect(chan);
EXIUnlock(chan);
return CARD_RESULT_NOCARD;
}
if (card->cmd[0] == 0x52 &&
!EXIImmEx(chan, (u8* )card->workArea + sizeof(CARDID), card->latency, EXI_WRITE))
{
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;
ASSERTLINE(718, 0 <= chan && chan < 2);
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 = NULL;
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();
ASSERTLINE(784, 0 <= chan && chan < 2);
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;
ASSERTLINE(846, 0 <= chan && chan < 2);
card = &__CARDBlock[chan];
ASSERTLINE(848, card->addr % CARD_SEG_SIZE == 0);
ASSERTLINE(849, card->addr < (u32) card->size * 1024 * 1024 / 8);
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, EXI_WRITE) ||
!EXIImmEx(chan, (u8* )card->workArea + sizeof(CARDID), card->latency,
EXI_WRITE) || // XXX use DMA if possible
!EXIDma(chan, card->buffer, 512, card->mode, __CARDTxHandler))
{
card->txCallback = NULL;
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;
ASSERTLINE(903, 0 <= chan && chan < 2);
card = &__CARDBlock[chan];
ASSERTLINE(905, card->addr % card->pageSize == 0);
ASSERTLINE(906, card->addr < (u32) card->size * 1024 * 1024 / 8);
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, EXI_WRITE) ||
!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;
ASSERTLINE(1010, 0 <= chan && chan < 2);
card = &__CARDBlock[chan];
ASSERTLINE(1012, addr % card->sectorSize == 0);
ASSERTLINE(1013, addr < (u32) card->size * 1024 * 1024 / 8);
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, EXI_WRITE)) {
result = CARD_RESULT_NOCARD;
card->exiCallback = NULL;
} else {
result = CARD_RESULT_READY;
}
EXIDeselect(chan);
EXIUnlock(chan);
}
return result;
}
void CARDInit(void) {
int chan;
if (__CARDBlock[0].diskID && __CARDBlock[1].diskID) {
return;
}
__CARDEncode = OSGetFontEncode();
OSRegisterVersion(__CARDVersion);
DSPInit();
OSInitAlarm();
for (chan = 0; chan < 2; ++chan) {
CARDControl* card = &__CARDBlock[chan];
card->result = CARD_RESULT_NOCARD;
OSInitThreadQueue(&card->threadQueue);
OSCreateAlarm(&card->alarm);
}
__CARDSetDiskID((void*)OSPhysicalToCached(0));
OSRegisterResetFunction(&ResetFunctionInfo);
}
u16 __CARDGetFontEncode(void) {
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 == 0) {
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 = NULL;
*pcard = card;
}
OSRestoreInterrupts(enabled);
return result;
}
s32 __CARDPutControlBlock(CARDControl* card, s32 result) {
BOOL enabled;
ASSERTLINE(1259, result != CARD_RESULT_BUSY);
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;
ASSERTLINE(1292, 0 <= chan && chan < 2);
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 __CARDSync(s32 chan) {
CARDControl* block;
s32 result;
s32 enabled;
block = &__CARDBlock[chan];
enabled = OSDisableInterrupts();
while ((result = CARDGetResultCode(chan)) == CARD_RESULT_BUSY) {
OSSleepThread(&block->threadQueue);
}
OSRestoreInterrupts(enabled);
return result;
}
static BOOL OnReset(BOOL final) {
if (!final) {
if (CARDUnmount(0) == CARD_RESULT_BUSY || CARDUnmount(1) == CARD_RESULT_BUSY) {
return FALSE;
}
}
return TRUE;
}
+134
View File
@@ -0,0 +1,134 @@
#include "dolphin/card.h"
// prototypes
static void WriteCallback(s32 chan, s32 result);
static void EraseCallback(s32 chan, s32 result);
s32 __CARDUpdateFatBlock(s32 chan, u16* fat, CARDCallback callback);
void* __CARDGetFatBlock(CARDControl* card) {
ASSERTLINE(57, card->currentFat);
return card->currentFat;
}
static void WriteCallback(s32 chan, s32 result) {
CARDControl* card;
CARDCallback callback;
u16* fat0;
u16* fat1;
card = &__CARDBlock[chan];
if (result >= 0) {
fat0 = (u16*)((u8*)card->workArea + 0x6000);
fat1 = (u16*)((u8*)card->workArea + 0x8000);
ASSERTLINE(82, card->currentFat);
if (card->currentFat == fat0) {
card->currentFat = fat1;
memcpy(fat1, fat0, 0x2000);
} else {
ASSERTLINE(90, card->currentFat == fat1);
card->currentFat = fat0;
memcpy(fat0, fat1, 0x2000);
}
}
if (!card->apiCallback)
__CARDPutControlBlock(card, result);
callback = card->eraseCallback;
if (callback) {
card->eraseCallback = NULL;
callback(chan, result);
}
}
static void EraseCallback(s32 chan, s32 result) {
CARDControl* card = &__CARDBlock[chan];
CARDCallback callback;
u16* fat;
u32 addr;
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)
__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;
ASSERTLINE(182, 0 < cBlock);
ASSERTLINE(183, 0 <= chan && chan < 2);
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 __CARDUpdateFatBlock(s32 chan, u16* fat, CARDCallback callback) {
CARDControl* card;
u32 addr;
ASSERTLINE(295, 0 <= chan && chan < 2);
card = &__CARDBlock[chan];
++fat[2];
__CARDCheckSum(fat + 2, 0x1FFC, fat, fat + 1);
DCStoreRange(fat, 0x2000);
card->eraseCallback = callback;
addr = (((char*)fat - (char*)card->workArea) / 8192u) * card->sectorSize;
return __CARDEraseSector(chan, addr, EraseCallback);
}
+343
View File
@@ -0,0 +1,343 @@
#include "dolphin/card.h"
// prototypes
static s32 VerifyID(CARDControl* card);
static s32 VerifyDir(CARDControl* card, int* pcurrent);
static s32 VerifyFAT(CARDControl* card, int* pcurrent);
extern void __CARDSyncCallback(s32 chan, s32 result);
extern u16 __CARDGetFontEncode(void);
void __CARDCheckSum(void* ptr, int length, u16* checksum, u16* checksumInv) {
u16* p;
int i;
ASSERTLINE(82, length % sizeof(u16) == 0);
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;
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);
if (id->encode != __CARDGetFontEncode())
return CARD_RESULT_ENCODING;
return CARD_RESULT_READY;
}
static s32 VerifyDir(CARDControl* card, int* pcurrent) {
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 (pcurrent)
*pcurrent = current;
return errors;
}
static s32 VerifyFAT(CARDControl* card, int* pcurrent) {
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 (pcurrent)
*pcurrent = 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:
ASSERTLINE(301, card->currentDir);
ASSERTLINE(302, card->currentFat);
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;
ASSERTLINE(346, 0 <= chan && chan < 2);
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);
ASSERTLINE(377, errors == 0 || errors == 1);
switch (errors) {
case 0:
ASSERTLINE(381, card->currentDir);
ASSERTLINE(382, card->currentFat);
break;
case 1:
if (!card->currentDir) {
ASSERTLINE(387, card->currentFat);
card->currentDir = dir[currentDir];
memcpy(dir[currentDir], dir[currentDir ^ 1], CARD_SYSTEM_BLOCK_SIZE);
updateDir = TRUE;
} else {
ASSERTLINE(394, !card->currentFat);
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 CARDCheckEx(s32 chan, s32* xferBytes) {
s32 result = CARDCheckExAsync(chan, xferBytes, __CARDSyncCallback);
if (result < 0 || xferBytes == 0) {
return result;
}
return __CARDSync(chan);
}
s32 CARDCheck(s32 chan) {
s32 xferBytes;
return CARDCheckEx(chan, &xferBytes);
}
+129
View File
@@ -0,0 +1,129 @@
#include "dolphin/card.h"
extern CARDDir* __CARDGetDirBlock(CARDControl* card);
extern void* __CARDGetFatBlock(CARDControl* card);
extern void __CARDDefaultApiCallback(s32 chan, s32 result);
extern void __CARDSyncCallback(s32 chan, s32 result);
// prototypes
static void CreateCallbackFat(s32 chan, s32 result);
static void CreateCallbackFat(s32 chan, s32 result) {
CARDControl* card;
CARDDir* dir;
CARDDir* ent;
CARDCallback callback;
card = &__CARDBlock[chan];
callback = card->apiCallback;
card->apiCallback = NULL;
if (result >= 0) {
dir = __CARDGetDirBlock(card);
ent = &dir[card->freeNo];
memcpy(ent->gameName, card->diskID->game_name, sizeof(ent->gameName));
memcpy(ent->company, card->diskID->company, sizeof(ent->company));
ent->permission = 4;
ent->copyTimes = 0;
ASSERTLINE(111, CARDIsValidBlockNo(card, card->startBlock));
ent->startBlock = (u16)card->startBlock;
ent->bannerFormat = 0;
ent->iconAddr = -1;
ent->iconFormat = 0;
ent->iconSpeed = 0;
ent->commentAddr = -1;
CARDSetIconSpeed(ent, 0, CARD_STAT_SPEED_FAST);
card->fileInfo->offset = 0;
card->fileInfo->iBlock = ent->startBlock;
ent->time = OSTicksToSeconds(OSGetTime());
result = __CARDUpdateDir(chan, callback);
if (result < 0) {
goto after;
}
} else {
after:;
__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;
u16 fileNo;
u16 freeNo;
u16* fat;
s32 result;
ASSERTLINE(175, 0 <= chan && chan < 2);
ASSERTLINE(176, strlen(fileName) <= CARD_FILENAME_MAX);
if (strlen(fileName) > (u32)CARD_FILENAME_MAX) {
return CARD_RESULT_NAMETOOLONG;
}
result = __CARDGetControlBlock(chan, &card);
if (result < 0) {
return result;
}
ASSERTLINE(188, 0 < size && (size % card->sectorSize) == 0);
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->game_name, 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);
strncpy((char*)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);
}
+87
View File
@@ -0,0 +1,87 @@
#include "dolphin/card.h"
// prototypes
static void WriteCallback(s32 chan, s32 result);
static void EraseCallback(s32 chan, s32 result);
CARDDir* __CARDGetDirBlock(CARDControl* card) {
ASSERTLINE(54, card->currentDir);
return card->currentDir;
}
static void WriteCallback(s32 chan, s32 result) {
CARDControl* card = &__CARDBlock[chan];
CARDCallback callback;
if (result >= 0) {
CARDDir* dir0 = (CARDDir*)((u8*)card->workArea + 0x2000);
CARDDir* dir1 = (CARDDir*)((u8*)card->workArea + 0x4000);
ASSERTLINE(79, card->currentDir);
if (card->currentDir == dir0) {
card->currentDir = dir1;
memcpy(dir1, dir0, 0x2000);
} else {
ASSERTLINE(87, card->currentDir == dir1);
card->currentDir = dir0;
memcpy(dir0, dir1, 0x2000);
}
}
if (!card->apiCallback)
__CARDPutControlBlock(card, result);
callback = card->eraseCallback;
if (callback) {
card->eraseCallback = NULL;
callback(chan, result);
}
}
static void EraseCallback(s32 chan, s32 result) {
CARDControl* card = &__CARDBlock[chan];
CARDCallback callback;
CARDDir* dir;
u32 addr;
if (result >= 0) {
dir = __CARDGetDirBlock(card);
addr = ((u32)dir - (u32)card->workArea) / 0x2000 * card->sectorSize;
result = __CARDWrite(chan, addr, 0x2000, dir, WriteCallback);
if (result >= 0)
return;
}
if (!card->apiCallback)
__CARDPutControlBlock(card, result);
callback = card->eraseCallback;
if (callback) {
card->eraseCallback = NULL;
callback(chan, result);
}
}
s32 __CARDUpdateDir(s32 chan, CARDCallback callback) {
CARDControl* card;
CARDDirCheck* check;
u32 addr;
CARDDir* dir;
ASSERTLINE(173, 0 <= chan && chan < 2);
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);
}
+126
View File
@@ -0,0 +1,126 @@
#include "dolphin/card.h"
#include "dolphin/vi/vi.h"
extern void __CARDDefaultApiCallback(s32 chan, s32 result);
extern void __CARDSyncCallback(s32 chan, s32 result);
extern u16 __CARDGetFontEncode(void);
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 (result >= 0)
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 = NULL;
__CARDPutControlBlock(card, result);
ASSERTLINE(133, callback);
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 dvdstatus;
OSTime time;
OSTime rand;
ASSERTLINE(167, encode == CARD_ENCODE_ANSI || encode == CARD_ENCODE_SJIS);
ASSERTLINE(168, 0 <= chan && chan < 2);
result = __CARDGetControlBlock(chan, &card);
if (result < 0)
return result;
id = (CARDID*)card->workArea;
memset(id, 0xff, CARD_SYSTEM_BLOCK_SIZE);
dvdstatus = __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] = dvdstatus;
*(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 CARDFormat(s32 chan) {
s32 result = __CARDFormatRegionAsync(chan, __CARDGetFontEncode(), &__CARDSyncCallback);
if (result < 0) {
return result;
}
return __CARDSync(chan);
}
+378
View File
@@ -0,0 +1,378 @@
#include "dolphin/card.h"
extern u16 __CARDVendorID;
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,
};
// prototypes
static s32 DoMount(s32 chan);
static void DoUnmount(s32 chan, s32 result);
void __CARDMountCallback(s32 chan, s32 result);
extern void __CARDExiHandler(s32 chan, OSContext* context);
extern void __CARDUnlockedHandler(s32 chan, OSContext* context);
extern void __CARDDefaultApiCallback(s32 chan, s32 result);
extern void __CARDExtHandler(s32 chan, OSContext* context);
extern void __CARDSyncCallback(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;
}
int CARDProbe(s32 chan) {
if (__gUnknown800030E3 & 0x80) {
return 0;
} else {
return EXIProbe(chan);
}
}
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 (__gUnknown800030E3 & 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;
ASSERTLINE(399, 0 <= chan && chan < 2);
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);
ASSERTLINE(424, card->size);
card->sectorSize = SectorSizeTable[(id & 0x00003800) >> 11];
ASSERTLINE(426, card->sectorSize);
card->cBlock = (u16)((card->size * 1024 * 1024 / 8) / card->sectorSize);
ASSERTLINE(428, 8 <= card->cBlock);
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;
ASSERTLINE(570, 0 <= chan && chan < 2);
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 (result >= 0)
return;
break;
case CARD_RESULT_IOERROR:
case CARD_RESULT_NOCARD:
DoUnmount(chan, result);
break;
}
callback = card->apiCallback;
card->apiCallback = NULL;
__CARDPutControlBlock(card, result);
ASSERTLINE(620, callback);
callback(chan, result);
}
s32 CARDMountAsync(s32 chan, void* workArea, CARDCallback detachCallback, CARDCallback attachCallback) {
CARDControl* card;
BOOL enabled;
ASSERTLINE(652, workArea && ((u32) workArea % 32 == 0));
ASSERTLINE(653, 0 <= chan && chan < 2);
if (chan < 0 || 2 <= chan)
return CARD_RESULT_FATAL_ERROR;
if (__gUnknown800030E3 & 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 detachCallback) {
s32 result = CARDMountAsync(chan, workArea, detachCallback, __CARDSyncCallback);
if (result < 0)
return result;
return __CARDSync(chan);
}
static void DoUnmount(s32 chan, s32 result) {
CARDControl* card;
BOOL enabled;
ASSERTLINE(758, 0 <= chan && chan < 2);
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;
ASSERTLINE(793, 0 <= chan && chan < 2);
result = __CARDGetControlBlock(chan, &card);
if (result < 0)
return result;
DoUnmount(chan, CARD_RESULT_NOCARD);
return CARD_RESULT_READY;
}
+32
View File
@@ -0,0 +1,32 @@
#include "dolphin/card.h"
extern void __CARDSyncCallback(s32 chan, s32 result);
u16 __CARDVendorID = 0xFFFF;
s32 CARDGetSerialNo(s32 chan, u64* serialNo) {
CARDControl* card;
s32 result;
CARDID* id;
u64 code;
int i;
ASSERTLINE(105, 0 <= chan && chan < 2);
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);
}
+116
View File
@@ -0,0 +1,116 @@
#include "dolphin/card.h"
extern u8 __CARDPermMask;
extern CARDDir* __CARDGetDirBlock(CARDControl* card);
BOOL __CARDCompareFileName(CARDDir* ent, const char* fileName) {
char* entName = (char*)ent->fileName;
char c1;
char c2;
int n = CARD_FILENAME_MAX;
while (--n >= 0) {
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->game_name, sizeof(ent->gameName)) == 0
&& memcmp(ent->company, card->diskID->company, sizeof(ent->company)) == 0))
return CARD_RESULT_READY;
return CARD_RESULT_NOPERM;
}
s32 __CARDIsPublic(CARDDir* ent) {
if (ent->gameName[0] == 0xFF)
return CARD_RESULT_NOFILE;
if (ent->permission & 4)
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;
s32 fileNo;
s32 result;
CARDDir* dir;
CARDDir* ent;
ASSERTLINE(336, 0 <= chan && chan < 2);
fileInfo->chan = -1;
result = __CARDGetControlBlock(chan, &card);
if (result < 0)
return result;
result = __CARDGetFileNo(card, fileName, &fileNo);
if (result >= 0) {
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;
ASSERTLINE(380, 0 <= fileInfo->chan && fileInfo->chan < 2);
ASSERTLINE(381, 0 <= fileInfo->fileNo && fileInfo->fileNo < CARD_MAX_FILE);
result = __CARDGetControlBlock(fileInfo->chan, &card);
if (result < 0)
return result;
fileInfo->chan = -1;
return __CARDPutControlBlock(card, CARD_RESULT_READY);
}
+98
View File
@@ -0,0 +1,98 @@
#include "dolphin/card.h"
// prototypes
static void BlockReadCallback(s32 chan, s32 result);
static void BlockWriteCallback(s32 chan, s32 result);
static void BlockReadCallback(s32 chan, s32 result) {
CARDControl* card;
CARDCallback callback;
card = &__CARDBlock[chan];
if ((result >= 0)) {
card->xferred += 0x200;
card->addr += 0x200;
((u8*)card->buffer) += 0x200;
if (--card->repeat > 0) {
result = __CARDReadSegment(chan, BlockReadCallback);
if (result >= 0) {
return;
}
}
}
if (!card->apiCallback) {
__CARDPutControlBlock(card, result);
}
callback = card->xferCallback;
if (callback) {
card->xferCallback = NULL;
callback(chan, result);
}
}
s32 __CARDRead(s32 chan, u32 addr, s32 length, void* dst, CARDCallback callback) {
CARDControl* card;
ASSERTLINE(91, 0 < length && length % CARD_SEG_SIZE == 0);
ASSERTLINE(92, 0 <= chan && chan < 2);
card = &__CARDBlock[chan];
if (card->attached == 0) {
return CARD_RESULT_NOCARD;
}
card->xferCallback = callback;
card->repeat = (length / 512u);
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) {
card->xferred += 0x80;
card->addr += 0x80;
((u8*)card->buffer) += 0x80;
if (--card->repeat > 0) {
result = __CARDWritePage(chan, BlockWriteCallback);
if (result >= 0) {
return;
}
}
}
if (!card->apiCallback) {
__CARDPutControlBlock(card, result);
}
callback = card->xferCallback;
if (callback) {
card->xferCallback = NULL;
callback(chan, result);
}
}
s32 __CARDWrite(s32 chan, u32 addr, s32 length, void* dst, CARDCallback callback) {
CARDControl* card;
card = &__CARDBlock[chan];
ASSERTLINE(153, 0 < length && length % card->pageSize == 0);
ASSERTLINE(154, 0 <= chan && chan < 2);
if (card->attached == 0) {
return CARD_RESULT_NOCARD;
}
card->xferCallback = callback;
card->repeat = (int)(length / 128u);
card->addr = addr;
card->buffer = dst;
return __CARDWritePage(chan, BlockWriteCallback);
}
+159
View File
@@ -0,0 +1,159 @@
#include "dolphin/card.h"
#define TRUNC(n, a) (((u32)(n)) & ~((a)-1))
#define OFFSET(addr, align) (((u32)(addr) & ((align)-1)))
extern CARDDir* __CARDGetDirBlock(CARDControl* card);
extern void* __CARDGetFatBlock(CARDControl* card);
extern void __CARDDefaultApiCallback(s32 chan, s32 result);
extern void __CARDSyncCallback(s32 chan, s32 result);
// prototypes
static void ReadCallback(s32 chan, s32 result);
s32 __CARDSeek(CARDFileInfo* fileInfo, s32 length, s32 offset, CARDControl** pcard) {
CARDControl* card;
CARDDir* dir;
CARDDir* ent;
s32 result;
u16* fat;
ASSERTLINE(98, 0 <= fileInfo->chan && fileInfo->chan < 2);
ASSERTLINE(99, 0 <= fileInfo->fileNo && fileInfo->fileNo < CARD_MAX_FILE);
result = __CARDGetControlBlock(fileInfo->chan, &card);
if (result < 0)
return result;
ASSERTLINE(106, CARDIsValidBlockNo(card, fileInfo->iBlock));
ASSERTLINE(107, fileInfo->offset < card->cBlock * card->sectorSize);
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];
ASSERTLINE(117, ent->gameName[0] != 0xff);
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 = 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;
}
ASSERTLINE(199, OFFSET(fileInfo->length, CARD_SEG_SIZE) == 0);
ASSERTLINE(200, OFFSET(fileInfo->offset, card->sectorSize) == 0);
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 = NULL;
__CARDPutControlBlock(card, result);
ASSERTLINE(217, callback);
callback(chan, result);
}
s32 CARDReadAsync(CARDFileInfo* fileInfo, void* buf, s32 length, s32 offset, CARDCallback callback) {
CARDControl* card;
s32 result;
CARDDir* dir;
CARDDir* ent;
ASSERTLINE(250, buf && OFFSET(buf, 32) == 0);
ASSERTLINE(251, OFFSET(offset, CARD_SEG_SIZE) == 0);
ASSERTLINE(252, 0 < length && OFFSET(length, CARD_SEG_SIZE) == 0);
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);
}
+160
View File
@@ -0,0 +1,160 @@
#include "dolphin/card.h"
extern CARDDir* __CARDGetDirBlock(CARDControl* card);
extern void __CARDSyncCallback(s32 chan, s32 result);
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;
ASSERTLINE(172, 0 <= chan && chan < 2);
ASSERTLINE(173, 0 <= fileNo && fileNo < CARD_MAX_FILE);
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;
ASSERTLINE(231, 0 <= fileNo && fileNo < CARD_MAX_FILE);
ASSERTLINE(232, 0 <= chan && chan < 2);
ASSERTMSGLINE(240, stat->iconAddr == 0xffffffff || stat->iconAddr < CARD_READ_SIZE, "CARDSetStatus[Async](): stat->iconAddr must be 0xffffffff or less than CARD_READ_SIZE.");
ASSERTMSGLINE(243, stat->commentAddr == 0xffffffff || (stat->commentAddr & 0x1FFF) <= 8128, "CARDSetStatus[Async](): comment strings (set by stat->commentAddr) must not cross 8KB byte boundary.");
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);
}
+401
View File
@@ -0,0 +1,401 @@
#include "dolphin/card.h"
static u8 CardData[352] 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,
};
static u32 next = 1;
// prototypes
static u32 exnor_1st(u32 data, u32 rshift);
static u32 exnor(u32 data, u32 lshift);
static u32 bitrev(u32 data);
static s32 ReadArrayUnlock(s32 chan, u32 data, void* rbuf, s32 rlen, int mode);
static u32 GetInitVal(void);
static s32 DummyLen(void);
static void InitCallback(void* _task);
static void DoneCallback(void* _task);
static int CARDRand(void) {
next = (next * 0x41C64E6D) + 0x3039;
return (next / 0x10000) & 0x7FFF;
}
static void CARDSrand(unsigned int seed) {
next = seed;
}
static u32 exnor_1st(u32 data, u32 rshift) {
u32 wk;
u32 work;
u32 i;
work = data;
for (i = 0; i < rshift; i++) {
wk = ~(work ^ (work >> 7) ^ (work >> 15) ^ (work >> 23));
work = (work >> 1) | ((wk << 30) & 0x40000000);
}
return work;
}
static u32 exnor(u32 data, u32 lshift) {
u32 wk;
u32 work;
u32 i;
work = data;
for (i = 0; i < lshift; i++) {
// 1bit Left Shift
wk = ~(work ^ (work << 7) ^ (work << 15) ^ (work << 23));
work = (work << 1) | ((wk >> 30) & 0x00000002);
}
return work;
}
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, int mode) {
CARDControl* card;
BOOL err;
u8 cmd[5];
ASSERTLINE(240, 0 <= chan && chan < 2);
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;
}
static u32 GetInitVal(void) {
u32 tmp;
u32 tick;
tick = OSGetTick();
CARDSrand(tick);
tmp = 0x7fec8000;
tmp |= CARDRand();
tmp &= 0xfffff000;
return tmp;
}
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;
CARDDecParam* param;
u8* input;
u8* output;
card = &__CARDBlock[chan];
task = &card->task;
param = (CARDDecParam*)card->workArea;
input = (u8*)((u8* )param + sizeof(CARDDecParam));
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(CARDDecParam));
task->priority = 255;
task->iram_mmem_addr = (u16*)OSCachedToPhysical(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;
CARDDecParam* param;
task = _task;
for (chan = 0; chan < 2; ++chan) {
card = &__CARDBlock[chan];
if ((DSPTaskInfo*)&card->task == task)
break;
}
ASSERTLINE(514, 0 <= chan && chan < 2);
param = (CARDDecParam*)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;
CARDDecParam* param;
u8* input;
u8* output;
task = _task;
for (chan = 0; chan < 2; ++chan) {
card = &__CARDBlock[chan];
if ((DSPTaskInfo* )&card->task == task)
break;
}
ASSERTLINE(563, 0 <= chan && chan < 2);
param = (CARDDecParam*)card->workArea;
input = (u8*)((u8*)param + sizeof(CARDDecParam));
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);
}

Some files were not shown because too many files have changed in this diff Show More