mirror of
https://github.com/zeldaret/tww.git
synced 2026-06-27 18:12:58 -04:00
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:
@@ -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:
|
||||
|
||||
@@ -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:
|
||||
|
||||
@@ -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:
|
||||
|
||||
@@ -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
@@ -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"),
|
||||
],
|
||||
},
|
||||
|
||||
|
||||
@@ -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
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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); \
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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
@@ -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
|
||||
};
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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)
|
||||
|
||||
@@ -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:
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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() {
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
}
|
||||
@@ -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;
|
||||
}
|
||||
@@ -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);
|
||||
}
|
||||
@@ -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;
|
||||
}
|
||||
@@ -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, ®istersLength, TRUE);
|
||||
|
||||
if (error == DS_NoError) {
|
||||
error = TRKTargetAccessFP(0, 33, b, ®istersLength, TRUE);
|
||||
}
|
||||
if (error == DS_NoError) {
|
||||
error = TRKTargetAccessExtended1(0, 0x60, b, ®istersLength, TRUE);
|
||||
}
|
||||
if (error == DS_NoError) {
|
||||
error = TRKTargetAccessExtended2(0, 31, b, ®istersLength, 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, ®istersLength, FALSE);
|
||||
break;
|
||||
case DSREG_FP:
|
||||
error = TRKTargetAccessFP(firstRegister, lastRegister, b, ®istersLength, FALSE);
|
||||
break;
|
||||
case DSREG_Extended1:
|
||||
error = TRKTargetAccessExtended1(firstRegister, lastRegister, b, ®istersLength, FALSE);
|
||||
break;
|
||||
case DSREG_Extended2:
|
||||
error = TRKTargetAccessExtended2(firstRegister, lastRegister, b, ®istersLength, 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;
|
||||
}
|
||||
@@ -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);
|
||||
}
|
||||
@@ -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;
|
||||
}
|
||||
@@ -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;
|
||||
}
|
||||
@@ -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;
|
||||
}
|
||||
@@ -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
@@ -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;
|
||||
}
|
||||
@@ -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())
|
||||
;
|
||||
}
|
||||
@@ -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;
|
||||
}
|
||||
@@ -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);
|
||||
}
|
||||
@@ -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
|
||||
}
|
||||
@@ -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;
|
||||
}
|
||||
@@ -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);
|
||||
}
|
||||
@@ -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, ¤tDir);
|
||||
errors += VerifyFAT(card, ¤tFat);
|
||||
if (1 < errors) {
|
||||
return __CARDPutControlBlock(card, CARD_RESULT_BROKEN);
|
||||
}
|
||||
|
||||
dir[0] = (CARDDir*)((u8*)card->workArea + (1 + 0) * CARD_SYSTEM_BLOCK_SIZE);
|
||||
dir[1] = (CARDDir*)((u8*)card->workArea + (1 + 1) * CARD_SYSTEM_BLOCK_SIZE);
|
||||
fat[0] = (u16*)((u8*)card->workArea + (3 + 0) * CARD_SYSTEM_BLOCK_SIZE);
|
||||
fat[1] = (u16*)((u8*)card->workArea + (3 + 1) * CARD_SYSTEM_BLOCK_SIZE);
|
||||
|
||||
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);
|
||||
}
|
||||
@@ -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);
|
||||
}
|
||||
@@ -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);
|
||||
}
|
||||
@@ -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);
|
||||
}
|
||||
@@ -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;
|
||||
}
|
||||
@@ -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);
|
||||
}
|
||||
@@ -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);
|
||||
}
|
||||
@@ -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);
|
||||
}
|
||||
@@ -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);
|
||||
}
|
||||
@@ -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);
|
||||
}
|
||||
@@ -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
Reference in New Issue
Block a user